-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdeterminants-examples.lisp
258 lines (198 loc) · 6.94 KB
/
determinants-examples.lisp
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
;;; -*- SYNTAX: COMMON-LISP; MODE: LISP; BASE: 10; PACKAGE: *LISP; -*-
(in-package '*lisp)
;;;; The goal of this exercise is to have a three dimensional
;;;; cubic vp set of arbitrary size, in which, in each processor
;;;; we place a square complex matrix of arbitrary size.
;;;; We then calculate the determinant of each matrix
;;;; in those processors which lie along the main diagonal
;;;; of the cube, and copy this result to all the other
;;;; processors in the X-Y plane determined by the Z
;;;; coordinate of the processor which has computed
;;;; the determinate.
;;;; Define a vp set of unknown size which has a pvar
;;;; which will eventually contain a complex matrix
;;;; of unknown size in each virtual processor.
(def-vp-set complex-cube-vp-set nil
:*defvars
((matrix-pvar))
)
;;;; Here we obtain the matrix we wish to deal with,
;;;; select its main diagonal, calculate the determinate
;;;; in each of the selected processors, and spread the
;;;; result out to every processor in the same XY plane.
(*proclaim '(*defun determinant-of-complex-matrix!!))
(defun main (side-of-cube side-of-matrix)
(*cold-boot)
(get-complex-matrix side-of-cube side-of-matrix)
(*with-vp-set complex-cube-vp-set
(*let ((determinant (!! 0.0)))
(declare (type single-complex-pvar determinant))
(*when (=!! (self-address-grid!! (!! 0))
(self-address-grid!! (!! 1))
(self-address-grid!! (!! 2))
)
(*set determinant (determinant-of-complex-matrix!! matrix-pvar))
(*pset :no-collisions determinant determinant
(cube-from-grid-address!!
(!! 0) (!! 0) (self-address-grid!! (!! 2))
)))
(*set determinant (spread!! determinant 0 0))
(*set determinant (spread!! determinant 1 0))
(ppp determinant :mode :grid :end '(4 4 2) :ordering '(2 0 1))
))
(deallocate-vp-set-processors complex-cube-vp-set)
)
;;;; We first instantiate the complex-cube-vp-set to have
;;;; some defined size. Then we create a complex matrix
;;;; of some defined square size
;;;; and make matrix-pvar contain that array.
;;;; Finally, we initialize the elements of the matrix
;;;; with random values.
(defun get-complex-matrix (side-of-cube side-of-matrix)
(allocate-vp-set-processors
complex-cube-vp-set
(list side-of-cube side-of-cube side-of-cube)
)
(*with-vp-set
complex-cube-vp-set
(progn
;;(with-compile-time-local-property (compile-time-prop *compilep* nil)
(*set matrix-pvar
(make-array!!
(list side-of-matrix side-of-matrix)
:element-type 'single-complex-pvar
)))
(*map
#'(lambda (x)
(*set (the single-complex-pvar x)
(complex!! (!! (the fixnum (random 5))))
))
matrix-pvar
)))
;;;; This proclamation tells the *Lisp compiler what
;;;; type of pvar is returned from the named function.
(*proclaim '(ftype (function (t) single-complex-pvar)
determinant-of-complex-matrix!!
recursive-determinant
))
(*defun determinant-of-complex-matrix!! (complex-square-matrix)
(declare (type (array-pvar (complex single-float) 2) complex-square-matrix))
;; Figure out how large on a side our matrix is.
(let ((matrix-row-size (*array-dimension complex-square-matrix 0)))
(*let ((determinant (!! 0.0)))
(declare (type single-complex-pvar determinant))
(cond
;; A 1-element matrix is its own determinant.
((eql 1 matrix-row-size)
(*set determinant (aref!! complex-square-matrix (!! 0) (!! 0)))
)
;; A two-by-two matrix
;; A B
;; C D
;; has determinant AD - BC
((eql 2 matrix-row-size)
(*set determinant
(-!!
(*!! (aref!! complex-square-matrix (!! 0) (!! 0))
(aref!! complex-square-matrix (!! 1) (!! 1)))
(*!! (aref!! complex-square-matrix (!! 1) (!! 0))
(aref!! complex-square-matrix (!! 0) (!! 1)))
)))
(t
(*set determinant
(recursive-determinant complex-square-matrix matrix-row-size)
))
)
determinant
)))
(defun recursive-determinant (complex-square-matrix matrix-row-size)
;; For more than two dimensions, we use a recursion
;; algorithm. We allocate a complex matrix less by
;; 1 on a side than the original matrix. Then for
;; each element of the top row of the original
;; matrix we copy the appropriate elements into
;; the reduced matrix and recurse.
(*locally
(declare (type (array-pvar (complex single-float) 2) complex-square-matrix))
(let ((reduced-size (1- matrix-row-size))
(sign 1)
)
(*let (reduced-array determinant)
(declare
(type (array-pvar (complex single-float) (reduced-size reduced-size))
reduced-array
))
(declare (type single-complex-pvar determinant))
(*set determinant (!! 0.0))
(dotimes (j matrix-row-size)
nil
(let ((reduced-column-index 0))
nil
(do ((column-index 1 (1+ column-index)))
((= column-index matrix-row-size))
nil
(let ((reduced-row-index 0))
nil
(dotimes (row-index matrix-row-size)
nil
(when (not (eql row-index j))
(*locally
(declare (type fixnum reduced-row-index row-index))
(declare (type fixnum reduced-column-index column-index))
(*setf (aref!! reduced-array
(!! reduced-row-index)
(!! reduced-column-index)
)
(aref!! complex-square-matrix
(!! row-index)
(!! column-index)
)))
(incf reduced-row-index)
)))
(incf reduced-column-index)
))
(*let ((sub-determinate (determinant-of-complex-matrix!! reduced-array))
(multiplicand
(aref!! complex-square-matrix (!! (the fixnum j)) (!! 0))))
(declare (type single-complex-pvar sub-determinate multiplicand))
(print (list 'DETERMINANT-OF-SUBMATRIX (pref sub-determinate 0)))
(print (list 'MUTLIPLICAND (pref multiplicand 0)))
(print (list 'SIGN sign))
(*set determinant
(+!! determinant
(*!! sub-determinate multiplicand (!! (the fixnum sign)))
)))
(print (list 'SUBTOTAL (pref determinant 0)))
(setq sign (* sign -1))
)
determinant
))))
#|
(main 8 3)
(DETERMINANT-OF-SUBMATRIX #C(8.0 0.0))
(MUTLIPLICAND #C(1.0 0.0))
(SIGN 1)
(SUBTOTAL #C(8.0 0.0))
(DETERMINANT-OF-SUBMATRIX #C(4.0 0.0))
(MUTLIPLICAND #C(4.0 0.0))
(SIGN -1)
(SUBTOTAL #C(-8.0 0.0))
(DETERMINANT-OF-SUBMATRIX #C(-2.0 0.0))
(MUTLIPLICAND #C(3.0 0.0))
(SIGN 1)
(SUBTOTAL #C(-14.0 0.0))
(2 0 1)
DIMENSION 2, COORDINATE 0
DIMENSION 0 ----->
#C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0)
#C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0)
#C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0)
#C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0)
DIMENSION 2, COORDINATE 1
DIMENSION 0 ----->
#C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0)
#C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0)
#C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0)
#C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0) #C(-14.0 0.0)
NIL
|#