1 ;; dgeqrf.lisp -- Maxima interface to lapack::dgeqrf
2 ;; copyright 2011 by Robert Dodier
3 ;; I release this work under terms of the GNU General Public License.
6 ;; dgeqrf(a) computes QR factorization of m-by-n Maxima matrix,
7 ;; where m and n might be equal or unequal.
12 (multiple-value-bind (a-nrow a-ncol
)
13 (maxima-matrix-dims a
)
15 ((a-mat (lapack-lispify-matrix a a-nrow a-ncol
))
16 (work (make-array 1 :element-type
'flonum
))
17 (tau (make-array (min a-nrow a-ncol
) :element-type
'flonum
)))
19 ;; First call DGEQRF with LWORK = -1 to find optimal block size NB.
20 ;; Use that to compute LWORK.
22 (multiple-value-bind (foo-1 foo-2 foo-3 foo-4 foo-5 foo-6 foo-7 foo-8
)
23 (lapack::dgeqrf a-nrow a-ncol a-mat a-nrow tau work -
1 0)
24 (declare (ignore foo-1 foo-2 foo-3 foo-4 foo-5 foo-6 foo-7 foo-8
))
27 ((lwork (floor (aref work
0)))
28 (work (make-array lwork
:element-type
'flonum
)))
30 (multiple-value-bind (foo-1 foo-2 foo-3 foo-4 foo-5 foo-6 foo-7 z-info
)
31 (lapack::dgeqrf a-nrow a-ncol a-mat a-nrow tau work lwork
0)
32 (declare (ignore foo-1 foo-2 foo-3 foo-4 foo-5 foo-6 foo-7
))
36 (merror "dgeqrf: ~M-th argument has an illegal value." (- z-info
)))
38 (dgeqrf-unpack a-nrow a-ncol a-mat tau
)))))))))
40 (defun dgeqrf-unpack (a-nrow a-ncol a-mat tau
)
42 ((r (dgeqrf-unpack-r a-nrow a-ncol a-mat
))
43 (q (dgeqrf-unpack-q a-nrow a-ncol a-mat tau
)))
46 (defun dgeqrf-unpack-r (a-nrow a-ncol a-mat
)
50 (r-mat (make-array (* r-ncol r-nrow
) :element-type
'flonum
51 :initial-element
0e0
)))
56 ((a-ij (+ (* j a-nrow
) i
))
57 (r-ij (+ (* j r-nrow
) i
)))
58 (setf (aref r-mat r-ij
) (aref a-mat a-ij
))))))
59 (lapack-maxify-matrix r-nrow r-ncol r-mat
)))
61 (defun dgeqrf-unpack-q (a-nrow a-ncol a-mat tau
)
62 (let ((q-mat (make-array (* a-nrow a-nrow
) :element-type
'flonum
63 :initial-element
0e0
)))
65 (setf (aref q-mat
(+ (* i a-nrow
) i
)) 1e0
))
66 (dotimes (i (min a-nrow a-ncol
))
67 (let ((h-mat-i (dgeqrf-h i tau a-nrow a-mat
)))
68 (dgeqrf-multiply-into a-nrow q-mat h-mat-i
)))
69 (lapack-maxify-matrix a-nrow a-nrow q-mat
)))
71 (defun dgeqrf-h (i tau a-nrow a-mat
)
72 (let ((h-mat (make-array (* a-nrow a-nrow
) :element-type
'flonum
)))
76 ((v-j (dgeqrf-v i j a-nrow a-mat
))
77 (v-k (dgeqrf-v i k a-nrow a-mat
))
78 (foo (* (aref tau i
) v-j v-k
))
79 (bar (if (= j k
) (1+ (- foo
)) (- foo
))))
80 (setf (aref h-mat
(+ (* k a-nrow
) j
)) bar
))))
83 (defun dgeqrf-v (i j a-nrow a-mat
)
86 ((> j i
) (aref a-mat
(+ (* i a-nrow
) j
)))
89 (defun dgeqrf-multiply-into (n mat-1 mat-2
)
90 (let ((row (make-array n
:element-type
'flonum
:initial-element
0e0
)))
93 (setf (aref row j
) (dgeqrf-inner-product n mat-1 mat-2 i j
)))
95 (setf (aref mat-1
(+ (* j n
) i
)) (aref row j
))))))
97 (defun dgeqrf-inner-product (n mat-1 mat-2 i j
)
100 (setq sum
(+ sum
(* (aref mat-1
(+ (* k n
) i
)) (aref mat-2
(+ (* j n
) k
))))))