From: Tassilo Horn
Subject: Problems with make-array
Date: 
Message-ID: <87lkrig4e6.fsf@baldur.nicundtas.de>
Hi all,

I wrote this function for matrix multiplication:

--8<---------------cut here---------------start------------->8---
(defun multiply-matrices (m1 m2)
  "Multiplies the given two matrices (2-dimensional arrays)."
  (if (not (eql (array-dimension m1 1)
                (array-dimension m2 0)))
      (error "Dimension mismatch: you need (m x n) * (n x o)")
      (progn
        (let* ((m (array-dimension m1 0))
               (o (car (last (array-dimensions m2))))
               (result (make-array (list m o))))
          (loop for i from 0 below m do
               (loop for j from 0 below o do
                    (setf (aref result i j)
                          (scalar-product (matrix-row m1 i)
                                          (matrix-col m2 j)))))
          result))))
--8<---------------cut here---------------end--------------->8---

If I do this

,----
| CL-USER> *m1*
| #2A((1 2 3) (4 5 6))
| CL-USER> *m2*
| #2A((6 -1) (3 2) (0 -3))
| CL-USER> (multiply-matrices *m1* *m2*)
`----

I get this error:

,----
| There are 2 elements in the :INITIAL-CONTENTS, but the vector length
| is 3.  [Condition of type SIMPLE-ERROR]
| 
| Restarts:
|   0: [ABORT-REQUEST] Abort handling SLIME request.
|   1: [TERMINATE-THREAD] Terminate this thread 
|                         (#<THREAD "repl-thread" {ACAC8F9}>)
| 
| Backtrace:
|   0: (MAKE-ARRAY 3)
|       Locals:
|         SB-DEBUG::ARG-0 = 5
|         SB-DEBUG::ARG-1 = 3
|   1: (MULTIPLY-MATRICES #2A((1 2 3) (4 5 6)) #2A((6 -1) (3 2) (0 -3)))
|       Locals:
|         SB-DEBUG::ARG-0 = #2A((1 2 3) (4 5 6))
|         SB-DEBUG::ARG-1 = #2A((6 -1) (3 2) (0 -3))
|   2: (SB-INT:EVAL-IN-LEXENV (MULTIPLY-MATRICES *M1* *M2*) 
|                             #<NULL-LEXENV>)
`----

If I print m and o before the call to make-array I can see that both of
them are 2, so the call should be (make-array (list 2 2)) which works at
the REPL.

What am I doing wrong?

Bye,
Tassilo
-- 
A morning without coffee is like something without something else.

From: Giorgos Pontikakis
Subject: Re: Problems with make-array
Date: 
Message-ID: <87d5cuejlz.fsf@artemis.extherm.gr>
I could not test your code, you did not provide the definitions for
scalar-product, matrix-row and matrix-column.

Anyway, this works for me, if it is of any help:

(defgeneric mat* (a b)
  (:documentation
   "Multiplies two arrays or an array with a scalar."))


(defmethod mat* ((a array) (b array))
  (let* ((rows (array-dimension a 0))
         (cols (array-dimension b 1))
         (c (make-array (list rows cols))))
    (dotimes (i rows c)
      (dotimes (j cols)
        (setf (aref c i j)
              (sum (map 'vector #'*
                        (arow a i)
                        (acol b j))))))))


(defmethod mat* ((a number) (b array))
  (let ((n (array-total-size b))
        (c (make-array (array-dimensions b))))
    (dotimes (i n c)
      (setf (row-major-aref c i)
            (* a (row-major-aref b i))))))


where sum is defined as:

(defun sum (seq)
  "Sum of the elements of a sequence."
  (reduce #'+ seq))

Disclaimer: I am new to lisp.

Regards,

-- Giorgos
From: Giorgos Pontikakis
Subject: Re: Problems with make-array
Date: 
Message-ID: <878xniejd4.fsf@artemis.extherm.gr>
Giorgos Pontikakis <···@freemail.gr> writes:

> I could not test your code, you did not provide the definitions for
> scalar-product, matrix-row and matrix-column.
>
> Anyway, this works for me, if it is of any help:
>
> (defgeneric mat* (a b)
>   (:documentation
>    "Multiplies two arrays or an array with a scalar."))
>
>
> (defmethod mat* ((a array) (b array))
>   (let* ((rows (array-dimension a 0))
>          (cols (array-dimension b 1))
>          (c (make-array (list rows cols))))
>     (dotimes (i rows c)
>       (dotimes (j cols)
>         (setf (aref c i j)
>               (sum (map 'vector #'*
>                         (arow a i)
>                         (acol b j))))))))
>
>
> (defmethod mat* ((a number) (b array))
>   (let ((n (array-total-size b))
>         (c (make-array (array-dimensions b))))
>     (dotimes (i n c)
>       (setf (row-major-aref c i)
>             (* a (row-major-aref b i))))))
>
>
> where sum is defined as:
>
> (defun sum (seq)
>   "Sum of the elements of a sequence."
>   (reduce #'+ seq))
>
> Disclaimer: I am new to lisp.
>
> Regards,
>
> -- Giorgos

Sorry, I just realised that I forgot to include the following
definitions in my post:

(defun arow (arr-in i)
  "Returns a vector which is a part of a 2D array"
  (let* ((ncols (array-dimension arr-in 1))
	 (result (make-array ncols)))
    (dotimes (j ncols result)
      (setf (svref result j) (aref arr-in i j)))))

(defun acol (arr-in j)
  "Returns a vector which is a column of a 2D array"
  (let* ((nrows (array-dimension arr-in 0))
	 (result (make-array nrows)))
    (dotimes (i nrows result)
      (setf (svref result i) (aref arr-in i j)))))

Bye,

-- Giorgos
From: Tassilo Horn
Subject: Re: Problems with make-array
Date: 
Message-ID: <87zmfxu2rl.fsf@baldur.nicundtas.de>
Hi Giorgos,

some minutes after I posted this question I figured out the problem
(with the help of some guys on #lisp). The make-array in
multiply-matrices wasn't the problem, it was some more or less trivial
thing in another function, but the backtrace was kinda misleading.

Thanks anyway for you code, I'll have a look at it.

Bye,
Tassilo
-- 
My opinions may have changed, but not the fact that I am right.
From: Pascal Bourguignon
Subject: Re: Problems with make-array
Date: 
Message-ID: <87ejx92y7y.fsf@thalassa.informatimago.com>
Tassilo Horn <········@uni-koblenz.de> writes:

> Hi Giorgos,
>
> some minutes after I posted this question I figured out the problem
> (with the help of some guys on #lisp). The make-array in
> multiply-matrices wasn't the problem, it was some more or less trivial
> thing in another function, but the backtrace was kinda misleading.

(proclaim '(optimize (debug 3) (speed 0) (space 0)))

> Thanks anyway for you code, I'll have a look at it.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"By filing this bug report you have challenged the honor of my
family. Prepare to die!"
From: Barry Margolin
Subject: Re: Problems with make-array
Date: 
Message-ID: <barmar-AA6EEC.23595527062006@comcast.dca.giganews.com>
In article <··············@baldur.nicundtas.de>,
 Tassilo Horn <········@uni-koblenz.de> wrote:

> Hi all,
> 
> I wrote this function for matrix multiplication:
> 
> --8<---------------cut here---------------start------------->8---
> (defun multiply-matrices (m1 m2)
>   "Multiplies the given two matrices (2-dimensional arrays)."
>   (if (not (eql (array-dimension m1 1)
>                 (array-dimension m2 0)))
>       (error "Dimension mismatch: you need (m x n) * (n x o)")
>       (progn
>         (let* ((m (array-dimension m1 0))
>                (o (car (last (array-dimensions m2))))
>                (result (make-array (list m o))))
>           (loop for i from 0 below m do
>                (loop for j from 0 below o do
>                     (setf (aref result i j)
>                           (scalar-product (matrix-row m1 i)
>                                           (matrix-col m2 j)))))
>           result))))
> --8<---------------cut here---------------end--------------->8---
> 
> If I do this
> 
> ,----
> | CL-USER> *m1*
> | #2A((1 2 3) (4 5 6))
> | CL-USER> *m2*
> | #2A((6 -1) (3 2) (0 -3))
> | CL-USER> (multiply-matrices *m1* *m2*)
> `----
> 
> I get this error:

Unless either SCALAR-PRODUCT or MATRIX-ROW is a macro or inline 
function, I don't see any way that the function above could produce this 
error.  The backtrace shows MAKE-ARRAY being called with an integer 
argument, but the only call to MAKE-ARRAY above passes a two-element 
list as the argument.

> 
> ,----
> | There are 2 elements in the :INITIAL-CONTENTS, but the vector length
> | is 3.  [Condition of type SIMPLE-ERROR]
> | 
> | Restarts:
> |   0: [ABORT-REQUEST] Abort handling SLIME request.
> |   1: [TERMINATE-THREAD] Terminate this thread 
> |                         (#<THREAD "repl-thread" {ACAC8F9}>)
> | 
> | Backtrace:
> |   0: (MAKE-ARRAY 3)
> |       Locals:
> |         SB-DEBUG::ARG-0 = 5
> |         SB-DEBUG::ARG-1 = 3
> |   1: (MULTIPLY-MATRICES #2A((1 2 3) (4 5 6)) #2A((6 -1) (3 2) (0 -3)))
> |       Locals:
> |         SB-DEBUG::ARG-0 = #2A((1 2 3) (4 5 6))
> |         SB-DEBUG::ARG-1 = #2A((6 -1) (3 2) (0 -3))
> |   2: (SB-INT:EVAL-IN-LEXENV (MULTIPLY-MATRICES *M1* *M2*) 
> |                             #<NULL-LEXENV>)
> `----
> 
> If I print m and o before the call to make-array I can see that both of
> them are 2, so the call should be (make-array (list 2 2)) which works at
> the REPL.
> 
> What am I doing wrong?
> 
> Bye,
> Tassilo

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Christophe Rhodes
Subject: Re: Problems with make-array
Date: 
Message-ID: <sqsllpby84.fsf@cam.ac.uk>
Barry Margolin <······@alum.mit.edu> writes:

> Unless either SCALAR-PRODUCT or MATRIX-ROW is a macro or inline 
> function, I don't see any way that the function above could produce this 
> error.  The backtrace shows MAKE-ARRAY being called with an integer 
> argument, but the only call to MAKE-ARRAY above passes a two-element 
> list as the argument.

A third way that the backtrace can look like this (and, I believe, the
actual reason) is if MATRIX-ROW or SCALAR-PRODUCT calls MAKE-ARRAY in
tail position, and the implementation has merged the tail call.

Christophe
From: Tassilo Horn
Subject: Re: Problems with make-array
Date: 
Message-ID: <87veqlu2n9.fsf@baldur.nicundtas.de>
Christophe Rhodes <·····@cam.ac.uk> writes:

Hi Christophe,

>> Unless either SCALAR-PRODUCT or MATRIX-ROW is a macro or inline
>> function, I don't see any way that the function above could produce
>> this error. The backtrace shows MAKE-ARRAY being called with an
>> integer argument, but the only call to MAKE-ARRAY above passes a
>> two-element list as the argument.
>
> A third way that the backtrace can look like this (and, I believe, the
> actual reason) is if MATRIX-ROW or SCALAR-PRODUCT calls MAKE-ARRAY in
> tail position, and the implementation has merged the tail call.

Exactly that was the problem. With the help of the guys on #lisp I
finally found the wrong call.

Thanks for your reply,
Tassilo
-- 
A morning without coffee is like something without something else.
From: William James
Subject: Re: Problems with make-array
Date: 
Message-ID: <1151514110.409040.289950@d56g2000cwd.googlegroups.com>
Tassilo Horn wrote:
> Hi all,
>
> I wrote this function for matrix multiplication:
>
> --8<---------------cut here---------------start------------->8---
> (defun multiply-matrices (m1 m2)
>   "Multiplies the given two matrices (2-dimensional arrays)."
>   (if (not (eql (array-dimension m1 1)
>                 (array-dimension m2 0)))
>       (error "Dimension mismatch: you need (m x n) * (n x o)")
>       (progn
>         (let* ((m (array-dimension m1 0))
>                (o (car (last (array-dimensions m2))))
>                (result (make-array (list m o))))
>           (loop for i from 0 below m do
>                (loop for j from 0 below o do
>                     (setf (aref result i j)
>                           (scalar-product (matrix-row m1 i)
>                                           (matrix-col m2 j)))))
>           result))))
> --8<---------------cut here---------------end--------------->8---
>
> If I do this
>
> ,----
> | CL-USER> *m1*
> | #2A((1 2 3) (4 5 6))
> | CL-USER> *m2*
> | #2A((6 -1) (3 2) (0 -3))
> | CL-USER> (multiply-matrices *m1* *m2*)
> `----
>
> I get this error:
>
> ,----
> | There are 2 elements in the :INITIAL-CONTENTS, but the vector length
> | is 3.  [Condition of type SIMPLE-ERROR]
> |
> | Restarts:
> |   0: [ABORT-REQUEST] Abort handling SLIME request.
> |   1: [TERMINATE-THREAD] Terminate this thread
> |                         (#<THREAD "repl-thread" {ACAC8F9}>)
> |
> | Backtrace:
> |   0: (MAKE-ARRAY 3)
> |       Locals:
> |         SB-DEBUG::ARG-0 = 5
> |         SB-DEBUG::ARG-1 = 3
> |   1: (MULTIPLY-MATRICES #2A((1 2 3) (4 5 6)) #2A((6 -1) (3 2) (0 -3)))
> |       Locals:
> |         SB-DEBUG::ARG-0 = #2A((1 2 3) (4 5 6))
> |         SB-DEBUG::ARG-1 = #2A((6 -1) (3 2) (0 -3))
> |   2: (SB-INT:EVAL-IN-LEXENV (MULTIPLY-MATRICES *M1* *M2*)
> |                             #<NULL-LEXENV>)
> `----
>
> If I print m and o before the call to make-array I can see that both of
> them are 2, so the call should be (make-array (list 2 2)) which works at
> the REPL.
>
> What am I doing wrong?

It's somewhat easier in newLISP:

> (set 'A '((1 5)(9 -2)(0 -3)))
((1 5) (9 -2) (0 -3))
> (set 'B '((8 1 2)(4 3 7)))
((8 1 2) (4 3 7))
> (multiply A B)
((28 16 37) (64 3 4) (-12 -9 -21))