nmatrix 0.0.9 → 0.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -0
- data/History.txt +95 -1
- data/LICENSE.txt +2 -2
- data/README.rdoc +24 -26
- data/Rakefile +32 -16
- data/ext/nmatrix/data/complex.h +2 -2
- data/ext/nmatrix/data/data.cpp +27 -51
- data/ext/nmatrix/data/data.h +92 -4
- data/ext/nmatrix/data/meta.h +2 -2
- data/ext/nmatrix/data/rational.h +2 -2
- data/ext/nmatrix/data/ruby_object.h +2 -2
- data/ext/nmatrix/extconf.rb +87 -86
- data/ext/nmatrix/math.cpp +45 -40
- data/ext/nmatrix/math/asum.h +3 -3
- data/ext/nmatrix/math/geev.h +2 -2
- data/ext/nmatrix/math/gemm.h +6 -2
- data/ext/nmatrix/math/gemv.h +6 -2
- data/ext/nmatrix/math/ger.h +2 -2
- data/ext/nmatrix/math/gesdd.h +2 -2
- data/ext/nmatrix/math/gesvd.h +2 -2
- data/ext/nmatrix/math/getf2.h +2 -2
- data/ext/nmatrix/math/getrf.h +2 -2
- data/ext/nmatrix/math/getri.h +2 -2
- data/ext/nmatrix/math/getrs.h +7 -3
- data/ext/nmatrix/math/idamax.h +2 -2
- data/ext/nmatrix/math/inc.h +12 -6
- data/ext/nmatrix/math/laswp.h +2 -2
- data/ext/nmatrix/math/long_dtype.h +2 -2
- data/ext/nmatrix/math/math.h +16 -10
- data/ext/nmatrix/math/nrm2.h +3 -3
- data/ext/nmatrix/math/potrs.h +7 -3
- data/ext/nmatrix/math/rot.h +2 -2
- data/ext/nmatrix/math/rotg.h +2 -2
- data/ext/nmatrix/math/scal.h +2 -2
- data/ext/nmatrix/math/swap.h +2 -2
- data/ext/nmatrix/math/trsm.h +7 -3
- data/ext/nmatrix/nm_memory.h +60 -0
- data/ext/nmatrix/nmatrix.cpp +13 -47
- data/ext/nmatrix/nmatrix.h +37 -12
- data/ext/nmatrix/ruby_constants.cpp +4 -2
- data/ext/nmatrix/ruby_constants.h +4 -2
- data/ext/nmatrix/ruby_nmatrix.c +937 -170
- data/ext/nmatrix/storage/common.cpp +2 -2
- data/ext/nmatrix/storage/common.h +2 -2
- data/ext/nmatrix/storage/{dense.cpp → dense/dense.cpp} +253 -100
- data/ext/nmatrix/storage/{dense.h → dense/dense.h} +6 -5
- data/ext/nmatrix/storage/{list.cpp → list/list.cpp} +517 -98
- data/ext/nmatrix/storage/{list.h → list/list.h} +13 -6
- data/ext/nmatrix/storage/storage.cpp +48 -19
- data/ext/nmatrix/storage/storage.h +4 -4
- data/ext/nmatrix/storage/yale/class.h +112 -43
- data/ext/nmatrix/storage/yale/iterators/base.h +2 -2
- data/ext/nmatrix/storage/yale/iterators/iterator.h +2 -2
- data/ext/nmatrix/storage/yale/iterators/row.h +2 -2
- data/ext/nmatrix/storage/yale/iterators/row_stored.h +2 -2
- data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +4 -3
- data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +2 -2
- data/ext/nmatrix/storage/yale/math/transpose.h +2 -2
- data/ext/nmatrix/storage/yale/yale.cpp +343 -52
- data/ext/nmatrix/storage/yale/yale.h +7 -3
- data/ext/nmatrix/types.h +2 -2
- data/ext/nmatrix/util/io.cpp +5 -5
- data/ext/nmatrix/util/io.h +2 -2
- data/ext/nmatrix/util/sl_list.cpp +40 -27
- data/ext/nmatrix/util/sl_list.h +3 -3
- data/ext/nmatrix/util/util.h +2 -2
- data/lib/nmatrix.rb +2 -2
- data/lib/nmatrix/blas.rb +2 -2
- data/lib/nmatrix/enumerate.rb +17 -6
- data/lib/nmatrix/io/market.rb +2 -3
- data/lib/nmatrix/io/mat5_reader.rb +2 -2
- data/lib/nmatrix/io/mat_reader.rb +2 -2
- data/lib/nmatrix/lapack.rb +46 -46
- data/lib/nmatrix/math.rb +213 -20
- data/lib/nmatrix/monkeys.rb +24 -2
- data/lib/nmatrix/nmatrix.rb +394 -9
- data/lib/nmatrix/nvector.rb +2 -64
- data/lib/nmatrix/rspec.rb +2 -2
- data/lib/nmatrix/shortcuts.rb +14 -61
- data/lib/nmatrix/version.rb +11 -3
- data/lib/nmatrix/yale_functions.rb +4 -4
- data/nmatrix.gemspec +2 -7
- data/scripts/mac-brew-gcc.sh +11 -8
- data/scripts/mac-mavericks-brew-gcc.sh +22 -0
- data/spec/00_nmatrix_spec.rb +116 -7
- data/spec/01_enum_spec.rb +17 -3
- data/spec/02_slice_spec.rb +11 -3
- data/spec/blas_spec.rb +5 -2
- data/spec/elementwise_spec.rb +5 -2
- data/spec/io_spec.rb +27 -17
- data/spec/lapack_spec.rb +157 -9
- data/spec/math_spec.rb +95 -4
- data/spec/nmatrix_yale_spec.rb +21 -26
- data/spec/rspec_monkeys.rb +27 -0
- data/spec/rspec_spec.rb +2 -2
- data/spec/shortcuts_spec.rb +5 -10
- data/spec/slice_set_spec.rb +6 -2
- data/spec/spec_helper.rb +3 -2
- data/spec/stat_spec.rb +174 -158
- metadata +15 -15
@@ -9,8 +9,8 @@
|
|
9
9
|
#
|
10
10
|
# == Copyright Information
|
11
11
|
#
|
12
|
-
# SciRuby is Copyright (c) 2010 -
|
13
|
-
# NMatrix is Copyright (c) 2012, Ruby Science Foundation
|
12
|
+
# SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
|
13
|
+
# NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
|
14
14
|
#
|
15
15
|
# Please see LICENSE.txt for additional copyright notices.
|
16
16
|
#
|
data/lib/nmatrix/lapack.rb
CHANGED
@@ -9,8 +9,8 @@
|
|
9
9
|
#
|
10
10
|
# == Copyright Information
|
11
11
|
#
|
12
|
-
# SciRuby is Copyright (c) 2010 -
|
13
|
-
# NMatrix is Copyright (c)
|
12
|
+
# SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
|
13
|
+
# NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
|
14
14
|
#
|
15
15
|
# Please see LICENSE.txt for additional copyright notices.
|
16
16
|
#
|
@@ -64,16 +64,16 @@ class NMatrix
|
|
64
64
|
# - +nrhs+ ->
|
65
65
|
# - +a+ ->
|
66
66
|
# - +lda+ ->
|
67
|
-
# - +ipiv+ ->
|
68
67
|
# - +b+ ->
|
69
68
|
# - +ldb+ ->
|
69
|
+
# - +ipiv+ -> A pivot array (if nil, one will be generated with +clapack_getrf+)
|
70
70
|
# * *Returns* :
|
71
71
|
# -
|
72
72
|
# * *Raises* :
|
73
73
|
# - ++ ->
|
74
74
|
#
|
75
|
-
def clapack_gesv(order, n, nrhs, a, lda,
|
76
|
-
clapack_getrf(order, n, n, a, lda
|
75
|
+
def clapack_gesv(order, n, nrhs, a, lda, b, ldb, ipiv=nil)
|
76
|
+
ipiv ||= clapack_getrf(order, n, n, a, lda)
|
77
77
|
clapack_getrs(order, :no_transpose, n, nrhs, a, lda, ipiv, b, ldb)
|
78
78
|
end
|
79
79
|
|
@@ -120,47 +120,6 @@ class NMatrix
|
|
120
120
|
clapack_potrs(order, uplo, n, nrhs, a, lda, b, ldb)
|
121
121
|
end
|
122
122
|
|
123
|
-
#
|
124
|
-
# call-seq:
|
125
|
-
# gesvd(matrix, type)
|
126
|
-
#
|
127
|
-
#
|
128
|
-
# * *Arguments* :
|
129
|
-
# - +matrix+ -> matrix for which to compute the singular values ##TODO make this a self
|
130
|
-
# - +type+ -> :all_values, :both, :left, :right, :left_matrix, :right_matrix, :overwrite_right, :overwrite_left, :none , or signifying what combination of singular values and matrices are desired in your output.
|
131
|
-
# * *Returns* :
|
132
|
-
# - Array with the result values in an array
|
133
|
-
# * *Raises* :
|
134
|
-
# - +ArgumentError+ -> Expected dense NMatrix as first argument.
|
135
|
-
#
|
136
|
-
def gesvd(matrix, type = :both)
|
137
|
-
raise ArgumentError, 'Expected dense NMatrix as first argument.' unless matrix.is_a?(NMatrix) and matrix.stype == :dense
|
138
|
-
#define jobu, jobvt
|
139
|
-
jobu, jobvt = :none, :none
|
140
|
-
case type
|
141
|
-
when :both
|
142
|
-
jobu, jobvt = :all, :all
|
143
|
-
when :arrays
|
144
|
-
jobu, jobvt = :return, :return
|
145
|
-
when :left
|
146
|
-
jobu = :return
|
147
|
-
when :right
|
148
|
-
jobvt = :return
|
149
|
-
end
|
150
|
-
|
151
|
-
# Build up the u and vt matrices
|
152
|
-
m, n = matrix.shape
|
153
|
-
dtype = matrix.dtype
|
154
|
-
s_matrix = NMatrix.new([1,matrix.shape.min], dtype: dtype)
|
155
|
-
u_matrix = NMatrix.new([m,m], dtype: dtype)
|
156
|
-
v_matrix = NMatrix.new([n,n], dtype: dtype)
|
157
|
-
# test this
|
158
|
-
s = gesvd(type, matrix, s_matrix, u_matrix, v_matrix)
|
159
|
-
|
160
|
-
# what should this return?
|
161
|
-
[s_matrix, u_matrix, v_matrix]
|
162
|
-
end # #svd
|
163
|
-
|
164
123
|
# laswp(matrix, ipiv) -> NMatrix
|
165
124
|
#
|
166
125
|
# Permute the columns of a matrix (in-place) according to the Array +ipiv+.
|
@@ -173,6 +132,47 @@ class NMatrix
|
|
173
132
|
clapack_laswp(matrix.shape[0], matrix, matrix.shape[1], 0, ipiv.size-1, ipiv, 1)
|
174
133
|
end
|
175
134
|
|
135
|
+
def alloc_svd_result(matrix)
|
136
|
+
[
|
137
|
+
NMatrix.new(matrix.shape[0], dtype: matrix.dtype),
|
138
|
+
NMatrix.new([matrix.shape[0],1], dtype: matrix.dtype),
|
139
|
+
NMatrix.new(matrix.shape[1], dtype: matrix.dtype)
|
140
|
+
]
|
141
|
+
end
|
142
|
+
|
143
|
+
#
|
144
|
+
# call-seq:
|
145
|
+
# gesvd -> [u, sigma, v_transpose]
|
146
|
+
# gesvd -> [u, sigma, v_conjugate_transpose] # complex
|
147
|
+
#
|
148
|
+
# Compute the singular value decomposition of a matrix using LAPACK's GESVD function.
|
149
|
+
#
|
150
|
+
# Optionally accepts a +workspace_size+ parameter, which will be honored only if it is larger than what LAPACK
|
151
|
+
# requires.
|
152
|
+
#
|
153
|
+
def gesvd(matrix, workspace_size=1)
|
154
|
+
result = alloc_svd_result(matrix)
|
155
|
+
NMatrix::LAPACK::lapack_gesvd(:a, :a, matrix.shape[0], matrix.shape[1], matrix, matrix.shape[0], result[1], result[0], matrix.shape[0], result[2], matrix.shape[1], workspace_size)
|
156
|
+
result
|
157
|
+
end
|
158
|
+
|
159
|
+
#
|
160
|
+
# call-seq:
|
161
|
+
# gesdd -> [u, sigma, v_transpose]
|
162
|
+
# gesdd -> [u, sigma, v_conjugate_transpose] # complex
|
163
|
+
#
|
164
|
+
# Compute the singular value decomposition of a matrix using LAPACK's GESDD function. This uses a divide-and-conquer
|
165
|
+
# strategy. See also #gesvd.
|
166
|
+
#
|
167
|
+
# Optionally accepts a +workspace_size+ parameter, which will be honored only if it is larger than what LAPACK
|
168
|
+
# requires.
|
169
|
+
#
|
170
|
+
def gesdd(matrix, workspace_size=100000)
|
171
|
+
result = alloc_svd_result(matrix)
|
172
|
+
NMatrix::LAPACK::lapack_gesdd(:a, matrix.shape[0], matrix.shape[1], matrix, matrix.shape[0], result[1], result[0], matrix.shape[0], result[2], matrix.shape[1], workspace_size)
|
173
|
+
result
|
174
|
+
end
|
175
|
+
|
176
176
|
end
|
177
177
|
end
|
178
178
|
end
|
data/lib/nmatrix/math.rb
CHANGED
@@ -9,8 +9,8 @@
|
|
9
9
|
#
|
10
10
|
# == Copyright Information
|
11
11
|
#
|
12
|
-
# SciRuby is Copyright (c) 2010 -
|
13
|
-
# NMatrix is Copyright (c)
|
12
|
+
# SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
|
13
|
+
# NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
|
14
14
|
#
|
15
15
|
# Please see LICENSE.txt for additional copyright notices.
|
16
16
|
#
|
@@ -29,6 +29,13 @@
|
|
29
29
|
#++
|
30
30
|
|
31
31
|
class NMatrix
|
32
|
+
|
33
|
+
module NMMath
|
34
|
+
METHODS_ARITY_2 = [:atan2, :ldexp, :hypot]
|
35
|
+
METHODS_ARITY_1 = [:cos, :sin, :tan, :acos, :asin, :atan, :cosh, :sinh, :tanh, :acosh,
|
36
|
+
:asinh, :atanh, :exp, :log2, :log10, :sqrt, :cbrt, :erf, :erfc, :gamma]
|
37
|
+
end
|
38
|
+
|
32
39
|
#
|
33
40
|
# call-seq:
|
34
41
|
# invert! -> NMatrix
|
@@ -75,10 +82,66 @@ class NMatrix
|
|
75
82
|
# - +StorageTypeError+ -> ATLAS functions only work on dense matrices.
|
76
83
|
#
|
77
84
|
def getrf!
|
78
|
-
raise(StorageTypeError, "ATLAS functions only work on dense matrices") unless self.
|
85
|
+
raise(StorageTypeError, "ATLAS functions only work on dense matrices") unless self.dense?
|
79
86
|
NMatrix::LAPACK::clapack_getrf(:row, self.shape[0], self.shape[1], self, self.shape[1])
|
80
87
|
end
|
81
88
|
|
89
|
+
|
90
|
+
#
|
91
|
+
# call-seq:
|
92
|
+
# getrf -> NMatrix
|
93
|
+
#
|
94
|
+
# In-place version of #getrf!. Returns the new matrix, which contains L and U matrices.
|
95
|
+
#
|
96
|
+
# * *Raises* :
|
97
|
+
# - +StorageTypeError+ -> ATLAS functions only work on dense matrices.
|
98
|
+
#
|
99
|
+
def getrf
|
100
|
+
a = self.clone
|
101
|
+
a.getrf!
|
102
|
+
return a
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
#
|
107
|
+
# call-seq:
|
108
|
+
# potrf!(upper_or_lower) -> NMatrix
|
109
|
+
#
|
110
|
+
# Cholesky factorization of a symmetric positive-definite matrix -- or, if complex,
|
111
|
+
# a Hermitian positive-definite matrix +A+. This uses the ATLAS function clapack_potrf,
|
112
|
+
# so the result will be written in either the upper or lower triangular portion of the
|
113
|
+
# matrix upon which it is called.
|
114
|
+
#
|
115
|
+
# * *Returns* :
|
116
|
+
# the triangular portion specified by the parameter
|
117
|
+
# * *Raises* :
|
118
|
+
# - +StorageTypeError+ -> ATLAS functions only work on dense matrices.
|
119
|
+
#
|
120
|
+
def potrf!(which)
|
121
|
+
raise(StorageTypeError, "ATLAS functions only work on dense matrices") unless self.dense?
|
122
|
+
# FIXME: Surely there's an easy way to calculate one of these from the other. Do we really need to run twice?
|
123
|
+
NMatrix::LAPACK::clapack_potrf(:row, which, self.shape[0], self, self.shape[1])
|
124
|
+
end
|
125
|
+
|
126
|
+
def potrf_upper!
|
127
|
+
potrf! :upper
|
128
|
+
end
|
129
|
+
|
130
|
+
def potrf_lower!
|
131
|
+
potrf! :lower
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
#
|
136
|
+
# call-seq:
|
137
|
+
# factorize_cholesky -> ...
|
138
|
+
#
|
139
|
+
# Cholesky factorization of a matrix.
|
140
|
+
def factorize_cholesky
|
141
|
+
[self.clone.potrf_upper!.triu!,
|
142
|
+
self.clone.potrf_lower!.tril!]
|
143
|
+
end
|
144
|
+
|
82
145
|
#
|
83
146
|
# call-seq:
|
84
147
|
# factorize_lu -> ...
|
@@ -97,12 +160,19 @@ class NMatrix
|
|
97
160
|
t.transpose
|
98
161
|
end
|
99
162
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
163
|
+
#
|
164
|
+
# call-seq:
|
165
|
+
# gesvd! -> [u, sigma, v_transpose]
|
166
|
+
# gesvd! -> [u, sigma, v_conjugate_transpose] # complex
|
167
|
+
#
|
168
|
+
# Compute the singular value decomposition of a matrix using LAPACK's GESVD function.
|
169
|
+
# This is destructive, modifying the source NMatrix. See also #gesdd.
|
170
|
+
#
|
171
|
+
# Optionally accepts a +workspace_size+ parameter, which will be honored only if it is larger than what LAPACK
|
172
|
+
# requires.
|
173
|
+
#
|
174
|
+
def gesvd!(workspace_size=1)
|
175
|
+
NMatrix::LAPACK::gesvd(self, workspace_size)
|
106
176
|
end
|
107
177
|
|
108
178
|
#
|
@@ -116,12 +186,26 @@ class NMatrix
|
|
116
186
|
# requires.
|
117
187
|
#
|
118
188
|
def gesvd(workspace_size=1)
|
119
|
-
|
120
|
-
NMatrix::LAPACK::lapack_gesvd(:a, :a, self.shape[0], self.shape[1], self, self.shape[0], result[1], result[0], self.shape[0], result[2], self.shape[1], workspace_size)
|
121
|
-
result
|
189
|
+
self.clone.gesvd!(workspace_size)
|
122
190
|
end
|
123
191
|
|
124
192
|
|
193
|
+
|
194
|
+
#
|
195
|
+
# call-seq:
|
196
|
+
# gesdd! -> [u, sigma, v_transpose]
|
197
|
+
# gesdd! -> [u, sigma, v_conjugate_transpose] # complex
|
198
|
+
#
|
199
|
+
# Compute the singular value decomposition of a matrix using LAPACK's GESDD function. This uses a divide-and-conquer
|
200
|
+
# strategy. This is destructive, modifying the source NMatrix. See also #gesvd.
|
201
|
+
#
|
202
|
+
# Optionally accepts a +workspace_size+ parameter, which will be honored only if it is larger than what LAPACK
|
203
|
+
# requires.
|
204
|
+
#
|
205
|
+
def gesdd!(workspace_size=1)
|
206
|
+
NMatrix::LAPACK::gesdd(self, workspace_size)
|
207
|
+
end
|
208
|
+
|
125
209
|
#
|
126
210
|
# call-seq:
|
127
211
|
# gesdd -> [u, sigma, v_transpose]
|
@@ -134,11 +218,8 @@ class NMatrix
|
|
134
218
|
# requires.
|
135
219
|
#
|
136
220
|
def gesdd(workspace_size=1)
|
137
|
-
|
138
|
-
NMatrix::LAPACK::lapack_gesvd(:a, :a, self.shape[0], self.shape[1], self, self.shape[0], result[1], result[0], self.shape[0], result[2], self.shape[1], workspace_size)
|
139
|
-
result
|
221
|
+
self.clone.gesdd!(workspace_size)
|
140
222
|
end
|
141
|
-
|
142
223
|
#
|
143
224
|
# call-seq:
|
144
225
|
# laswp!(ary) -> NMatrix
|
@@ -279,8 +360,8 @@ class NMatrix
|
|
279
360
|
reduce_dtype = :float64
|
280
361
|
end
|
281
362
|
inject_rank(dimen, 0.0, reduce_dtype) do |mean, sub_mat|
|
282
|
-
mean + sub_mat
|
283
|
-
end
|
363
|
+
mean + sub_mat
|
364
|
+
end / shape[dimen]
|
284
365
|
end
|
285
366
|
|
286
367
|
##
|
@@ -372,7 +453,7 @@ class NMatrix
|
|
372
453
|
# @see #inject_rank
|
373
454
|
#
|
374
455
|
def std(dimen=0)
|
375
|
-
variance(dimen).
|
456
|
+
variance(dimen).sqrt
|
376
457
|
end
|
377
458
|
|
378
459
|
|
@@ -409,6 +490,38 @@ class NMatrix
|
|
409
490
|
end.cast(self.stype, abs_dtype)
|
410
491
|
end
|
411
492
|
|
493
|
+
|
494
|
+
#
|
495
|
+
# call-seq:
|
496
|
+
# absolute_sum -> Numeric
|
497
|
+
#
|
498
|
+
# == Arguments
|
499
|
+
# - +incx+ -> the skip size (defaults to 1, no skip)
|
500
|
+
# - +n+ -> the number of elements to include
|
501
|
+
#
|
502
|
+
# Return the sum of the contents of the vector. This is the BLAS asum routine.
|
503
|
+
def asum incx=1, n=nil
|
504
|
+
return method_missing(:asum, incx, n) unless vector?
|
505
|
+
NMatrix::BLAS::asum(self, incx, self.size / incx)
|
506
|
+
end
|
507
|
+
alias :absolute_sum :asum
|
508
|
+
|
509
|
+
#
|
510
|
+
# call-seq:
|
511
|
+
# norm2 -> Numeric
|
512
|
+
#
|
513
|
+
# == Arguments
|
514
|
+
# - +incx+ -> the skip size (defaults to 1, no skip)
|
515
|
+
# - +n+ -> the number of elements to include
|
516
|
+
#
|
517
|
+
# Return the 2-norm of the vector. This is the BLAS nrm2 routine.
|
518
|
+
def nrm2 incx=1, n=nil
|
519
|
+
return method_missing(:nrm2, incx, n) unless vector?
|
520
|
+
NMatrix::BLAS::nrm2(self, incx, self.size / incx)
|
521
|
+
end
|
522
|
+
alias :norm2 :nrm2
|
523
|
+
|
524
|
+
|
412
525
|
alias :permute_columns :laswp
|
413
526
|
alias :permute_columns! :laswp!
|
414
527
|
|
@@ -437,6 +550,86 @@ protected
|
|
437
550
|
end
|
438
551
|
end
|
439
552
|
|
553
|
+
# These don't actually take an argument -- they're called reverse-polish style on the matrix.
|
554
|
+
# This group always gets casted to float64.
|
555
|
+
[:log2, :log10, :sqrt, :sin, :cos, :tan, :acos, :asin, :atan, :cosh, :sinh, :tanh, :acosh, :asinh, :atanh, :exp, :erf, :erfc, :gamma, :cbrt].each do |ewop|
|
556
|
+
define_method("__list_unary_#{ewop}__") do
|
557
|
+
self.__list_map_stored__(nil) { |l| Math.send(ewop, l) }.cast(stype, NMatrix.upcast(dtype, :float64))
|
558
|
+
end
|
559
|
+
define_method("__yale_unary_#{ewop}__") do
|
560
|
+
self.__yale_map_stored__ { |l| Math.send(ewop, l) }.cast(stype, NMatrix.upcast(dtype, :float64))
|
561
|
+
end
|
562
|
+
define_method("__dense_unary_#{ewop}__") do
|
563
|
+
self.__dense_map__ { |l| Math.send(ewop, l) }.cast(stype, NMatrix.upcast(dtype, :float64))
|
564
|
+
end
|
565
|
+
end
|
566
|
+
|
567
|
+
# log takes an optional single argument, the base. Default to natural log.
|
568
|
+
def __list_unary_log__(base)
|
569
|
+
self.__list_map_stored__(nil) { |l| Math.log(l, base) }.cast(stype, NMatrix.upcast(dtype, :float64))
|
570
|
+
end
|
571
|
+
|
572
|
+
def __yale_unary_log__(base)
|
573
|
+
self.__yale_map_stored__ { |l| Math.log(l, base) }.cast(stype, NMatrix.upcast(dtype, :float64))
|
574
|
+
end
|
575
|
+
|
576
|
+
def __dense_unary_log__(base)
|
577
|
+
self.__dense_map__ { |l| Math.log(l, base) }.cast(stype, NMatrix.upcast(dtype, :float64))
|
578
|
+
end
|
579
|
+
|
580
|
+
# These take two arguments. One might be a matrix, and one might be a scalar.
|
581
|
+
# See also monkeys.rb, which contains Math module patches to let the first
|
582
|
+
# arg be a scalar
|
583
|
+
[:atan2, :ldexp, :hypot].each do |ewop|
|
584
|
+
define_method("__list_elementwise_#{ewop}__") do |rhs,order|
|
585
|
+
if order then
|
586
|
+
self.__list_map_merged_stored__(rhs, nil) { |r,l| Math.send(ewop,l,r) }
|
587
|
+
else
|
588
|
+
self.__list_map_merged_stored__(rhs, nil) { |l,r| Math.send(ewop,l,r) }
|
589
|
+
end.cast(stype, NMatrix.upcast(dtype, :float64))
|
590
|
+
end
|
591
|
+
|
592
|
+
define_method("__dense_elementwise_#{ewop}__") do |rhs, order|
|
593
|
+
if order then
|
594
|
+
self.__dense_map_pair__(rhs) { |r,l| Math.send(ewop,l,r) }
|
595
|
+
else
|
596
|
+
self.__dense_map_pair__(rhs) { |l,r| Math.send(ewop,l,r) }
|
597
|
+
end.cast(stype, NMatrix.upcast(dtype, :float64))
|
598
|
+
end
|
599
|
+
|
600
|
+
define_method("__yale_elementwise_#{ewop}__") do |rhs, order|
|
601
|
+
if order then
|
602
|
+
self.__yale_map_merged_stored__(rhs, nil) { |r,l| Math.send(ewop,l,r) }
|
603
|
+
else
|
604
|
+
self.__yale_map_merged_stored__(rhs, nil) { |l,r| Math.send(ewop,l,r) }
|
605
|
+
end.cast(stype, NMatrix.upcast(dtype, :float64))
|
606
|
+
end
|
607
|
+
|
608
|
+
define_method("__list_scalar_#{ewop}__") do |rhs,order|
|
609
|
+
if order then
|
610
|
+
self.__list_map_stored__(nil) { |l| Math.send(ewop, rhs, l) }
|
611
|
+
else
|
612
|
+
self.__list_map_stored__(nil) { |l| Math.send(ewop, l, rhs) }
|
613
|
+
end.cast(stype, NMatrix.upcast(dtype, :float64))
|
614
|
+
end
|
615
|
+
|
616
|
+
define_method("__yale_scalar_#{ewop}__") do |rhs,order|
|
617
|
+
if order then
|
618
|
+
self.__yale_map_stored__ { |l| Math.send(ewop, rhs, l) }
|
619
|
+
else
|
620
|
+
self.__yale_map_stored__ { |l| Math.send(ewop, l, rhs) }
|
621
|
+
end.cast(stype, NMatrix.upcast(dtype, :float64))
|
622
|
+
end
|
623
|
+
|
624
|
+
define_method("__dense_scalar_#{ewop}__") do |rhs,order|
|
625
|
+
if order
|
626
|
+
self.__dense_map__ { |l| Math.send(ewop, rhs, l) }
|
627
|
+
else
|
628
|
+
self.__dense_map__ { |l| Math.send(ewop, l, rhs) }
|
629
|
+
end.cast(stype, NMatrix.upcast(dtype, :float64))
|
630
|
+
end
|
631
|
+
end
|
632
|
+
|
440
633
|
# Equality operators do not involve a cast. We want to get back matrices of TrueClass and FalseClass.
|
441
634
|
{eqeq: :==, neq: :!=, lt: :<, gt: :>, leq: :<=, geq: :>=}.each_pair do |ewop, op|
|
442
635
|
define_method("__list_elementwise_#{ewop}__") do |rhs|
|
@@ -459,4 +652,4 @@ protected
|
|
459
652
|
self.__dense_map__ { |l| l.send(op,rhs) }
|
460
653
|
end
|
461
654
|
end
|
462
|
-
end
|
655
|
+
end
|
data/lib/nmatrix/monkeys.rb
CHANGED
@@ -9,8 +9,8 @@
|
|
9
9
|
#
|
10
10
|
# == Copyright Information
|
11
11
|
#
|
12
|
-
# SciRuby is Copyright (c) 2010 -
|
13
|
-
# NMatrix is Copyright (c)
|
12
|
+
# SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
|
13
|
+
# NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
|
14
14
|
#
|
15
15
|
# Please see LICENSE.txt for additional copyright notices.
|
16
16
|
#
|
@@ -26,6 +26,8 @@
|
|
26
26
|
# Ruby core extensions for NMatrix.
|
27
27
|
#++
|
28
28
|
|
29
|
+
require 'nmatrix/math'
|
30
|
+
|
29
31
|
#######################
|
30
32
|
# Classes and Modules #
|
31
33
|
#######################
|
@@ -60,3 +62,23 @@ class Object #:nodoc:
|
|
60
62
|
value
|
61
63
|
end
|
62
64
|
end
|
65
|
+
|
66
|
+
|
67
|
+
module Math
|
68
|
+
class << self
|
69
|
+
NMatrix::NMMath::METHODS_ARITY_2.each do |meth|
|
70
|
+
define_method "nm_#{meth}" do |arg0, arg1|
|
71
|
+
if arg0.is_a? NMatrix then
|
72
|
+
arg0.send(meth, arg1)
|
73
|
+
elsif arg1.is_a? NMatrix then
|
74
|
+
arg1.send(meth, arg0, true)
|
75
|
+
else
|
76
|
+
self.send("old_#{meth}".to_sym, arg0, arg1)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
alias_method "old_#{meth}".to_sym, meth
|
80
|
+
alias_method meth, "nm_#{meth}".to_sym
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|