nmatrix-lapacke 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/nmatrix/data/complex.h +364 -0
- data/ext/nmatrix/data/data.h +638 -0
- data/ext/nmatrix/data/meta.h +64 -0
- data/ext/nmatrix/data/ruby_object.h +389 -0
- data/ext/nmatrix/math/asum.h +120 -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 +79 -0
- data/ext/nmatrix/math/laswp.h +165 -0
- data/ext/nmatrix/math/long_dtype.h +49 -0
- data/ext/nmatrix/math/math.h +744 -0
- data/ext/nmatrix/math/nrm2.h +160 -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 +332 -0
- data/ext/nmatrix/math/util.h +148 -0
- data/ext/nmatrix/nm_memory.h +60 -0
- data/ext/nmatrix/nmatrix.h +408 -0
- data/ext/nmatrix/ruby_constants.h +106 -0
- data/ext/nmatrix/storage/common.h +176 -0
- data/ext/nmatrix/storage/dense/dense.h +128 -0
- data/ext/nmatrix/storage/list/list.h +137 -0
- data/ext/nmatrix/storage/storage.h +98 -0
- data/ext/nmatrix/storage/yale/class.h +1139 -0
- data/ext/nmatrix/storage/yale/iterators/base.h +142 -0
- data/ext/nmatrix/storage/yale/iterators/iterator.h +130 -0
- data/ext/nmatrix/storage/yale/iterators/row.h +449 -0
- data/ext/nmatrix/storage/yale/iterators/row_stored.h +139 -0
- data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +168 -0
- data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +123 -0
- data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
- data/ext/nmatrix/storage/yale/yale.h +202 -0
- data/ext/nmatrix/types.h +54 -0
- data/ext/nmatrix/util/io.h +115 -0
- data/ext/nmatrix/util/sl_list.h +143 -0
- data/ext/nmatrix/util/util.h +78 -0
- data/ext/nmatrix_lapacke/extconf.rb +200 -0
- data/ext/nmatrix_lapacke/lapacke.cpp +100 -0
- data/ext/nmatrix_lapacke/lapacke/include/lapacke.h +16445 -0
- data/ext/nmatrix_lapacke/lapacke/include/lapacke_config.h +119 -0
- data/ext/nmatrix_lapacke/lapacke/include/lapacke_mangling.h +17 -0
- data/ext/nmatrix_lapacke/lapacke/include/lapacke_mangling_with_flags.h +17 -0
- data/ext/nmatrix_lapacke/lapacke/include/lapacke_utils.h +579 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgeev.c +89 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgeev_work.c +141 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgesdd.c +106 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgesdd_work.c +158 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgesvd.c +94 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgesvd_work.c +149 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgetrf.c +51 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgetrf_work.c +83 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgetri.c +77 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgetri_work.c +89 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgetrs.c +56 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgetrs_work.c +102 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cpotrf.c +50 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cpotrf_work.c +82 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cpotri.c +50 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cpotri_work.c +82 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cpotrs.c +55 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_cpotrs_work.c +101 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgeev.c +78 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgeev_work.c +136 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgesdd.c +88 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgesdd_work.c +153 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgesvd.c +83 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgesvd_work.c +144 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgetrf.c +50 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgetrf_work.c +81 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgetri.c +75 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgetri_work.c +87 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgetrs.c +55 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgetrs_work.c +99 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dpotrf.c +50 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dpotrf_work.c +81 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dpotri.c +50 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dpotri_work.c +81 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dpotrs.c +54 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_dpotrs_work.c +97 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgeev.c +78 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgeev_work.c +134 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgesdd.c +88 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgesdd_work.c +152 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgesvd.c +83 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgesvd_work.c +143 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgetrf.c +50 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgetrf_work.c +81 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgetri.c +75 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgetri_work.c +87 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgetrs.c +55 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgetrs_work.c +99 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_spotrf.c +50 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_spotrf_work.c +81 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_spotri.c +50 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_spotri_work.c +81 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_spotrs.c +54 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_spotrs_work.c +97 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgeev.c +89 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgeev_work.c +141 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgesdd.c +106 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgesdd_work.c +158 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgesvd.c +94 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgesvd_work.c +149 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgetrf.c +51 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgetrf_work.c +83 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgetri.c +77 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgetri_work.c +89 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgetrs.c +56 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgetrs_work.c +102 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zpotrf.c +50 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zpotrf_work.c +82 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zpotri.c +50 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zpotri_work.c +82 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zpotrs.c +55 -0
- data/ext/nmatrix_lapacke/lapacke/src/lapacke_zpotrs_work.c +101 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_cge_nancheck.c +62 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_cge_trans.c +65 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_cpo_nancheck.c +43 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_cpo_trans.c +45 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_ctr_nancheck.c +85 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_ctr_trans.c +85 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_dge_nancheck.c +62 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_dge_trans.c +65 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_dpo_nancheck.c +43 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_dpo_trans.c +45 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_dtr_nancheck.c +85 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_dtr_trans.c +85 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_lsame.c +41 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_sge_nancheck.c +62 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_sge_trans.c +65 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_spo_nancheck.c +43 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_spo_trans.c +45 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_str_nancheck.c +85 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_str_trans.c +85 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_xerbla.c +46 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_zge_nancheck.c +62 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_zge_trans.c +65 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_zpo_nancheck.c +43 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_zpo_trans.c +45 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_ztr_nancheck.c +85 -0
- data/ext/nmatrix_lapacke/lapacke/utils/lapacke_ztr_trans.c +85 -0
- data/ext/nmatrix_lapacke/lapacke_nmatrix.h +16 -0
- data/ext/nmatrix_lapacke/make_lapacke_cpp.rb +9 -0
- data/ext/nmatrix_lapacke/math_lapacke.cpp +967 -0
- data/ext/nmatrix_lapacke/math_lapacke/cblas_local.h +576 -0
- data/ext/nmatrix_lapacke/math_lapacke/cblas_templates_lapacke.h +51 -0
- data/ext/nmatrix_lapacke/math_lapacke/lapacke_templates.h +356 -0
- data/ext/nmatrix_lapacke/nmatrix_lapacke.cpp +42 -0
- data/lib/nmatrix/lapack_ext_common.rb +69 -0
- data/lib/nmatrix/lapacke.rb +213 -0
- data/spec/00_nmatrix_spec.rb +730 -0
- data/spec/01_enum_spec.rb +190 -0
- data/spec/02_slice_spec.rb +389 -0
- data/spec/03_nmatrix_monkeys_spec.rb +78 -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 +193 -0
- data/spec/elementwise_spec.rb +303 -0
- data/spec/homogeneous_spec.rb +99 -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 +149 -0
- data/spec/lapack_core_spec.rb +482 -0
- data/spec/leakcheck.rb +16 -0
- data/spec/math_spec.rb +730 -0
- data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
- data/spec/nmatrix_yale_spec.rb +286 -0
- data/spec/plugins/lapacke/lapacke_spec.rb +303 -0
- data/spec/rspec_monkeys.rb +56 -0
- data/spec/rspec_spec.rb +34 -0
- data/spec/shortcuts_spec.rb +310 -0
- data/spec/slice_set_spec.rb +157 -0
- data/spec/spec_helper.rb +140 -0
- data/spec/stat_spec.rb +203 -0
- data/spec/test.pcd +20 -0
- data/spec/utm5940.mtx +83844 -0
- metadata +262 -0
data/spec/leakcheck.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "./lib/nmatrix"
|
2
|
+
|
3
|
+
# Fixed:
|
4
|
+
#n = NMatrix.new(:yale, [8,2], :int64)
|
5
|
+
#m = NMatrix.new(:yale, [2,8], :int64)
|
6
|
+
#100.times do
|
7
|
+
# n.dot(m)
|
8
|
+
#end
|
9
|
+
#GC.start
|
10
|
+
|
11
|
+
# Remaining:
|
12
|
+
100.times do |t|
|
13
|
+
n = NMatrix.new(:dense, 1000, :float64)
|
14
|
+
n[0,t] = 1.0
|
15
|
+
puts n[t,0]
|
16
|
+
end
|
data/spec/math_spec.rb
ADDED
@@ -0,0 +1,730 @@
|
|
1
|
+
# = NMatrix
|
2
|
+
#
|
3
|
+
# A linear algebra library for scientific computation in Ruby.
|
4
|
+
# NMatrix is part of SciRuby.
|
5
|
+
#
|
6
|
+
# NMatrix was originally inspired by and derived from NArray, by
|
7
|
+
# Masahiro Tanaka: http://narray.rubyforge.org
|
8
|
+
#
|
9
|
+
# == Copyright Information
|
10
|
+
#
|
11
|
+
# SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
|
12
|
+
# NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
|
13
|
+
#
|
14
|
+
# Please see LICENSE.txt for additional copyright notices.
|
15
|
+
#
|
16
|
+
# == Contributing
|
17
|
+
#
|
18
|
+
# By contributing source code to SciRuby, you agree to be bound by
|
19
|
+
# our Contributor Agreement:
|
20
|
+
#
|
21
|
+
# * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
|
22
|
+
#
|
23
|
+
# == math_spec.rb
|
24
|
+
#
|
25
|
+
# Tests for non-BLAS and non-LAPACK math functions, or for simplified
|
26
|
+
# versions of unfriendly BLAS and LAPACK functions.
|
27
|
+
#
|
28
|
+
|
29
|
+
require 'spec_helper'
|
30
|
+
|
31
|
+
describe "math" do
|
32
|
+
context "elementwise math functions" do
|
33
|
+
|
34
|
+
[:dense,:list,:yale].each do |stype|
|
35
|
+
context stype do
|
36
|
+
|
37
|
+
[:int64,:float64].each do |dtype|
|
38
|
+
context dtype do
|
39
|
+
before :each do
|
40
|
+
@size = [2,2]
|
41
|
+
@m = NMatrix.seq(@size, dtype: dtype, stype: stype)+1
|
42
|
+
@a = @m.to_a.flatten
|
43
|
+
end
|
44
|
+
|
45
|
+
NMatrix::NMMath::METHODS_ARITY_1.each do |meth|
|
46
|
+
#skip inverse regular trig functions
|
47
|
+
next if meth.to_s.start_with?('a') and (not meth.to_s.end_with?('h')) \
|
48
|
+
and NMatrix::NMMath::METHODS_ARITY_1.include?(
|
49
|
+
meth.to_s[1...meth.to_s.length].to_sym)
|
50
|
+
next if meth == :atanh
|
51
|
+
|
52
|
+
if meth == :-@
|
53
|
+
it "should correctly apply elementwise negation" do
|
54
|
+
expect(@m.send(meth)).to eq N.new(@size, @a.map { |e| -e }, dtype: dtype, stype: stype)
|
55
|
+
end
|
56
|
+
next
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should correctly apply elementwise #{meth}" do
|
60
|
+
|
61
|
+
expect(@m.send(meth)).to eq N.new(@size, @a.map{ |e| Math.send(meth, e) },
|
62
|
+
dtype: :float64, stype: stype)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
NMatrix::NMMath::METHODS_ARITY_2.each do |meth|
|
67
|
+
next if meth == :atan2
|
68
|
+
it "should correctly apply elementwise #{meth}" do
|
69
|
+
expect(@m.send(meth, @m)).to eq N.new(@size, @a.map{ |e|
|
70
|
+
Math.send(meth, e, e) },
|
71
|
+
dtype: :float64,
|
72
|
+
stype: stype)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should correctly apply elementwise #{meth} with a scalar first arg" do
|
76
|
+
expect(Math.send(meth, 1, @m)).to eq N.new(@size, @a.map { |e| Math.send(meth, 1, e) }, dtype: :float64, stype: stype)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should correctly apply elementwise #{meth} with a scalar second arg" do
|
80
|
+
expect(@m.send(meth, 1)).to eq N.new(@size, @a.map { |e| Math.send(meth, e, 1) }, dtype: :float64, stype: stype)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should correctly apply elementwise natural log" do
|
85
|
+
expect(@m.log).to eq N.new(@size, [0, Math.log(2), Math.log(3), Math.log(4)],
|
86
|
+
dtype: :float64, stype: stype)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should correctly apply elementwise log with arbitrary base" do
|
90
|
+
expect(@m.log(3)).to eq N.new(@size, [0, Math.log(2,3), 1, Math.log(4,3)],
|
91
|
+
dtype: :float64, stype: stype)
|
92
|
+
end
|
93
|
+
|
94
|
+
context "inverse trig functions" do
|
95
|
+
before :each do
|
96
|
+
@m = NMatrix.seq(@size, dtype: dtype, stype: stype)/4
|
97
|
+
@a = @m.to_a.flatten
|
98
|
+
end
|
99
|
+
[:asin, :acos, :atan, :atanh].each do |atf|
|
100
|
+
|
101
|
+
it "should correctly apply elementwise #{atf}" do
|
102
|
+
expect(@m.send(atf)).to eq N.new(@size,
|
103
|
+
@a.map{ |e| Math.send(atf, e) },
|
104
|
+
dtype: :float64, stype: stype)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should correctly apply elementtwise atan2" do
|
109
|
+
expect(@m.atan2(@m*0+1)).to eq N.new(@size,
|
110
|
+
@a.map { |e| Math.send(:atan2, e, 1) }, dtype: :float64, stype: stype)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should correctly apply elementwise atan2 with a scalar first arg" do
|
114
|
+
expect(Math.atan2(1, @m)).to eq N.new(@size, @a.map { |e| Math.send(:atan2, 1, e) }, dtype: :float64, stype: stype)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should correctly apply elementwise atan2 with a scalar second arg" do
|
118
|
+
expect(@m.atan2(1)).to eq N.new(@size, @a.map { |e| Math.send(:atan2, e, 1) }, dtype: :float64, stype: stype)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "Floor and ceil for #{stype}" do
|
125
|
+
|
126
|
+
[:floor, :ceil].each do |meth|
|
127
|
+
ALL_DTYPES.each do |dtype|
|
128
|
+
context dtype do
|
129
|
+
before :each do
|
130
|
+
@size = [2,2]
|
131
|
+
@m = NMatrix.seq(@size, dtype: dtype, stype: stype)+1
|
132
|
+
@a = @m.to_a.flatten
|
133
|
+
end
|
134
|
+
|
135
|
+
if dtype.to_s.match(/int/) or [:byte, :object].include?(dtype)
|
136
|
+
it "should return #{dtype} for #{dtype}" do
|
137
|
+
|
138
|
+
expect(@m.send(meth)).to eq N.new(@size, @a.map { |e| e.send(meth) }, dtype: dtype, stype: stype)
|
139
|
+
|
140
|
+
if dtype == :object
|
141
|
+
expect(@m.send(meth).dtype).to eq :object
|
142
|
+
else
|
143
|
+
expect(@m.send(meth).integer_dtype?).to eq true
|
144
|
+
end
|
145
|
+
end
|
146
|
+
elsif dtype.to_s.match(/float/)
|
147
|
+
it "should return dtype int64 for #{dtype}" do
|
148
|
+
|
149
|
+
expect(@m.send(meth)).to eq N.new(@size, @a.map { |e| e.send(meth) }, dtype: dtype, stype: stype)
|
150
|
+
|
151
|
+
expect(@m.send(meth).dtype).to eq :int64
|
152
|
+
end
|
153
|
+
elsif dtype.to_s.match(/complex/)
|
154
|
+
it "should properly calculate #{meth} for #{dtype}" do
|
155
|
+
|
156
|
+
expect(@m.send(meth)).to eq N.new(@size, @a.map { |e| e = Complex(e.real.send(meth), e.imag.send(meth)) }, dtype: dtype, stype: stype)
|
157
|
+
|
158
|
+
expect(@m.send(meth).dtype).to eq :complex64 if dtype == :complex64
|
159
|
+
expect(@m.send(meth).dtype).to eq :complex128 if dtype == :complex128
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context "#round for #{stype}" do
|
168
|
+
ALL_DTYPES.each do |dtype|
|
169
|
+
context dtype do
|
170
|
+
before :each do
|
171
|
+
@size = [2,2]
|
172
|
+
@mat = NMatrix.new @size, [1.33334, 0.9998, 1.9999, -8.9999],
|
173
|
+
dtype: dtype, stype: stype
|
174
|
+
@ans = @mat.to_a.flatten
|
175
|
+
end
|
176
|
+
|
177
|
+
it "rounds" do
|
178
|
+
expect(@mat.round).to eq(N.new(@size, @ans.map { |a| a.round},
|
179
|
+
dtype: dtype, stype: stype))
|
180
|
+
end unless(/complex/ =~ dtype)
|
181
|
+
|
182
|
+
it "rounds with args" do
|
183
|
+
expect(@mat.round(2)).to eq(N.new(@size, @ans.map { |a| a.round(2)},
|
184
|
+
dtype: dtype, stype: stype))
|
185
|
+
end unless(/complex/ =~ dtype)
|
186
|
+
|
187
|
+
it "rounds complex with args" do
|
188
|
+
puts @mat.round(2)
|
189
|
+
expect(@mat.round(2)).to be_within(0.0001).of(N.new [2,2], @ans.map {|a|
|
190
|
+
Complex(a.real.round(2), a.imag.round(2))},dtype: dtype, stype: stype)
|
191
|
+
end if(/complex/ =~ dtype)
|
192
|
+
|
193
|
+
it "rounds complex" do
|
194
|
+
expect(@mat.round).to eq(N.new [2,2], @ans.map {|a|
|
195
|
+
Complex(a.real.round, a.imag.round)},dtype: dtype, stype: stype)
|
196
|
+
end if(/complex/ =~ dtype)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
NON_INTEGER_DTYPES.each do |dtype|
|
206
|
+
next if dtype == :object
|
207
|
+
context dtype do
|
208
|
+
before do
|
209
|
+
@m = NMatrix.new([3,4], GETRF_EXAMPLE_ARRAY, dtype: dtype)
|
210
|
+
@err = case dtype
|
211
|
+
when :float32, :complex64
|
212
|
+
1e-6
|
213
|
+
when :float64, :complex128
|
214
|
+
1e-14
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
#haven't check this spec yet. Also it doesn't check all the elements of the matrix.
|
219
|
+
it "should correctly factorize a matrix" do
|
220
|
+
a = @m.factorize_lu
|
221
|
+
expect(a).to be_within(@err).of(NMatrix.new([3,4], GETRF_SOLUTION_ARRAY, dtype: dtype))
|
222
|
+
end
|
223
|
+
|
224
|
+
it "also returns the permutation matrix" do
|
225
|
+
a, p = @m.factorize_lu perm_matrix: true
|
226
|
+
|
227
|
+
expect(a).to be_within(@err).of(NMatrix.new([3,4], GETRF_SOLUTION_ARRAY, dtype: dtype))
|
228
|
+
|
229
|
+
p_true = NMatrix.new([3,3], [0,0,1,1,0,0,0,1,0], dtype: dtype)
|
230
|
+
expect(p).to eq(p_true)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
NON_INTEGER_DTYPES.each do |dtype|
|
236
|
+
next if dtype == :object
|
237
|
+
context dtype do
|
238
|
+
|
239
|
+
it "calculates cholesky decomposition using potrf (lower)" do
|
240
|
+
#a = NMatrix.new([3,3],[1,1,1, 1,2,2, 1,2,6], dtype: dtype)
|
241
|
+
# We use the matrix
|
242
|
+
# 1 1 1
|
243
|
+
# 1 2 2
|
244
|
+
# 1 2 6
|
245
|
+
# which is symmetric and positive-definite as required, but
|
246
|
+
# we need only store the lower-half of the matrix.
|
247
|
+
a = NMatrix.new([3,3],[1,0,0, 1,2,0, 1,2,6], dtype: dtype)
|
248
|
+
begin
|
249
|
+
r = a.potrf!(:lower)
|
250
|
+
|
251
|
+
b = NMatrix.new([3,3],[1,0,0, 1,1,0, 1,1,2], dtype: dtype)
|
252
|
+
expect(a).to eq(b)
|
253
|
+
expect(r).to eq(b)
|
254
|
+
rescue NotImplementedError
|
255
|
+
pending "potrf! not implemented without plugins"
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
it "calculates cholesky decomposition using potrf (upper)" do
|
260
|
+
a = NMatrix.new([3,3],[1,1,1, 0,2,2, 0,0,6], dtype: dtype)
|
261
|
+
begin
|
262
|
+
r = a.potrf!(:upper)
|
263
|
+
|
264
|
+
b = NMatrix.new([3,3],[1,1,1, 0,1,1, 0,0,2], dtype: dtype)
|
265
|
+
expect(a).to eq(b)
|
266
|
+
expect(r).to eq(b)
|
267
|
+
rescue NotImplementedError
|
268
|
+
pending "potrf! not implemented without plugins"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
it "calculates cholesky decomposition using #factorize_cholesky" do
|
273
|
+
a = NMatrix.new([3,3],[1,2,1, 2,13,5, 1,5,6], dtype: dtype)
|
274
|
+
begin
|
275
|
+
u,l = a.factorize_cholesky
|
276
|
+
|
277
|
+
l_true = NMatrix.new([3,3],[1,0,0, 2,3,0, 1,1,2], dtype: dtype)
|
278
|
+
u_true = l_true.transpose
|
279
|
+
expect(u).to eq(u_true)
|
280
|
+
expect(l).to eq(l_true)
|
281
|
+
rescue NotImplementedError
|
282
|
+
pending "potrf! not implemented without plugins"
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
ALL_DTYPES.each do |dtype|
|
289
|
+
next if dtype == :byte #doesn't work for unsigned types
|
290
|
+
next if dtype == :object
|
291
|
+
|
292
|
+
context dtype do
|
293
|
+
err = case dtype
|
294
|
+
when :float32, :complex64
|
295
|
+
1e-4
|
296
|
+
else #integer matrices will return :float64
|
297
|
+
1e-13
|
298
|
+
end
|
299
|
+
|
300
|
+
it "should correctly invert a matrix in place (bang)" do
|
301
|
+
a = NMatrix.new(:dense, 5, [1, 8,-9, 7, 5,
|
302
|
+
0, 1, 0, 4, 4,
|
303
|
+
0, 0, 1, 2, 5,
|
304
|
+
0, 0, 0, 1,-5,
|
305
|
+
0, 0, 0, 0, 1 ], dtype)
|
306
|
+
b = NMatrix.new(:dense, 5, [1,-8, 9, 7, 17,
|
307
|
+
0, 1, 0,-4,-24,
|
308
|
+
0, 0, 1,-2,-15,
|
309
|
+
0, 0, 0, 1, 5,
|
310
|
+
0, 0, 0, 0, 1,], dtype)
|
311
|
+
if a.integer_dtype?
|
312
|
+
expect{a.invert!}.to raise_error(DataTypeError)
|
313
|
+
else
|
314
|
+
#should return inverse as well as modifying a
|
315
|
+
r = a.invert!
|
316
|
+
expect(a).to be_within(err).of(b)
|
317
|
+
expect(r).to be_within(err).of(b)
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
it "should correctly invert a matrix out-of-place" do
|
322
|
+
a = NMatrix.new(:dense, 3, [1,2,3,0,1,4,5,6,0], dtype)
|
323
|
+
|
324
|
+
if a.integer_dtype?
|
325
|
+
b = NMatrix.new(:dense, 3, [-24,18,5,20,-15,-4,-5,4,1], :float64)
|
326
|
+
else
|
327
|
+
b = NMatrix.new(:dense, 3, [-24,18,5,20,-15,-4,-5,4,1], dtype)
|
328
|
+
end
|
329
|
+
|
330
|
+
expect(a.invert).to be_within(err).of(b)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
# TODO: Get it working with ROBJ too
|
336
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64].each do |left_dtype|
|
337
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64].each do |right_dtype|
|
338
|
+
|
339
|
+
# Won't work if they're both 1-byte, due to overflow.
|
340
|
+
next if [:byte,:int8].include?(left_dtype) && [:byte,:int8].include?(right_dtype)
|
341
|
+
|
342
|
+
# For now, don't bother testing int-int mult.
|
343
|
+
#next if [:int8,:int16,:int32,:int64].include?(left_dtype) && [:int8,:int16,:int32,:int64].include?(right_dtype)
|
344
|
+
it "dense handles #{left_dtype.to_s} dot #{right_dtype.to_s} matrix multiplication" do
|
345
|
+
#STDERR.puts "dtype=#{dtype.to_s}"
|
346
|
+
#STDERR.puts "2"
|
347
|
+
|
348
|
+
nary = if left_dtype.to_s =~ /complex/
|
349
|
+
COMPLEX_MATRIX43A_ARRAY
|
350
|
+
else
|
351
|
+
MATRIX43A_ARRAY
|
352
|
+
end
|
353
|
+
|
354
|
+
mary = if right_dtype.to_s =~ /complex/
|
355
|
+
COMPLEX_MATRIX32A_ARRAY
|
356
|
+
else
|
357
|
+
MATRIX32A_ARRAY
|
358
|
+
end
|
359
|
+
|
360
|
+
n = NMatrix.new([4,3], nary, dtype: left_dtype, stype: :dense)
|
361
|
+
m = NMatrix.new([3,2], mary, dtype: right_dtype, stype: :dense)
|
362
|
+
|
363
|
+
expect(m.shape[0]).to eq(3)
|
364
|
+
expect(m.shape[1]).to eq(2)
|
365
|
+
expect(m.dim).to eq(2)
|
366
|
+
|
367
|
+
expect(n.shape[0]).to eq(4)
|
368
|
+
expect(n.shape[1]).to eq(3)
|
369
|
+
expect(n.dim).to eq(2)
|
370
|
+
|
371
|
+
expect(n.shape[1]).to eq(m.shape[0])
|
372
|
+
|
373
|
+
r = n.dot m
|
374
|
+
|
375
|
+
expect(r[0,0]).to eq(273.0)
|
376
|
+
expect(r[0,1]).to eq(455.0)
|
377
|
+
expect(r[1,0]).to eq(243.0)
|
378
|
+
expect(r[1,1]).to eq(235.0)
|
379
|
+
expect(r[2,0]).to eq(244.0)
|
380
|
+
expect(r[2,1]).to eq(205.0)
|
381
|
+
expect(r[3,0]).to eq(102.0)
|
382
|
+
expect(r[3,1]).to eq(160.0)
|
383
|
+
|
384
|
+
#r.dtype.should == :float64 unless left_dtype == :float32 && right_dtype == :float32
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64].each do |left_dtype|
|
390
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64].each do |right_dtype|
|
391
|
+
|
392
|
+
# Won't work if they're both 1-byte, due to overflow.
|
393
|
+
next if [:byte,:int8].include?(left_dtype) && [:byte,:int8].include?(right_dtype)
|
394
|
+
|
395
|
+
it "dense handles #{left_dtype.to_s} dot #{right_dtype.to_s} vector multiplication" do
|
396
|
+
#STDERR.puts "dtype=#{dtype.to_s}"
|
397
|
+
#STDERR.puts "2"
|
398
|
+
n = NMatrix.new([4,3], [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0], dtype: left_dtype)
|
399
|
+
|
400
|
+
m = NMatrix.new([3,1], [2.0, 1.0, 0.0], dtype: right_dtype)
|
401
|
+
|
402
|
+
expect(m.shape[0]).to eq(3)
|
403
|
+
expect(m.shape[1]).to eq(1)
|
404
|
+
|
405
|
+
expect(n.shape[0]).to eq(4)
|
406
|
+
expect(n.shape[1]).to eq(3)
|
407
|
+
expect(n.dim).to eq(2)
|
408
|
+
|
409
|
+
expect(n.shape[1]).to eq(m.shape[0])
|
410
|
+
|
411
|
+
r = n.dot m
|
412
|
+
# r.class.should == NVector
|
413
|
+
|
414
|
+
expect(r[0,0]).to eq(4)
|
415
|
+
expect(r[1,0]).to eq(13)
|
416
|
+
expect(r[2,0]).to eq(22)
|
417
|
+
expect(r[3,0]).to eq(31)
|
418
|
+
|
419
|
+
#r.dtype.should == :float64 unless left_dtype == :float32 && right_dtype == :float32
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
ALL_DTYPES.each do |dtype|
|
425
|
+
next if integer_dtype?(dtype)
|
426
|
+
context "#cov dtype #{dtype}" do
|
427
|
+
before do
|
428
|
+
@n = NMatrix.new( [5,3], [4.0,2.0,0.60,
|
429
|
+
4.2,2.1,0.59,
|
430
|
+
3.9,2.0,0.58,
|
431
|
+
4.3,2.1,0.62,
|
432
|
+
4.1,2.2,0.63], dtype: dtype)
|
433
|
+
end
|
434
|
+
|
435
|
+
it "calculates variance co-variance matrix (sample)" do
|
436
|
+
expect(@n.cov).to be_within(0.0001).of(NMatrix.new([3,3],
|
437
|
+
[0.025 , 0.0075, 0.00175,
|
438
|
+
0.0075, 0.007 , 0.00135,
|
439
|
+
0.00175, 0.00135 , 0.00043 ], dtype: dtype)
|
440
|
+
)
|
441
|
+
end
|
442
|
+
|
443
|
+
it "calculates variance co-variance matrix (population)" do
|
444
|
+
expect(@n.cov(for_sample_data: false)).to be_within(0.0001).of(NMatrix.new([3,3],
|
445
|
+
[2.0000e-02, 6.0000e-03, 1.4000e-03,
|
446
|
+
6.0000e-03, 5.6000e-03, 1.0800e-03,
|
447
|
+
1.4000e-03, 1.0800e-03, 3.4400e-04], dtype: dtype)
|
448
|
+
)
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
context "#corr #{dtype}" do
|
453
|
+
it "calculates the correlation matrix" do
|
454
|
+
n = NMatrix.new([5,3], [4.0,2.0,0.60,
|
455
|
+
4.2,2.1,0.59,
|
456
|
+
3.9,2.0,0.58,
|
457
|
+
4.3,2.1,0.62,
|
458
|
+
4.1,2.2,0.63], dtype: dtype)
|
459
|
+
expect(n.corr).to be_within(0.001).of(NMatrix.new([3,3],
|
460
|
+
[1.00000, 0.56695, 0.53374,
|
461
|
+
0.56695, 1.00000, 0.77813,
|
462
|
+
0.53374, 0.77813, 1.00000], dtype: dtype))
|
463
|
+
end unless dtype =~ /complex/
|
464
|
+
end
|
465
|
+
|
466
|
+
context "#symmetric? for #{dtype}" do
|
467
|
+
it "should return true for symmetric matrix" do
|
468
|
+
n = NMatrix.new([3,3], [1.00000, 0.56695, 0.53374,
|
469
|
+
0.56695, 1.00000, 0.77813,
|
470
|
+
0.53374, 0.77813, 1.00000], dtype: dtype)
|
471
|
+
expect(n.symmetric?).to be_truthy
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
context "#hermitian? for #{dtype}" do
|
476
|
+
it "should return true for complex hermitian or non-complex symmetric matrix" do
|
477
|
+
n = NMatrix.new([3,3], [1.00000, 0.56695, 0.53374,
|
478
|
+
0.56695, 1.00000, 0.77813,
|
479
|
+
0.53374, 0.77813, 1.00000], dtype: dtype) unless dtype =~ /complex/
|
480
|
+
n = NMatrix.new([3,3], [1.1, Complex(1.2,1.3), Complex(1.4,1.5),
|
481
|
+
Complex(1.2,-1.3), 1.9, Complex(1.8,1.7),
|
482
|
+
Complex(1.4,-1.5), Complex(1.8,-1.7), 1.3], dtype: dtype) if dtype =~ /complex/
|
483
|
+
expect(n.hermitian?).to be_truthy
|
484
|
+
end
|
485
|
+
end
|
486
|
+
|
487
|
+
context "#permute_columns for #{dtype}" do
|
488
|
+
it "check that #permute_columns works correctly by considering every premutation of a 3x3 matrix" do
|
489
|
+
n = NMatrix.new([3,3], [1,0,0,
|
490
|
+
0,2,0,
|
491
|
+
0,0,3], dtype: dtype)
|
492
|
+
expect(n.permute_columns([0,1,2], {convention: :intuitive})).to eq(NMatrix.new([3,3], [1,0,0,
|
493
|
+
0,2,0,
|
494
|
+
0,0,3], dtype: dtype))
|
495
|
+
expect(n.permute_columns([0,2,1], {convention: :intuitive})).to eq(NMatrix.new([3,3], [1,0,0,
|
496
|
+
0,0,2,
|
497
|
+
0,3,0], dtype: dtype))
|
498
|
+
expect(n.permute_columns([1,0,2], {convention: :intuitive})).to eq(NMatrix.new([3,3], [0,1,0,
|
499
|
+
2,0,0,
|
500
|
+
0,0,3], dtype: dtype))
|
501
|
+
expect(n.permute_columns([1,2,0], {convention: :intuitive})).to eq(NMatrix.new([3,3], [0,0,1,
|
502
|
+
2,0,0,
|
503
|
+
0,3,0], dtype: dtype))
|
504
|
+
expect(n.permute_columns([2,0,1], {convention: :intuitive})).to eq(NMatrix.new([3,3], [0,1,0,
|
505
|
+
0,0,2,
|
506
|
+
3,0,0], dtype: dtype))
|
507
|
+
expect(n.permute_columns([2,1,0], {convention: :intuitive})).to eq(NMatrix.new([3,3], [0,0,1,
|
508
|
+
0,2,0,
|
509
|
+
3,0,0], dtype: dtype))
|
510
|
+
expect(n.permute_columns([0,1,2], {convention: :lapack})).to eq(NMatrix.new([3,3], [1,0,0,
|
511
|
+
0,2,0,
|
512
|
+
0,0,3], dtype: dtype))
|
513
|
+
expect(n.permute_columns([0,2,2], {convention: :lapack})).to eq(NMatrix.new([3,3], [1,0,0,
|
514
|
+
0,0,2,
|
515
|
+
0,3,0], dtype: dtype))
|
516
|
+
expect(n.permute_columns([1,1,2], {convention: :lapack})).to eq(NMatrix.new([3,3], [0,1,0,
|
517
|
+
2,0,0,
|
518
|
+
0,0,3], dtype: dtype))
|
519
|
+
expect(n.permute_columns([1,2,2], {convention: :lapack})).to eq(NMatrix.new([3,3], [0,0,1,
|
520
|
+
2,0,0,
|
521
|
+
0,3,0], dtype: dtype))
|
522
|
+
expect(n.permute_columns([2,2,2], {convention: :lapack})).to eq(NMatrix.new([3,3], [0,1,0,
|
523
|
+
0,0,2,
|
524
|
+
3,0,0], dtype: dtype))
|
525
|
+
expect(n.permute_columns([2,1,2], {convention: :lapack})).to eq(NMatrix.new([3,3], [0,0,1,
|
526
|
+
0,2,0,
|
527
|
+
3,0,0], dtype: dtype))
|
528
|
+
end
|
529
|
+
it "additional tests for #permute_columns with convention :intuitive" do
|
530
|
+
m = NMatrix.new([1,4], [0,1,2,3], dtype: dtype)
|
531
|
+
perm = [1,0,3,2]
|
532
|
+
expect(m.permute_columns(perm, {convention: :intuitive})).to eq(NMatrix.new([1,4], perm, dtype: dtype))
|
533
|
+
|
534
|
+
m = NMatrix.new([1,5], [0,1,2,3,4], dtype: dtype)
|
535
|
+
perm = [1,0,4,3,2]
|
536
|
+
expect(m.permute_columns(perm, {convention: :intuitive})).to eq(NMatrix.new([1,5], perm, dtype: dtype))
|
537
|
+
|
538
|
+
m = NMatrix.new([1,6], [0,1,2,3,4,5], dtype: dtype)
|
539
|
+
perm = [2,4,1,0,5,3]
|
540
|
+
expect(m.permute_columns(perm, {convention: :intuitive})).to eq(NMatrix.new([1,6], perm, dtype: dtype))
|
541
|
+
|
542
|
+
m = NMatrix.new([1,7], [0,1,2,3,4,5,6], dtype: dtype)
|
543
|
+
perm = [1,3,5,6,0,2,4]
|
544
|
+
expect(m.permute_columns(perm, {convention: :intuitive})).to eq(NMatrix.new([1,7], perm, dtype: dtype))
|
545
|
+
|
546
|
+
m = NMatrix.new([1,8], [0,1,2,3,4,5,6,7], dtype: dtype)
|
547
|
+
perm = [6,7,5,4,1,3,0,2]
|
548
|
+
expect(m.permute_columns(perm, {convention: :intuitive})).to eq(NMatrix.new([1,8], perm, dtype: dtype))
|
549
|
+
end
|
550
|
+
end
|
551
|
+
end
|
552
|
+
|
553
|
+
context "#solve" do
|
554
|
+
NON_INTEGER_DTYPES.each do |dtype|
|
555
|
+
next if dtype == :object # LU factorization doesnt work for :object yet
|
556
|
+
it "solves linear equation for dtype #{dtype}" do
|
557
|
+
a = NMatrix.new [2,2], [3,1,1,2], dtype: dtype
|
558
|
+
b = NMatrix.new [2,1], [9,8], dtype: dtype
|
559
|
+
|
560
|
+
expect(a.solve(b)).to eq(NMatrix.new [2,1], [2,3], dtype: dtype)
|
561
|
+
end
|
562
|
+
|
563
|
+
it "solves linear equation for #{dtype} (non-symmetric matrix)" do
|
564
|
+
a = NMatrix.new [3,3], [1,1,1, -1,0,1, 3,4,6], dtype: dtype
|
565
|
+
b = NMatrix.new [3,1], [6,2,29], dtype: dtype
|
566
|
+
|
567
|
+
err = case dtype
|
568
|
+
when :float32, :complex64
|
569
|
+
1e-5
|
570
|
+
else
|
571
|
+
1e-14
|
572
|
+
end
|
573
|
+
|
574
|
+
expect(a.solve(b)).to be_within(err).of(NMatrix.new([3,1], [1,2,3], dtype: dtype))
|
575
|
+
end
|
576
|
+
|
577
|
+
it "solves linear equation for dtype #{dtype} (non-vector rhs)" do
|
578
|
+
a = NMatrix.new [3,3], [1,0,0, -1,0,1, 2,1,1], dtype: dtype
|
579
|
+
b = NMatrix.new [3,2], [1,0, 1,2, 4,2], dtype: dtype
|
580
|
+
|
581
|
+
expect(a.solve(b)).to eq(NMatrix.new [3,2], [1,0, 0,0, 2,2], dtype: dtype)
|
582
|
+
end
|
583
|
+
end
|
584
|
+
end
|
585
|
+
|
586
|
+
context "#hessenberg" do
|
587
|
+
FLOAT_DTYPES.each do |dtype|
|
588
|
+
context dtype do
|
589
|
+
before do
|
590
|
+
@n = NMatrix.new [5,5],
|
591
|
+
[0, 2, 0, 1, 1,
|
592
|
+
2, 2, 3, 2, 2,
|
593
|
+
4,-3, 0, 1, 3,
|
594
|
+
6, 1,-6,-5, 4,
|
595
|
+
5, 6, 4, 1, 5], dtype: dtype
|
596
|
+
end
|
597
|
+
|
598
|
+
it "transforms a matrix to Hessenberg form" do
|
599
|
+
expect(@n.hessenberg).to be_within(0.0001).of(NMatrix.new([5,5],
|
600
|
+
[0.00000,-1.66667, 0.79432,-0.45191,-1.54501,
|
601
|
+
-9.00000, 2.95062,-6.89312, 3.22250,-0.19012,
|
602
|
+
0.00000,-8.21682,-0.57379, 5.26966,-1.69976,
|
603
|
+
0.00000, 0.00000,-3.74630,-0.80893, 3.99708,
|
604
|
+
0.00000, 0.00000, 0.00000, 0.04102, 0.43211], dtype: dtype))
|
605
|
+
end
|
606
|
+
end
|
607
|
+
end
|
608
|
+
end
|
609
|
+
|
610
|
+
ALL_DTYPES.each do |dtype|
|
611
|
+
[:dense, :yale].each do |stype|
|
612
|
+
answer_dtype = integer_dtype?(dtype) ? :int64 : dtype
|
613
|
+
next if dtype == :byte
|
614
|
+
|
615
|
+
context "#pow #{dtype} #{stype}" do
|
616
|
+
before do
|
617
|
+
@n = NMatrix.new [4,4], [0, 2, 0, 1,
|
618
|
+
2, 2, 3, 2,
|
619
|
+
4,-3, 0, 1,
|
620
|
+
6, 1,-6,-5], dtype: dtype, stype: stype
|
621
|
+
end
|
622
|
+
|
623
|
+
it "raises a square matrix to even power" do
|
624
|
+
expect(@n.pow(4)).to eq(NMatrix.new([4,4], [292, 28,-63, -42,
|
625
|
+
360, 96, 51, -14,
|
626
|
+
448,-231,-24,-87,
|
627
|
+
-1168, 595,234, 523],
|
628
|
+
dtype: answer_dtype,
|
629
|
+
stype: stype))
|
630
|
+
end
|
631
|
+
|
632
|
+
it "raises a square matrix to odd power" do
|
633
|
+
expect(@n.pow(9)).to eq(NMatrix.new([4,4],[-275128, 279917, 176127, 237451,
|
634
|
+
-260104, 394759, 166893, 296081,
|
635
|
+
-704824, 285700, 186411, 262002,
|
636
|
+
3209256,-1070870,-918741,-1318584],
|
637
|
+
dtype: answer_dtype, stype: stype))
|
638
|
+
end
|
639
|
+
|
640
|
+
it "raises a sqaure matrix to negative power" do
|
641
|
+
expect(@n.pow(-3)).to be_within(0.00001).of (NMatrix.new([4,4],
|
642
|
+
[1.0647e-02, 4.2239e-04,-6.2281e-05, 2.7680e-03,
|
643
|
+
-1.6415e-02, 2.1296e-02, 1.0718e-02, 4.8589e-03,
|
644
|
+
8.6956e-03,-8.6569e-03, 2.8993e-02, 7.2015e-03,
|
645
|
+
5.0034e-02,-1.7500e-02,-3.6777e-02,-1.2128e-02], dtype: answer_dtype,
|
646
|
+
stype: stype))
|
647
|
+
end unless stype =~ /yale/ or dtype == :object or ALL_DTYPES.grep(/int/).include? dtype
|
648
|
+
|
649
|
+
it "raises a square matrix to zero" do
|
650
|
+
expect(@n.pow(0)).to eq(NMatrix.eye([4,4], dtype: answer_dtype,
|
651
|
+
stype: stype))
|
652
|
+
end
|
653
|
+
|
654
|
+
it "raises a square matrix to one" do
|
655
|
+
expect(@n.pow(1)).to eq(@n)
|
656
|
+
end
|
657
|
+
end
|
658
|
+
end
|
659
|
+
end
|
660
|
+
|
661
|
+
ALL_DTYPES.each do |dtype|
|
662
|
+
[:dense, :yale].each do |stype|
|
663
|
+
context "#kron_prod #{dtype} #{stype}" do
|
664
|
+
before do
|
665
|
+
@a = NMatrix.new([2,2], [1,2,
|
666
|
+
3,4], dtype: dtype, stype: stype)
|
667
|
+
@b = NMatrix.new([2,3], [1,1,1,
|
668
|
+
1,1,1], dtype: dtype, stype: stype)
|
669
|
+
@c = NMatrix.new([4,6], [1, 1, 1, 2, 2, 2,
|
670
|
+
1, 1, 1, 2, 2, 2,
|
671
|
+
3, 3, 3, 4, 4, 4,
|
672
|
+
3, 3, 3, 4, 4, 4], dtype: dtype, stype: stype)
|
673
|
+
end
|
674
|
+
it "Compute the Kronecker product of two NMatrix" do
|
675
|
+
expect(@a.kron_prod(@b)).to eq(@c)
|
676
|
+
end
|
677
|
+
end
|
678
|
+
end
|
679
|
+
end
|
680
|
+
|
681
|
+
context "determinants" do
|
682
|
+
ALL_DTYPES.each do |dtype|
|
683
|
+
next if dtype == :object
|
684
|
+
context dtype do
|
685
|
+
before do
|
686
|
+
@a = NMatrix.new([2,2], [1,2,
|
687
|
+
3,4], dtype: dtype)
|
688
|
+
@b = NMatrix.new([3,3], [1,2,3,
|
689
|
+
5,0,1,
|
690
|
+
4,1,3], dtype: dtype)
|
691
|
+
@c = NMatrix.new([4,4], [1, 0, 1, 1,
|
692
|
+
1, 2, 3, 1,
|
693
|
+
3, 3, 3, 1,
|
694
|
+
1, 2, 3, 4], dtype: dtype)
|
695
|
+
@err = case dtype
|
696
|
+
when :float32, :complex64
|
697
|
+
1e-6
|
698
|
+
when :float64, :complex128
|
699
|
+
1e-14
|
700
|
+
else
|
701
|
+
1e-64 # FIXME: should be 0, but be_within(0) does not work.
|
702
|
+
end
|
703
|
+
end
|
704
|
+
it "computes the determinant of 2x2 matrix" do
|
705
|
+
expect(@a.det).to be_within(@err).of(-2)
|
706
|
+
end
|
707
|
+
it "computes the determinant of 3x3 matrix" do
|
708
|
+
expect(@b.det).to be_within(@err).of(-8)
|
709
|
+
end
|
710
|
+
it "computes the determinant of 4x4 matrix" do
|
711
|
+
expect(@c.det).to be_within(@err).of(-18)
|
712
|
+
end
|
713
|
+
it "computes the exact determinant of 2x2 matrix" do
|
714
|
+
if dtype == :byte
|
715
|
+
expect{@a.det_exact}.to raise_error(DataTypeError)
|
716
|
+
else
|
717
|
+
expect(@a.det_exact).to be_within(@err).of(-2)
|
718
|
+
end
|
719
|
+
end
|
720
|
+
it "computes the exact determinant of 3x3 matrix" do
|
721
|
+
if dtype == :byte
|
722
|
+
expect{@a.det_exact}.to raise_error(DataTypeError)
|
723
|
+
else
|
724
|
+
expect(@b.det_exact).to be_within(@err).of(-8)
|
725
|
+
end
|
726
|
+
end
|
727
|
+
end
|
728
|
+
end
|
729
|
+
end
|
730
|
+
end
|