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
data/ext/nmatrix/data/meta.h
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
|
//
|
data/ext/nmatrix/data/rational.h
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
|
//
|
@@ -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
|
//
|
data/ext/nmatrix/extconf.rb
CHANGED
@@ -8,8 +8,8 @@
|
|
8
8
|
#
|
9
9
|
# == Copyright Information
|
10
10
|
#
|
11
|
-
# SciRuby is Copyright (c) 2010 -
|
12
|
-
# NMatrix is Copyright (c)
|
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
13
|
#
|
14
14
|
# Please see LICENSE.txt for additional copyright notices.
|
15
15
|
#
|
@@ -102,22 +102,65 @@ if /cygwin|mingw/ =~ RUBY_PLATFORM
|
|
102
102
|
end
|
103
103
|
|
104
104
|
$DEBUG = true
|
105
|
-
$CFLAGS = ["-Wall ",$CFLAGS].join(" ")
|
106
|
-
|
107
|
-
$
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
105
|
+
$CFLAGS = ["-Wall -Werror=return-type",$CFLAGS].join(" ")
|
106
|
+
$CXXFLAGS = ["-Wall -Werror=return-type",$CXXFLAGS].join(" ")
|
107
|
+
$CPPFLAGS = ["-Wall -Werror=return-type",$CPPFLAGS].join(" ")
|
108
|
+
|
109
|
+
# When adding objects here, make sure their directories are included in CLEANOBJS down at the bottom of extconf.rb.
|
110
|
+
basenames = %w{nmatrix ruby_constants data/data util/io math util/sl_list storage/common storage/storage storage/dense/dense storage/yale/yale storage/list/list}
|
111
|
+
$objs = basenames.map { |b| "#{b}.o" }
|
112
|
+
$srcs = basenames.map { |b| "#{b}.cpp" }
|
113
|
+
|
114
|
+
#CONFIG['CXX'] = 'clang++'
|
115
|
+
CONFIG['CXX'] = 'g++'
|
116
|
+
|
117
|
+
def find_newer_gplusplus #:nodoc:
|
118
|
+
print "checking for apparent GNU g++ binary with C++0x/C++11 support... "
|
119
|
+
[9,8,7,6,5,4,3].each do |minor|
|
120
|
+
ver = "4.#{minor}"
|
121
|
+
gpp = "g++-#{ver}"
|
122
|
+
result = `which #{gpp}`
|
123
|
+
next if result.empty?
|
124
|
+
CONFIG['CXX'] = gpp
|
125
|
+
puts ver
|
126
|
+
return CONFIG['CXX']
|
127
|
+
end
|
128
|
+
false
|
129
|
+
end
|
130
|
+
|
131
|
+
def gplusplus_version #:nodoc:
|
132
|
+
cxxvar = proc { |n| `#{CONFIG['CXX']} -E -dM - </dev/null | grep #{n}`.chomp.split(' ')[2] }
|
133
|
+
major = cxxvar.call('__GNUC__')
|
134
|
+
minor = cxxvar.call('__GNUC_MINOR__')
|
135
|
+
patch = cxxvar.call('__GNUC_PATCHLEVEL__')
|
136
|
+
|
137
|
+
raise("unable to determine g++ version (match to get version was nil)") if major.nil? || minor.nil? || patch.nil?
|
138
|
+
|
139
|
+
"#{major}.#{minor}.#{patch}"
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
if CONFIG['CXX'] == 'clang++'
|
144
|
+
$CPP_STANDARD = 'c++11'
|
145
|
+
|
146
|
+
else
|
147
|
+
version = gplusplus_version
|
148
|
+
if version < '4.3.0' && CONFIG['CXX'] == 'g++' # see if we can find a newer G++, unless it's been overridden by user
|
149
|
+
if !find_newer_gplusplus
|
150
|
+
raise("You need a version of g++ which supports -std=c++0x or -std=c++11. If you're on a Mac and using Homebrew, we recommend using mac-brew-gcc.sh to install a more recent g++.")
|
151
|
+
end
|
152
|
+
version = gplusplus_version
|
153
|
+
end
|
154
|
+
|
155
|
+
if version < '4.7.0'
|
156
|
+
$CPP_STANDARD = 'c++0x'
|
157
|
+
else
|
158
|
+
$CPP_STANDARD = 'c++11'
|
159
|
+
end
|
160
|
+
puts "using C++ standard... #{$CPP_STANDARD}"
|
161
|
+
puts "g++ reports version... " + `#{CONFIG['CXX']} --version|head -n 1|cut -f 3 -d " "`
|
162
|
+
end
|
163
|
+
|
121
164
|
# add smmp in to get generic transp; remove smmp2 to eliminate funcptr transp
|
122
165
|
|
123
166
|
# The next line allows the user to supply --with-atlas-dir=/usr/local/atlas,
|
@@ -138,9 +181,16 @@ idefaults = {lapack: ["/usr/include/atlas"],
|
|
138
181
|
cblas: ["/usr/local/atlas/include", "/usr/include/atlas"],
|
139
182
|
atlas: ["/usr/local/atlas/include", "/usr/include/atlas"]}
|
140
183
|
|
141
|
-
|
142
|
-
|
143
|
-
|
184
|
+
# For some reason, if we try to look for /usr/lib64/atlas on a Mac OS X Mavericks system, and the directory does not
|
185
|
+
# exist, it will give a linker error -- even if the lib dir is already correctly included with -L. So we need to check
|
186
|
+
# that Dir.exists?(d) for each.
|
187
|
+
ldefaults = {lapack: ["/usr/local/lib", "/usr/local/atlas/lib", "/usr/lib64/atlas"].delete_if { |d| !Dir.exists?(d) },
|
188
|
+
cblas: ["/usr/local/lib", "/usr/local/atlas/lib", "/usr/lib64/atlas"].delete_if { |d| !Dir.exists?(d) },
|
189
|
+
atlas: ["/usr/local/lib", "/usr/local/atlas/lib", "/usr/lib", "/usr/lib64/atlas"].delete_if { |d| !Dir.exists?(d) }}
|
190
|
+
|
191
|
+
if have_library("clapack") # Usually only applies for Mac OS X
|
192
|
+
$libs += " -lclapack "
|
193
|
+
end
|
144
194
|
|
145
195
|
unless have_library("lapack")
|
146
196
|
dir_config("lapack", idefaults[:lapack], ldefaults[:lapack])
|
@@ -154,22 +204,19 @@ unless have_library("atlas")
|
|
154
204
|
dir_config("atlas", idefaults[:atlas], ldefaults[:atlas])
|
155
205
|
end
|
156
206
|
|
157
|
-
#
|
158
|
-
#
|
159
|
-
|
160
|
-
have_header("clapack.h")
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
unless have_header("cblas.h")
|
165
|
-
find_header("cblas.h", *idefaults[:cblas])
|
207
|
+
# If BLAS and LAPACK headers are in an atlas directory, prefer those. Otherwise,
|
208
|
+
# we try our luck with the default location.
|
209
|
+
if have_header("atlas/cblas.h")
|
210
|
+
have_header("atlas/clapack.h")
|
211
|
+
else
|
212
|
+
have_header("cblas.h")
|
213
|
+
have_header("clapack.h")
|
166
214
|
end
|
167
215
|
|
168
|
-
have_header("cblas.h")
|
169
216
|
|
170
217
|
have_func("clapack_dgetrf", ["cblas.h", "clapack.h"])
|
171
218
|
have_func("clapack_dgetri", ["cblas.h", "clapack.h"])
|
172
|
-
have_func("dgesvd_", "clapack.h")
|
219
|
+
have_func("dgesvd_", "clapack.h") # This may not do anything. dgesvd_ seems to be in LAPACK, not CLAPACK.
|
173
220
|
|
174
221
|
have_func("cblas_dgemm", "cblas.h")
|
175
222
|
|
@@ -178,59 +225,15 @@ have_func("cblas_dgemm", "cblas.h")
|
|
178
225
|
#find_library("lapack", "clapack_dgetrf")
|
179
226
|
#find_library("cblas", "cblas_dgemm")
|
180
227
|
#find_library("atlas", "ATL_dgemmNN")
|
181
|
-
|
182
228
|
# Order matters here: ATLAS has to go after LAPACK: http://mail.scipy.org/pipermail/scipy-user/2007-January/010717.html
|
183
229
|
$libs += " -llapack -lcblas -latlas "
|
230
|
+
#$libs += " -lprofiler "
|
184
231
|
|
185
|
-
$objs = %w{nmatrix ruby_constants data/data util/io math util/sl_list storage/common storage/storage storage/dense storage/yale/yale storage/list}.map { |i| i + ".o" }
|
186
|
-
|
187
|
-
#CONFIG['CXX'] = 'clang++'
|
188
|
-
CONFIG['CXX'] = 'g++'
|
189
|
-
|
190
|
-
def find_newer_gplusplus #:nodoc:
|
191
|
-
print "checking for apparent GNU g++ binary with C++0x/C++11 support... "
|
192
|
-
[9,8,7,6,5,4,3].each do |minor|
|
193
|
-
ver = "4.#{minor}"
|
194
|
-
gpp = "g++-#{ver}"
|
195
|
-
result = `which #{gpp}`
|
196
|
-
next if result.empty?
|
197
|
-
CONFIG['CXX'] = gpp
|
198
|
-
puts ver
|
199
|
-
return CONFIG['CXX']
|
200
|
-
end
|
201
|
-
false
|
202
|
-
end
|
203
|
-
|
204
|
-
def gplusplus_version #:nodoc:
|
205
|
-
`LANG="en_US" #{CONFIG['CXX']} -v 2>&1`.lines.to_a.last.match(/gcc\sversion\s(\d\.\d.\d)/).captures.first
|
206
|
-
end
|
207
|
-
|
208
|
-
|
209
|
-
if CONFIG['CXX'] == 'clang++'
|
210
|
-
$CPP_STANDARD = 'c++11'
|
211
|
-
|
212
|
-
else
|
213
|
-
version = gplusplus_version
|
214
|
-
if version < '4.3.0' && CONFIG['CXX'] == 'g++' # see if we can find a newer G++, unless it's been overridden by user
|
215
|
-
if !find_newer_gplusplus
|
216
|
-
raise("You need a version of g++ which supports -std=c++0x or -std=c++11. If you're on a Mac and using Homebrew, we recommend using mac-brew-gcc.sh to install a more recent g++.")
|
217
|
-
end
|
218
|
-
version = gplusplus_version
|
219
|
-
end
|
220
|
-
|
221
|
-
if version < '4.7.0'
|
222
|
-
$CPP_STANDARD = 'c++0x'
|
223
|
-
else
|
224
|
-
$CPP_STANDARD = 'c++11'
|
225
|
-
end
|
226
|
-
puts "using C++ standard... #{$CPP_STANDARD}"
|
227
|
-
puts "g++ reports version... " + `#{CONFIG['CXX']} --version|head -n 1|cut -f 3 -d " "`
|
228
|
-
end
|
229
232
|
|
230
233
|
# For release, these next two should both be changed to -O3.
|
231
|
-
$CFLAGS += " -O3 " #" -O0 -g "
|
234
|
+
$CFLAGS += " -O3 -g" #" -O0 -g "
|
232
235
|
#$CFLAGS += " -static -O0 -g "
|
233
|
-
$CPPFLAGS += " -O3 -std=#{$CPP_STANDARD} " #" -O0 -g -std=#{$CPP_STANDARD} " #-fmax-errors=10 -save-temps
|
236
|
+
$CPPFLAGS += " -O3 -std=#{$CPP_STANDARD} -g" #" -O0 -g -std=#{$CPP_STANDARD} " #-fmax-errors=10 -save-temps
|
234
237
|
#$CPPFLAGS += " -static -O0 -g -std=#{$CPP_STANDARD} "
|
235
238
|
|
236
239
|
CONFIG['warnflags'].gsub!('-Wshorten-64-to-32', '') # doesn't work except in Mac-patched gcc (4.2)
|
@@ -244,15 +247,13 @@ Dir.mkdir("data") unless Dir.exists?("data")
|
|
244
247
|
Dir.mkdir("util") unless Dir.exists?("util")
|
245
248
|
Dir.mkdir("storage") unless Dir.exists?("storage")
|
246
249
|
Dir.chdir("storage") do
|
247
|
-
Dir.mkdir("yale")
|
248
|
-
Dir.
|
249
|
-
|
250
|
-
end
|
250
|
+
Dir.mkdir("yale") unless Dir.exists?("yale")
|
251
|
+
Dir.mkdir("list") unless Dir.exists?("list")
|
252
|
+
Dir.mkdir("dense") unless Dir.exists?("dense")
|
251
253
|
end
|
252
254
|
|
253
255
|
# to clean up object files in subdirectories:
|
254
256
|
open('Makefile', 'a') do |f|
|
255
|
-
|
256
|
-
CLEANOBJS := $(CLEANOBJS)
|
257
|
-
EOS
|
257
|
+
clean_objs_paths = %w{data storage storage/dense storage/yale storage/list util}.map { |d| "#{d}/*.#{CONFIG["OBJEXT"]}" }
|
258
|
+
f.write("CLEANOBJS := $(CLEANOBJS) #{clean_objs_paths.join(' ')}")
|
258
259
|
end
|
data/ext/nmatrix/math.cpp
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
|
//
|
@@ -140,7 +140,7 @@
|
|
140
140
|
#include "math/rot.h"
|
141
141
|
#include "math/rotg.h"
|
142
142
|
#include "math/math.h"
|
143
|
-
#include "storage/dense.h"
|
143
|
+
#include "storage/dense/dense.h"
|
144
144
|
|
145
145
|
#include "nmatrix.h"
|
146
146
|
#include "ruby_constants.h"
|
@@ -150,8 +150,10 @@
|
|
150
150
|
*/
|
151
151
|
|
152
152
|
extern "C" {
|
153
|
-
#
|
153
|
+
#if defined HAVE_CLAPACK_H
|
154
154
|
#include <clapack.h>
|
155
|
+
#elif defined HAVE_ATLAS_CLAPACK_H
|
156
|
+
#include <atlas/clapack.h>
|
155
157
|
#endif
|
156
158
|
|
157
159
|
static VALUE nm_cblas_nrm2(VALUE self, VALUE n, VALUE x, VALUE incx);
|
@@ -503,8 +505,10 @@ static VALUE nm_cblas_rotg(VALUE self, VALUE ab) {
|
|
503
505
|
return Qnil;
|
504
506
|
|
505
507
|
} else {
|
506
|
-
|
507
|
-
|
508
|
+
NM_CONSERVATIVE(nm_register_value(self));
|
509
|
+
NM_CONSERVATIVE(nm_register_value(ab));
|
510
|
+
void *pC = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]),
|
511
|
+
*pS = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]);
|
508
512
|
|
509
513
|
// extract A and B from the NVector (first two elements)
|
510
514
|
void* pA = NM_STORAGE_DENSE(ab)->elements;
|
@@ -522,7 +526,8 @@ static VALUE nm_cblas_rotg(VALUE self, VALUE ab) {
|
|
522
526
|
rb_ary_store(result, 0, rubyobj_from_cval(pC, dtype).rval);
|
523
527
|
rb_ary_store(result, 1, rubyobj_from_cval(pS, dtype).rval);
|
524
528
|
}
|
525
|
-
|
529
|
+
NM_CONSERVATIVE(nm_unregister_value(ab));
|
530
|
+
NM_CONSERVATIVE(nm_unregister_value(self));
|
526
531
|
return result;
|
527
532
|
}
|
528
533
|
}
|
@@ -575,18 +580,18 @@ static VALUE nm_cblas_rot(VALUE self, VALUE n, VALUE x, VALUE incx, VALUE y, VAL
|
|
575
580
|
|
576
581
|
// We need to ensure the cosine and sine arguments are the correct dtype -- which may differ from the actual dtype.
|
577
582
|
if (dtype == nm::COMPLEX64) {
|
578
|
-
pC =
|
579
|
-
pS =
|
583
|
+
pC = NM_ALLOCA_N(float,1);
|
584
|
+
pS = NM_ALLOCA_N(float,1);
|
580
585
|
rubyval_to_cval(c, nm::FLOAT32, pC);
|
581
586
|
rubyval_to_cval(s, nm::FLOAT32, pS);
|
582
587
|
} else if (dtype == nm::COMPLEX128) {
|
583
|
-
pC =
|
584
|
-
pS =
|
588
|
+
pC = NM_ALLOCA_N(double,1);
|
589
|
+
pS = NM_ALLOCA_N(double,1);
|
585
590
|
rubyval_to_cval(c, nm::FLOAT64, pC);
|
586
591
|
rubyval_to_cval(s, nm::FLOAT64, pS);
|
587
592
|
} else {
|
588
|
-
pC =
|
589
|
-
pS =
|
593
|
+
pC = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]);
|
594
|
+
pS = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]);
|
590
595
|
rubyval_to_cval(c, dtype, pC);
|
591
596
|
rubyval_to_cval(s, dtype, pS);
|
592
597
|
}
|
@@ -646,7 +651,7 @@ static VALUE nm_cblas_nrm2(VALUE self, VALUE n, VALUE x, VALUE incx) {
|
|
646
651
|
if (dtype == nm::COMPLEX64) rdtype = nm::FLOAT32;
|
647
652
|
else if (dtype == nm::COMPLEX128) rdtype = nm::FLOAT64;
|
648
653
|
|
649
|
-
void *Result =
|
654
|
+
void *Result = NM_ALLOCA_N(char, DTYPE_SIZES[rdtype]);
|
650
655
|
|
651
656
|
ttable[dtype](FIX2INT(n), NM_STORAGE_DENSE(x)->elements, FIX2INT(incx), Result);
|
652
657
|
|
@@ -698,7 +703,7 @@ static VALUE nm_cblas_asum(VALUE self, VALUE n, VALUE x, VALUE incx) {
|
|
698
703
|
if (dtype == nm::COMPLEX64) rdtype = nm::FLOAT32;
|
699
704
|
else if (dtype == nm::COMPLEX128) rdtype = nm::FLOAT64;
|
700
705
|
|
701
|
-
void *Result =
|
706
|
+
void *Result = NM_ALLOCA_N(char, DTYPE_SIZES[rdtype]);
|
702
707
|
|
703
708
|
ttable[dtype](FIX2INT(n), NM_STORAGE_DENSE(x)->elements, FIX2INT(incx), Result);
|
704
709
|
|
@@ -743,8 +748,8 @@ static VALUE nm_cblas_gemm(VALUE self,
|
|
743
748
|
|
744
749
|
nm::dtype_t dtype = NM_DTYPE(a);
|
745
750
|
|
746
|
-
void *pAlpha =
|
747
|
-
*pBeta =
|
751
|
+
void *pAlpha = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]),
|
752
|
+
*pBeta = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]);
|
748
753
|
rubyval_to_cval(alpha, dtype, pAlpha);
|
749
754
|
rubyval_to_cval(beta, dtype, pBeta);
|
750
755
|
|
@@ -788,8 +793,8 @@ static VALUE nm_cblas_gemv(VALUE self,
|
|
788
793
|
|
789
794
|
nm::dtype_t dtype = NM_DTYPE(a);
|
790
795
|
|
791
|
-
void *pAlpha =
|
792
|
-
*pBeta =
|
796
|
+
void *pAlpha = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]),
|
797
|
+
*pBeta = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]);
|
793
798
|
rubyval_to_cval(alpha, dtype, pAlpha);
|
794
799
|
rubyval_to_cval(beta, dtype, pBeta);
|
795
800
|
|
@@ -825,7 +830,7 @@ static VALUE nm_cblas_trsm(VALUE self,
|
|
825
830
|
if (!ttable[dtype]) {
|
826
831
|
rb_raise(nm_eDataTypeError, "this matrix operation undefined for integer matrices");
|
827
832
|
} else {
|
828
|
-
void *pAlpha =
|
833
|
+
void *pAlpha = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]);
|
829
834
|
rubyval_to_cval(alpha, dtype, pAlpha);
|
830
835
|
|
831
836
|
ttable[dtype](blas_order_sym(order), blas_side_sym(side), blas_uplo_sym(uplo), blas_transpose_sym(trans_a), blas_diag_sym(diag), FIX2INT(m), FIX2INT(n), pAlpha, NM_STORAGE_DENSE(a)->elements, FIX2INT(lda), NM_STORAGE_DENSE(b)->elements, FIX2INT(ldb));
|
@@ -865,7 +870,7 @@ static VALUE nm_cblas_trmm(VALUE self,
|
|
865
870
|
if (!ttable[dtype]) {
|
866
871
|
rb_raise(nm_eDataTypeError, "this matrix operation not yet defined for non-BLAS dtypes");
|
867
872
|
} else {
|
868
|
-
void *pAlpha =
|
873
|
+
void *pAlpha = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]);
|
869
874
|
rubyval_to_cval(alpha, dtype, pAlpha);
|
870
875
|
|
871
876
|
ttable[dtype](blas_order_sym(order), blas_side_sym(side), blas_uplo_sym(uplo), blas_transpose_sym(trans_a), blas_diag_sym(diag), FIX2INT(m), FIX2INT(n), pAlpha, NM_STORAGE_DENSE(a)->elements, FIX2INT(lda), NM_STORAGE_DENSE(b)->elements, FIX2INT(ldb));
|
@@ -903,8 +908,8 @@ static VALUE nm_cblas_syrk(VALUE self,
|
|
903
908
|
if (!ttable[dtype]) {
|
904
909
|
rb_raise(nm_eDataTypeError, "this matrix operation undefined for integer matrices");
|
905
910
|
} else {
|
906
|
-
void *pAlpha =
|
907
|
-
*pBeta =
|
911
|
+
void *pAlpha = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]),
|
912
|
+
*pBeta = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]);
|
908
913
|
rubyval_to_cval(alpha, dtype, pAlpha);
|
909
914
|
rubyval_to_cval(beta, dtype, pBeta);
|
910
915
|
|
@@ -984,12 +989,12 @@ static VALUE nm_lapack_gesvd(VALUE self, VALUE jobu, VALUE jobvt, VALUE m, VALUE
|
|
984
989
|
|
985
990
|
// only need rwork for complex matrices
|
986
991
|
int rwork_size = (dtype == nm::COMPLEX64 || dtype == nm::COMPLEX128) ? 5 * min_mn : 0;
|
987
|
-
void* rwork = rwork_size > 0 ?
|
992
|
+
void* rwork = rwork_size > 0 ? NM_ALLOCA_N(char, DTYPE_SIZES[dtype] * rwork_size) : NULL;
|
988
993
|
int work_size = FIX2INT(lwork);
|
989
994
|
|
990
995
|
// ignore user argument for lwork if it's too small.
|
991
996
|
work_size = NM_MAX((dtype == nm::COMPLEX64 || dtype == nm::COMPLEX128 ? 2 * min_mn + max_mn : NM_MAX(3*min_mn + max_mn, 5*min_mn)), work_size);
|
992
|
-
void* work =
|
997
|
+
void* work = NM_ALLOCA_N(char, DTYPE_SIZES[dtype] * work_size);
|
993
998
|
|
994
999
|
int info = gesvd_table[dtype](JOBU, JOBVT, M, N, NM_STORAGE_DENSE(a)->elements, FIX2INT(lda),
|
995
1000
|
NM_STORAGE_DENSE(s)->elements, NM_STORAGE_DENSE(u)->elements, FIX2INT(ldu), NM_STORAGE_DENSE(vt)->elements, FIX2INT(ldvt),
|
@@ -1046,7 +1051,7 @@ static VALUE nm_lapack_gesdd(VALUE self, VALUE jobz, VALUE m, VALUE n, VALUE a,
|
|
1046
1051
|
int work_size = FIX2INT(lwork); // Make sure we allocate enough work, regardless of the user request.
|
1047
1052
|
if (dtype == nm::COMPLEX64 || dtype == nm::COMPLEX128) {
|
1048
1053
|
int rwork_size = min_mn * (JOBZ == 'N' ? 5 : NM_MAX(5*min_mn + 7, 2*max_mn + 2*min_mn + 1));
|
1049
|
-
rwork =
|
1054
|
+
rwork = NM_ALLOCA_N(char, DTYPE_SIZES[dtype] * rwork_size);
|
1050
1055
|
|
1051
1056
|
if (JOBZ == 'N') work_size = NM_MAX(work_size, 3*min_mn + NM_MAX(max_mn, 6*min_mn));
|
1052
1057
|
else if (JOBZ == 'O') work_size = NM_MAX(work_size, 3*min_mn*min_mn + NM_MAX(max_mn, 5*min_mn*min_mn + 4*min_mn));
|
@@ -1056,8 +1061,8 @@ static VALUE nm_lapack_gesdd(VALUE self, VALUE jobz, VALUE m, VALUE n, VALUE a,
|
|
1056
1061
|
else if (JOBZ == 'O') work_size = NM_MAX(work_size, 2*min_mn*min_mn + max_mn + 2*min_mn);
|
1057
1062
|
else work_size = NM_MAX(work_size, min_mn*min_mn + max_mn + 2*min_mn);
|
1058
1063
|
}
|
1059
|
-
void* work =
|
1060
|
-
int* iwork =
|
1064
|
+
void* work = NM_ALLOCA_N(char, DTYPE_SIZES[dtype] * work_size);
|
1065
|
+
int* iwork = NM_ALLOCA_N(int, 8*min_mn);
|
1061
1066
|
|
1062
1067
|
int info = gesdd_table[dtype](JOBZ, M, N, NM_STORAGE_DENSE(a)->elements, FIX2INT(lda),
|
1063
1068
|
NM_STORAGE_DENSE(s)->elements, NM_STORAGE_DENSE(u)->elements, FIX2INT(ldu), NM_STORAGE_DENSE(vt)->elements, FIX2INT(ldvt),
|
@@ -1114,7 +1119,7 @@ static VALUE nm_lapack_geev(VALUE self, VALUE compute_left, VALUE compute_right,
|
|
1114
1119
|
|
1115
1120
|
// only need rwork for complex matrices (wi == Qnil for complex)
|
1116
1121
|
int rwork_size = dtype == nm::COMPLEX64 || dtype == nm::COMPLEX128 ? N * DTYPE_SIZES[dtype] : 0; // 2*N*floattype for complex only, otherwise 0
|
1117
|
-
void* rwork = rwork_size > 0 ?
|
1122
|
+
void* rwork = rwork_size > 0 ? NM_ALLOCA_N(char, rwork_size) : NULL;
|
1118
1123
|
int work_size = FIX2INT(lwork);
|
1119
1124
|
void* work;
|
1120
1125
|
|
@@ -1123,11 +1128,11 @@ static VALUE nm_lapack_geev(VALUE self, VALUE compute_left, VALUE compute_right,
|
|
1123
1128
|
// if work size is 0 or -1, query.
|
1124
1129
|
if (work_size <= 0) {
|
1125
1130
|
work_size = -1;
|
1126
|
-
work =
|
1131
|
+
work = NM_ALLOC_N(char, DTYPE_SIZES[dtype]); //2*N * DTYPE_SIZES[dtype]);
|
1127
1132
|
info = geev_table[dtype](JOBVL, JOBVR, N, A, FIX2INT(lda), WR, WI, VL, FIX2INT(ldvl), VR, FIX2INT(ldvr), work, work_size, rwork);
|
1128
1133
|
work_size = (int)(dtype == nm::COMPLEX64 || dtype == nm::FLOAT32 ? reinterpret_cast<float*>(work)[0] : reinterpret_cast<double*>(work)[0]);
|
1129
1134
|
// line above is basically: work_size = (int)(work[0]); // now have new work_size
|
1130
|
-
|
1135
|
+
NM_FREE(work);
|
1131
1136
|
if (info == 0)
|
1132
1137
|
rb_warn("geev: calculated optimal lwork of %d; to eliminate this message, use a positive value for lwork (at least 2*shape[i])", work_size);
|
1133
1138
|
else return INT2FIX(info); // error of some kind on query!
|
@@ -1140,7 +1145,7 @@ static VALUE nm_lapack_geev(VALUE self, VALUE compute_left, VALUE compute_right,
|
|
1140
1145
|
}
|
1141
1146
|
|
1142
1147
|
// Allocate work array for actual run
|
1143
|
-
work =
|
1148
|
+
work = NM_ALLOCA_N(char, work_size * DTYPE_SIZES[dtype]);
|
1144
1149
|
|
1145
1150
|
// Perform the actual calculation.
|
1146
1151
|
info = geev_table[dtype](JOBVL, JOBVR, N, A, FIX2INT(lda), WR, WI, VL, FIX2INT(ldvl), VR, FIX2INT(ldvr), work, work_size, rwork);
|
@@ -1158,7 +1163,7 @@ static VALUE nm_lapack_geev(VALUE self, VALUE compute_left, VALUE compute_right,
|
|
1158
1163
|
static VALUE nm_clapack_scal(VALUE self, VALUE n, VALUE scale, VALUE vector, VALUE incx) {
|
1159
1164
|
nm::dtype_t dtype = NM_DTYPE(vector);
|
1160
1165
|
|
1161
|
-
void* da =
|
1166
|
+
void* da = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]);
|
1162
1167
|
rubyval_to_cval(scale, dtype, da);
|
1163
1168
|
|
1164
1169
|
NAMED_DTYPE_TEMPLATE_TABLE(ttable, nm::math::clapack_scal, void, const int n, const void* da, void* dx, const int incx);
|
@@ -1251,7 +1256,7 @@ static VALUE nm_clapack_getrf(VALUE self, VALUE order, VALUE m, VALUE n, VALUE a
|
|
1251
1256
|
|
1252
1257
|
// Allocate the pivot index array, which is of size MIN(M, N).
|
1253
1258
|
size_t ipiv_size = std::min(M,N);
|
1254
|
-
int* ipiv =
|
1259
|
+
int* ipiv = NM_ALLOCA_N(int, ipiv_size);
|
1255
1260
|
|
1256
1261
|
if (!ttable[NM_DTYPE(a)]) {
|
1257
1262
|
rb_raise(nm_eDataTypeError, "this matrix operation undefined for integer matrices");
|
@@ -1282,7 +1287,7 @@ static VALUE nm_clapack_getrf(VALUE self, VALUE order, VALUE m, VALUE n, VALUE a
|
|
1282
1287
|
*/
|
1283
1288
|
static VALUE nm_clapack_potrf(VALUE self, VALUE order, VALUE uplo, VALUE n, VALUE a, VALUE lda) {
|
1284
1289
|
#ifndef HAVE_CLAPACK_H
|
1285
|
-
rb_raise(rb_eNotImpError, "potrf currently requires
|
1290
|
+
rb_raise(rb_eNotImpError, "potrf currently requires CLAPACK");
|
1286
1291
|
#endif
|
1287
1292
|
|
1288
1293
|
static int (*ttable[nm::NUM_DTYPES])(const enum CBLAS_ORDER, const enum CBLAS_UPLO, const int n, void* a, const int lda) = {
|
@@ -1343,7 +1348,7 @@ static VALUE nm_clapack_getrs(VALUE self, VALUE order, VALUE trans, VALUE n, VAL
|
|
1343
1348
|
if (TYPE(ipiv) != T_ARRAY) {
|
1344
1349
|
rb_raise(rb_eArgError, "ipiv must be of type Array");
|
1345
1350
|
} else {
|
1346
|
-
ipiv_ =
|
1351
|
+
ipiv_ = NM_ALLOCA_N(int, RARRAY_LEN(ipiv));
|
1347
1352
|
for (int index = 0; index < RARRAY_LEN(ipiv); ++index) {
|
1348
1353
|
ipiv_[index] = FIX2INT( RARRAY_PTR(ipiv)[index] );
|
1349
1354
|
}
|
@@ -1411,7 +1416,7 @@ static VALUE nm_clapack_potrs(VALUE self, VALUE order, VALUE uplo, VALUE n, VALU
|
|
1411
1416
|
*/
|
1412
1417
|
static VALUE nm_clapack_getri(VALUE self, VALUE order, VALUE n, VALUE a, VALUE lda, VALUE ipiv) {
|
1413
1418
|
#ifndef HAVE_CLAPACK_H
|
1414
|
-
rb_raise(rb_eNotImpError, "getri currently requires
|
1419
|
+
rb_raise(rb_eNotImpError, "getri currently requires CLAPACK");
|
1415
1420
|
#endif
|
1416
1421
|
|
1417
1422
|
static int (*ttable[nm::NUM_DTYPES])(const enum CBLAS_ORDER, const int n, void* a, const int lda, const int* ipiv) = {
|
@@ -1437,7 +1442,7 @@ static VALUE nm_clapack_getri(VALUE self, VALUE order, VALUE n, VALUE a, VALUE l
|
|
1437
1442
|
if (TYPE(ipiv) != T_ARRAY) {
|
1438
1443
|
rb_raise(rb_eArgError, "ipiv must be of type Array");
|
1439
1444
|
} else {
|
1440
|
-
ipiv_ =
|
1445
|
+
ipiv_ = NM_ALLOCA_N(int, RARRAY_LEN(ipiv));
|
1441
1446
|
for (int index = 0; index < RARRAY_LEN(ipiv); ++index) {
|
1442
1447
|
ipiv_[index] = FIX2INT( RARRAY_PTR(ipiv)[index] );
|
1443
1448
|
}
|
@@ -1468,7 +1473,7 @@ static VALUE nm_clapack_getri(VALUE self, VALUE order, VALUE n, VALUE a, VALUE l
|
|
1468
1473
|
*/
|
1469
1474
|
static VALUE nm_clapack_potri(VALUE self, VALUE order, VALUE uplo, VALUE n, VALUE a, VALUE lda) {
|
1470
1475
|
#ifndef HAVE_CLAPACK_H
|
1471
|
-
rb_raise(rb_eNotImpError, "getri currently requires
|
1476
|
+
rb_raise(rb_eNotImpError, "getri currently requires CLAPACK");
|
1472
1477
|
#endif
|
1473
1478
|
|
1474
1479
|
static int (*ttable[nm::NUM_DTYPES])(const enum CBLAS_ORDER, const enum CBLAS_UPLO, const int n, void* a, const int lda) = {
|
@@ -1534,7 +1539,7 @@ static VALUE nm_clapack_laswp(VALUE self, VALUE n, VALUE a, VALUE lda, VALUE k1,
|
|
1534
1539
|
if (TYPE(ipiv) != T_ARRAY) {
|
1535
1540
|
rb_raise(rb_eArgError, "ipiv must be of type Array");
|
1536
1541
|
} else {
|
1537
|
-
ipiv_ =
|
1542
|
+
ipiv_ = NM_ALLOCA_N(int, RARRAY_LEN(ipiv));
|
1538
1543
|
for (int index = 0; index < RARRAY_LEN(ipiv); ++index) {
|
1539
1544
|
ipiv_[index] = FIX2INT( RARRAY_PTR(ipiv)[index] );
|
1540
1545
|
}
|