1 (in-package :neldermead
)
3 ;; Simple matrix-vector facility. Optimized for staying out of the way.
4 (defmacro with-matrix-dimensions
(varforms &body body
)
5 (let ((form `(progn ,@body
)))
6 (dolist (vform varforms
)
8 `(destructuring-bind ,(car vform
)
9 (array-dimensions ,(cadr vform
))
10 (declare (fixnum ,@(car vform
))
11 (ignorable ,@(car vform
)))
15 (defun ip (v w
&optional
(start 0))
18 (dotimes (i (- l start
))
19 (incf ax
(* (aref v
(+ i start
))
20 (aref w
(+ i start
)))))
23 (defun norm (v &optional
(start 0))
24 (sqrt (ip v v start
)))
26 (defun make-matrix (m n
)
27 (make-array (list m n
)
28 :element-type
'double-float
29 :initial-element
0.0d0
))
31 (defun make-vector (n &key
(initial-element 0.0d0
))
33 :element-type
'double-float
34 :initial-element initial-element
))
36 (defun v*c
(vector constant
)
37 (let* ((n (length vector
))
38 (res (make-vector n
)))
41 (* constant
(aref vector i
))))
45 (assert (= (length v
) (length w
)))
47 (res (make-vector n
)))
54 (defun qr-factorization (mat &key
(with-q t
))
55 (declare (type (simple-array double-float
(* *)) mat
)
56 (optimize (speed 3) (safety 0)))
57 (with-matrix-dimensions (((m n
) mat
))
59 (let ((pq (make-matrix m n
)))
60 (declare (type (simple-array double-float
(* *)) pq
))
61 (dotimes (i (min m n
))
62 (setf (aref pq i i
) 1.0d0
))
65 (loop for i from
0 below
(- m
1) do
66 (loop for j from
(+ i
1) below m do
67 (let ((a (aref mat i i
))
70 (let* ((r (sqrt (+ (* a a
) (* b b
))))
74 (loop for k from i below m do
75 (let ((olda (aref mat i k
))
76 (oldb (aref mat j k
)))
79 (+ (* c olda
) (* s oldb
))
81 (+ (* (- s
) olda
) (* c oldb
)))))
85 (declare (type (simple-array double-float
(* *)) q
))
86 (loop for k from
0 below m do
87 (let ((olda (aref q k i
))
91 (+ (* c olda
) (* s oldb
))
93 (+ (* (- s
) olda
) (* c oldb
))))))))))))