-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathmatrix-extra.lisp
More file actions
384 lines (342 loc) · 12.3 KB
/
matrix-extra.lisp
File metadata and controls
384 lines (342 loc) · 12.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
;; matrix-extralisp -- Matrix Operations
;; DM/RAL 01/24
;; ----------------------------------------------------
(defpackage #:xmatrix
(:use :common-lisp)
(:export
))
(in-package :xmatrix)
;; -----------------------------------------------------
(defun idn (nrows)
(let ((ans (make-array nrows)))
(loop for ix from 0 below nrows do
(let ((row (make-array nrows
:initial-element 0)))
(setf (cl:aref row ix) 1
(cl:aref ans ix) row)))
ans))
(defun zero-mat (nrows ncols)
(let ((ans (make-array nrows)))
(loop for rix from 0 below nrows do
(setf (aref ans rix) (make-array ncols
:initial-element 0)))
ans))
(defun noise-mat (nrows ncols &key (mean 0.0) (sd 1.0))
(let ((ans (make-array nrows)))
(loop for ix from 0 below nrows do
(setf (cl:aref ans ix) (vm:gnoise ncols :mean mean :sd sd)))
ans))
(defun copy-matrix (mat)
(let ((ans (copy-seq mat)))
(loop for v across mat
for ix from 0
do
(setf (cl:aref ans ix) (copy-seq v)))
ans))
(defun mat-inv (mat &optional mextra)
(let* ((nrows (length mat))
(ncols (length (cl:aref mat 0)))
(idn (idn nrows))
(mat (copy-matrix mat))
(invdet 1)
(mextra (and mextra
(copy-matrix mextra))))
(labels ((sub-scaled-row (dst sf row)
(map-into dst (lambda (a b)
(cl:- a (* sf b)))
dst row)))
(loop for rix from 0 below (min nrows ncols) do
(let* ((row (aref mat rix))
(cix (position-if (complement #'zerop) row)))
(when cix
(let* ((irow (cl:aref idn rix))
(xrow (and mextra
(cl:aref mextra rix)))
(rinv (/ (aref row cix)))
(scaler (um:rcurry #'* rinv)))
(setf invdet (* invdet rinv))
(map-into row scaler row)
(map-into irow scaler irow)
(when mextra
(map-into xrow scaler xrow)
(setf (cl:aref mextra rix) xrow))
(setf (cl:aref mat rix) row
(cl:aref idn rix) irow)
(loop for rrix from 0 below nrows do
(unless (eql rrix rix)
(let ((rr (cl:aref (cl:aref mat rrix) cix)))
(sub-scaled-row (cl:aref mat rrix) rr row)
(sub-scaled-row (cl:aref idn rrix) rr irow)
(when mextra
(sub-scaled-row (cl:aref mextra rrix) rr xrow))
)))
))
)))
(values mat idn (/ invdet) mextra)
))
(defun trn (a)
(let* ((nrows (length a))
(ncols (length (cl:aref a 0)))
(ans (make-array ncols)))
(loop for ix from 0 below ncols do
(let ((v (make-array nrows)))
(loop for jx from 0 below nrows do
(setf (cl:aref v jx) (cl:aref (cl:aref a jx) ix)))
(setf (cl:aref ans ix) v)))
ans))
(defun dot-prod (a b)
(reduce #'cl:+ (map 'vector #'* a b)))
(defun mat-mul (a b)
(let* ((nrows (length a))
(bt (trn b))
(ncols (length bt))
(ans (make-array nrows)))
(loop for rix from 0 below nrows do
(let ((v (make-array ncols))
(row (cl:aref a rix)))
(loop for cix from 0 below ncols do
(setf (cl:aref v cix)
(dot-prod row (cl:aref bt cix))))
(setf (cl:aref ans rix) v)))
ans))
(defun mat-left (m ncols)
(let* ((nrows (length m))
(ans (make-array nrows)))
(loop for rix from 0 below nrows do
(let* ((v (cl:aref m rix))
(row (make-array ncols
:initial-element 0)))
(replace row v)
(setf (cl:aref ans rix) row)))
ans))
(defun mat-right (m ncols)
(let* ((nrows (length m))
(ans (make-array nrows)))
(loop for rix from 0 below nrows do
(let* ((v (cl:aref m rix))
(vcols (length v))
(start2 (max 0 (cl:- vcols ncols)))
(row (make-array ncols
:initial-element 0)))
(replace row v :start2 start2)
(setf (cl:aref ans rix) row)))
ans))
(defun mat-top (m nrows)
(let* ((ans (make-array nrows))
(mrows (length m))
(ncols (length (cl:aref m 0))))
(loop for rix from 0 below (min nrows mrows) do
(setf (cl:aref ans rix) (copy-seq (cl:aref m rix))))
(loop for rix from (min nrows mrows) below nrows do
(setf (cl:aref ans rix) (make-array ncols
:initial-element 0)))
ans))
(defun mat-bottom (m nrows)
(let* ((ans (make-array nrows))
(mrows (length m))
(ncols (length (cl:aref m 0)))
(start (max 0 (cl:- mrows nrows))))
(loop for rix from 0 below (min nrows mrows) do
(setf (cl:aref ans rix) (copy-seq (cl:aref m (cl:+ start rix)))))
(loop for rix from (min nrows mrows) below nrows do
(setf (cl:aref ans rix) (make-array ncols
:initial-element 0)))
ans))
(defun normalize-matrix (m)
(let* ((nrows (length m))
(ncols (reduce #'max (map 'vector #'length m)))
(ans (make-array nrows))
(m (coerce m 'vector)))
(loop for rix from 0 below nrows do
(let ((v (make-array ncols
:initial-element 0))
(mv (cl:aref m rix)))
(replace v (coerce mv 'vector))
(setf (cl:aref ans rix) v)))
ans))
(defun matrix-section (m &key
(start-row 0)
(start-col 0)
nrows ncols)
(let* ((nrows (or nrows
(length m)))
(ncols (or ncols
(length (cl:aref m 0))))
(ans (make-array nrows)))
(loop for rix from 0 below (min nrows (length m)) do
(let ((v (make-array ncols
:initial-element 0)))
(replace v (cl:aref m (cl:+ start-row rix)) :start2 start-col)
(setf (cl:aref ans rix) v)))
(loop for rix from (length m) below nrows do
(setf (cl:aref ans rix) (make-array ncols
:initial-element 0)))
ans))
(defun adjust-matrix (m nrows ncols)
(let ((mrows (length m))
(ans (make-array nrows)))
(loop for rix from 0 below (min nrows mrows) do
(let ((v (make-array ncols
:initial-element 0)))
(replace v (cl:aref m rix))
(setf (cl:aref ans rix) v)))
(loop for rix from mrows below nrows do
(setf (cl:aref ans rix) (make-array ncols
:initial-element 0)))
ans))
(defun adjoin-rows (m1 m2)
(let* ((nrows1 (length m1))
(nrows2 (length m2))
(ncols1 (length (cl:aref m1 0)))
(ncols2 (length (cl:aref m2 0)))
(ans (make-array (cl:+ nrows1 nrows2))))
(loop for rix from 0 below nrows1 do
(let ((v (make-array (max ncols1 ncols2)
:initial-element 0)))
(replace v (cl:aref m1 rix))
(setf (cl:aref ans rix) v)))
(loop for rix from 0 below nrows2 do
(let ((v (make-array (max ncols1 ncols2)
:initial-element 0)))
(replace v (cl:aref m2 rix))
(setf (cl:aref ans (cl:+ rix nrows1)) v)))
ans))
(defun adjoin-cols (m1 m2)
(let* ((nrows1 (length m1))
(nrows2 (length m2))
(ncols1 (length (cl:aref m1 0)))
(ncols2 (length (cl:aref m2 0)))
(ans (make-array (max nrows1 nrows2))))
(loop for rix from 0 below (min nrows1 nrows2) do
(let ((v (make-array (cl:+ ncols1 ncols2))))
(replace v (cl:aref m1 rix))
(replace v (cl:aref m2 rix) :start1 ncols1)
(setf (cl:aref ans rix) v)))
(cond ((> nrows1 nrows2)
(loop for rix from nrows2 below nrows1 do
(let ((v (make-array (cl:+ ncols1 ncols2)
:initial-element 0)))
(replace v (cl:aref m1 rix))
(setf (cl:aref ans rix) v))))
((< nrows1 nrows2)
(loop for rix from nrows1 below nrows2 do
(let ((v (make-array (cl:+ ncols1 ncols2)
:initial-element 0)))
(replace v (cl:aref m1 rix) :start1 ncols1)
(setf (cl:aref ans rix) v)))) )
ans))
(defun sw-cols (m col1 col2)
(let* ((ans (copy-matrix m))
(nrows (length ans)))
(loop for rix from 0 below nrows do
(let* ((row (aref ans rix))
(x (aref row col1)))
(setf (aref row col1) (aref row col2)
(aref row col2) x
(aref ans rix) row)
))
ans))
(defun sw-rows (m row1 row2)
(let* ((ans (copy-matrix m))
(v (aref ans row1)))
(setf (aref ans row1) (aref ans row2)
(aref ans row2) v)
ans))
(defun mat+ (m1 m2)
(map 'vector (lambda (row1 row2)
(map 'vector #'+ row1 row2))
m1 m2))
(defun mat- (m1 m2)
(map 'vector (lambda (row1 row2)
(map 'vector #'- row1 row2))
m1 m2))
(defun mat-neg (m)
(map 'vector (lambda (row)
(map 'vector #'- row))
m))
(defun mat-scale (m sf)
(map 'vector (lambda (row)
(map 'vector (um:rcurry #'* sf) row))
m))
#|
(let* ((m (noise-mat 3 3)))
(list m (mat-left (mat-top m 2) 2)))
(let* ((mat (noise-mat 3 4))
(v (vector 1 2 3)))
(multiple-value-bind (_ vinv inv det)
(mat-inv mat v)
(list
:mat mat
:v v
:inv inv
:vinv vinv
:det det
:prod (mat-mul mat inv))))
(normalize-matrix '((1 2) (2 3 4)))
(let* ((m (noise-mat 4 4))
(mx (matrix-section m
:start-row 1
:start-col 1
:nrows 2
:ncols 2)))
(list m mx))
(let* ((m (noise-mat 2 2)))
(adjust-matrix m 3 4))
(let* ((m1 #(#(1 2 3)))
(m2 #(#(4 6))))
(adjoin-cols (trn m1) (trn m2)))
(adjust-matrix (trn #(#(1 1 2))) 3 3)
(let* ((mat-a #(#(3 6 6 3 9) #(6 12 13 0 3))))
(mat-inv mat-a))
(let* ((a #(#(1 0 -3 0 2 -8)
#(0 1 5 0 -1 4)
#(0 0 0 1 7 -9)
#(0 0 0 0 0 0))))
(mat-mul (trn a) #(#(0 0 1 0 0 0)
#(0 0 0 0 1 0)
#(0 0 0 0 0 1)))))
x1 = 3 x3 - 2 x5 + 8 x6
x2 = -5 x3 + x5 - 4 x6
x3
x4 = -7 x5 + 9 x6
x5
x6
(let* ((a #(#(1 0 -3 0 2 -8)
#(0 1 5 0 -1 4)
#(0 0 0 1 7 -9)
#(0 0 0 0 0 0))))
(mat-mul a (trn #(#( 3 -5 1 0 0 0)
#(-2 1 0 -7 1 0)
#( 8 -4 0 9 0 1)))))
(let* ((a #(#(1 0 -3 0 2 -8)
#(0 1 5 0 -1 4)
#(0 0 0 1 7 -9)
#(0 0 0 0 0 0))))
(mat-mul a (trn #(#(0 0 0 0 0 1)))))
(let* ((a #(#(2 3 5)
#(1 4 7))))
(mat-inv (adjoin-cols a (trn #(#(23 30))))))
(let* ((a #(#(2 3 5)
#(1 4 7))))
(mat-mul a (trn #(#(1 2 3)))))
(let* ((a #(#(2 3 5)
#(1 4 7)))
(s (trn #(#(1 2 3))))
(p (mat-mul a s))
(noise (trn #(#(10 -23))))
(pn (mat+ p noise))
(r #(#(2 1))))
(print a)
(print s)
(print p)
(print (mat-mul r pn))
(print (mat-mul r a))
(mat- (mat-mul r pn) (mat-mul (mat-mul r a) (valias 0))))
(defun valias (x3)
(trn (vector
(vector (+ 2/5 (* 1/5 x3))
(- 37/5 (* 9/5 x3))
x3))))
(valias 0)
|#
;; -----------------------------------------------------