mdarray 0.5.4-java → 0.5.5-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,120 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ##########################################################################################
4
+ # Copyright © 2013 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
5
+ # and distribute this software and its documentation, without fee and without a signed
6
+ # licensing agreement, is hereby granted, provided that the above copyright notice, this
7
+ # paragraph and the following two paragraphs appear in all copies, modifications, and
8
+ # distributions.
9
+ #
10
+ # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
11
+ # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
12
+ # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
13
+ # POSSIBILITY OF SUCH DAMAGE.
14
+ #
15
+ # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
17
+ # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
18
+ # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
19
+ # OR MODIFICATIONS.
20
+ ##########################################################################################
21
+
22
+ require 'rubygems'
23
+ require "test/unit"
24
+ require 'shoulda'
25
+
26
+ require 'mdarray'
27
+
28
+ class MDArrayTest < Test::Unit::TestCase
29
+
30
+ context "Colt Matrix" do
31
+
32
+ setup do
33
+
34
+ end
35
+
36
+ #-------------------------------------------------------------------------------------
37
+ #
38
+ #-------------------------------------------------------------------------------------
39
+
40
+ should "test multiple matrix operations" do
41
+
42
+ # Dot product (or inner product of scalar product) of 2 vectors
43
+ x = MDMatrix.double([3], [1, -2, 0.0])
44
+ y = MDMatrix.double([3], [2, 5, -1.0])
45
+ assert_equal(-8.0, x * y)
46
+
47
+ # Matrix product.
48
+ a = MDMatrix.double([3, 3], [3.2, -1, 2, 2, -2, 4, 1.5,-1,-4])
49
+ b = MDMatrix.double([3, 2], [1.0, 2.0, -1.0, 2.0, 2, -1.5])
50
+ product = a * b
51
+ product.print
52
+ printf("\n\n")
53
+
54
+ # Matrix-vector product
55
+ x = MDMatrix.double([3], [1, -2, 0.0])
56
+ result = a * x
57
+ result.print
58
+ printf("\n\n")
59
+
60
+ # transpose matrix
61
+ a.transpose.print
62
+ printf("\n\n")
63
+
64
+ # trace
65
+ assert_equal(-2.8, a.trace)
66
+
67
+ # Determinant and inverse
68
+ assert_equal(26.400000000000002, a.det)
69
+ a.inverse.print
70
+ printf("\n\n")
71
+
72
+ # Eigenvalue and Eigenvectors
73
+ eig = a.eig
74
+ # eigenvalue matrix
75
+ eig[0].print
76
+ printf("\n\n")
77
+ eig[1].print
78
+ printf("\n\n")
79
+ eig[2].print
80
+ printf("\n\n")
81
+ eig[3].print
82
+ printf("\n\n")
83
+
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
90
+
91
+ =begin
92
+
93
+ Diagonal, transpose and trace
94
+
95
+ [Not yet a good way of working with the diagonal in MDMatrix]
96
+
97
+ >>> print sp.diagonal(A) #returns the diagonal of A
98
+ array([ 3.2, -2., -4.])
99
+ >>> D = sp.diag((1, 2, 3)) # return a diagonal matrix
100
+ [[1 0 0]
101
+ [0 2 0]
102
+ [0 0 3]]
103
+
104
+ 1.2 Eigenvalue and Eigenvectors
105
+
106
+ [Value from NunPy and MDMatrix are different... is this wrong?!]
107
+
108
+ >>> print e_vectors # row i corresponds to the eigenvector
109
+ # associated with eigenvalues i
110
+ [[ 0.88158576+0.j, -0.25687900+0.02847007j, -0.25687900-0.02847007j]
111
+ [ 0.45531661+0.j, -0.89064266+0.j, -0.89064266+0.j ]
112
+ [ 0.12447222+0.j, 0.32503863-0.18522464j, 0.32503863+0.18522464j]]
113
+
114
+ 3 x 3 matrix
115
+ 0,881586 1,37094 0,510170
116
+ 0,455317 4,50194 2,26780
117
+ 0,124472 -2,11460 0,108628
118
+
119
+
120
+ =end
@@ -0,0 +1,649 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ ##########################################################################################
4
+ # Copyright © 2013 Rodrigo Botafogo. All Rights Reserved. Permission to use, copy, modify,
5
+ # and distribute this software and its documentation, without fee and without a signed
6
+ # licensing agreement, is hereby granted, provided that the above copyright notice, this
7
+ # paragraph and the following two paragraphs appear in all copies, modifications, and
8
+ # distributions.
9
+ #
10
+ # IN NO EVENT SHALL RODRIGO BOTAFOGO BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
11
+ # INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF
12
+ # THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF RODRIGO BOTAFOGO HAS BEEN ADVISED OF THE
13
+ # POSSIBILITY OF SUCH DAMAGE.
14
+ #
15
+ # RODRIGO BOTAFOGO SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16
+ # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
17
+ # SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
18
+ # RODRIGO BOTAFOGO HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
19
+ # OR MODIFICATIONS.
20
+ ##########################################################################################
21
+
22
+ require 'rubygems'
23
+ require "test/unit"
24
+ require 'shoulda'
25
+
26
+ require 'mdarray'
27
+
28
+ class MDArrayTest < Test::Unit::TestCase
29
+
30
+ context "Colt Matrix" do
31
+
32
+ setup do
33
+
34
+ end
35
+
36
+ #-------------------------------------------------------------------------------------
37
+ #
38
+ #-------------------------------------------------------------------------------------
39
+
40
+ should "test double matrices properties" do
41
+
42
+ d1 = MDArray.typed_arange("double", 0, 90)
43
+ d1.reshape!([5, 3, 6])
44
+
45
+ # take a slice of d1 on the first dimension (0) and taking only the first (0) index.
46
+ d2 = d1.slice(0, 0)
47
+ m1 = MDMatrix.from_mdarray(d2)
48
+
49
+ d2 = d1.slice(0, 1)
50
+ m2 = MDMatrix.from_mdarray(d2)
51
+
52
+ d2 = d1.slice(1, 1)
53
+ m3 = MDMatrix.from_mdarray(d2)
54
+
55
+ rect = MDMatrix.from_mdarray(d1.reshape([5, 3, 6])
56
+ .region(:spec => "0:4, 0:2, 0:0", :reduce => true))
57
+ square = MDMatrix.from_mdarray(d1.reshape([5, 3, 6])
58
+ .region(:spec => "0:2, 0:2, 0:0", :reduce => true))
59
+
60
+ # identity matrix
61
+ identity = MDMatrix.fromfunction("double", [5, 5]) { |i, j| 1 if i == j }
62
+
63
+ # diagonaly dominant matrix by row and column
64
+ diag_dominant = MDMatrix.fromfunction("double", [4, 4]) do |x, y|
65
+ (x == y)? 5 * (x +1) + 5 * (y + 1) : x + y
66
+ end
67
+
68
+ # upper diagonal matrix
69
+ ud = MDMatrix.fromfunction("double", [4, 4]) { |x, y| x + y if x < y }
70
+
71
+ # lower diagonal matrix
72
+ ld = MDMatrix.fromfunction("double", [4, 4]) { |x, y| x + y if x > y }
73
+
74
+ c2 = MDMatrix.double([2, 2], [2, 2, 2, 2])
75
+
76
+ # zero matrix
77
+ zero = MDMatrix.double([3, 3])
78
+
79
+ # Checks whether the given matrix A is rectangular, i.e., if columns >= rows.
80
+ # If not rectangular raise exception, otherwise, does nothing.
81
+ assert_raise ( RuntimeError ) { m1.check_rectangular }
82
+ rect.check_rectangular
83
+
84
+ # Checks that the matrix is a square matrix. If not, raises an exception
85
+ assert_raise ( RuntimeError ) { rect.check_square }
86
+ square.check_square
87
+
88
+ # Returns the matrix's fraction of non-zero cells; A.cardinality() / A.size().
89
+ assert_equal(0.8888888888888888, square.density)
90
+
91
+ # array square is not diagnonal
92
+ assert_equal(false, square.diagonal?)
93
+
94
+ #------------------------------------------------------------------------------------
95
+ # A matrix A is diagonally dominant by column if the absolute value of each diagonal
96
+ # element is larger than the sum of the absolute values of the off-diagonal elements
97
+ # in the corresponding column. returns true if for all i: abs(A[i,i]) >
98
+ # Sum(abs(A[j,i])); j != i. Matrix may but need not be square.
99
+ #
100
+ # Note: Ignores tolerance.
101
+ #------------------------------------------------------------------------------------
102
+ assert_equal(true, diag_dominant.diagonally_dominant_by_column?)
103
+ assert_equal(false, square.diagonally_dominant_by_column?)
104
+
105
+ #------------------------------------------------------------------------------------
106
+ # A matrix A is diagonally dominant by row if the absolute value of each diagonal
107
+ # element is larger than the sum of the absolute values of the off-diagonal elements in
108
+ # the corresponding row. returns true if for all i: abs(A[i,i]) > Sum(abs(A[i,j]));
109
+ # j != i. Matrix may but need not be square.
110
+ #
111
+ # Note: Ignores tolerance.
112
+ #------------------------------------------------------------------------------------
113
+ assert_equal(true, diag_dominant.diagonally_dominant_by_row?)
114
+
115
+ non_sing = square.copy
116
+ # modifies the matrix to a non-singular matrix
117
+ non_sing.generate_non_singular!
118
+
119
+ assert_equal(true, c2.equals?(2))
120
+ assert_equal(true, identity.equals?(identity))
121
+ assert_equal(false, c2.equals?(identity))
122
+ assert_equal(true, identity.identity?)
123
+ assert_equal(true, zero.lower_bidiagonal?)
124
+ assert_equal(true, ld.lower_triangular?)
125
+ assert_equal(true, c2.non_negative?)
126
+ assert_equal(false, c2.orthogonal?)
127
+ assert_equal(true, identity.orthogonal?)
128
+ assert_equal(true, c2.positive?)
129
+ assert_equal(true, c2.singular?)
130
+ assert_equal(false, non_sing.singular?)
131
+
132
+ # making a skew symmetric matrix by building the upper part and the lower part and
133
+ # adding them together
134
+ l = MDArray.fromfunction("double", [5, 5]) do |x, y|
135
+ x + y if x > y
136
+ end
137
+ lt = MDMatrix.from_mdarray(l)
138
+
139
+ u = MDArray.fromfunction("double", [5, 5]) do |x, y|
140
+ -(x + y) if x < y
141
+ end
142
+ ut = MDMatrix.from_mdarray(u)
143
+ ss = MDMatrix.from_mdarray(u + l)
144
+
145
+ assert_equal(true, ss.skew_symmetric?)
146
+ assert_equal(true, square.square?)
147
+ assert_equal(false, rect.square?)
148
+ assert_equal(true, lt.strictly_lower_triangular?)
149
+ assert_equal(false, ut.strictly_lower_triangular?)
150
+ assert_equal(true, lt.strictly_triangular?)
151
+ assert_equal(true, ut.strictly_triangular?)
152
+ assert_equal(true, ut.strictly_upper_triangular?)
153
+ assert_equal(true, c2.symmetric?)
154
+ assert_equal(true, ut.triangular?)
155
+
156
+ tri = MDArray.fromfunction("double", [5, 6]) do |i, j|
157
+ ((i - j).abs > 1)? 0 : i + j
158
+ end
159
+ assert_equal(true, MDMatrix.from_mdarray(tri).tridiagonal?)
160
+
161
+ unittri = MDArray.fromfunction("double", [5, 6]) do |i, j|
162
+ (i > j)? i + j : ((i == j)? 1 : 0)
163
+ end
164
+ assert_equal(true, MDMatrix.from_mdarray(unittri).unit_triangular?)
165
+
166
+ upbi = MDArray.fromfunction("double", [5, 6]) do |i, j|
167
+ ((i == j) || (i == j-1))? i + j : 0
168
+ end
169
+ assert_equal(true, MDMatrix.from_mdarray(upbi).upper_bidiagonal?)
170
+
171
+ assert_equal(true, ut.upper_triangular?)
172
+ assert_equal(true, zero.zero?)
173
+ assert_equal(3, diag_dominant.lower_bandwidth)
174
+ assert_equal(4, diag_dominant.semi_bandwidth)
175
+ assert_equal(3, diag_dominant.upper_bandwidth)
176
+
177
+ diag_dominant.properties
178
+
179
+ end
180
+
181
+ #-------------------------------------------------------------------------------------
182
+ #
183
+ #-------------------------------------------------------------------------------------
184
+
185
+ should "test float matrices properties" do
186
+
187
+ d1 = MDArray.typed_arange("float", 0, 90)
188
+ d1.reshape!([5, 3, 6])
189
+
190
+ # take a slice of d1 on the first dimension (0) and taking only the first (0) index.
191
+ d2 = d1.slice(0, 0)
192
+ m1 = MDMatrix.from_mdarray(d2)
193
+
194
+ d2 = d1.slice(0, 1)
195
+ m2 = MDMatrix.from_mdarray(d2)
196
+
197
+ d2 = d1.slice(1, 1)
198
+ m3 = MDMatrix.from_mdarray(d2)
199
+
200
+ rect = MDMatrix.from_mdarray(d1.reshape([5, 3, 6])
201
+ .region(:spec => "0:4, 0:2, 0:0", :reduce => true))
202
+ square = MDMatrix.from_mdarray(d1.reshape([5, 3, 6])
203
+ .region(:spec => "0:2, 0:2, 0:0", :reduce => true))
204
+
205
+ # identity matrix
206
+ identity = MDMatrix
207
+ .from_mdarray(MDArray.fromfunction("float", [5, 5]) { |x, y| 1 if x == y })
208
+
209
+ # diagonaly dominant matrix by row and column
210
+ diag_dominant = MDMatrix
211
+ .from_mdarray(MDArray.fromfunction("float", [4, 4]) do |x, y|
212
+ if (x == y)
213
+ 5 * (x +1) + 5 * (y + 1)
214
+ else
215
+ x + y
216
+ end
217
+ end)
218
+
219
+ # upper diagonal matrix
220
+ ud = MDMatrix
221
+ .from_mdarray(MDArray.fromfunction("float", [4, 4]) { |x, y|
222
+ x + y if x < y })
223
+
224
+ # lower diagonal matrix
225
+ ld = MDMatrix
226
+ .from_mdarray(MDArray.fromfunction("float", [4, 4]) { |x, y|
227
+ x + y if x > y })
228
+
229
+ c2 = MDMatrix.from_mdarray(MDArray.float([2, 2], [2, 2, 2, 2]))
230
+
231
+ # zero matrix
232
+ zero = MDMatrix.from_mdarray(MDArray.float([3, 3]))
233
+
234
+ # Checks whether the given matrix A is rectangular, i.e., if columns >= rows.
235
+ # If not rectangular raise exception, otherwise, does nothing.
236
+ assert_raise ( RuntimeError ) { m1.check_rectangular }
237
+ rect.check_rectangular
238
+
239
+ # Checks that the matrix is a square matrix. If not, raises an exception
240
+ assert_raise ( RuntimeError ) { rect.check_square }
241
+ square.check_square
242
+
243
+ # Returns the matrix's fraction of non-zero cells; A.cardinality() / A.size().
244
+ assert_equal(0.8888888955116272, square.density)
245
+
246
+ # array square is not diagnonal
247
+ assert_equal(false, square.diagonal?)
248
+
249
+ #------------------------------------------------------------------------------------
250
+ # A matrix A is diagonally dominant by column if the absolute value of each diagonal
251
+ # element is larger than the sum of the absolute values of the off-diagonal elements
252
+ # in the corresponding column. returns true if for all i: abs(A[i,i]) >
253
+ # Sum(abs(A[j,i])); j != i. Matrix may but need not be square.
254
+ #
255
+ # Note: Ignores tolerance.
256
+ #------------------------------------------------------------------------------------
257
+ assert_equal(true, diag_dominant.diagonally_dominant_by_column?)
258
+ assert_equal(false, square.diagonally_dominant_by_column?)
259
+
260
+ #------------------------------------------------------------------------------------
261
+ # A matrix A is diagonally dominant by row if the absolute value of each diagonal
262
+ # element is larger than the sum of the absolute values of the off-diagonal elements in
263
+ # the corresponding row. returns true if for all i: abs(A[i,i]) > Sum(abs(A[i,j]));
264
+ # j != i. Matrix may but need not be square.
265
+ #
266
+ # Note: Ignores tolerance.
267
+ #------------------------------------------------------------------------------------
268
+ assert_equal(true, diag_dominant.diagonally_dominant_by_row?)
269
+
270
+ non_sing = square.copy
271
+ # modifies the matrix to a non-singular matrix
272
+ non_sing.generate_non_singular!
273
+
274
+ assert_equal(true, c2.equals?(2))
275
+ assert_equal(true, identity.equals?(identity))
276
+ assert_equal(false, c2.equals?(identity))
277
+ assert_equal(true, identity.identity?)
278
+ assert_equal(true, zero.lower_bidiagonal?)
279
+ assert_equal(true, ld.lower_triangular?)
280
+ assert_equal(true, c2.non_negative?)
281
+ assert_equal(false, c2.orthogonal?)
282
+ assert_equal(true, identity.orthogonal?)
283
+ assert_equal(true, c2.positive?)
284
+ assert_equal(true, c2.singular?)
285
+ assert_equal(false, non_sing.singular?)
286
+
287
+ # making a skew symmetric matrix by building the upper part and the lower part and
288
+ # adding them together
289
+ l = MDArray.fromfunction("float", [5, 5]) do |x, y|
290
+ x + y if x > y
291
+ end
292
+ lt = MDMatrix.from_mdarray(l)
293
+
294
+ u = MDArray.fromfunction("float", [5, 5]) do |x, y|
295
+ -(x + y) if x < y
296
+ end
297
+ ut = MDMatrix.from_mdarray(u)
298
+ ss = MDMatrix.from_mdarray(u + l)
299
+
300
+ assert_equal(true, ss.skew_symmetric?)
301
+ assert_equal(true, square.square?)
302
+ assert_equal(false, rect.square?)
303
+ assert_equal(true, lt.strictly_lower_triangular?)
304
+ assert_equal(false, ut.strictly_lower_triangular?)
305
+ assert_equal(true, lt.strictly_triangular?)
306
+ assert_equal(true, ut.strictly_triangular?)
307
+ assert_equal(true, ut.strictly_upper_triangular?)
308
+ assert_equal(true, c2.symmetric?)
309
+ assert_equal(true, ut.triangular?)
310
+
311
+ tri = MDArray.fromfunction("float", [5, 6]) do |i, j|
312
+ ((i - j).abs > 1)? 0 : i + j
313
+ end
314
+ assert_equal(true, MDMatrix.from_mdarray(tri).tridiagonal?)
315
+
316
+ unittri = MDArray.fromfunction("float", [5, 6]) do |i, j|
317
+ (i > j)? i + j : ((i == j)? 1 : 0)
318
+ end
319
+ assert_equal(true, MDMatrix.from_mdarray(unittri).unit_triangular?)
320
+
321
+ upbi = MDArray.fromfunction("float", [5, 6]) do |i, j|
322
+ ((i == j) || (i == j-1))? i + j : 0
323
+ end
324
+ assert_equal(true, MDMatrix.from_mdarray(upbi).upper_bidiagonal?)
325
+
326
+ assert_equal(true, ut.upper_triangular?)
327
+ assert_equal(true, zero.zero?)
328
+ assert_equal(3, diag_dominant.lower_bandwidth)
329
+ assert_equal(4, diag_dominant.semi_bandwidth)
330
+ assert_equal(3, diag_dominant.upper_bandwidth)
331
+
332
+ diag_dominant.properties
333
+
334
+ end
335
+
336
+ #-------------------------------------------------------------------------------------
337
+ #
338
+ #-------------------------------------------------------------------------------------
339
+
340
+ should "test long matrices properties" do
341
+
342
+ d1 = MDArray.typed_arange("long", 0, 90)
343
+ d1.reshape!([5, 3, 6])
344
+
345
+ # take a slice of d1 on the first dimension (0) and taking only the first (0) index.
346
+ d2 = d1.slice(0, 0)
347
+ m1 = MDMatrix.from_mdarray(d2)
348
+
349
+ d2 = d1.slice(0, 1)
350
+ m2 = MDMatrix.from_mdarray(d2)
351
+
352
+ d2 = d1.slice(1, 1)
353
+ m3 = MDMatrix.from_mdarray(d2)
354
+
355
+ rect = MDMatrix.from_mdarray(d1.reshape([5, 3, 6])
356
+ .region(:spec => "0:4, 0:2, 0:0", :reduce => true))
357
+ square = MDMatrix.from_mdarray(d1.reshape([5, 3, 6])
358
+ .region(:spec => "0:2, 0:2, 0:0", :reduce => true))
359
+
360
+ # identity matrix
361
+ identity = MDMatrix
362
+ .from_mdarray(MDArray.fromfunction("long", [5, 5]) { |x, y| 1 if x == y })
363
+
364
+ # diagonaly dominant matrix by row and column
365
+ diag_dominant = MDMatrix
366
+ .from_mdarray(MDArray.fromfunction("long", [4, 4]) do |x, y|
367
+ if (x == y)
368
+ 5 * (x +1) + 5 * (y + 1)
369
+ else
370
+ x + y
371
+ end
372
+ end)
373
+
374
+ # upper diagonal matrix
375
+ ud = MDMatrix
376
+ .from_mdarray(MDArray.fromfunction("long", [4, 4]) { |x, y|
377
+ x + y if x < y })
378
+
379
+ # lower diagonal matrix
380
+ ld = MDMatrix
381
+ .from_mdarray(MDArray.fromfunction("long", [4, 4]) { |x, y|
382
+ x + y if x > y })
383
+
384
+ c2 = MDMatrix.from_mdarray(MDArray.long([2, 2], [2, 2, 2, 2]))
385
+
386
+ # zero matrix
387
+ zero = MDMatrix.from_mdarray(MDArray.long([3, 3]))
388
+
389
+ # Checks whether the given matrix A is rectangular, i.e., if columns >= rows.
390
+ # If not rectangular raise exception, otherwise, does nothing.
391
+ assert_raise ( RuntimeError ) { m1.check_rectangular }
392
+ rect.check_rectangular
393
+
394
+ # Checks that the matrix is a square matrix. If not, raises an exception
395
+ assert_raise ( RuntimeError ) { rect.check_square }
396
+ square.check_square
397
+
398
+ # Returns the matrix's fraction of non-zero cells; A.cardinality() / A.size().
399
+ assert_equal(0, square.density)
400
+
401
+ # array square is not diagnonal
402
+ assert_equal(false, square.diagonal?)
403
+
404
+ #------------------------------------------------------------------------------------
405
+ # A matrix A is diagonally dominant by column if the absolute value of each diagonal
406
+ # element is larger than the sum of the absolute values of the off-diagonal elements
407
+ # in the corresponding column. returns true if for all i: abs(A[i,i]) >
408
+ # Sum(abs(A[j,i])); j != i. Matrix may but need not be square.
409
+ #
410
+ # Note: Ignores tolerance.
411
+ #------------------------------------------------------------------------------------
412
+ assert_equal(true, diag_dominant.diagonally_dominant_by_column?)
413
+ assert_equal(false, square.diagonally_dominant_by_column?)
414
+
415
+ #------------------------------------------------------------------------------------
416
+ # A matrix A is diagonally dominant by row if the absolute value of each diagonal
417
+ # element is larger than the sum of the absolute values of the off-diagonal elements in
418
+ # the corresponding row. returns true if for all i: abs(A[i,i]) > Sum(abs(A[i,j]));
419
+ # j != i. Matrix may but need not be square.
420
+ #
421
+ # Note: Ignores tolerance.
422
+ #------------------------------------------------------------------------------------
423
+ assert_equal(true, diag_dominant.diagonally_dominant_by_row?)
424
+
425
+ non_sing = square.copy
426
+ # modifies the matrix to a non-singular matrix
427
+ non_sing.generate_non_singular!
428
+
429
+ assert_equal(true, c2.equals?(2))
430
+ assert_equal(true, identity.equals?(identity))
431
+ assert_equal(false, c2.equals?(identity))
432
+ assert_equal(true, identity.identity?)
433
+ assert_equal(true, zero.lower_bidiagonal?)
434
+ assert_equal(true, ld.lower_triangular?)
435
+ assert_equal(true, c2.non_negative?)
436
+ assert_equal(false, c2.orthogonal?)
437
+ assert_equal(true, identity.orthogonal?)
438
+ assert_equal(true, c2.positive?)
439
+
440
+ assert_raise( RuntimeError ) { c2.singular?}
441
+ assert_raise( RuntimeError ) { non_sing.singular? }
442
+
443
+ # making a skew symmetric matrix by building the upper part and the lower part and
444
+ # adding them together
445
+ l = MDArray.fromfunction("long", [5, 5]) do |x, y|
446
+ x + y if x > y
447
+ end
448
+ lt = MDMatrix.from_mdarray(l)
449
+
450
+ u = MDArray.fromfunction("long", [5, 5]) do |x, y|
451
+ -(x + y) if x < y
452
+ end
453
+ ut = MDMatrix.from_mdarray(u)
454
+ ss = MDMatrix.from_mdarray(u + l)
455
+
456
+ assert_equal(true, ss.skew_symmetric?)
457
+ assert_equal(true, square.square?)
458
+ assert_equal(false, rect.square?)
459
+ assert_equal(true, lt.strictly_lower_triangular?)
460
+ assert_equal(false, ut.strictly_lower_triangular?)
461
+ assert_equal(true, lt.strictly_triangular?)
462
+ assert_equal(true, ut.strictly_triangular?)
463
+ assert_equal(true, ut.strictly_upper_triangular?)
464
+ assert_equal(true, c2.symmetric?)
465
+ assert_equal(true, ut.triangular?)
466
+
467
+ tri = MDArray.fromfunction("long", [5, 6]) do |i, j|
468
+ ((i - j).abs > 1)? 0 : i + j
469
+ end
470
+ assert_equal(true, MDMatrix.from_mdarray(tri).tridiagonal?)
471
+
472
+ unittri = MDArray.fromfunction("long", [5, 6]) do |i, j|
473
+ (i > j)? i + j : ((i == j)? 1 : 0)
474
+ end
475
+ assert_equal(true, MDMatrix.from_mdarray(unittri).unit_triangular?)
476
+
477
+ upbi = MDArray.fromfunction("long", [5, 6]) do |i, j|
478
+ ((i == j) || (i == j-1))? i + j : 0
479
+ end
480
+ assert_equal(true, MDMatrix.from_mdarray(upbi).upper_bidiagonal?)
481
+
482
+ assert_equal(true, ut.upper_triangular?)
483
+ assert_equal(true, zero.zero?)
484
+ assert_equal(3, diag_dominant.lower_bandwidth)
485
+ assert_equal(4, diag_dominant.semi_bandwidth)
486
+ assert_equal(3, diag_dominant.upper_bandwidth)
487
+
488
+ diag_dominant.properties
489
+
490
+ end
491
+
492
+ #-------------------------------------------------------------------------------------
493
+ #
494
+ #-------------------------------------------------------------------------------------
495
+
496
+ should "test int matrices properties" do
497
+
498
+ d1 = MDArray.typed_arange("int", 0, 90)
499
+ d1.reshape!([5, 3, 6])
500
+
501
+ # take a slice of d1 on the first dimension (0) and taking only the first (0) index.
502
+ d2 = d1.slice(0, 0)
503
+ m1 = MDMatrix.from_mdarray(d2)
504
+
505
+ d2 = d1.slice(0, 1)
506
+ m2 = MDMatrix.from_mdarray(d2)
507
+
508
+ d2 = d1.slice(1, 1)
509
+ m3 = MDMatrix.from_mdarray(d2)
510
+
511
+ rect = MDMatrix.from_mdarray(d1.reshape([5, 3, 6])
512
+ .region(:spec => "0:4, 0:2, 0:0", :reduce => true))
513
+ square = MDMatrix.from_mdarray(d1.reshape([5, 3, 6])
514
+ .region(:spec => "0:2, 0:2, 0:0", :reduce => true))
515
+
516
+ # identity matrix
517
+ identity = MDMatrix
518
+ .from_mdarray(MDArray.fromfunction("int", [5, 5]) { |x, y| 1 if x == y })
519
+
520
+ # diagonaly dominant matrix by row and column
521
+ diag_dominant = MDMatrix
522
+ .from_mdarray(MDArray.fromfunction("int", [4, 4]) do |x, y|
523
+ if (x == y)
524
+ 5 * (x +1) + 5 * (y + 1)
525
+ else
526
+ x + y
527
+ end
528
+ end)
529
+
530
+ # upper diagonal matrix
531
+ ud = MDMatrix
532
+ .from_mdarray(MDArray.fromfunction("int", [4, 4]) { |x, y|
533
+ x + y if x < y })
534
+
535
+ # lower diagonal matrix
536
+ ld = MDMatrix
537
+ .from_mdarray(MDArray.fromfunction("int", [4, 4]) { |x, y|
538
+ x + y if x > y })
539
+
540
+ c2 = MDMatrix.from_mdarray(MDArray.int([2, 2], [2, 2, 2, 2]))
541
+
542
+ # zero matrix
543
+ zero = MDMatrix.from_mdarray(MDArray.int([3, 3]))
544
+
545
+ # Checks whether the given matrix A is rectangular, i.e., if columns >= rows.
546
+ # If not rectangular raise exception, otherwise, does nothing.
547
+ assert_raise ( RuntimeError ) { m1.check_rectangular }
548
+ rect.check_rectangular
549
+
550
+ # Checks that the matrix is a square matrix. If not, raises an exception
551
+ assert_raise ( RuntimeError ) { rect.check_square }
552
+ square.check_square
553
+
554
+ # Returns the matrix's fraction of non-zero cells; A.cardinality() / A.size().
555
+ assert_equal(0, square.density)
556
+
557
+ # array square is not diagnonal
558
+ assert_equal(false, square.diagonal?)
559
+
560
+ #------------------------------------------------------------------------------------
561
+ # A matrix A is diagonally dominant by column if the absolute value of each diagonal
562
+ # element is larger than the sum of the absolute values of the off-diagonal elements
563
+ # in the corresponding column. returns true if for all i: abs(A[i,i]) >
564
+ # Sum(abs(A[j,i])); j != i. Matrix may but need not be square.
565
+ #
566
+ # Note: Ignores tolerance.
567
+ #------------------------------------------------------------------------------------
568
+ assert_equal(true, diag_dominant.diagonally_dominant_by_column?)
569
+ assert_equal(false, square.diagonally_dominant_by_column?)
570
+
571
+ #------------------------------------------------------------------------------------
572
+ # A matrix A is diagonally dominant by row if the absolute value of each diagonal
573
+ # element is larger than the sum of the absolute values of the off-diagonal elements in
574
+ # the corresponding row. returns true if for all i: abs(A[i,i]) > Sum(abs(A[i,j]));
575
+ # j != i. Matrix may but need not be square.
576
+ #
577
+ # Note: Ignores tolerance.
578
+ #------------------------------------------------------------------------------------
579
+ assert_equal(true, diag_dominant.diagonally_dominant_by_row?)
580
+
581
+ non_sing = square.copy
582
+ # modifies the matrix to a non-singular matrix
583
+ non_sing.generate_non_singular!
584
+
585
+ assert_equal(true, c2.equals?(2))
586
+ assert_equal(true, identity.equals?(identity))
587
+ assert_equal(false, c2.equals?(identity))
588
+ assert_equal(true, identity.identity?)
589
+ assert_equal(true, zero.lower_bidiagonal?)
590
+ assert_equal(true, ld.lower_triangular?)
591
+ assert_equal(true, c2.non_negative?)
592
+ assert_equal(false, c2.orthogonal?)
593
+ assert_equal(true, identity.orthogonal?)
594
+ assert_equal(true, c2.positive?)
595
+ assert_raise ( RuntimeError ) { c2.singular? }
596
+ assert_raise ( RuntimeError ) { non_sing.singular? }
597
+
598
+ # making a skew symmetric matrix by building the upper part and the lower part and
599
+ # adding them together
600
+ l = MDArray.fromfunction("int", [5, 5]) do |x, y|
601
+ x + y if x > y
602
+ end
603
+ lt = MDMatrix.from_mdarray(l)
604
+
605
+ u = MDArray.fromfunction("int", [5, 5]) do |x, y|
606
+ -(x + y) if x < y
607
+ end
608
+ ut = MDMatrix.from_mdarray(u)
609
+ ss = MDMatrix.from_mdarray(u + l)
610
+
611
+ assert_equal(true, ss.skew_symmetric?)
612
+ assert_equal(true, square.square?)
613
+ assert_equal(false, rect.square?)
614
+ assert_equal(true, lt.strictly_lower_triangular?)
615
+ assert_equal(false, ut.strictly_lower_triangular?)
616
+ assert_equal(true, lt.strictly_triangular?)
617
+ assert_equal(true, ut.strictly_triangular?)
618
+ assert_equal(true, ut.strictly_upper_triangular?)
619
+ assert_equal(true, c2.symmetric?)
620
+ assert_equal(true, ut.triangular?)
621
+
622
+ tri = MDArray.fromfunction("int", [5, 6]) do |i, j|
623
+ ((i - j).abs > 1)? 0 : i + j
624
+ end
625
+ assert_equal(true, MDMatrix.from_mdarray(tri).tridiagonal?)
626
+
627
+ unittri = MDArray.fromfunction("int", [5, 6]) do |i, j|
628
+ (i > j)? i + j : ((i == j)? 1 : 0)
629
+ end
630
+ assert_equal(true, MDMatrix.from_mdarray(unittri).unit_triangular?)
631
+
632
+ upbi = MDArray.fromfunction("int", [5, 6]) do |i, j|
633
+ ((i == j) || (i == j-1))? i + j : 0
634
+ end
635
+ assert_equal(true, MDMatrix.from_mdarray(upbi).upper_bidiagonal?)
636
+
637
+ assert_equal(true, ut.upper_triangular?)
638
+ assert_equal(true, zero.zero?)
639
+ assert_equal(3, diag_dominant.lower_bandwidth)
640
+ assert_equal(4, diag_dominant.semi_bandwidth)
641
+ assert_equal(3, diag_dominant.upper_bandwidth)
642
+
643
+ diag_dominant.properties
644
+
645
+ end
646
+
647
+ end
648
+
649
+ end