| Paste number 78132: | macrolet confusion |
| Pasted by: | rswarbrick |
| When: | 1 year, 4 months ago |
| Share: | Tweet this! | http://paste.lisp.org/+1OAC |
| Channel: | #lisp |
| Paste contents: |
(defun add-row/column (mx i k mult row? width-or-height)
"Set MX(I,) or MX(,I) (depending on ROW?) to be MX(I,)+MULT*MX(K,) or
similarly for columns. Takes WIDTH-OR-HEIGHT to know over which indices to
iterate."
(declare (optimize (debug 3)
(speed 0)
(safety 3)))
(macrolet ((r/c-element (index subindex by-row?)
(if by-row?
`(aref mx ,index ,subindex)
`(aref mx ,subindex ,index))))
(loop
for j from 0 to (1- width-or-height)
doing (setf (r/c-element i j row?)
(+ (r/c-element i j row?) (* mult (r/c-element k j row?))))))
(values))
(let ((mat (make-array
'(4 4)
:initial-contents '((1 0 0 0) (0 2 5 4) (0 1 5 6) (0 3 1 2)))))
(add-row/column mat 0 1 1 nil 4)
mat)
;; I would expect a matrix like '((1 0 0 0) (2 2 5 4) (1 1 5 6) (3 3 1 2)) to
;; be the result of this (add the 1st column to the 0th column). Instead, the
;; code appears to completely ignore ROW? and add by rows.
;;
;; SBCL complains as follows:
;;
;; ; compiling (DEFUN ADD-ROW/COLUMN ...)
;;
;; ; file: /tmp/file6XuwAV.lisp
;; ; in: DEFUN ADD-ROW/COLUMN
;; ; (DEFUN MAXIMA::ADD-ROW/COLUMN
;; ; (MAXIMA::MX MAXIMA::I MAXIMA::K MAXIMA::MULT MAXIMA::ROW?
;; ; MAXIMA::WIDTH-OR-HEIGHT)
;; ; "Set MX(I,) or MX(,I) (depending on ROW?) to be MX(I,)+MULT*MX(K,) or
;; ; similarly for columns. Takes WIDTH-OR-HEIGHT to know over which indices to
;; ; iterate."
;; ; (DECLARE (OPTIMIZE (DEBUG 3) (SPEED 0) (SAFETY 3)))
;; ; (MACROLET ((MAXIMA::R/C-ELEMENT
;; ; (MAXIMA::INDEX MAXIMA::SUBINDEX MAXIMA::BY-ROW?)
;; ; (IF MAXIMA::BY-ROW? `# `#)))
;; ; (LOOP MAXIMA::FOR MAXIMA::J MAXIMA::FROM 0 MAXIMA::TO
;; ; (1- MAXIMA::WIDTH-OR-HEIGHT) MAXIMA::DOING
;; ; (SETF (MAXIMA::R/C-ELEMENT MAXIMA::I MAXIMA::J MAXIMA::ROW?)
;; ; (+ # #))))
;; ; (VALUES))
;; ; --> PROGN EVAL-WHEN
;; ; ==>
;; ; (SB-IMPL::%DEFUN 'MAXIMA::ADD-ROW/COLUMN
;; ; (SB-INT:NAMED-LAMBDA MAXIMA::ADD-ROW/COLUMN
;; ; (MAXIMA::MX MAXIMA::I MAXIMA::K
;; ; MAXIMA::MULT MAXIMA::ROW?
;; ; MAXIMA::WIDTH-OR-HEIGHT)
;; ; (DECLARE
;; ; (OPTIMIZE (DEBUG 3) (SPEED 0)
;; ; (SAFETY 3)))
;; ; (BLOCK MAXIMA::ADD-ROW/COLUMN
;; ; (MACROLET (#)
;; ; (LOOP MAXIMA::FOR MAXIMA::J
;; ; MAXIMA::FROM 0 MAXIMA::TO #
;; ; MAXIMA::DOING #))
;; ; (VALUES)))
;; ; "Set MX(I,) or MX(,I) (depending on ROW?) to be MX(I,)+MULT*MX(K,) or
;; ; similarly for columns. Takes WIDTH-OR-HEIGHT to know over which indices to
;; ; iterate."
;; ; 'NIL (SB-C:SOURCE-LOCATION))
;; ;
;; ; caught STYLE-WARNING:
;; ; The variable ROW? is defined but never used.
;; ;
;; ; compilation unit finished
;; ; caught 1 STYLE-WARNING condition
;; STYLE-WARNING: redefining ADD-ROW/COLUMN in DEFUNAnnotations for this paste:
| Annotation number 1: | defining macro |
| Pasted by: | rswarbrick |
| When: | 1 year, 4 months ago |
| Share: | Tweet this! | http://paste.lisp.org/+1OAC/1 |
| Paste contents: |
(defmacro define-row/column-adder (row?)
(flet ((r/c-element (index subindex)
(if row?
`(aref mx ,index ,subindex)
`(aref mx ,subindex ,index))))
`(defun ,(intern (concatenate 'string "ADD-" (if row? "ROW" "COLUMN")))
(mx i k mult width-or-height)
"Set MX(I,) or MX(,I) to be MX(I,)+MULT*MX(K,) or similarly for
columns. Takes WIDTH-OR-HEIGHT to know over which indices to iterate."
(loop
for j from 0 to (1- width-or-height)
doing (setf ,(r/c-element 'i 'j)
(+ ,(r/c-element 'i 'j)
(* mult ,(r/c-element 'k 'j)))))
(values))))
| Annotation number 2: | the sensible way to do it? |
| Pasted by: | rswarbrick |
| When: | 1 year, 4 months ago |
| Share: | Tweet this! | http://paste.lisp.org/+1OAC/2 |
| Paste contents: |
(defun add-row/column (mx i k mult width-or-height row?)
"Set MX(I,) or MX(,I) to be MX(I,)+MULT*MX(K,) or similarly for
columns. Takes WIDTH-OR-HEIGHT to know over which indices to iterate."
(loop
for j from 0 to (1- width-or-height)
doing
(if row?
(setf (aref mx i j)
(+ (aref mx i j) (* mult (aref mx k j))))
(setf (aref mx j i)
(+ (aref mx j i) (* mult (aref mx j k))))))
(values))