pnmatrix 1.2.4
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.
- checksums.yaml +7 -0
- data/ext/nmatrix/binary_format.txt +53 -0
- data/ext/nmatrix/data/complex.h +388 -0
- data/ext/nmatrix/data/data.cpp +274 -0
- data/ext/nmatrix/data/data.h +651 -0
- data/ext/nmatrix/data/meta.h +64 -0
- data/ext/nmatrix/data/ruby_object.h +386 -0
- data/ext/nmatrix/extconf.rb +70 -0
- data/ext/nmatrix/math/asum.h +99 -0
- data/ext/nmatrix/math/cblas_enums.h +36 -0
- data/ext/nmatrix/math/cblas_templates_core.h +507 -0
- data/ext/nmatrix/math/gemm.h +241 -0
- data/ext/nmatrix/math/gemv.h +178 -0
- data/ext/nmatrix/math/getrf.h +255 -0
- data/ext/nmatrix/math/getrs.h +121 -0
- data/ext/nmatrix/math/imax.h +82 -0
- data/ext/nmatrix/math/laswp.h +165 -0
- data/ext/nmatrix/math/long_dtype.h +62 -0
- data/ext/nmatrix/math/magnitude.h +54 -0
- data/ext/nmatrix/math/math.h +751 -0
- data/ext/nmatrix/math/nrm2.h +165 -0
- data/ext/nmatrix/math/rot.h +117 -0
- data/ext/nmatrix/math/rotg.h +106 -0
- data/ext/nmatrix/math/scal.h +71 -0
- data/ext/nmatrix/math/trsm.h +336 -0
- data/ext/nmatrix/math/util.h +162 -0
- data/ext/nmatrix/math.cpp +1368 -0
- data/ext/nmatrix/nm_memory.h +60 -0
- data/ext/nmatrix/nmatrix.cpp +285 -0
- data/ext/nmatrix/nmatrix.h +476 -0
- data/ext/nmatrix/ruby_constants.cpp +151 -0
- data/ext/nmatrix/ruby_constants.h +106 -0
- data/ext/nmatrix/ruby_nmatrix.c +3130 -0
- data/ext/nmatrix/storage/common.cpp +77 -0
- data/ext/nmatrix/storage/common.h +183 -0
- data/ext/nmatrix/storage/dense/dense.cpp +1096 -0
- data/ext/nmatrix/storage/dense/dense.h +129 -0
- data/ext/nmatrix/storage/list/list.cpp +1628 -0
- data/ext/nmatrix/storage/list/list.h +138 -0
- data/ext/nmatrix/storage/storage.cpp +730 -0
- data/ext/nmatrix/storage/storage.h +99 -0
- data/ext/nmatrix/storage/yale/class.h +1139 -0
- data/ext/nmatrix/storage/yale/iterators/base.h +143 -0
- data/ext/nmatrix/storage/yale/iterators/iterator.h +131 -0
- data/ext/nmatrix/storage/yale/iterators/row.h +450 -0
- data/ext/nmatrix/storage/yale/iterators/row_stored.h +140 -0
- data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +169 -0
- data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +124 -0
- data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
- data/ext/nmatrix/storage/yale/yale.cpp +2074 -0
- data/ext/nmatrix/storage/yale/yale.h +203 -0
- data/ext/nmatrix/types.h +55 -0
- data/ext/nmatrix/util/io.cpp +279 -0
- data/ext/nmatrix/util/io.h +115 -0
- data/ext/nmatrix/util/sl_list.cpp +627 -0
- data/ext/nmatrix/util/sl_list.h +144 -0
- data/ext/nmatrix/util/util.h +78 -0
- data/lib/nmatrix/blas.rb +378 -0
- data/lib/nmatrix/cruby/math.rb +744 -0
- data/lib/nmatrix/enumerate.rb +253 -0
- data/lib/nmatrix/homogeneous.rb +241 -0
- data/lib/nmatrix/io/fortran_format.rb +138 -0
- data/lib/nmatrix/io/harwell_boeing.rb +221 -0
- data/lib/nmatrix/io/market.rb +263 -0
- data/lib/nmatrix/io/point_cloud.rb +189 -0
- data/lib/nmatrix/jruby/decomposition.rb +24 -0
- data/lib/nmatrix/jruby/enumerable.rb +13 -0
- data/lib/nmatrix/jruby/error.rb +4 -0
- data/lib/nmatrix/jruby/math.rb +501 -0
- data/lib/nmatrix/jruby/nmatrix_java.rb +840 -0
- data/lib/nmatrix/jruby/operators.rb +283 -0
- data/lib/nmatrix/jruby/slice.rb +264 -0
- data/lib/nmatrix/lapack_core.rb +181 -0
- data/lib/nmatrix/lapack_plugin.rb +44 -0
- data/lib/nmatrix/math.rb +953 -0
- data/lib/nmatrix/mkmf.rb +100 -0
- data/lib/nmatrix/monkeys.rb +137 -0
- data/lib/nmatrix/nmatrix.rb +1172 -0
- data/lib/nmatrix/rspec.rb +75 -0
- data/lib/nmatrix/shortcuts.rb +1163 -0
- data/lib/nmatrix/version.rb +39 -0
- data/lib/nmatrix/yale_functions.rb +118 -0
- data/lib/nmatrix.rb +28 -0
- data/spec/00_nmatrix_spec.rb +892 -0
- data/spec/01_enum_spec.rb +196 -0
- data/spec/02_slice_spec.rb +407 -0
- data/spec/03_nmatrix_monkeys_spec.rb +80 -0
- data/spec/2x2_dense_double.mat +0 -0
- data/spec/4x4_sparse.mat +0 -0
- data/spec/4x5_dense.mat +0 -0
- data/spec/blas_spec.rb +215 -0
- data/spec/elementwise_spec.rb +311 -0
- data/spec/homogeneous_spec.rb +100 -0
- data/spec/io/fortran_format_spec.rb +88 -0
- data/spec/io/harwell_boeing_spec.rb +98 -0
- data/spec/io/test.rua +9 -0
- data/spec/io_spec.rb +159 -0
- data/spec/lapack_core_spec.rb +482 -0
- data/spec/leakcheck.rb +16 -0
- data/spec/math_spec.rb +1363 -0
- data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
- data/spec/nmatrix_yale_spec.rb +286 -0
- data/spec/rspec_monkeys.rb +56 -0
- data/spec/rspec_spec.rb +35 -0
- data/spec/shortcuts_spec.rb +474 -0
- data/spec/slice_set_spec.rb +162 -0
- data/spec/spec_helper.rb +172 -0
- data/spec/stat_spec.rb +214 -0
- data/spec/test.pcd +20 -0
- data/spec/utm5940.mtx +83844 -0
- metadata +295 -0
|
@@ -0,0 +1,1163 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# = NMatrix
|
|
3
|
+
#
|
|
4
|
+
# A linear algebra library for scientific computation in Ruby.
|
|
5
|
+
# NMatrix is part of SciRuby.
|
|
6
|
+
#
|
|
7
|
+
# NMatrix was originally inspired by and derived from NArray, by
|
|
8
|
+
# Masahiro Tanaka: http://narray.rubyforge.org
|
|
9
|
+
#
|
|
10
|
+
# == Copyright Information
|
|
11
|
+
#
|
|
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
|
+
#
|
|
15
|
+
# Please see LICENSE.txt for additional copyright notices.
|
|
16
|
+
#
|
|
17
|
+
# == Contributing
|
|
18
|
+
#
|
|
19
|
+
# By contributing source code to SciRuby, you agree to be bound by
|
|
20
|
+
# our Contributor Agreement:
|
|
21
|
+
#
|
|
22
|
+
# * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
|
|
23
|
+
#
|
|
24
|
+
# == shortcuts.rb
|
|
25
|
+
#
|
|
26
|
+
# These are shortcuts for NMatrix and NVector creation, contributed by Daniel
|
|
27
|
+
# Carrera (dcarrera@hush.com) and Carlos Agarie (carlos.agarie@gmail.com).
|
|
28
|
+
#
|
|
29
|
+
# TODO Make all the shortcuts available through modules, allowing someone
|
|
30
|
+
# to include them to make "MATLAB-like" scripts.
|
|
31
|
+
#
|
|
32
|
+
# There are some questions to be answered before this can be done, tho.
|
|
33
|
+
#++
|
|
34
|
+
|
|
35
|
+
class NMatrix
|
|
36
|
+
|
|
37
|
+
# Methods for generating magic matrix.
|
|
38
|
+
module MagicHelpers
|
|
39
|
+
class << self
|
|
40
|
+
def odd_magic(nm, shape)
|
|
41
|
+
row = shape - 1
|
|
42
|
+
col = shape / 2
|
|
43
|
+
nm[row,col] = 1
|
|
44
|
+
(2..shape * shape).each do |index|
|
|
45
|
+
if nm[(row + 1) % shape,(col + 1) % shape] == 0
|
|
46
|
+
row = (row + 1) % shape
|
|
47
|
+
col = (col + 1) % shape
|
|
48
|
+
else
|
|
49
|
+
row = (row - 1 + shape) % shape
|
|
50
|
+
end
|
|
51
|
+
nm[row,col] = index
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def doubly_even_magic(nm, shape)
|
|
56
|
+
mini_square_num = shape / 4
|
|
57
|
+
count = 1
|
|
58
|
+
inv_count = shape * shape
|
|
59
|
+
shape.times do |row|
|
|
60
|
+
shape.times do |col|
|
|
61
|
+
if col >= mini_square_num and col < shape - mini_square_num
|
|
62
|
+
if row >= mini_square_num and row < shape - mini_square_num
|
|
63
|
+
nm[row,col] = count
|
|
64
|
+
else
|
|
65
|
+
nm[row,col] = inv_count
|
|
66
|
+
end
|
|
67
|
+
elsif row < mini_square_num or row >= shape - mini_square_num
|
|
68
|
+
nm[row,col] = count
|
|
69
|
+
else
|
|
70
|
+
nm[row,col] = inv_count
|
|
71
|
+
end
|
|
72
|
+
count += 1
|
|
73
|
+
inv_count -= 1
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def singly_even_magic(nm, shape)
|
|
79
|
+
half_shape = shape / 2
|
|
80
|
+
complementary_pair = (shape - 2) / 4
|
|
81
|
+
swap_col = NMatrix.new([shape])
|
|
82
|
+
index = 0
|
|
83
|
+
mini_magic = NMatrix.new([half_shape,half_shape], 0, dtype: nm.dtype)
|
|
84
|
+
odd_magic mini_magic, half_shape
|
|
85
|
+
half_shape.times do |row|
|
|
86
|
+
half_shape.times do |col|
|
|
87
|
+
nm[row,col] = mini_magic[row,col]
|
|
88
|
+
nm[row + half_shape,col + half_shape] = mini_magic[row,col] + half_shape * half_shape
|
|
89
|
+
nm[row,col + half_shape] = mini_magic[row,col] + 2 * half_shape * half_shape
|
|
90
|
+
nm[row + half_shape,col] = mini_magic[row,col] + 3 * half_shape * half_shape
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
(1..complementary_pair).each do |complementary_entry|
|
|
95
|
+
swap_col[index] = complementary_entry
|
|
96
|
+
index += 1
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
(shape - complementary_pair + 2..shape).each do |center|
|
|
100
|
+
swap_col[index] = center
|
|
101
|
+
index += 1
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
(1..half_shape).each do |row|
|
|
105
|
+
(1..index).each do |col|
|
|
106
|
+
temp = nm[row - 1,swap_col[col - 1] - 1]
|
|
107
|
+
nm[row - 1,swap_col[col - 1] - 1] = nm[row + half_shape - 1,swap_col[col - 1] - 1]
|
|
108
|
+
nm[row + half_shape - 1,swap_col[col - 1] - 1] = temp
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
temp = nm[complementary_pair,0]
|
|
113
|
+
nm[complementary_pair,0] = nm[complementary_pair + half_shape,0]
|
|
114
|
+
nm[complementary_pair + half_shape,0] = temp
|
|
115
|
+
|
|
116
|
+
temp = nm[complementary_pair + half_shape,complementary_pair]
|
|
117
|
+
nm[complementary_pair + half_shape,complementary_pair] = nm[complementary_pair,complementary_pair]
|
|
118
|
+
nm[complementary_pair,complementary_pair] = temp
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# call-seq:
|
|
124
|
+
# m.dense? -> true or false
|
|
125
|
+
#
|
|
126
|
+
# Determine if +m+ is a dense matrix.
|
|
127
|
+
def dense?; return stype == :dense; end
|
|
128
|
+
|
|
129
|
+
# call-seq:
|
|
130
|
+
# m.yale? -> true or false
|
|
131
|
+
#
|
|
132
|
+
# Determine if +m+ is a Yale matrix.
|
|
133
|
+
def yale?; return stype == :yale; end
|
|
134
|
+
|
|
135
|
+
# call-seq:
|
|
136
|
+
# m.list? -> true or false
|
|
137
|
+
#
|
|
138
|
+
# Determine if +m+ is a list-of-lists matrix.
|
|
139
|
+
def list?; return stype == :list; end
|
|
140
|
+
|
|
141
|
+
class << self
|
|
142
|
+
# call-seq:
|
|
143
|
+
# NMatrix[Numeric, ..., Numeric, dtype: Symbol] -> NMatrix
|
|
144
|
+
# NMatrix[Array, dtype: Symbol] -> NMatrix
|
|
145
|
+
#
|
|
146
|
+
# The default value for +dtype+ is guessed from the first parameter. For example:
|
|
147
|
+
# NMatrix[1.0, 2.0].dtype # => :float64
|
|
148
|
+
#
|
|
149
|
+
# But this is just a *guess*. If the other values can't be converted to
|
|
150
|
+
# this dtype, a +TypeError+ will be raised.
|
|
151
|
+
#
|
|
152
|
+
# You can use the +N+ constant in this way:
|
|
153
|
+
# N = NMatrix
|
|
154
|
+
# N[1, 2, 3]
|
|
155
|
+
#
|
|
156
|
+
# NMatrix needs to have a succinct way to create a matrix by specifying the
|
|
157
|
+
# components directly. This is very useful for using it as an advanced
|
|
158
|
+
# calculator, it is useful for learning how to use, for testing language
|
|
159
|
+
# features and for developing algorithms.
|
|
160
|
+
#
|
|
161
|
+
# The NMatrix::[] method provides a way to create a matrix in a way that is compact and
|
|
162
|
+
# natural. The components are specified using Ruby array syntax. Optionally,
|
|
163
|
+
# one can specify a dtype as the last parameter (default is :float64).
|
|
164
|
+
#
|
|
165
|
+
# Examples:
|
|
166
|
+
#
|
|
167
|
+
# a = N[ 1,2,3,4 ] => 1 2 3 4
|
|
168
|
+
#
|
|
169
|
+
# a = N[ 1,2,3,4, :int32 ] => 1 2 3 4
|
|
170
|
+
#
|
|
171
|
+
# a = N[ [1,2,3], [3,4,5] ] => 1.0 2.0 3.0
|
|
172
|
+
# 3.0 4.0 5.0
|
|
173
|
+
#
|
|
174
|
+
# a = N[ 3,6,9 ].transpose => 3
|
|
175
|
+
# 6
|
|
176
|
+
# 9
|
|
177
|
+
#
|
|
178
|
+
# SYNTAX COMPARISON:
|
|
179
|
+
#
|
|
180
|
+
# MATLAB: a = [ [1 2 3] ; [4 5 6] ] or [ 1 2 3 ; 4 5 6 ]
|
|
181
|
+
# IDL: a = [ [1,2,3] , [4,5,6] ]
|
|
182
|
+
# NumPy: a = array( [1,2,3], [4,5,6] )
|
|
183
|
+
#
|
|
184
|
+
# SciRuby: a = NMatrix[ [1,2,3], [4,5,6] ]
|
|
185
|
+
# Ruby array: a = [ [1,2,3], [4,5,6] ]
|
|
186
|
+
def [](*params)
|
|
187
|
+
options = params.last.is_a?(Hash) ? params.pop : {}
|
|
188
|
+
|
|
189
|
+
# First find the dimensions of the array.
|
|
190
|
+
i = 0
|
|
191
|
+
shape = []
|
|
192
|
+
row = params
|
|
193
|
+
while row.is_a?(Array)
|
|
194
|
+
shape[i] = row.length
|
|
195
|
+
row = row[0]
|
|
196
|
+
i += 1
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# A row vector should be stored as 1xN, not N
|
|
200
|
+
#shape.unshift(1) if shape.size == 1
|
|
201
|
+
|
|
202
|
+
# Then flatten the array.
|
|
203
|
+
NMatrix.new(shape, params.flatten, options)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
#
|
|
207
|
+
# call-seq:
|
|
208
|
+
# zeros(shape) -> NMatrix
|
|
209
|
+
# zeros(shape, dtype: dtype) -> NMatrix
|
|
210
|
+
# zeros(shape, dtype: dtype, stype: stype) -> NMatrix
|
|
211
|
+
#
|
|
212
|
+
# Creates a new matrix of zeros with the dimensions supplied as
|
|
213
|
+
# parameters.
|
|
214
|
+
#
|
|
215
|
+
# * *Arguments* :
|
|
216
|
+
# - +shape+ -> Array (or integer for square matrix) specifying the dimensions.
|
|
217
|
+
# - +dtype+ -> (optional) Default is +:float64+
|
|
218
|
+
# - +stype+ -> (optional) Default is +:dense+.
|
|
219
|
+
# * *Returns* :
|
|
220
|
+
# - NMatrix filled with zeros.
|
|
221
|
+
#
|
|
222
|
+
# Examples:
|
|
223
|
+
#
|
|
224
|
+
# NMatrix.zeros(2) # => 0.0 0.0
|
|
225
|
+
# 0.0 0.0
|
|
226
|
+
#
|
|
227
|
+
# NMatrix.zeros([2, 3], dtype: :int32) # => 0 0 0
|
|
228
|
+
# 0 0 0
|
|
229
|
+
#
|
|
230
|
+
# NMatrix.zeros([1, 5], dtype: :int32) # => 0 0 0 0 0
|
|
231
|
+
#
|
|
232
|
+
def zeros(shape, opts = {})
|
|
233
|
+
NMatrix.new(shape, 0, {:dtype => :float64}.merge(opts))
|
|
234
|
+
end
|
|
235
|
+
alias :zeroes :zeros
|
|
236
|
+
|
|
237
|
+
#
|
|
238
|
+
# call-seq:
|
|
239
|
+
# ones(shape) -> NMatrix
|
|
240
|
+
# ones(shape, dtype: dtype, stype: stype) -> NMatrix
|
|
241
|
+
#
|
|
242
|
+
# Creates a matrix filled with ones.
|
|
243
|
+
#
|
|
244
|
+
# * *Arguments* :
|
|
245
|
+
# - +shape+ -> Array (or integer for square matrix) specifying the shape.
|
|
246
|
+
# - +opts+ -> (optional) Hash of options from NMatrix#initialize
|
|
247
|
+
# * *Returns* :
|
|
248
|
+
# - NMatrix filled with ones.
|
|
249
|
+
#
|
|
250
|
+
# Examples:
|
|
251
|
+
#
|
|
252
|
+
# NMatrix.ones([1, 3]) # => 1.0 1.0 1.0
|
|
253
|
+
#
|
|
254
|
+
# NMatrix.ones([2, 3], dtype: :int32) # => 1 1 1
|
|
255
|
+
# 1 1 1
|
|
256
|
+
#
|
|
257
|
+
def ones(shape, opts={})
|
|
258
|
+
NMatrix.new(shape, 1, {:dtype => :float64, :default => 1}.merge(opts))
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
# call-seq:
|
|
262
|
+
# ones_like(nm) -> NMatrix
|
|
263
|
+
#
|
|
264
|
+
# Creates a new matrix of ones with the same dtype and shape as the
|
|
265
|
+
# provided matrix.
|
|
266
|
+
#
|
|
267
|
+
# @param [NMatrix] nm the nmatrix whose dtype and shape will be used
|
|
268
|
+
# @return [NMatrix] a new nmatrix filled with ones.
|
|
269
|
+
#
|
|
270
|
+
def ones_like(nm)
|
|
271
|
+
NMatrix.ones(nm.shape, dtype: nm.dtype, stype: nm.stype, capacity: nm.capacity, default: 1)
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# call-seq:
|
|
275
|
+
# zeros_like(nm) -> NMatrix
|
|
276
|
+
#
|
|
277
|
+
# Creates a new matrix of zeros with the same stype, dtype, and shape
|
|
278
|
+
# as the provided matrix.
|
|
279
|
+
#
|
|
280
|
+
# @param [NMatrix] nm the nmatrix whose stype, dtype, and shape will be used
|
|
281
|
+
# @return [NMatrix] a new nmatrix filled with zeros.
|
|
282
|
+
#
|
|
283
|
+
def zeros_like(nm)
|
|
284
|
+
NMatrix.zeros(nm.shape, dtype: nm.dtype, stype: nm.stype, capacity: nm.capacity, default: 0)
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
#
|
|
288
|
+
# call-seq:
|
|
289
|
+
# eye(shape) -> NMatrix
|
|
290
|
+
# eye(shape, dtype: dtype) -> NMatrix
|
|
291
|
+
# eye(shape, stype: stype, dtype: dtype) -> NMatrix
|
|
292
|
+
#
|
|
293
|
+
# Creates an identity matrix (square matrix rank 2).
|
|
294
|
+
#
|
|
295
|
+
# * *Arguments* :
|
|
296
|
+
# - +size+ -> Array (or integer for square matrix) specifying the dimensions.
|
|
297
|
+
# - +dtype+ -> (optional) Default is +:float64+
|
|
298
|
+
# - +stype+ -> (optional) Default is +:dense+.
|
|
299
|
+
# * *Returns* :
|
|
300
|
+
# - An identity matrix.
|
|
301
|
+
#
|
|
302
|
+
# Examples:
|
|
303
|
+
#
|
|
304
|
+
# NMatrix.eye(3) # => 1.0 0.0 0.0
|
|
305
|
+
# 0.0 1.0 0.0
|
|
306
|
+
# 0.0 0.0 1.0
|
|
307
|
+
#
|
|
308
|
+
# NMatrix.eye(3, dtype: :int32) # => 1 0 0
|
|
309
|
+
# 0 1 0
|
|
310
|
+
# 0 0 1
|
|
311
|
+
#
|
|
312
|
+
# NMatrix.eye(2, dtype: :int32, stype: :yale) # => 1 0
|
|
313
|
+
# 0 1
|
|
314
|
+
#
|
|
315
|
+
def eye(shape, opts={})
|
|
316
|
+
# Fill the diagonal with 1's.
|
|
317
|
+
m = NMatrix.zeros(shape, {:dtype => :float64}.merge(opts))
|
|
318
|
+
(0...m.shape[0]).each do |i|
|
|
319
|
+
m[i, i] = 1
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
m
|
|
323
|
+
end
|
|
324
|
+
alias :identity :eye
|
|
325
|
+
|
|
326
|
+
#
|
|
327
|
+
# call-seq:
|
|
328
|
+
# hilbert(shape) -> NMatrix
|
|
329
|
+
# hilbert(shape, dtype: dtype) -> NMatrix
|
|
330
|
+
# hilbert(shape, stype: stype, dtype: dtype) -> NMatrix
|
|
331
|
+
#
|
|
332
|
+
# Creates an hilbert matrix (square matrix).
|
|
333
|
+
#
|
|
334
|
+
# * *Arguments* :
|
|
335
|
+
# - +size+ -> integer ( for square matrix) specifying the dimensions.
|
|
336
|
+
# - +dtype+ -> (optional) Default is +:float64+
|
|
337
|
+
# - +stype+ -> (optional) Default is +:dense+.
|
|
338
|
+
# * *Returns* :
|
|
339
|
+
# - A hilbert matrix.
|
|
340
|
+
#
|
|
341
|
+
# Examples:
|
|
342
|
+
#
|
|
343
|
+
# NMatrix.hilbert(3) # => 1.0 0.5 0.3333333333333333
|
|
344
|
+
# 0.5 0.3333333333333333 0.25
|
|
345
|
+
# 0.3333333333333333 0.25 0.2
|
|
346
|
+
#
|
|
347
|
+
def hilbert(shape, opts={})
|
|
348
|
+
m = NMatrix.new([shape,shape], {:dtype => :float64}.merge(opts))
|
|
349
|
+
0.upto(shape - 1) do |i|
|
|
350
|
+
0.upto(i) do |j|
|
|
351
|
+
m[i,j] = 1.0 / (j + i + 1)
|
|
352
|
+
m[j,i] = m[i,j] if i != j
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
m
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
#
|
|
359
|
+
# call-seq:
|
|
360
|
+
# inv_hilbert(shape) -> NMatrix
|
|
361
|
+
# inv_hilbert(shape, dtype: dtype) -> NMatrix
|
|
362
|
+
# inv_hilbert(shape, stype: stype, dtype: dtype) -> NMatrix
|
|
363
|
+
#
|
|
364
|
+
# Creates an inverse hilbert matrix (square matrix rank 2).
|
|
365
|
+
#
|
|
366
|
+
# * *Arguments* :
|
|
367
|
+
# - +size+ -> Array (or integer for square matrix) specifying the dimensions.
|
|
368
|
+
# - +dtype+ -> (optional) Default is +:float64+
|
|
369
|
+
# - +stype+ -> (optional) Default is +:dense+.
|
|
370
|
+
# * *Returns* :
|
|
371
|
+
# - A hilbert matrix.
|
|
372
|
+
#
|
|
373
|
+
# Examples:
|
|
374
|
+
# NMatrix.inv_hilbert(3) # => 9.0, -36.0, 30.0
|
|
375
|
+
# -36.0, 192.0, -180.0
|
|
376
|
+
# 30.0, -180.0, 180.0
|
|
377
|
+
#
|
|
378
|
+
#
|
|
379
|
+
def inv_hilbert(shape, opts={})
|
|
380
|
+
opts = {:dtype => :float64}.merge(opts)
|
|
381
|
+
m = NMatrix.new([shape,shape],opts)
|
|
382
|
+
combination = NMatrix.new([2*shape,2*shape],opts)
|
|
383
|
+
#combinations refers to the combination of n things taken k at a time
|
|
384
|
+
0.upto(2*shape-1) do |i|
|
|
385
|
+
0.upto(i) do |j|
|
|
386
|
+
if j != 0 and j != i
|
|
387
|
+
combination[i,j] = combination[i-1,j] + combination[i-1,j-1]
|
|
388
|
+
else
|
|
389
|
+
combination[i,j] = 1
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
0.upto(shape-1) do |i|
|
|
395
|
+
0.upto(i) do |j|
|
|
396
|
+
m[i,j] = combination[shape + j,shape - i - 1] * ((i+j)+1) * \
|
|
397
|
+
combination[shape + i,shape - j - 1] * (-1) ** ((i+j)) * \
|
|
398
|
+
combination[(i+j),i] * combination[(i+j),i]
|
|
399
|
+
m[j,i] = m[i,j] if i != j
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
m
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
#
|
|
406
|
+
# call-seq:
|
|
407
|
+
# diagonals(array) -> NMatrix
|
|
408
|
+
# diagonals(array, dtype: dtype, stype: stype) -> NMatrix
|
|
409
|
+
#
|
|
410
|
+
# Creates a matrix filled with specified diagonals.
|
|
411
|
+
#
|
|
412
|
+
# * *Arguments* :
|
|
413
|
+
# - +entries+ -> Array containing input values for diagonal matrix
|
|
414
|
+
# - +options+ -> (optional) Hash with options for NMatrix#initialize
|
|
415
|
+
# * *Returns* :
|
|
416
|
+
# - NMatrix filled with specified diagonal values.
|
|
417
|
+
#
|
|
418
|
+
# Examples:
|
|
419
|
+
#
|
|
420
|
+
# NMatrix.diagonal([1.0,2,3,4]) # => 1.0 0.0 0.0 0.0
|
|
421
|
+
# 0.0 2.0 0.0 0.0
|
|
422
|
+
# 0.0 0.0 3.0 0.0
|
|
423
|
+
# 0.0 0.0 0.0 4.0
|
|
424
|
+
#
|
|
425
|
+
# NMatrix.diagonal([1,2,3,4], dtype: :int32) # => 1 0 0 0
|
|
426
|
+
# 0 2 0 0
|
|
427
|
+
# 0 0 3 0
|
|
428
|
+
# 0 0 0 4
|
|
429
|
+
#
|
|
430
|
+
#
|
|
431
|
+
def diagonal(entries, opts={})
|
|
432
|
+
m = NMatrix.zeros(entries.size,
|
|
433
|
+
{:dtype => guess_dtype(entries[0]), :capacity => entries.size + 1}.merge(opts)
|
|
434
|
+
)
|
|
435
|
+
entries.each_with_index do |n, i|
|
|
436
|
+
m[i,i] = n
|
|
437
|
+
end
|
|
438
|
+
m
|
|
439
|
+
end
|
|
440
|
+
alias :diag :diagonal
|
|
441
|
+
alias :diagonals :diagonal
|
|
442
|
+
|
|
443
|
+
# Generate a block-diagonal NMatrix from the supplied 2D square matrices.
|
|
444
|
+
#
|
|
445
|
+
# * *Arguments*
|
|
446
|
+
# - +*params+ -> An array that collects all arguments passed to the method. The method
|
|
447
|
+
# can receive any number of arguments. Optionally, the last entry of +params+ is
|
|
448
|
+
# a hash of options from NMatrix#initialize. All other entries of +params+ are
|
|
449
|
+
# the blocks of the desired block-diagonal matrix. Each such matrix block can be
|
|
450
|
+
# supplied as a square 2D NMatrix object, or alternatively as an array of arrays
|
|
451
|
+
# (with dimensions corresponding to a square matrix), or alternatively as a number.
|
|
452
|
+
# * *Returns*
|
|
453
|
+
# - NMatrix of block-diagonal form filled with specified matrices
|
|
454
|
+
# as the blocks along the diagonal.
|
|
455
|
+
#
|
|
456
|
+
# * *Example*
|
|
457
|
+
#
|
|
458
|
+
# a = NMatrix.new([2,2], [1,2,3,4])
|
|
459
|
+
# b = NMatrix.new([1,1], [123], dtype: :float64)
|
|
460
|
+
# c = Array.new(2) { [[10,10], [10,10]] }
|
|
461
|
+
# d = Array[[1,2,3], [4,5,6], [7,8,9]]
|
|
462
|
+
# m = NMatrix.block_diagonal(a, b, *c, d, 10.0, 11, dtype: :int64, stype: :yale)
|
|
463
|
+
# =>
|
|
464
|
+
# [
|
|
465
|
+
# [1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
|
466
|
+
# [3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
|
467
|
+
# [0, 0, 123, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
|
468
|
+
# [0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0]
|
|
469
|
+
# [0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0]
|
|
470
|
+
# [0, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0]
|
|
471
|
+
# [0, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0]
|
|
472
|
+
# [0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0]
|
|
473
|
+
# [0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 0]
|
|
474
|
+
# [0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0]
|
|
475
|
+
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0]
|
|
476
|
+
# [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11]
|
|
477
|
+
# ]
|
|
478
|
+
#
|
|
479
|
+
def block_diagonal(*params)
|
|
480
|
+
options = params.last.is_a?(Hash) ? params.pop : {}
|
|
481
|
+
|
|
482
|
+
params.each_index do |i|
|
|
483
|
+
params[i] = params[i].to_nm if params[i].is_a?(Array) # Convert Array to NMatrix
|
|
484
|
+
params[i] = NMatrix.new([1,1], [params[i]]) if params[i].is_a?(Numeric) # Convert number to NMatrix
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
block_sizes = [] #holds the size of each matrix block
|
|
488
|
+
params.each do |b|
|
|
489
|
+
unless b.is_a?(NMatrix)
|
|
490
|
+
raise(ArgumentError, "Only NMatrix or appropriate Array objects or single numbers allowed")
|
|
491
|
+
end
|
|
492
|
+
raise(ArgumentError, "Only 2D matrices or 2D arrays allowed") unless b.shape.size == 2
|
|
493
|
+
raise(ArgumentError, "Only square-shaped blocks allowed") unless b.shape[0] == b.shape[1]
|
|
494
|
+
block_sizes << b.shape[0]
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
block_diag_mat = NMatrix.zeros(block_sizes.inject(0,:+), options)
|
|
498
|
+
(0...params.length).each do |n|
|
|
499
|
+
# First determine the size and position of the n'th block in the block-diagonal matrix
|
|
500
|
+
block_size = block_sizes[n]
|
|
501
|
+
block_pos = block_sizes[0...n].inject(0,:+)
|
|
502
|
+
# populate the n'th block in the block-diagonal matrix
|
|
503
|
+
(0...block_size).each do |i|
|
|
504
|
+
(0...block_size).each do |j|
|
|
505
|
+
block_diag_mat[block_pos+i,block_pos+j] = params[n][i,j]
|
|
506
|
+
end
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
return block_diag_mat
|
|
511
|
+
end
|
|
512
|
+
alias :block_diag :block_diagonal
|
|
513
|
+
|
|
514
|
+
#
|
|
515
|
+
# call-seq:
|
|
516
|
+
# random(shape) -> NMatrix
|
|
517
|
+
#
|
|
518
|
+
# Creates a +:dense+ NMatrix with random numbers between 0 and 1 generated
|
|
519
|
+
# by +Random::rand+. The parameter is the dimension of the matrix.
|
|
520
|
+
#
|
|
521
|
+
# If you use an integer dtype, make sure to specify :scale as a parameter, or you'll
|
|
522
|
+
# only get a matrix of 0s.
|
|
523
|
+
#
|
|
524
|
+
# * *Arguments* :
|
|
525
|
+
# - +shape+ -> Array (or integer for square matrix) specifying the dimensions.
|
|
526
|
+
# * *Returns* :
|
|
527
|
+
# - NMatrix filled with random values.
|
|
528
|
+
#
|
|
529
|
+
# Examples:
|
|
530
|
+
#
|
|
531
|
+
# NMatrix.random([2, 2]) # => 0.4859439730644226 0.1783195585012436
|
|
532
|
+
# 0.23193766176700592 0.4503345191478729
|
|
533
|
+
#
|
|
534
|
+
# NMatrix.random([2, 2], :dtype => :byte, :scale => 255) # => [ [252, 108] [44, 12] ]
|
|
535
|
+
#
|
|
536
|
+
def random(shape, opts={})
|
|
537
|
+
scale = opts.delete(:scale) || 1.0
|
|
538
|
+
|
|
539
|
+
if opts[:seed].nil?
|
|
540
|
+
rng = Random.new
|
|
541
|
+
else
|
|
542
|
+
rng = Random.new(opts[:seed])
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
random_values = []
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
# Construct the values of the final matrix based on the dimension.
|
|
550
|
+
if opts[:dtype] == :complex64 || opts[:dtype] == :complex128
|
|
551
|
+
NMatrix.size(shape).times { |i| random_values << Complex(rng.rand(scale), rng.rand(scale)) }
|
|
552
|
+
else
|
|
553
|
+
NMatrix.size(shape).times { |i| random_values << rng.rand(scale) }
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
NMatrix.new(shape, random_values, {:dtype => :float64, :stype => :dense}.merge(opts))
|
|
557
|
+
end
|
|
558
|
+
alias :rand :random
|
|
559
|
+
|
|
560
|
+
#
|
|
561
|
+
# call-seq:
|
|
562
|
+
# magic(shape) -> NMatrix
|
|
563
|
+
# magic(shape, dtype: dtype) -> NMatrix
|
|
564
|
+
#
|
|
565
|
+
# The parameter is the dimension of the matrix.
|
|
566
|
+
#
|
|
567
|
+
# Creates a +:dense+ NMatrix with the following properties:
|
|
568
|
+
# - An arrangement of the numbers from 1 to n^2 (n-squared) in the matrix, with each number occurring exactly once.
|
|
569
|
+
# - The sum of the entries of any row, any column, or any main diagonal is the same.
|
|
570
|
+
# - This sum must be n(n^2+1)/2.
|
|
571
|
+
#
|
|
572
|
+
# See: http://www.mathworks.com/help/matlab/ref/magic.html
|
|
573
|
+
#
|
|
574
|
+
# * *Arguments* :
|
|
575
|
+
# - +shape+ -> Array (or integer for square matrix) specifying the dimensions.
|
|
576
|
+
# - +dtype+ -> (optional) Default is +:float64+
|
|
577
|
+
# * *Returns* :
|
|
578
|
+
# - NMatrix with the above given properties.
|
|
579
|
+
#
|
|
580
|
+
# Examples:
|
|
581
|
+
#
|
|
582
|
+
# NMatrix.magic(3) # => [ [4.0, 9.0, 2.0] [3.0, 5.0, 7.0] [8.0, 1.0, 6.0] ]
|
|
583
|
+
#
|
|
584
|
+
# NMatrix.magic(4, dtype :int32) # => [ [ 1, 15, 14, 4]
|
|
585
|
+
# [12, 6, 7, 9]
|
|
586
|
+
# [ 8, 10, 11, 5]
|
|
587
|
+
# [13, 3, 2, 16] ]
|
|
588
|
+
#
|
|
589
|
+
# NMatrix.magic(6,dtype: :int64) # => [ [31, 9, 2, 22, 27, 20]
|
|
590
|
+
# [ 3, 32, 7, 21, 23, 25]
|
|
591
|
+
# [35, 1, 6, 26, 19, 24]
|
|
592
|
+
# [ 4, 36, 29, 13, 18, 11]
|
|
593
|
+
# [30, 5, 34, 12, 14, 16]
|
|
594
|
+
# [ 8, 28, 33, 17, 10, 15] ]
|
|
595
|
+
#
|
|
596
|
+
def magic(shape, opts={})
|
|
597
|
+
raise(ArgumentError, "shape of two is not allowed") if shape == 2
|
|
598
|
+
nm = NMatrix.new([shape,shape], 0, {:dtype => :float64}.merge(opts))
|
|
599
|
+
if shape % 2 != 0
|
|
600
|
+
MagicHelpers.odd_magic nm, shape
|
|
601
|
+
elsif shape % 4 == 0
|
|
602
|
+
MagicHelpers.doubly_even_magic nm, shape
|
|
603
|
+
else
|
|
604
|
+
MagicHelpers.singly_even_magic nm, shape
|
|
605
|
+
end
|
|
606
|
+
nm
|
|
607
|
+
end
|
|
608
|
+
|
|
609
|
+
#
|
|
610
|
+
# call-seq:
|
|
611
|
+
# linspace(base, limit) -> 1x100 NMatrix
|
|
612
|
+
# linspace(base, limit, *shape) -> NMatrix
|
|
613
|
+
#
|
|
614
|
+
# Returns an NMatrix with +[shape[0] x shape[1] x .. x shape[dim-1]]+ values of dtype +:float64+ equally spaced from
|
|
615
|
+
# +base+ to +limit+, inclusive.
|
|
616
|
+
#
|
|
617
|
+
# See: http://www.mathworks.com/help/matlab/ref/linspace.html
|
|
618
|
+
#
|
|
619
|
+
# * *Arguments* :
|
|
620
|
+
# - +base+ -> The first value in the sequence.
|
|
621
|
+
# - +limit+ -> The last value in the sequence.
|
|
622
|
+
# - +shape+ -> Desired output shape. Default returns a 1x100 row vector.
|
|
623
|
+
# * *Returns* :
|
|
624
|
+
# - NMatrix with +:float64+ values.
|
|
625
|
+
#
|
|
626
|
+
# Examples :-
|
|
627
|
+
#
|
|
628
|
+
# NMatrix.linspace(1,Math::PI, 6)
|
|
629
|
+
# =>[1.0,
|
|
630
|
+
# 1.4283185005187988,
|
|
631
|
+
# 1.8566370010375977,
|
|
632
|
+
# 2.2849555015563965,
|
|
633
|
+
# 2.7132740020751953,
|
|
634
|
+
# 3.1415927410125732
|
|
635
|
+
# ]
|
|
636
|
+
#
|
|
637
|
+
# NMatrix.linspace(1,10, [3,2])
|
|
638
|
+
# =>[
|
|
639
|
+
# [ 1.0, 2.799999952316284]
|
|
640
|
+
# [4.599999904632568, 6.400000095367432]
|
|
641
|
+
# [8.199999809265137, 10.0]
|
|
642
|
+
# ]
|
|
643
|
+
#
|
|
644
|
+
def linspace(base, limit, shape = [100])
|
|
645
|
+
|
|
646
|
+
# Convert shape to array format
|
|
647
|
+
shape = [shape] if shape.is_a? Integer
|
|
648
|
+
|
|
649
|
+
#Calculate number of elements
|
|
650
|
+
count = shape.inject(:*)
|
|
651
|
+
|
|
652
|
+
# Linear spacing between elements calculated in step
|
|
653
|
+
# step = limit - base / (count - 1)
|
|
654
|
+
# [Result Sequence] = [0->N sequence] * step + [Base]
|
|
655
|
+
step = (limit - base) * (1.0 / (count - 1))
|
|
656
|
+
result = NMatrix.seq(shape, {:dtype => :float64}) * step
|
|
657
|
+
result += NMatrix.new(shape, base)
|
|
658
|
+
result
|
|
659
|
+
end
|
|
660
|
+
|
|
661
|
+
# call-seq:
|
|
662
|
+
# logspace(base, limit) -> 1x50 NMatrix with exponent_base = 10
|
|
663
|
+
# logspace(base, limit, shape , exponent_base:) -> NMatrix
|
|
664
|
+
# logspace(base, :pi, n) -> 1xn NMatrix with interval [10 ^ base, Math::PI]
|
|
665
|
+
#
|
|
666
|
+
# Returns an NMatrix with +[shape[0] x shape[1] x .. x shape[dim-1]]+ values of dtype +:float64+ logarithmically spaced from
|
|
667
|
+
# +exponent_base ^ base+ to +exponent_base ^ limit+, inclusive.
|
|
668
|
+
#
|
|
669
|
+
# See: http://www.mathworks.com/help/matlab/ref/logspace.html
|
|
670
|
+
#
|
|
671
|
+
# * *Arguments* :
|
|
672
|
+
# - +base+ -> exponent_base ** base is the first value in the sequence
|
|
673
|
+
# - +limit+ -> exponent_base ** limit is the last value in the sequence.
|
|
674
|
+
# - +shape+ -> Desired output shape. Default returns a 1x50 row vector.
|
|
675
|
+
# * *Returns* :
|
|
676
|
+
# - NMatrix with +:float64+ values.
|
|
677
|
+
#
|
|
678
|
+
# Examples :-
|
|
679
|
+
#
|
|
680
|
+
# NMatrix.logspace(1,:pi,7)
|
|
681
|
+
# =>[
|
|
682
|
+
# 10.0000,
|
|
683
|
+
# 8.2450,
|
|
684
|
+
# 6.7980,
|
|
685
|
+
# 5.6050,
|
|
686
|
+
# 4.6213,
|
|
687
|
+
# 3.8103,
|
|
688
|
+
# 3.1416
|
|
689
|
+
# ]
|
|
690
|
+
#
|
|
691
|
+
# NMatrix.logspace(1,2,[3,2])
|
|
692
|
+
# =>[
|
|
693
|
+
# [10.0, 15.8489]
|
|
694
|
+
# [25.1189, 39.8107]
|
|
695
|
+
# [63.0957, 100.0]
|
|
696
|
+
# ]
|
|
697
|
+
#
|
|
698
|
+
def logspace(base, limit, shape = [50], exponent_base: 10)
|
|
699
|
+
|
|
700
|
+
#Calculate limit for [10 ^ base ... Math::PI] if limit = :pi
|
|
701
|
+
limit = Math.log(Math::PI, exponent_base = 10) if limit == :pi
|
|
702
|
+
shape = [shape] if shape.is_a? Integer
|
|
703
|
+
|
|
704
|
+
#[base...limit] -> [exponent_base ** base ... exponent_base ** limit]
|
|
705
|
+
result = NMatrix.linspace(base, limit, shape)
|
|
706
|
+
result.map {|element| exponent_base ** element}
|
|
707
|
+
end
|
|
708
|
+
|
|
709
|
+
#
|
|
710
|
+
# call-seq:
|
|
711
|
+
# linspace(base, limit) -> 1x100 NMatrix
|
|
712
|
+
# linspace(base, limit, *shape) -> NMatrix
|
|
713
|
+
#
|
|
714
|
+
# Returns an NMatrix with +[shape[0] x shape[1] x .. x shape[dim-1]]+ values of dtype +:float64+ equally spaced from
|
|
715
|
+
# +base+ to +limit+, inclusive.
|
|
716
|
+
#
|
|
717
|
+
# See: http://www.mathworks.com/help/matlab/ref/linspace.html
|
|
718
|
+
#
|
|
719
|
+
# * *Arguments* :
|
|
720
|
+
# - +base+ -> The first value in the sequence.
|
|
721
|
+
# - +limit+ -> The last value in the sequence.
|
|
722
|
+
# - +shape+ -> Desired output shape. Default returns a 1x100 row vector.
|
|
723
|
+
# * *Returns* :
|
|
724
|
+
# - NMatrix with +:float64+ values.
|
|
725
|
+
#
|
|
726
|
+
# Examples :-
|
|
727
|
+
#
|
|
728
|
+
# NMatrix.linspace(1,Math::PI, 6)
|
|
729
|
+
# =>[1.0,
|
|
730
|
+
# 1.4283185005187988,
|
|
731
|
+
# 1.8566370010375977,
|
|
732
|
+
# 2.2849555015563965,
|
|
733
|
+
# 2.7132740020751953,
|
|
734
|
+
# 3.1415927410125732
|
|
735
|
+
# ]
|
|
736
|
+
#
|
|
737
|
+
# NMatrix.linspace(1,10, [3,2])
|
|
738
|
+
# =>[
|
|
739
|
+
# [ 1.0, 2.799999952316284]
|
|
740
|
+
# [4.599999904632568, 6.400000095367432]
|
|
741
|
+
# [8.199999809265137, 10.0]
|
|
742
|
+
# ]
|
|
743
|
+
#
|
|
744
|
+
def linspace(base, limit, shape = [100])
|
|
745
|
+
|
|
746
|
+
# Convert shape to array format
|
|
747
|
+
shape = [shape] if shape.is_a? Integer
|
|
748
|
+
|
|
749
|
+
#Calculate number of elements
|
|
750
|
+
count = shape.inject(:*)
|
|
751
|
+
|
|
752
|
+
# Linear spacing between elements calculated in step
|
|
753
|
+
# step = limit - base / (count - 1)
|
|
754
|
+
# [Result Sequence] = [0->N sequence] * step + [Base]
|
|
755
|
+
step = (limit - base) * (1.0 / (count - 1))
|
|
756
|
+
result = NMatrix.seq(shape, {:dtype => :float64}) * step
|
|
757
|
+
result += NMatrix.new(shape, base)
|
|
758
|
+
result
|
|
759
|
+
end
|
|
760
|
+
|
|
761
|
+
# call-seq:
|
|
762
|
+
# logspace(base, limit) -> 1x50 NMatrix with exponent_base = 10
|
|
763
|
+
# logspace(base, limit, shape , exponent_base:) -> NMatrix
|
|
764
|
+
# logspace(base, :pi, n) -> 1xn NMatrix with interval [10 ^ base, Math::PI]
|
|
765
|
+
#
|
|
766
|
+
# Returns an NMatrix with +[shape[0] x shape[1] x .. x shape[dim-1]]+ values of dtype +:float64+ logarithmically spaced from
|
|
767
|
+
# +exponent_base ^ base+ to +exponent_base ^ limit+, inclusive.
|
|
768
|
+
#
|
|
769
|
+
# See: http://www.mathworks.com/help/matlab/ref/logspace.html
|
|
770
|
+
#
|
|
771
|
+
# * *Arguments* :
|
|
772
|
+
# - +base+ -> exponent_base ** base is the first value in the sequence
|
|
773
|
+
# - +limit+ -> exponent_base ** limit is the last value in the sequence.
|
|
774
|
+
# - +shape+ -> Desired output shape. Default returns a 1x50 row vector.
|
|
775
|
+
# * *Returns* :
|
|
776
|
+
# - NMatrix with +:float64+ values.
|
|
777
|
+
#
|
|
778
|
+
# Examples :-
|
|
779
|
+
#
|
|
780
|
+
# NMatrix.logspace(1,:pi,7)
|
|
781
|
+
# =>[
|
|
782
|
+
# 10.0000,
|
|
783
|
+
# 8.2450,
|
|
784
|
+
# 6.7980,
|
|
785
|
+
# 5.6050,
|
|
786
|
+
# 4.6213,
|
|
787
|
+
# 3.8103,
|
|
788
|
+
# 3.1416
|
|
789
|
+
# ]
|
|
790
|
+
#
|
|
791
|
+
# NMatrix.logspace(1,2,[3,2])
|
|
792
|
+
# =>[
|
|
793
|
+
# [10.0, 15.8489]
|
|
794
|
+
# [25.1189, 39.8107]
|
|
795
|
+
# [63.0957, 100.0]
|
|
796
|
+
# ]
|
|
797
|
+
#
|
|
798
|
+
def logspace(base, limit, shape = [50], exponent_base: 10)
|
|
799
|
+
|
|
800
|
+
#Calculate limit for [10 ^ base ... Math::PI] if limit = :pi
|
|
801
|
+
limit = Math.log(Math::PI, exponent_base = 10) if limit == :pi
|
|
802
|
+
shape = [shape] if shape.is_a? Integer
|
|
803
|
+
|
|
804
|
+
#[base...limit] -> [exponent_base ** base ... exponent_base ** limit]
|
|
805
|
+
result = NMatrix.linspace(base, limit, shape)
|
|
806
|
+
result.map {|element| exponent_base ** element}
|
|
807
|
+
end
|
|
808
|
+
|
|
809
|
+
#
|
|
810
|
+
# call-seq:
|
|
811
|
+
# seq(shape) -> NMatrix
|
|
812
|
+
# seq(shape, options) -> NMatrix
|
|
813
|
+
# bindgen(shape) -> NMatrix of :byte
|
|
814
|
+
# indgen(shape) -> NMatrix of :int64
|
|
815
|
+
# findgen(shape) -> NMatrix of :float32
|
|
816
|
+
# dindgen(shape) -> NMatrix of :float64
|
|
817
|
+
# cindgen(shape) -> NMatrix of :complex64
|
|
818
|
+
# zindgen(shape) -> NMatrix of :complex128
|
|
819
|
+
# rbindgen(shape) -> NMatrix of :object
|
|
820
|
+
#
|
|
821
|
+
# Creates a matrix filled with a sequence of integers starting at zero.
|
|
822
|
+
#
|
|
823
|
+
# * *Arguments* :
|
|
824
|
+
# - +shape+ -> Array (or integer for square matrix) specifying the dimensions.
|
|
825
|
+
# - +options+ -> (optional) Options permissible for NMatrix#initialize
|
|
826
|
+
# * *Returns* :
|
|
827
|
+
# - NMatrix filled with values 0 through +size+.
|
|
828
|
+
#
|
|
829
|
+
# Examples:
|
|
830
|
+
#
|
|
831
|
+
# NMatrix.seq(2) # => 0 1
|
|
832
|
+
# 2 3
|
|
833
|
+
#
|
|
834
|
+
# NMatrix.seq([3, 3], dtype: :float32) # => 0.0 1.0 2.0
|
|
835
|
+
# 3.0 4.0 5.0
|
|
836
|
+
# 6.0 7.0 8.0
|
|
837
|
+
#
|
|
838
|
+
def seq(shape, options={})
|
|
839
|
+
|
|
840
|
+
# Construct the values of the final matrix based on the dimension.
|
|
841
|
+
values = (0 ... NMatrix.size(shape)).to_a
|
|
842
|
+
|
|
843
|
+
# It'll produce :int32, except if a dtype is provided.
|
|
844
|
+
NMatrix.new(shape, values, {:stype => :dense}.merge(options))
|
|
845
|
+
end
|
|
846
|
+
|
|
847
|
+
{:bindgen => :byte, :indgen => :int64, :findgen => :float32, :dindgen => :float64,
|
|
848
|
+
:cindgen => :complex64, :zindgen => :complex128,
|
|
849
|
+
:rbindgen => :object}.each_pair do |meth, dtype|
|
|
850
|
+
define_method(meth) { |shape| NMatrix.seq(shape, :dtype => dtype) }
|
|
851
|
+
end
|
|
852
|
+
end
|
|
853
|
+
end
|
|
854
|
+
|
|
855
|
+
module NVector #:nodoc:
|
|
856
|
+
|
|
857
|
+
class << self
|
|
858
|
+
#
|
|
859
|
+
# call-seq:
|
|
860
|
+
# new(shape) -> NVector
|
|
861
|
+
# new(stype, shape) -> NVector
|
|
862
|
+
# new(shape, init) -> NVector
|
|
863
|
+
# new(:dense, shape, init) -> NVector
|
|
864
|
+
# new(:list, shape, init) -> NVector
|
|
865
|
+
# new(shape, init, dtype) -> NVector
|
|
866
|
+
# new(stype, shape, init, dtype) -> NVector
|
|
867
|
+
# new(stype, shape, dtype) -> NVector
|
|
868
|
+
#
|
|
869
|
+
# Creates a new NVector. See also NMatrix#initialize for a more detailed explanation of
|
|
870
|
+
# the arguments.
|
|
871
|
+
#
|
|
872
|
+
# * *Arguments* :
|
|
873
|
+
# - +stype+ -> (optional) Storage type of the vector (:list, :dense, :yale). Defaults to :dense.
|
|
874
|
+
# - +shape+ -> Shape of the vector. Accepts [n,1], [1,n], or n, where n is a Fixnum.
|
|
875
|
+
# - +init+ -> (optional) Yale: capacity; List: default value (0); Dense: initial value or values (uninitialized by default).
|
|
876
|
+
# - +dtype+ -> (optional if +init+ provided) Data type stored in the vector. For :dense and :list, can be inferred from +init+.
|
|
877
|
+
# * *Returns* :
|
|
878
|
+
# -
|
|
879
|
+
#
|
|
880
|
+
def new(*args)
|
|
881
|
+
stype = args[0].is_a?(Symbol) ? args.shift : :dense
|
|
882
|
+
shape = args[0].is_a?(Array) ? args.shift : [1,args.shift]
|
|
883
|
+
|
|
884
|
+
if shape.size != 2 || !shape.include?(1) || shape == [1,1]
|
|
885
|
+
raise(ArgumentError, "shape must be a Fixnum or an Array of positive Fixnums where exactly one value is 1")
|
|
886
|
+
end
|
|
887
|
+
|
|
888
|
+
warn "NVector is deprecated and not guaranteed to work any longer"
|
|
889
|
+
|
|
890
|
+
NMatrix.new(stype, shape, *args)
|
|
891
|
+
end
|
|
892
|
+
|
|
893
|
+
#
|
|
894
|
+
# call-seq:
|
|
895
|
+
# zeros(size) -> NMatrix
|
|
896
|
+
# zeros(size, dtype) -> NMatrix
|
|
897
|
+
#
|
|
898
|
+
# Creates a new vector of zeros with the dimensions supplied as
|
|
899
|
+
# parameters.
|
|
900
|
+
#
|
|
901
|
+
# * *Arguments* :
|
|
902
|
+
# - +size+ -> Array (or integer for square matrix) specifying the dimensions.
|
|
903
|
+
# - +dtype+ -> (optional) Default is +:float64+.
|
|
904
|
+
# * *Returns* :
|
|
905
|
+
# - NVector filled with zeros.
|
|
906
|
+
#
|
|
907
|
+
# Examples:
|
|
908
|
+
#
|
|
909
|
+
# NVector.zeros(2) # => 0.0
|
|
910
|
+
# 0.0
|
|
911
|
+
#
|
|
912
|
+
# NVector.zeros(3, :int32) # => 0
|
|
913
|
+
# 0
|
|
914
|
+
# 0
|
|
915
|
+
#
|
|
916
|
+
def zeros(size, dtype = :float64)
|
|
917
|
+
NMatrix.new([size,1], 0, dtype: dtype)
|
|
918
|
+
end
|
|
919
|
+
alias :zeroes :zeros
|
|
920
|
+
|
|
921
|
+
#
|
|
922
|
+
# call-seq:
|
|
923
|
+
# ones(size) -> NVector
|
|
924
|
+
# ones(size, dtype) -> NVector
|
|
925
|
+
#
|
|
926
|
+
# Creates a vector of ones with the dimensions supplied as
|
|
927
|
+
# parameters.
|
|
928
|
+
#
|
|
929
|
+
# * *Arguments* :
|
|
930
|
+
# - +size+ -> Array (or integer for square matrix) specifying the dimensions.
|
|
931
|
+
# - +dtype+ -> (optional) Default is +:float64+.
|
|
932
|
+
# * *Returns* :
|
|
933
|
+
# - NVector filled with ones.
|
|
934
|
+
#
|
|
935
|
+
# Examples:
|
|
936
|
+
#
|
|
937
|
+
# NVector.ones(2) # => 1.0
|
|
938
|
+
# 1.0
|
|
939
|
+
#
|
|
940
|
+
# NVector.ones(3, :int32) # => 1
|
|
941
|
+
# 1
|
|
942
|
+
# 1
|
|
943
|
+
#
|
|
944
|
+
def ones(size, dtype = :float64)
|
|
945
|
+
NMatrix.new([size,1], 1, dtype: dtype)
|
|
946
|
+
end
|
|
947
|
+
|
|
948
|
+
#
|
|
949
|
+
# call-seq:
|
|
950
|
+
# random(size) -> NVector
|
|
951
|
+
#
|
|
952
|
+
# Creates a vector with random numbers between 0 and 1 generated by
|
|
953
|
+
# +Random::rand+ with the dimensions supplied as parameters.
|
|
954
|
+
#
|
|
955
|
+
# * *Arguments* :
|
|
956
|
+
# - +size+ -> Array (or integer for square matrix) specifying the dimensions.
|
|
957
|
+
# - +opts+ -> (optional) NMatrix#initialize options
|
|
958
|
+
# * *Returns* :
|
|
959
|
+
# - NVector filled with random numbers generated by the +Random+ class.
|
|
960
|
+
#
|
|
961
|
+
# Examples:
|
|
962
|
+
#
|
|
963
|
+
# NVector.rand(2) # => 0.4859439730644226
|
|
964
|
+
# 0.1783195585012436
|
|
965
|
+
#
|
|
966
|
+
def random(size, opts = {})
|
|
967
|
+
rng = Random.new
|
|
968
|
+
|
|
969
|
+
random_values = []
|
|
970
|
+
size.times { |i| random_values << rng.rand }
|
|
971
|
+
|
|
972
|
+
NMatrix.new([size,1], random_values, opts)
|
|
973
|
+
end
|
|
974
|
+
|
|
975
|
+
#
|
|
976
|
+
# call-seq:
|
|
977
|
+
# seq(n) -> NVector
|
|
978
|
+
# seq(n, dtype) -> NVector
|
|
979
|
+
#
|
|
980
|
+
# Creates a vector with a sequence of +n+ integers starting at zero. You
|
|
981
|
+
# can choose other types based on the dtype parameter.
|
|
982
|
+
#
|
|
983
|
+
# * *Arguments* :
|
|
984
|
+
# - +n+ -> Number of integers in the sequence.
|
|
985
|
+
# - +dtype+ -> (optional) Default is +:int64+.
|
|
986
|
+
# * *Returns* :
|
|
987
|
+
# - NVector filled with +n+ integers.
|
|
988
|
+
#
|
|
989
|
+
# Examples:
|
|
990
|
+
#
|
|
991
|
+
# NVector.seq(2) # => 0
|
|
992
|
+
# 1
|
|
993
|
+
#
|
|
994
|
+
# NVector.seq(3, :float32) # => 0.0
|
|
995
|
+
# 1.0
|
|
996
|
+
# 2.0
|
|
997
|
+
#
|
|
998
|
+
def seq(size, dtype = :int64)
|
|
999
|
+
values = (0 ... size).to_a
|
|
1000
|
+
|
|
1001
|
+
NMatrix.new([size,1], values, dtype: dtype)
|
|
1002
|
+
end
|
|
1003
|
+
|
|
1004
|
+
#
|
|
1005
|
+
# call-seq:
|
|
1006
|
+
# indgen(n) -> NVector
|
|
1007
|
+
#
|
|
1008
|
+
# Returns an integer NVector. Equivalent to <tt>seq(n, :int32)</tt>.
|
|
1009
|
+
#
|
|
1010
|
+
# * *Arguments* :
|
|
1011
|
+
# - +n+ -> Size of the sequence.
|
|
1012
|
+
# * *Returns* :
|
|
1013
|
+
# - NVector filled with +n+ integers of dtype +:int32+.
|
|
1014
|
+
#
|
|
1015
|
+
def indgen(n)
|
|
1016
|
+
NVector.seq(n, :int32)
|
|
1017
|
+
end
|
|
1018
|
+
|
|
1019
|
+
#
|
|
1020
|
+
# call-seq:
|
|
1021
|
+
# findgen(n) -> NVector
|
|
1022
|
+
#
|
|
1023
|
+
# Returns a float NVector. Equivalent to <tt>seq(n, :float32)</tt>.
|
|
1024
|
+
#
|
|
1025
|
+
# * *Arguments* :
|
|
1026
|
+
# - +n+ -> Size of the sequence.
|
|
1027
|
+
# * *Returns* :
|
|
1028
|
+
# - NVector filled with +n+ integers of dtype +:float32+.
|
|
1029
|
+
#
|
|
1030
|
+
def findgen(n)
|
|
1031
|
+
NVector.seq(n, :float32)
|
|
1032
|
+
end
|
|
1033
|
+
|
|
1034
|
+
#
|
|
1035
|
+
# call-seq:
|
|
1036
|
+
# bindgen(n) -> NVector
|
|
1037
|
+
#
|
|
1038
|
+
# Returns a byte NVector. Equivalent to <tt>seq(n, :byte)</tt>.
|
|
1039
|
+
#
|
|
1040
|
+
# * *Arguments* :
|
|
1041
|
+
# - +n+ -> Size of the sequence.
|
|
1042
|
+
# * *Returns* :
|
|
1043
|
+
# - NVector filled with +n+ integers of dtype +:byte+.
|
|
1044
|
+
#
|
|
1045
|
+
def bindgen(n)
|
|
1046
|
+
NVector.seq(n, :byte)
|
|
1047
|
+
end
|
|
1048
|
+
|
|
1049
|
+
#
|
|
1050
|
+
# call-seq:
|
|
1051
|
+
# cindgen(n) -> NVector
|
|
1052
|
+
#
|
|
1053
|
+
# Returns a complex NVector. Equivalent to <tt>seq(n, :complex64)</tt>.
|
|
1054
|
+
#
|
|
1055
|
+
# * *Arguments* :
|
|
1056
|
+
# - +n+ -> Size of the sequence.
|
|
1057
|
+
# * *Returns* :
|
|
1058
|
+
# - NVector filled with +n+ integers of dtype +:complex64+.
|
|
1059
|
+
#
|
|
1060
|
+
def cindgen(n)
|
|
1061
|
+
NVector.seq(n, :complex64)
|
|
1062
|
+
end
|
|
1063
|
+
|
|
1064
|
+
#
|
|
1065
|
+
# call-seq:
|
|
1066
|
+
# linspace(a, b) -> NVector
|
|
1067
|
+
# linspace(a, b, n) -> NVector
|
|
1068
|
+
#
|
|
1069
|
+
# Returns a NVector with +n+ values of dtype +:float64+ equally spaced from
|
|
1070
|
+
# +a+ to +b+, inclusive.
|
|
1071
|
+
#
|
|
1072
|
+
# See: http://www.mathworks.com/help/matlab/ref/linspace.html
|
|
1073
|
+
#
|
|
1074
|
+
# * *Arguments* :
|
|
1075
|
+
# - +a+ -> The first value in the sequence.
|
|
1076
|
+
# - +b+ -> The last value in the sequence.
|
|
1077
|
+
# - +n+ -> The number of elements. Default is 100.
|
|
1078
|
+
# * *Returns* :
|
|
1079
|
+
# - NVector with +n+ +:float64+ values.
|
|
1080
|
+
#
|
|
1081
|
+
# Example:
|
|
1082
|
+
# x = NVector.linspace(0, Math::PI, 1000)
|
|
1083
|
+
# x.pretty_print
|
|
1084
|
+
# [0.0
|
|
1085
|
+
# 0.0031447373909807737
|
|
1086
|
+
# 0.006289474781961547
|
|
1087
|
+
# ...
|
|
1088
|
+
# 3.135303178807831
|
|
1089
|
+
# 3.138447916198812
|
|
1090
|
+
# 3.141592653589793]
|
|
1091
|
+
# => nil
|
|
1092
|
+
#
|
|
1093
|
+
def linspace(a, b, n = 100)
|
|
1094
|
+
# Formula: seq(n) * step + a
|
|
1095
|
+
|
|
1096
|
+
# step = ((b - a) / (n - 1))
|
|
1097
|
+
step = (b - a) * (1.0 / (n - 1))
|
|
1098
|
+
|
|
1099
|
+
# dtype = :float64 is used to prevent integer coercion.
|
|
1100
|
+
result = NVector.seq(n, :float64) * NMatrix.new([n,1], step, dtype: :float64)
|
|
1101
|
+
result += NMatrix.new([n,1], a, dtype: :float64)
|
|
1102
|
+
result
|
|
1103
|
+
end
|
|
1104
|
+
|
|
1105
|
+
#
|
|
1106
|
+
# call-seq:
|
|
1107
|
+
# logspace(a, b) -> NVector
|
|
1108
|
+
# logspace(a, b, n) -> NVector
|
|
1109
|
+
#
|
|
1110
|
+
# Returns a NVector with +n+ values of dtype +:float64+ logarithmically
|
|
1111
|
+
# spaced from +10^a+ to +10^b+, inclusive.
|
|
1112
|
+
#
|
|
1113
|
+
# See: http://www.mathworks.com/help/matlab/ref/logspace.html
|
|
1114
|
+
#
|
|
1115
|
+
# * *Arguments* :
|
|
1116
|
+
# - +a+ -> The first value in the sequence.
|
|
1117
|
+
# - +b+ -> The last value in the sequence.
|
|
1118
|
+
# - +n+ -> The number of elements. Default is 100.
|
|
1119
|
+
# * *Returns* :
|
|
1120
|
+
# - NVector with +n+ +:float64+ values.
|
|
1121
|
+
#
|
|
1122
|
+
# Example:
|
|
1123
|
+
# x = NVector.logspace(0, Math::PI, 10)
|
|
1124
|
+
# x.pretty_print
|
|
1125
|
+
# [1.0
|
|
1126
|
+
# 2.2339109164570266
|
|
1127
|
+
# 4.990357982665873
|
|
1128
|
+
# 11.148015174505757
|
|
1129
|
+
# 24.903672795156997
|
|
1130
|
+
# 55.632586516975095
|
|
1131
|
+
# 124.27824233101062
|
|
1132
|
+
# 277.6265222213364
|
|
1133
|
+
# 620.1929186882427
|
|
1134
|
+
# 1385.4557313670107]
|
|
1135
|
+
# => nil
|
|
1136
|
+
#
|
|
1137
|
+
def logspace(a, b, n = 100)
|
|
1138
|
+
# Formula: 10^a, 10^(a + step), ..., 10^b, where step = ((b-a) / (n-1)).
|
|
1139
|
+
|
|
1140
|
+
result = NVector.linspace(a, b, n)
|
|
1141
|
+
result.each_stored_with_index { |element, i| result[i] = 10 ** element }
|
|
1142
|
+
result
|
|
1143
|
+
end
|
|
1144
|
+
end
|
|
1145
|
+
end
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
# This constant is intended as a simple constructor for NMatrix meant for
|
|
1149
|
+
# experimenting.
|
|
1150
|
+
#
|
|
1151
|
+
# Examples:
|
|
1152
|
+
#
|
|
1153
|
+
# a = N[ 1,2,3,4 ] => 1 2 3 4
|
|
1154
|
+
#
|
|
1155
|
+
# a = N[ 1,2,3,4, :int32 ] => 1 2 3 4
|
|
1156
|
+
#
|
|
1157
|
+
# a = N[ [1,2,3], [3,4,5] ] => 1 2 3
|
|
1158
|
+
# 3 4 5
|
|
1159
|
+
#
|
|
1160
|
+
# a = N[ 3,6,9 ].transpose => 3
|
|
1161
|
+
# 6
|
|
1162
|
+
# 9
|
|
1163
|
+
N = NMatrix
|