nmatrix 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,283 @@
1
+ class NMatrix
2
+
3
+ # A dummy matrix is a matrix without the elements atrribute.
4
+ # NMatrix#create_dummy_matrix prevents creating copies as @s is set explicitly.
5
+ def +(other)
6
+ result = create_dummy_nmatrix
7
+ if (other.is_a?(NMatrix))
8
+ #check dimension
9
+ raise(ShapeError, "Cannot add matrices with different dimension") if (@dim != other.dim)
10
+ #check shape
11
+ (0...dim).each do |i|
12
+ raise(ShapeError, "Cannot add matrices with different shapes") if (@shape[i] != other.shape[i])
13
+ end
14
+ result.s = @s.copy.add(other.s)
15
+ else
16
+ result.s = @s.copy.mapAddToSelf(other)
17
+ end
18
+ result
19
+ end
20
+
21
+ def -(other)
22
+ result = create_dummy_nmatrix
23
+ if (other.is_a?(NMatrix))
24
+ #check dimension
25
+ raise(ShapeError, "Cannot subtract matrices with different dimension") if (@dim != other.dim)
26
+ #check shape
27
+ (0...dim).each do |i|
28
+ raise(ShapeError, "Cannot subtract matrices with different shapes") if (@shape[i] != other.shape[i])
29
+ end
30
+ result.s = @s.copy.subtract(other.s)
31
+ else
32
+ result.s = @s.copy.mapSubtractToSelf(other)
33
+ end
34
+ result
35
+ end
36
+
37
+ def *(other)
38
+ result = create_dummy_nmatrix
39
+ if (other.is_a?(NMatrix))
40
+ #check dimension
41
+ raise(ShapeError, "Cannot multiply matrices with different dimension") if (@dim != other.dim)
42
+ #check shape
43
+ (0...dim).each do |i|
44
+ raise(ShapeError, "Cannot multiply matrices with different shapes") if (@shape[i] != other.shape[i])
45
+ end
46
+ result.s = @s.copy.ebeMultiply(other.s)
47
+ else
48
+ result.s = @s.copy.mapMultiplyToSelf(other)
49
+ end
50
+ result
51
+ end
52
+
53
+ def /(other)
54
+ result = create_dummy_nmatrix
55
+ if (other.is_a?(NMatrix))
56
+ #check dimension
57
+ raise(ShapeError, "Cannot divide matrices with different dimension") if (@dim != other.dim)
58
+ #check shape
59
+ (0...dim).each do |i|
60
+ raise(ShapeError, "Cannot divide matrices with different shapes") if (@shape[i] != other.shape[i])
61
+ end
62
+ result.s = @s.copy.ebeDivide(other.s)
63
+ else
64
+ result.s = @s.copy.mapDivideToSelf(other)
65
+ end
66
+ result
67
+ end
68
+
69
+ def ** val
70
+ result = NMatrix.new(:copy)
71
+ result.shape = @shape
72
+ result.dim = @dim
73
+ result.s = @s.copy.mapToSelf(Power.new(val))
74
+ result
75
+ end
76
+
77
+ def %(other)
78
+ raise Exception.new("modulus not supported in NMatrix-jruby")
79
+ end
80
+
81
+ def atan2(other, scalar=false)
82
+ result = create_dummy_nmatrix
83
+ if scalar
84
+ result.s = ArrayRealVector.new MathHelper.atan2Scalar(other, @s.toArray)
85
+ else
86
+ if other.is_a? NMatrix
87
+ result.s = ArrayRealVector.new MathHelper.atan2(other.s.toArray, @s.toArray)
88
+ else
89
+ result.s = ArrayRealVector.new MathHelper.atan2Scalar2(other, @s.toArray)
90
+ end
91
+ end
92
+ result
93
+ end
94
+
95
+ def ldexp(other, scalar=false)
96
+ result = create_dummy_nmatrix
97
+ if scalar
98
+ result.s = ArrayRealVector.new MathHelper.ldexpScalar(other, @s.toArray)
99
+ else
100
+ if other.is_a? NMatrix
101
+ result.s = ArrayRealVector.new MathHelper.ldexp(other.s.toArray, @s.toArray)
102
+ else
103
+ result.s = ArrayRealVector.new MathHelper.ldexpScalar2(other, @s.toArray)
104
+ end
105
+ end
106
+ result
107
+ end
108
+
109
+ def hypot(other, scalar=false)
110
+ result = create_dummy_nmatrix
111
+ if scalar
112
+ result.s = ArrayRealVector.new MathHelper.hypotScalar(other, @s.toArray)
113
+ else
114
+ if other.is_a? NMatrix
115
+ result.s = ArrayRealVector.new MathHelper.hypot(other.s.toArray, @s.toArray)
116
+ else
117
+ result.s = ArrayRealVector.new MathHelper.hypotScalar(other, @s.toArray)
118
+ end
119
+ end
120
+ result
121
+ end
122
+
123
+ def sin
124
+ result = create_dummy_nmatrix
125
+ result.s = @s.copy.mapToSelf(Sin.new())
126
+ result
127
+ end
128
+
129
+ def cos
130
+ result = create_dummy_nmatrix
131
+ result.s = @s.copy.mapToSelf(Cos.new())
132
+ result
133
+ end
134
+
135
+ def tan
136
+ result = create_dummy_nmatrix
137
+ result.s = @s.copy.mapToSelf(Tan.new())
138
+ result
139
+ end
140
+
141
+ def asin
142
+ result = create_dummy_nmatrix
143
+ result.s = @s.copy.mapToSelf(Asin.new())
144
+ result
145
+ end
146
+
147
+ def acos
148
+ result = create_dummy_nmatrix
149
+ result.s = @s.copy.mapToSelf(Acos.new())
150
+ result
151
+ end
152
+
153
+ def atan
154
+ result = create_dummy_nmatrix
155
+ result.s = @s.copy.mapToSelf(Atan.new())
156
+ result
157
+ end
158
+
159
+ def sinh
160
+ result = create_dummy_nmatrix
161
+ result.s = @s.copy.mapToSelf(Sinh.new())
162
+ result
163
+ end
164
+
165
+ def cosh
166
+ result = create_dummy_nmatrix
167
+ result.s = @s.copy.mapToSelf(Cosh.new())
168
+ result
169
+ end
170
+
171
+ def tanh
172
+ result = NMatrix.new(:copy)
173
+ result.shape = @shape
174
+ result.dim = @dim
175
+ result.s = @s.copy.mapToSelf(Tanh.new())
176
+ result
177
+ end
178
+
179
+ def asinh
180
+ result = create_dummy_nmatrix
181
+ result.s = @s.copy.mapToSelf(Asinh.new())
182
+ result
183
+ end
184
+
185
+ def acosh
186
+ result = create_dummy_nmatrix
187
+ result.s = @s.copy.mapToSelf(Acosh.new())
188
+ result
189
+ end
190
+
191
+ def atanh
192
+ result = create_dummy_nmatrix
193
+ result.s = @s.copy.mapToSelf(Atanh.new())
194
+ result
195
+ end
196
+
197
+ def exp
198
+ result = create_dummy_nmatrix
199
+ result.s = @s.copy.mapToSelf(Exp.new())
200
+ result
201
+ end
202
+
203
+ def log(val = :natural)
204
+ result = create_dummy_nmatrix
205
+ if val == :natural
206
+ result.s = @s.copy.mapToSelf(Log.new())
207
+ else
208
+ result.s = ArrayRealVector.new MathHelper.log(val, @s.toArray)
209
+ end
210
+ result
211
+ end
212
+
213
+ def log2
214
+ self.log(2)
215
+ end
216
+
217
+ def log10
218
+ result = create_dummy_nmatrix
219
+ result.s = @s.copy.mapToSelf(Log10.new())
220
+ result
221
+ end
222
+
223
+ def sqrt
224
+ result = create_dummy_nmatrix
225
+ result.s = @s.copy.mapToSelf(Sqrt.new())
226
+ result
227
+ end
228
+
229
+ def erf
230
+ result = create_dummy_nmatrix
231
+ result.s = ArrayRealVector.new MathHelper.erf(@s.toArray)
232
+ result
233
+ end
234
+
235
+ def erfc
236
+ result = create_dummy_nmatrix
237
+ result.s = ArrayRealVector.new MathHelper.erfc(@s.toArray)
238
+ result
239
+ end
240
+
241
+ def cbrt
242
+ result = create_dummy_nmatrix
243
+ result.s = @s.copy.mapToSelf(Cbrt.new())
244
+ result
245
+ end
246
+
247
+ def gamma
248
+ result = create_dummy_nmatrix
249
+ result.s = ArrayRealVector.new MathHelper.gamma(@s.toArray)
250
+ result
251
+ end
252
+
253
+ def -@
254
+ result = create_dummy_nmatrix
255
+ result.s = @s.copy.mapMultiplyToSelf(-1)
256
+ result
257
+ end
258
+
259
+ def floor
260
+ result = create_dummy_nmatrix
261
+ # Need to be changed later
262
+ result.dtype = :int64
263
+ result.s = @s.copy.mapToSelf(Floor.new())
264
+ result
265
+ end
266
+
267
+ def ceil
268
+ result = create_dummy_nmatrix
269
+ # Need to be changed later
270
+ result.dtype = :int64
271
+ result.s = @s.copy.mapToSelf(Ceil.new())
272
+ result
273
+ end
274
+
275
+ def round
276
+ result = create_dummy_nmatrix
277
+ # Need to be changed later
278
+ result.dtype = :int64
279
+ result.s = ArrayRealVector.new MathHelper.round(@s.toArray)
280
+ result
281
+ end
282
+
283
+ end
@@ -0,0 +1,264 @@
1
+ class NMatrix
2
+
3
+ def get_slice(dim, args, shape_array)
4
+ slice = {}
5
+ slice[:coords]=[]
6
+ slice[:lengths]=[]
7
+ slice[:single] = true
8
+
9
+ argc = args.length
10
+
11
+ t = 0
12
+ (0...dim).each do |r|
13
+ v = t == argc ? nil : args[t]
14
+
15
+ if(argc - t + r < dim && shape_array[r] ==1)
16
+ slice[:coords][r] = 0
17
+ slice[:lengths][r] = 1
18
+ elsif v.is_a?(Fixnum)
19
+ v_ = v.to_i.to_int
20
+ if (v_ < 0) # checking for negative indexes
21
+ slice[:coords][r] = shape_array[r]+v_
22
+ else
23
+ slice[:coords][r] = v_
24
+ end
25
+ slice[:lengths][r] = 1
26
+ t+=1
27
+ elsif (v.is_a?(Symbol) && v == :*)
28
+ slice[:coords][r] = 0
29
+ slice[:lengths][r] = shape_array[r]
30
+ slice[:single] = false
31
+ t+=1
32
+ elsif v.is_a?(Range)
33
+ begin_ = v.begin
34
+ end_ = v.end
35
+ excl = v.exclude_end?
36
+ slice[:coords][r] = (begin_ < 0) ? shape[r] + begin_ : begin_
37
+
38
+ # Exclude last element for a...b range
39
+ if (end_ < 0)
40
+ slice[:lengths][r] = shape_array[r] + end_ - slice[:coords][r] + (excl ? 0 : 1)
41
+ else
42
+ slice[:lengths][r] = end_ - slice[:coords][r] + (excl ? 0 : 1)
43
+ end
44
+
45
+ slice[:single] = false
46
+ t+=1
47
+ else
48
+ raise(ArgumentError, "expected Fixnum or Range for slice component instead of #{v.class}")
49
+ end
50
+
51
+ if (slice[:coords][r] > shape_array[r] || slice[:coords][r] + slice[:lengths][r] > shape_array[r])
52
+ raise(RangeError, "slice is larger than matrix in dimension #{r} (slice component #{t})")
53
+ end
54
+ end
55
+
56
+ return slice
57
+ end
58
+
59
+ def get_stride(nmatrix)
60
+ stride = Array.new()
61
+ (0...nmatrix.dim).each do |i|
62
+ stride[i] = 1;
63
+ (i+1...dim).each do |j|
64
+ stride[i] *= nmatrix.shape[j]
65
+ end
66
+ end
67
+ stride
68
+ end
69
+
70
+ def xslice(args)
71
+ result = nil
72
+
73
+ if self.dim < args.length
74
+ raise(ArgumentError,"wrong number of arguments (#{args} for #{effective_dim(self)})")
75
+ else
76
+ result = Array.new()
77
+
78
+ slice = get_slice(@dim, args, @shape)
79
+ stride = get_stride(self)
80
+ if slice[:single]
81
+ if (@dtype == :object)
82
+ result = @s[dense_storage_get(slice,stride)]
83
+ else
84
+ s = @s.toArray().to_a
85
+ result = @s.getEntry(dense_storage_get(slice,stride))
86
+ end
87
+ else
88
+ result = dense_storage_get(slice,stride)
89
+ end
90
+ end
91
+ return result
92
+ end
93
+
94
+ #its by ref
95
+ def xslice_ref(args)
96
+ result = nil
97
+
98
+ if self.dim < args.length
99
+ raise(ArgumentError,"wrong number of arguments (#{args} for #{effective_dim(self)})")
100
+ else
101
+ result = Array.new()
102
+
103
+ slice = get_slice(@dim, args, @shape)
104
+ stride = get_stride(self)
105
+ if slice[:single]
106
+ if (@dtype == :object)
107
+ result = @s[dense_storage_get(slice,stride)]
108
+ else
109
+ result = @s.getEntry(dense_storage_get(slice,stride))
110
+ end
111
+ else
112
+ result = dense_storage_ref(slice,stride)
113
+ end
114
+ end
115
+ return result
116
+ end
117
+
118
+ def dense_storage_get(slice,stride)
119
+ if slice[:single]
120
+ return dense_storage_pos(slice[:coords],stride)
121
+ else
122
+ shape = @shape.dup
123
+ (0...@dim).each do |i|
124
+ shape[i] = slice[:lengths][i]
125
+ end
126
+ psrc = dense_storage_pos(slice[:coords], stride)
127
+ src = {}
128
+ result = NMatrix.new(:copy)
129
+ result.dim = dim
130
+ result.dtype = @dtype
131
+ resultShape= Array.new(dim)
132
+ (0...dim).each do |i|
133
+ resultShape[i] = slice[:lengths][i]
134
+ end
135
+ result.shape = resultShape
136
+ dest = {}
137
+ src[:stride] = get_stride(self)
138
+ if (@dtype == :object)
139
+ src[:elements] = @s
140
+ else
141
+ src[:elements] = @s.toArray().to_a
142
+ end
143
+ dest[:stride] = get_stride(result)
144
+ dest[:shape] = resultShape
145
+ dest[:elements] = []
146
+ temp = []
147
+ s = (slice_copy(src, dest, slice[:lengths], 0, psrc,0))
148
+ # if
149
+ # arr = Java::double[s.length].new
150
+ if (@dtype == :object)
151
+ arr = Java::boolean[s.length].new
152
+ else
153
+ arr = Java::double[s.length].new
154
+ end
155
+ (0...s.length).each do |i|
156
+ arr[i] = s[i]
157
+ end
158
+ if (@dtype == :object)
159
+ result.s = arr
160
+ else
161
+ result.s = ArrayRealVector.new(arr)
162
+ end
163
+
164
+ return result
165
+ end
166
+ end
167
+
168
+ def slice_copy(src, dest,lengths, pdest, psrc,n)
169
+ if @dim-n>1
170
+ (0...lengths[n]).each do |i|
171
+ slice_copy(src, dest, lengths,pdest+dest[:stride][n]*i,psrc+src[:stride][n]*i,n+1)
172
+ end
173
+ else
174
+ (0...dest[:shape][n]).each do |p|
175
+ dest[:elements][p+pdest] = src[:elements][p+psrc]
176
+ end
177
+ end
178
+ dest[:elements]
179
+ end
180
+
181
+ def dense_storage_coords(s, slice_pos, coords_out, stride, offset) #array, int, array
182
+ temp_pos = slice_pos;
183
+
184
+ (0...dim).each do |i|
185
+ coords_out[i] = (temp_pos - temp_pos % stride[i])/stride[i] - offset[i];
186
+ temp_pos = temp_pos % stride[i]
187
+ end
188
+
189
+ return temp_pos
190
+ end
191
+
192
+ def dense_storage_pos(coords,stride)
193
+ pos = 0;
194
+ offset = 0
195
+ (0...@dim).each do |i|
196
+ pos += coords[i] * stride[i] ;
197
+ end
198
+ return pos + offset;
199
+ end
200
+
201
+ def slice_set(dest, lengths, pdest, rank, v, v_size, v_offset)
202
+ if (dim - rank > 1)
203
+ (0...lengths[rank]).each do |i|
204
+ slice_set(dest, lengths, pdest + dest[:stride][rank] * i, rank + 1, v, v_size, v_offset);
205
+ end
206
+ else
207
+ (0...lengths[rank]).each do |p|
208
+ v_offset %= v_size if(v_offset >= v_size)
209
+ # elem = dest[:elements]
210
+ # elem[p + pdest] = v[v_offset]
211
+ if @dtype == :object
212
+ @s[p + pdest] = v[v_offset]
213
+ else
214
+ @s.setEntry(p + pdest, v[v_offset])
215
+ end
216
+ v_offset += 1
217
+ end
218
+ end
219
+ end
220
+
221
+ def dense_storage_set(slice, right)
222
+ stride = get_stride(self)
223
+ v_size = 1
224
+
225
+ if right.is_a?(NMatrix)
226
+ right = right.s.toArray.to_a
227
+ end
228
+
229
+ if(right.is_a?(Array))
230
+ v_size = right.length
231
+ v = right
232
+ if (dtype == :RUBYOBJ)
233
+ # nm_register_values(reinterpret_cast<VALUE*>(v), v_size)
234
+ end
235
+
236
+ (0...v_size).each do |m|
237
+ v[m] = right[m]
238
+ end
239
+ else
240
+ v = [right]
241
+ if (@dtype == :RUBYOBJ)
242
+ # nm_register_values(reinterpret_cast<VALUE*>(v), v_size)
243
+ end
244
+ end
245
+ if(slice[:single])
246
+ # reinterpret_cast<D*>(s->elements)[nm_dense_storage_pos(s, slice->coords)] = v;
247
+ pos = dense_storage_pos(slice[:coords],stride)
248
+ if @dtype == :object
249
+ @s[pos] = v[0]
250
+ else
251
+ @s.setEntry(pos, v[0])
252
+ end
253
+ else
254
+ v_offset = 0
255
+ dest = {}
256
+ dest[:stride] = get_stride(self)
257
+ dest[:shape] = shape
258
+ # dest[:elements] = @s.toArray().to_a
259
+ dense_pos = dense_storage_pos(slice[:coords],stride)
260
+ slice_set(dest, slice[:lengths], dense_pos, 0, v, v_size, v_offset)
261
+ end
262
+ end
263
+
264
+ end