Saltar al contenido

Multiplicación de matrices en Common Lisp

Mario, parte de este gran equipo de trabajo, nos ha hecho el favor de redactar esta reseña ya que controla a la perfección este tema.

Solución:

El problema habitual es que la aritmética flotante, aquí con flotantes dobles, (independiente del código circundante como la multiplicación de matrices) se repite.

Generalmente, lo primero que se debe hacer con SBCL en tales casos:

Poner el código en un archivo y compilarlo.

El compilador luego generará muchos problemas de optimización, dado que uno compila para la velocidad. A continuación, deberá examinar las notas y ver qué puede hacer.

Aquí por ejemplo el LOOP sum carece de información de tipo.

en realidad hay un LOOP sintaxis para declarar el tipo de la variable suma. No sé si SBCL se aprovecha de eso:

(loop repeat 10
      sum 1.0d0 of-type double-float)

SBCL 1.3.0 en ARM de 32 bits para su código:

* (compile-file "/tmp/test.lisp")

; compiling file "/tmp/test.lisp" (written 13 DEC 2015 11:34:26 AM):
; compiling (DEFUN MATRIX-MUL ...)
; file: /tmp/test.lisp

1)

; in: DEFUN MATRIX-MUL
;     (SETF (AREF DEST I)
;             (LOOP FOR J BELOW COLS
;                   SUM (THE DOUBLE-FLOAT (* # #))))
; --> LET* FUNCALL SB-C::%FUNCALL (SETF AREF)
; ==>
;   (SB-KERNEL:HAIRY-DATA-VECTOR-SET ARRAY SB-INT:INDEX SB-C::NEW-VALUE)
;
; note: unable to
;   avoid runtime dispatch on array element type
; due to type uncertainty:
;   The first argument is a (VECTOR DOUBLE-FLOAT), not a SIMPLE-ARRAY.

2)

;     (AREF MATRIX I J)
; --> LET*
; ==>
;   (SB-KERNEL:HAIRY-DATA-VECTOR-REF ARRAY SB-INT:INDEX)
;
; note: unable to
;   avoid runtime dispatch on array element type
; due to type uncertainty:
;   The first argument is a (ARRAY DOUBLE-FLOAT (* *)), not a SIMPLE-ARRAY.

3)

;     (AREF VECTOR J)
; ==>
;   (SB-KERNEL:HAIRY-DATA-VECTOR-REF ARRAY SB-INT:INDEX)
;
; note: unable to
;   avoid runtime dispatch on array element type
; due to type uncertainty:
;   The first argument is a (VECTOR DOUBLE-FLOAT), not a SIMPLE-ARRAY.

4)

;     (LOOP FOR J BELOW COLS
;           SUM (THE DOUBLE-FLOAT (* (AREF MATRIX I J) (AREF VECTOR J))))
; --> BLOCK LET SB-LOOP::WITH-SUM-COUNT LET SB-LOOP::LOOP-BODY TAGBODY SETQ THE
; ==>
;   (+ #:LOOP-SUM-8 (THE DOUBLE-FLOAT (* (AREF MATRIX I J) (AREF VECTOR J))))
;
; note: unable to
;   optimize
; due to type uncertainty:
;   The first argument is a NUMBER, not a (COMPLEX SINGLE-FLOAT).
;
; note: unable to
;   optimize
; due to type uncertainty:
;   The first argument is a NUMBER, not a (COMPLEX DOUBLE-FLOAT).

5)

; --> BLOCK LET SB-LOOP::WITH-SUM-COUNT LET SB-LOOP::LOOP-BODY TAGBODY WHEN IF
; --> >= OR LET IF OR THE = IF
; ==>
;   (= SB-C::X SB-C::Y)
;
; note: unable to open code because: The operands might not be the same type.

6)

;     (DOTIMES (I ROWS)
;       (SETF (AREF DEST I)
;               (LOOP FOR J BELOW COLS
;                     SUM (THE DOUBLE-FLOAT #))))
; --> DO BLOCK LET TAGBODY UNLESS IF >= IF
; ==>
;   (< SB-C::X SB-C::Y)
;
; note: forced to do static-fun Two-arg-< (cost 53)
;       unable to do inline fixnum comparison (cost 4) because:
;       The second argument is a INTEGER, not a FIXNUM.
;       unable to do inline (signed-byte 32) comparison (cost 6) because:
;       The second argument is a INTEGER, not a (SIGNED-BYTE 32).
;       etc.

7)

;     (LOOP FOR J BELOW COLS
;           SUM (THE DOUBLE-FLOAT (* (AREF MATRIX I J) (AREF VECTOR J))))
; --> BLOCK LET SB-LOOP::WITH-SUM-COUNT LET SB-LOOP::LOOP-BODY TAGBODY WHEN IF
; --> >= OR LET > IF
; ==>
;   (> SB-C::X SB-C::Y)
;
; note: forced to do static-fun Two-arg-> (cost 53)
;       unable to do inline fixnum comparison (cost 4) because:
;       The second argument is a REAL, not a FIXNUM.
;       unable to do inline (signed-byte 32) comparison (cost 6) because:
;       The second argument is a REAL, not a (SIGNED-BYTE 32).
;       etc.

8)

; --> BLOCK LET SB-LOOP::WITH-SUM-COUNT LET SB-LOOP::LOOP-BODY TAGBODY SETQ THE
; ==>
;   (+ #:LOOP-SUM-8 (THE DOUBLE-FLOAT (* (AREF MATRIX I J) (AREF VECTOR J))))
;
; note: forced to do static-fun Two-arg-+ (cost 53)
;       unable to do inline float arithmetic (cost 2) because:
;       The first argument is a NUMBER, not a DOUBLE-FLOAT.
;       The result is a (VALUES NUMBER &OPTIONAL), not a (VALUES DOUBLE-FLOAT
;                                                                &REST T).
;
; note: doing float to pointer coercion (cost 13), for:
;       the second argument of static-fun Two-arg-+
;
; compilation unit finished
;   printed 10 notes

Recuerda dar recomendación a esta reseña si si solucionó tu problema.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 3.5)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *