nmatrix-atlas 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/ext/nmatrix/data/complex.h +364 -0
  3. data/ext/nmatrix/data/data.h +638 -0
  4. data/ext/nmatrix/data/meta.h +64 -0
  5. data/ext/nmatrix/data/ruby_object.h +389 -0
  6. data/ext/nmatrix/math/asum.h +120 -0
  7. data/ext/nmatrix/math/cblas_enums.h +36 -0
  8. data/ext/nmatrix/math/cblas_templates_core.h +507 -0
  9. data/ext/nmatrix/math/gemm.h +241 -0
  10. data/ext/nmatrix/math/gemv.h +178 -0
  11. data/ext/nmatrix/math/getrf.h +255 -0
  12. data/ext/nmatrix/math/getrs.h +121 -0
  13. data/ext/nmatrix/math/imax.h +79 -0
  14. data/ext/nmatrix/math/laswp.h +165 -0
  15. data/ext/nmatrix/math/long_dtype.h +49 -0
  16. data/ext/nmatrix/math/math.h +744 -0
  17. data/ext/nmatrix/math/nrm2.h +160 -0
  18. data/ext/nmatrix/math/rot.h +117 -0
  19. data/ext/nmatrix/math/rotg.h +106 -0
  20. data/ext/nmatrix/math/scal.h +71 -0
  21. data/ext/nmatrix/math/trsm.h +332 -0
  22. data/ext/nmatrix/math/util.h +148 -0
  23. data/ext/nmatrix/nm_memory.h +60 -0
  24. data/ext/nmatrix/nmatrix.h +408 -0
  25. data/ext/nmatrix/ruby_constants.h +106 -0
  26. data/ext/nmatrix/storage/common.h +176 -0
  27. data/ext/nmatrix/storage/dense/dense.h +128 -0
  28. data/ext/nmatrix/storage/list/list.h +137 -0
  29. data/ext/nmatrix/storage/storage.h +98 -0
  30. data/ext/nmatrix/storage/yale/class.h +1139 -0
  31. data/ext/nmatrix/storage/yale/iterators/base.h +142 -0
  32. data/ext/nmatrix/storage/yale/iterators/iterator.h +130 -0
  33. data/ext/nmatrix/storage/yale/iterators/row.h +449 -0
  34. data/ext/nmatrix/storage/yale/iterators/row_stored.h +139 -0
  35. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +168 -0
  36. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +123 -0
  37. data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
  38. data/ext/nmatrix/storage/yale/yale.h +202 -0
  39. data/ext/nmatrix/types.h +54 -0
  40. data/ext/nmatrix/util/io.h +115 -0
  41. data/ext/nmatrix/util/sl_list.h +143 -0
  42. data/ext/nmatrix/util/util.h +78 -0
  43. data/ext/nmatrix_atlas/extconf.rb +250 -0
  44. data/ext/nmatrix_atlas/math_atlas.cpp +1206 -0
  45. data/ext/nmatrix_atlas/math_atlas/cblas_templates_atlas.h +72 -0
  46. data/ext/nmatrix_atlas/math_atlas/clapack_templates.h +332 -0
  47. data/ext/nmatrix_atlas/math_atlas/geev.h +82 -0
  48. data/ext/nmatrix_atlas/math_atlas/gesdd.h +83 -0
  49. data/ext/nmatrix_atlas/math_atlas/gesvd.h +81 -0
  50. data/ext/nmatrix_atlas/math_atlas/inc.h +47 -0
  51. data/ext/nmatrix_atlas/nmatrix_atlas.cpp +44 -0
  52. data/lib/nmatrix/atlas.rb +213 -0
  53. data/lib/nmatrix/lapack_ext_common.rb +69 -0
  54. data/spec/00_nmatrix_spec.rb +730 -0
  55. data/spec/01_enum_spec.rb +190 -0
  56. data/spec/02_slice_spec.rb +389 -0
  57. data/spec/03_nmatrix_monkeys_spec.rb +78 -0
  58. data/spec/2x2_dense_double.mat +0 -0
  59. data/spec/4x4_sparse.mat +0 -0
  60. data/spec/4x5_dense.mat +0 -0
  61. data/spec/blas_spec.rb +193 -0
  62. data/spec/elementwise_spec.rb +303 -0
  63. data/spec/homogeneous_spec.rb +99 -0
  64. data/spec/io/fortran_format_spec.rb +88 -0
  65. data/spec/io/harwell_boeing_spec.rb +98 -0
  66. data/spec/io/test.rua +9 -0
  67. data/spec/io_spec.rb +149 -0
  68. data/spec/lapack_core_spec.rb +482 -0
  69. data/spec/leakcheck.rb +16 -0
  70. data/spec/math_spec.rb +730 -0
  71. data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
  72. data/spec/nmatrix_yale_spec.rb +286 -0
  73. data/spec/plugins/atlas/atlas_spec.rb +242 -0
  74. data/spec/rspec_monkeys.rb +56 -0
  75. data/spec/rspec_spec.rb +34 -0
  76. data/spec/shortcuts_spec.rb +310 -0
  77. data/spec/slice_set_spec.rb +157 -0
  78. data/spec/spec_helper.rb +140 -0
  79. data/spec/stat_spec.rb +203 -0
  80. data/spec/test.pcd +20 -0
  81. data/spec/utm5940.mtx +83844 -0
  82. metadata +159 -0
@@ -0,0 +1,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe NMatrix do
4
+ describe "#to_a" do
5
+ it "creates an Array with the same dimensions" do
6
+ n = NMatrix.seq([3,2])
7
+ expect(n.to_a).to eq([[0, 1], [2, 3], [4, 5]])
8
+ end
9
+
10
+ it "creates an Array with the proper element type" do
11
+ n = NMatrix.seq([3,2], dtype: :float64)
12
+ expect(n.to_a).to eq([[0.0, 1.0], [2.0, 3.0], [4.0, 5.0]])
13
+ end
14
+
15
+ it "properly interprets list matrices" do
16
+ n = NMatrix.seq([3,2], stype: :list)
17
+ expect(n.to_a).to eq([[0, 1], [2, 3], [4, 5]])
18
+ end
19
+
20
+ it "properly interprets yale matrices" do
21
+ n = NMatrix.seq([3,2], stype: :yale)
22
+ expect(n.to_a).to eq([[0, 1], [2, 3], [4, 5]])
23
+ end
24
+ end
25
+ end
26
+
27
+ describe Array do
28
+ describe "#to_nm" do
29
+ # [0, 1, 2, 3, 4, 5]
30
+ let(:a) {(0..5).to_a}
31
+
32
+ it "uses a given shape and type" do
33
+ expect(a.to_nm([3,2]).dtype).to eq :int64
34
+ expect(a.to_nm([3,2])).to eq(NMatrix.seq([3,2]))
35
+ end
36
+
37
+ it "guesses dtype based on first element" do
38
+ a[0] = 0.0
39
+ expect(a.to_nm([3,2]).dtype).to eq :float64
40
+ end
41
+
42
+ it "defaults to dtype :object if necessary" do
43
+ a = %w(this is an array of strings)
44
+ expect(a.to_nm([3,2]).dtype).to eq :object
45
+ expect(a.to_nm([3,2])).to eq(NMatrix.new([3,2], a, dtype: :object))
46
+ end
47
+
48
+ it "attempts to intuit the shape of the Array" do
49
+ a = [[0, 1], [2, 3], [4, 5]]
50
+ expect(a.to_nm).to eq(NMatrix.new([3,2], a.flatten))
51
+ expect(a.to_nm.dtype).to eq :int64
52
+ end
53
+
54
+ it "creates an object Array for inconsistent dimensions" do
55
+ a = [[0, 1, 2], [3], [4, 5]]
56
+ expect(a.to_nm).to eq(NMatrix.new([3], a, dtype: :object))
57
+ expect(a.to_nm.dtype).to eq :object
58
+ end
59
+
60
+ it "intuits shape of Array into multiple dimensions" do
61
+ a = [[[0], [1]], [[2], [3]], [[4], [5]]]
62
+ expect(a.to_nm).to eq(NMatrix.new([3,2,1], a.flatten))
63
+ expect(a).to eq(a.to_nm.to_a)
64
+ end
65
+
66
+ it "is reflective with NMatrix#to_a" do
67
+ a = [[0, 1, 2], [3], [4, 5]]
68
+ expect(a).to eq(a.to_nm.to_a)
69
+ end
70
+
71
+ it "does not permanently alter the Array" do
72
+ a = [[0, 1], [2, 3], [4, 5]]
73
+ expect(a.to_nm).to eq(NMatrix.new([3,2], a.flatten))
74
+ expect(a).to eq([[0, 1], [2, 3], [4, 5]])
75
+ end
76
+ end
77
+ end
78
+
Binary file
Binary file
Binary file
@@ -0,0 +1,193 @@
1
+ # = NMatrix
2
+ #
3
+ # A linear algebra library for scientific computation in Ruby.
4
+ # NMatrix is part of SciRuby.
5
+ #
6
+ # NMatrix was originally inspired by and derived from NArray, by
7
+ # Masahiro Tanaka: http://narray.rubyforge.org
8
+ #
9
+ # == Copyright Information
10
+ #
11
+ # SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
12
+ # NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
13
+ #
14
+ # Please see LICENSE.txt for additional copyright notices.
15
+ #
16
+ # == Contributing
17
+ #
18
+ # By contributing source code to SciRuby, you agree to be bound by
19
+ # our Contributor Agreement:
20
+ #
21
+ # * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
22
+ #
23
+ # == blas_spec.rb
24
+ #
25
+ # Tests for properly exposed BLAS functions.
26
+ #
27
+
28
+ require 'spec_helper'
29
+
30
+ describe NMatrix::BLAS do
31
+ [:byte, :int8, :int16, :int32, :int64,
32
+ :float32, :float64, :complex64, :complex128,
33
+ :object
34
+ ].each do |dtype|
35
+ context dtype do
36
+ it "exposes cblas_scal" do
37
+ x = NMatrix.new([3, 1], [1, 2, 3], dtype: dtype)
38
+ NMatrix::BLAS.cblas_scal(3, 2, x, 1)
39
+ expect(x).to eq(NMatrix.new([3, 1], [2, 4, 6], dtype: dtype))
40
+ end
41
+
42
+ it "exposes cblas_imax" do
43
+ u = NMatrix.new([3,1], [1, 4, 3], dtype: dtype)
44
+ index = NMatrix::BLAS.cblas_imax(3, u, 1)
45
+ expect(index).to eq(1)
46
+ end
47
+ end
48
+ end
49
+
50
+ [:float32, :float64, :complex64, :complex128].each do |dtype|
51
+ context dtype do
52
+ # This is not the same as "exposes cblas trsm", which would be for a version defined in blas.rb (which
53
+ # would greatly simplify the calling of cblas_trsm in terms of arguments, and which would be accessible
54
+ # as NMatrix::BLAS::trsm)
55
+ it "exposes unfriendly cblas_trsm" do
56
+ a = NMatrix.new(3, [4,-1.0/2, -3.0/4, -2, 2, -1.0/4, -4, -2, -1.0/2], dtype: dtype)
57
+ b = NMatrix.new([3,1], [-1, 17, -9], dtype: dtype)
58
+ NMatrix::BLAS::cblas_trsm(:row, :right, :lower, :transpose, :nonunit, 1, 3, 1.0, a, 3, b, 3)
59
+
60
+ # These test results all come from actually running a matrix through BLAS. We use them to ensure that NMatrix's
61
+ # version of these functions give similar results.
62
+
63
+ expect(b[0]).to eq(-1.0/4)
64
+ expect(b[1]).to eq(33.0/4)
65
+ expect(b[2]).to eq(-13)
66
+
67
+ NMatrix::BLAS::cblas_trsm(:row, :right, :upper, :transpose, :unit, 1, 3, 1.0, a, 3, b, 3)
68
+
69
+ expect(b[0]).to eq(-15.0/2)
70
+ expect(b[1]).to eq(5)
71
+ expect(b[2]).to eq(-13)
72
+ end
73
+
74
+ # trmm multiplies two matrices, where one of the two is required to be
75
+ # triangular
76
+ it "exposes cblas_trmm" do
77
+ a = NMatrix.new([3,3], [1,1,1, 0,1,2, 0,0,-1], dtype: dtype)
78
+ b = NMatrix.new([3,3], [1,2,3, 4,5,6, 7,8,9], dtype: dtype)
79
+
80
+ begin
81
+ NMatrix::BLAS.cblas_trmm(:row, :left, :upper, false, :not_unit, 3, 3, 1, a, 3, b, 3)
82
+ rescue NotImplementedError => e
83
+ pending e.to_s
84
+ end
85
+
86
+ product = NMatrix.new([3,3], [12,15,18, 18,21,24, -7,-8,-9], dtype: dtype)
87
+ expect(b).to eq(product)
88
+ end
89
+ end
90
+ end
91
+
92
+ #should have a separate test for complex
93
+ [:float32, :float64, :complex64, :complex128, :object].each do |dtype|
94
+ context dtype do
95
+
96
+ it "exposes cblas rot" do
97
+ x = NMatrix.new([5,1], [1,2,3,4,5], dtype: dtype)
98
+ y = NMatrix.new([5,1], [-5,-4,-3,-2,-1], dtype: dtype)
99
+ x, y = NMatrix::BLAS::rot(x, y, 1.0/2, Math.sqrt(3)/2, -1)
100
+
101
+ expect(x).to be_within(1e-4).of(
102
+ NMatrix.new([5,1], [-0.3660254037844386, -0.7320508075688772, -1.098076211353316, -1.4641016151377544, -1.8301270189221928], dtype: dtype)
103
+ )
104
+
105
+ expect(y).to be_within(1e-4).of(
106
+ NMatrix.new([5,1], [-6.830127018922193, -5.464101615137754, -4.098076211353316, -2.732050807568877, -1.3660254037844386], dtype: dtype)
107
+ )
108
+ end
109
+
110
+ end
111
+ end
112
+
113
+ [:float32, :float64, :complex64, :complex128, :object].each do |dtype|
114
+ context dtype do
115
+
116
+ it "exposes cblas rotg" do
117
+ pending("broken for :object") if dtype == :object
118
+
119
+ ab = NMatrix.new([2,1], [6,-8], dtype: dtype)
120
+ begin
121
+ c,s = NMatrix::BLAS::rotg(ab)
122
+ rescue NotImplementedError => e
123
+ pending e.to_s
124
+ end
125
+
126
+ if [:float32, :float64].include?(dtype)
127
+ expect(ab[0]).to be_within(1e-6).of(-10)
128
+ expect(ab[1]).to be_within(1e-6).of(-5.0/3)
129
+ expect(c).to be_within(1e-6).of(-3.0/5)
130
+ else
131
+ pending "need correct test cases"
132
+ expect(ab[0]).to be_within(1e-6).of(10)
133
+ expect(ab[1]).to be_within(1e-6).of(5.0/3)
134
+ expect(c).to be_within(1e-6).of(3.0/5)
135
+ end
136
+ expect(s).to be_within(1e-6).of(4.0/5)
137
+ end
138
+
139
+ # Note: this exposes gemm, not cblas_gemm (which is the unfriendly CBLAS no-error-checking version)
140
+ it "exposes gemm" do
141
+ n = NMatrix.new([4,3], [14.0,9.0,3.0, 2.0,11.0,15.0, 0.0,12.0,17.0, 5.0,2.0,3.0], dtype: dtype)
142
+ m = NMatrix.new([3,2], [12.0,25.0, 9.0,10.0, 8.0,5.0], dtype: dtype)
143
+
144
+ #c = NMatrix.new([4,2], dtype)
145
+ r = NMatrix::BLAS.gemm(n, m) #, c)
146
+ #c.should equal(r) # check that both are same memory address
147
+
148
+ expect(r).to eq(NMatrix.new([4,2], [273,455,243,235,244,205,102,160], dtype: dtype))
149
+ end
150
+
151
+ it "exposes gemv" do
152
+ a = NMatrix.new([4,3], [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0], dtype: dtype)
153
+ x = NMatrix.new([3,1], [2.0, 1.0, 0.0], dtype: dtype)
154
+ y = NMatrix::BLAS.gemv(a, x)
155
+ expect(y).to eq(NMatrix.new([4,1],[4.0,13.0,22.0,31.0],dtype: dtype))
156
+ end
157
+
158
+ it "exposes asum" do
159
+ pending("broken for :object") if dtype == :object
160
+
161
+ x = NMatrix.new([4,1], [-1,2,3,4], dtype: dtype)
162
+ expect(NMatrix::BLAS.asum(x)).to eq(10)
163
+ end
164
+
165
+ it "exposes asum for single element" do
166
+ if [:complex64,:complex128].include?(dtype)
167
+ x = NMatrix.new([1], [Complex(-3,2)], dtype: dtype)
168
+ expect(x.asum).to eq(5.0)
169
+ else
170
+ x = NMatrix.new([1], [-1], dtype: dtype)
171
+ expect(x.asum).to eq(1.0)
172
+ end
173
+ end
174
+
175
+ it "exposes nrm2" do
176
+ pending("broken for :object") if dtype == :object
177
+ pending("Temporarily disable because the internal implementation of nrm2 is broken -WL 2015-05-17") if dtype == :complex64 || dtype == :complex128
178
+
179
+ x = NMatrix.new([4,1], [2,-4,3,5], dtype: dtype)
180
+ err = case dtype
181
+ when :float32, :complex64
182
+ 1e-6
183
+ when :float64, :complex128
184
+ 1e-14
185
+ else
186
+ 1e-14
187
+ end
188
+ expect(NMatrix::BLAS.nrm2(x, 1, 3)).to be_within(err).of(5.385164807134504)
189
+ end
190
+
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,303 @@
1
+ # = NMatrix
2
+ #
3
+ # A linear algebra library for scientific computation in Ruby.
4
+ # NMatrix is part of SciRuby.
5
+ #
6
+ # NMatrix was originally inspired by and derived from NArray, by
7
+ # Masahiro Tanaka: http://narray.rubyforge.org
8
+ #
9
+ # == Copyright Information
10
+ #
11
+ # SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
12
+ # NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
13
+ #
14
+ # Please see LICENSE.txt for additional copyright notices.
15
+ #
16
+ # == Contributing
17
+ #
18
+ # By contributing source code to SciRuby, you agree to be bound by
19
+ # our Contributor Agreement:
20
+ #
21
+ # * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
22
+ #
23
+ # == nmatrix_spec.rb
24
+ #
25
+ # Element-wise operation tests.
26
+ #
27
+
28
+ require 'spec_helper'
29
+
30
+ describe NMatrix do
31
+ context "yale" do
32
+ before :each do
33
+ @n = NMatrix.new(3, stype: :yale, dtype: :int64)
34
+ @n.extend NMatrix::YaleFunctions
35
+ @m = NMatrix.new(3, stype: :yale, dtype: :int64)
36
+ @n[0,0] = 52
37
+ @n[0,2] = 5
38
+ @n[1,1] = 40
39
+ @n[0,1] = 30
40
+ @n[2,0] = 6
41
+ @m[1,1] = -48
42
+ @m[0,2] = -5
43
+ @n.extend NMatrix::YaleFunctions
44
+ end
45
+
46
+ it "should perform scalar math" do
47
+ x = @n * 3
48
+ expect(x[0,0]).to eq(52 * 3)
49
+ expect(x[0,1]).to eq(30 * 3)
50
+ expect(x[0,2]).to eq(5 * 3)
51
+ expect(x[1,1]).to eq(40 * 3)
52
+ expect(x[2,0]).to eq(6 * 3)
53
+
54
+ r = NMatrix.new(3, stype: :yale, dtype: :int64)
55
+ y = r + 3
56
+ expect(y[0,0]).to eq(3)
57
+ end
58
+
59
+ it "should refuse to perform a dot operation on a yale with non-zero default" do
60
+ r = NMatrix.new(3, stype: :yale, dtype: :int64)
61
+ y = r + 3
62
+ expect { y.dot(r) }.to raise_error
63
+ expect { r.dot(y) }.to raise_error
64
+ end
65
+
66
+ it "should perform element-wise addition" do
67
+ expect(@n+@m).to eq(NMatrix.new(:dense, 3, [52,30,0,0,-8,0,6,0,0], :int64).cast(:yale, :int64))
68
+ end
69
+
70
+ it "should perform element-wise subtraction" do
71
+ expect(@n-@m).to eq(NMatrix.new(:dense, 3, [52,30,10,0,88,0,6,0,0], :int64).cast(:yale, :int64))
72
+ end
73
+
74
+ it "should perform element-wise multiplication" do
75
+ r = NMatrix.new(:dense, 3, [0,0,-25,0,-1920,0,0,0,0], :int64).cast(:yale, :int64)
76
+ m = NMatrix.new(2, stype: :yale, dtype: :int64)
77
+ expect(@n*@m).to eq(r)
78
+ end
79
+
80
+ it "should perform element-wise division" do
81
+ r = NMatrix.new(:dense, 3, [52, 30, -2, 0, -1, 0, 6, 0, 0], :int64).cast(:yale, :int64)
82
+ expect(@n/(@m+1)).to eq(r)
83
+ end
84
+
85
+ it "should perform element-wise modulo" do
86
+ m = NMatrix.new(3, stype: :yale, dtype: :int64, default: 0) + 5
87
+ expect(@n % m).to eq(NMatrix.new(:dense, 3, [2,0,0,0,0,0,1,0,0], :int64).cast(:yale, :int64))
88
+ end
89
+
90
+ it "should handle element-wise equality (=~)" do
91
+ expect(@n =~ @m).to eq(NMatrix.new(:dense, 3, [false,false,false,true,false,true,false,true,true], :object).cast(:yale, :object, false))
92
+ end
93
+
94
+ it "should handle element-wise inequality (!~)" do
95
+ expect(@n !~ @m).to eq(NMatrix.new(:dense, 3, [true,true,true,false,true,false,true,false,false], :object).cast(:yale, :object, true))
96
+ end
97
+
98
+ it "should handle element-wise less-than (<)" do
99
+ expect(@m < @n).to eq(NMatrix.new(:dense, 3, [true,true,true,false,true,false,true,false,false], :object).cast(:yale, :object, true))
100
+ end
101
+
102
+ it "should handle element-wise greater-than (>)" do
103
+ expect(@n > @m).to eq(NMatrix.new(:dense, 3, [true,true,true,false,true,false,true,false,false], :object).cast(:yale, :object, false))
104
+ end
105
+
106
+ it "should handle element-wise greater-than-or-equals (>=)" do
107
+ expect(@n >= @m).to eq(NMatrix.new(:dense, 3, true, :object).cast(:yale,:object, true))
108
+ end
109
+
110
+ it "should handle element-wise less-than-or-equals (<=)" do
111
+ r = NMatrix.new(:dense, 3, [false,false,false,true,false,true,false,true,true], :object).cast(:yale, :object, false)
112
+ expect(@n <= @m).to eq(r)
113
+ end
114
+ end
115
+
116
+
117
+ context "list" do
118
+ before :each do
119
+ @n = NMatrix.new(:list, 2, 0, :int64)
120
+ @m = NMatrix.new(:list, 2, 0, :int64)
121
+ @n[0,0] = 52
122
+ @m[1,1] = -48
123
+ @n[1,1] = 40
124
+ end
125
+
126
+ it "should perform scalar math" do
127
+ x = @n * 3
128
+ expect(x[0,0]).to eq(52 * 3)
129
+ expect(x[1,1]).to eq(40 * 3)
130
+ expect(x[0,1]).to eq(0)
131
+
132
+ r = NMatrix.new(3, stype: :list, default: 1)
133
+ y = r + 3
134
+ expect(y[0,0]).to eq(4)
135
+ end
136
+
137
+ it "should perform element-wise addition" do
138
+ r = NMatrix.new(2, stype: :list, dtype: :int64, default: 0)
139
+ r[0,0] = 52
140
+ r[1,1] = -8
141
+ q = @n + @m
142
+ expect(q).to eq(r)
143
+ end
144
+
145
+ it "should perform element-wise subtraction" do
146
+ r = NMatrix.new(:dense, 2, [52, 0, 0, 88], :int64).cast(:list, :int64)
147
+ expect(@n-@m).to eq(r)
148
+ end
149
+
150
+ it "should perform element-wise multiplication" do
151
+ r = NMatrix.new(:dense, 2, [52, 0, 0, -1920], :int64).cast(:list, :int64)
152
+ m = NMatrix.new(:list, 2, 1, :int64)
153
+ m[1,1] = -48
154
+ expect(@n*m).to eq(r)
155
+ end
156
+
157
+ it "should perform element-wise division" do
158
+ m = NMatrix.new(:list, 2, 1, :int64)
159
+ m[1,1] = 2
160
+ r = NMatrix.new(:dense, 2, [52, 0, 0, 20], :int64).cast(:list, :int64)
161
+ expect(@n/m).to eq(r)
162
+ end
163
+
164
+ it "should perform element-wise modulo" do
165
+ m = NMatrix.new(:list, 2, 1, :int64)
166
+ m[0,0] = 50
167
+ m[1,1] = 40
168
+ (@n % m)
169
+ end
170
+
171
+ it "should handle element-wise equality (=~)" do
172
+ r = NMatrix.new(:list, 2, false, :object)
173
+ r[0,1] = true
174
+ r[1,0] = true
175
+
176
+ expect(@n =~ @m).to eq(r)
177
+ end
178
+
179
+ it "should handle element-wise inequality (!~)" do
180
+ r = NMatrix.new(:list, 2, false, :object)
181
+ r[0,0] = true
182
+ r[1,1] = true
183
+
184
+ expect(@n !~ @m).to eq(r)
185
+ end
186
+
187
+ it "should handle element-wise less-than (<)" do
188
+ expect(@n < @m).to eq(NMatrix.new(:list, 2, false, :object))
189
+ end
190
+
191
+ it "should handle element-wise greater-than (>)" do
192
+ r = NMatrix.new(:list, 2, false, :object)
193
+ r[0,0] = true
194
+ r[1,1] = true
195
+ expect(@n > @m).to eq(r)
196
+ end
197
+
198
+ it "should handle element-wise greater-than-or-equals (>=)" do
199
+ expect(@n >= @m).to eq(NMatrix.new(:list, 2, true, :object))
200
+ end
201
+
202
+ it "should handle element-wise less-than-or-equals (<=)" do
203
+ r = NMatrix.new(:list, 2, false, :object)
204
+ r[0,1] = true
205
+ r[1,0] = true
206
+ expect(@n <= @m).to eq(r)
207
+ end
208
+ end
209
+
210
+ context "dense" do
211
+ context "scalar arithmetic" do
212
+ before :each do
213
+ @n = NMatrix.new(:dense, 2, [1,2,3,4], :int64)
214
+ end
215
+
216
+ it "works for integers" do
217
+ expect(@n+1).to eq(NMatrix.new(:dense, 2, [2,3,4,5], :int64))
218
+ end
219
+
220
+ #it "works for complex64" do
221
+ # n = @n.cast(:dtype => :complex64)
222
+ # (n + 10.0).to_a.should == [Complex(11.0), Complex(12.0), Complex(13.0), Complex(14.0)]
223
+ #end
224
+ end
225
+
226
+ context "elementwise arithmetic" do
227
+ before :each do
228
+ @n = NMatrix.new(:dense, 2, [1,2,3,4], :int64)
229
+ @m = NMatrix.new(:dense, 2, [-4,-1,0,66], :int64)
230
+ end
231
+
232
+ it "adds" do
233
+ r = @n+@m
234
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [-3, 1, 3, 70], :int64))
235
+ end
236
+
237
+ it "subtracts" do
238
+ r = @n-@m
239
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [5, 3, 3, -62], :int64))
240
+ end
241
+
242
+ it "multiplies" do
243
+ r = @n*@m
244
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [-4, -2, 0, 264], :int64))
245
+ end
246
+
247
+ it "divides in the Ruby way" do
248
+ m = @m.clone
249
+ m[1,0] = 3
250
+ r = @n/m
251
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [-1, -2, 1, 0], :int64))
252
+ end
253
+
254
+ it "exponentiates" do
255
+ r = @n ** 2
256
+ # TODO: We might have problems with the dtype.
257
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [1, 4, 9, 16], :int64))
258
+ end
259
+
260
+ it "modulo" do
261
+ expect(@n % (@m + 2)).to eq(NMatrix.new(:dense, [2,2], [-1, 0, 1, 4], :int64))
262
+ end
263
+ end
264
+
265
+ context "elementwise comparisons" do
266
+ before :each do
267
+ @n = NMatrix.new(:dense, 2, [1,2,3,4], :int64)
268
+ @m = NMatrix.new(:dense, 2, [-4,-1,3,2], :int64)
269
+ end
270
+
271
+ it "equals" do
272
+ r = @n =~ @m
273
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [false, false, true, false], :object))
274
+ end
275
+
276
+ it "is not equal" do
277
+ r = @n !~ @m
278
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [true, true, false, true], :object))
279
+ end
280
+
281
+ it "is less than" do
282
+ r = @n < @m
283
+ expect(r).to eq(NMatrix.new(:dense, [2,2], false, :object))
284
+ end
285
+
286
+ it "is greater than" do
287
+ r = @n > @m
288
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [true, true, false, true], :object))
289
+ end
290
+
291
+ it "is less than or equal to" do
292
+ r = @n <= @m
293
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [false, false, true, false], :object))
294
+ end
295
+
296
+ it "is greater than or equal to" do
297
+ n = NMatrix.new(:dense, [2,2], [1, 2, 2, 4], :int64)
298
+ r = n >= @m
299
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [true, true, false, true], :object))
300
+ end
301
+ end
302
+ end
303
+ end