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.
Files changed (185) hide show
  1. checksums.yaml +7 -0
  2. data/ext/nmatrix/data/complex.h +364 -0
  3. data/ext/nmatrix/data/data.h +638 -0
  4. data/ext/nmatrix/data/meta.h +64 -0
  5. data/ext/nmatrix/data/ruby_object.h +389 -0
  6. data/ext/nmatrix/math/asum.h +120 -0
  7. data/ext/nmatrix/math/cblas_enums.h +36 -0
  8. data/ext/nmatrix/math/cblas_templates_core.h +507 -0
  9. data/ext/nmatrix/math/gemm.h +241 -0
  10. data/ext/nmatrix/math/gemv.h +178 -0
  11. data/ext/nmatrix/math/getrf.h +255 -0
  12. data/ext/nmatrix/math/getrs.h +121 -0
  13. data/ext/nmatrix/math/imax.h +79 -0
  14. data/ext/nmatrix/math/laswp.h +165 -0
  15. data/ext/nmatrix/math/long_dtype.h +49 -0
  16. data/ext/nmatrix/math/math.h +744 -0
  17. data/ext/nmatrix/math/nrm2.h +160 -0
  18. data/ext/nmatrix/math/rot.h +117 -0
  19. data/ext/nmatrix/math/rotg.h +106 -0
  20. data/ext/nmatrix/math/scal.h +71 -0
  21. data/ext/nmatrix/math/trsm.h +332 -0
  22. data/ext/nmatrix/math/util.h +148 -0
  23. data/ext/nmatrix/nm_memory.h +60 -0
  24. data/ext/nmatrix/nmatrix.h +408 -0
  25. data/ext/nmatrix/ruby_constants.h +106 -0
  26. data/ext/nmatrix/storage/common.h +176 -0
  27. data/ext/nmatrix/storage/dense/dense.h +128 -0
  28. data/ext/nmatrix/storage/list/list.h +137 -0
  29. data/ext/nmatrix/storage/storage.h +98 -0
  30. data/ext/nmatrix/storage/yale/class.h +1139 -0
  31. data/ext/nmatrix/storage/yale/iterators/base.h +142 -0
  32. data/ext/nmatrix/storage/yale/iterators/iterator.h +130 -0
  33. data/ext/nmatrix/storage/yale/iterators/row.h +449 -0
  34. data/ext/nmatrix/storage/yale/iterators/row_stored.h +139 -0
  35. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +168 -0
  36. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +123 -0
  37. data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
  38. data/ext/nmatrix/storage/yale/yale.h +202 -0
  39. data/ext/nmatrix/types.h +54 -0
  40. data/ext/nmatrix/util/io.h +115 -0
  41. data/ext/nmatrix/util/sl_list.h +143 -0
  42. data/ext/nmatrix/util/util.h +78 -0
  43. data/ext/nmatrix_lapacke/extconf.rb +200 -0
  44. data/ext/nmatrix_lapacke/lapacke.cpp +100 -0
  45. data/ext/nmatrix_lapacke/lapacke/include/lapacke.h +16445 -0
  46. data/ext/nmatrix_lapacke/lapacke/include/lapacke_config.h +119 -0
  47. data/ext/nmatrix_lapacke/lapacke/include/lapacke_mangling.h +17 -0
  48. data/ext/nmatrix_lapacke/lapacke/include/lapacke_mangling_with_flags.h +17 -0
  49. data/ext/nmatrix_lapacke/lapacke/include/lapacke_utils.h +579 -0
  50. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgeev.c +89 -0
  51. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgeev_work.c +141 -0
  52. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgesdd.c +106 -0
  53. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgesdd_work.c +158 -0
  54. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgesvd.c +94 -0
  55. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgesvd_work.c +149 -0
  56. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgetrf.c +51 -0
  57. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgetrf_work.c +83 -0
  58. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgetri.c +77 -0
  59. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgetri_work.c +89 -0
  60. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgetrs.c +56 -0
  61. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cgetrs_work.c +102 -0
  62. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cpotrf.c +50 -0
  63. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cpotrf_work.c +82 -0
  64. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cpotri.c +50 -0
  65. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cpotri_work.c +82 -0
  66. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cpotrs.c +55 -0
  67. data/ext/nmatrix_lapacke/lapacke/src/lapacke_cpotrs_work.c +101 -0
  68. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgeev.c +78 -0
  69. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgeev_work.c +136 -0
  70. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgesdd.c +88 -0
  71. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgesdd_work.c +153 -0
  72. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgesvd.c +83 -0
  73. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgesvd_work.c +144 -0
  74. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgetrf.c +50 -0
  75. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgetrf_work.c +81 -0
  76. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgetri.c +75 -0
  77. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgetri_work.c +87 -0
  78. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgetrs.c +55 -0
  79. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dgetrs_work.c +99 -0
  80. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dpotrf.c +50 -0
  81. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dpotrf_work.c +81 -0
  82. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dpotri.c +50 -0
  83. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dpotri_work.c +81 -0
  84. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dpotrs.c +54 -0
  85. data/ext/nmatrix_lapacke/lapacke/src/lapacke_dpotrs_work.c +97 -0
  86. data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgeev.c +78 -0
  87. data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgeev_work.c +134 -0
  88. data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgesdd.c +88 -0
  89. data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgesdd_work.c +152 -0
  90. data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgesvd.c +83 -0
  91. data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgesvd_work.c +143 -0
  92. data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgetrf.c +50 -0
  93. data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgetrf_work.c +81 -0
  94. data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgetri.c +75 -0
  95. data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgetri_work.c +87 -0
  96. data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgetrs.c +55 -0
  97. data/ext/nmatrix_lapacke/lapacke/src/lapacke_sgetrs_work.c +99 -0
  98. data/ext/nmatrix_lapacke/lapacke/src/lapacke_spotrf.c +50 -0
  99. data/ext/nmatrix_lapacke/lapacke/src/lapacke_spotrf_work.c +81 -0
  100. data/ext/nmatrix_lapacke/lapacke/src/lapacke_spotri.c +50 -0
  101. data/ext/nmatrix_lapacke/lapacke/src/lapacke_spotri_work.c +81 -0
  102. data/ext/nmatrix_lapacke/lapacke/src/lapacke_spotrs.c +54 -0
  103. data/ext/nmatrix_lapacke/lapacke/src/lapacke_spotrs_work.c +97 -0
  104. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgeev.c +89 -0
  105. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgeev_work.c +141 -0
  106. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgesdd.c +106 -0
  107. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgesdd_work.c +158 -0
  108. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgesvd.c +94 -0
  109. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgesvd_work.c +149 -0
  110. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgetrf.c +51 -0
  111. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgetrf_work.c +83 -0
  112. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgetri.c +77 -0
  113. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgetri_work.c +89 -0
  114. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgetrs.c +56 -0
  115. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zgetrs_work.c +102 -0
  116. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zpotrf.c +50 -0
  117. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zpotrf_work.c +82 -0
  118. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zpotri.c +50 -0
  119. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zpotri_work.c +82 -0
  120. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zpotrs.c +55 -0
  121. data/ext/nmatrix_lapacke/lapacke/src/lapacke_zpotrs_work.c +101 -0
  122. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_cge_nancheck.c +62 -0
  123. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_cge_trans.c +65 -0
  124. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_cpo_nancheck.c +43 -0
  125. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_cpo_trans.c +45 -0
  126. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_ctr_nancheck.c +85 -0
  127. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_ctr_trans.c +85 -0
  128. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_dge_nancheck.c +62 -0
  129. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_dge_trans.c +65 -0
  130. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_dpo_nancheck.c +43 -0
  131. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_dpo_trans.c +45 -0
  132. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_dtr_nancheck.c +85 -0
  133. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_dtr_trans.c +85 -0
  134. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_lsame.c +41 -0
  135. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_sge_nancheck.c +62 -0
  136. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_sge_trans.c +65 -0
  137. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_spo_nancheck.c +43 -0
  138. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_spo_trans.c +45 -0
  139. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_str_nancheck.c +85 -0
  140. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_str_trans.c +85 -0
  141. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_xerbla.c +46 -0
  142. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_zge_nancheck.c +62 -0
  143. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_zge_trans.c +65 -0
  144. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_zpo_nancheck.c +43 -0
  145. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_zpo_trans.c +45 -0
  146. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_ztr_nancheck.c +85 -0
  147. data/ext/nmatrix_lapacke/lapacke/utils/lapacke_ztr_trans.c +85 -0
  148. data/ext/nmatrix_lapacke/lapacke_nmatrix.h +16 -0
  149. data/ext/nmatrix_lapacke/make_lapacke_cpp.rb +9 -0
  150. data/ext/nmatrix_lapacke/math_lapacke.cpp +967 -0
  151. data/ext/nmatrix_lapacke/math_lapacke/cblas_local.h +576 -0
  152. data/ext/nmatrix_lapacke/math_lapacke/cblas_templates_lapacke.h +51 -0
  153. data/ext/nmatrix_lapacke/math_lapacke/lapacke_templates.h +356 -0
  154. data/ext/nmatrix_lapacke/nmatrix_lapacke.cpp +42 -0
  155. data/lib/nmatrix/lapack_ext_common.rb +69 -0
  156. data/lib/nmatrix/lapacke.rb +213 -0
  157. data/spec/00_nmatrix_spec.rb +730 -0
  158. data/spec/01_enum_spec.rb +190 -0
  159. data/spec/02_slice_spec.rb +389 -0
  160. data/spec/03_nmatrix_monkeys_spec.rb +78 -0
  161. data/spec/2x2_dense_double.mat +0 -0
  162. data/spec/4x4_sparse.mat +0 -0
  163. data/spec/4x5_dense.mat +0 -0
  164. data/spec/blas_spec.rb +193 -0
  165. data/spec/elementwise_spec.rb +303 -0
  166. data/spec/homogeneous_spec.rb +99 -0
  167. data/spec/io/fortran_format_spec.rb +88 -0
  168. data/spec/io/harwell_boeing_spec.rb +98 -0
  169. data/spec/io/test.rua +9 -0
  170. data/spec/io_spec.rb +149 -0
  171. data/spec/lapack_core_spec.rb +482 -0
  172. data/spec/leakcheck.rb +16 -0
  173. data/spec/math_spec.rb +730 -0
  174. data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
  175. data/spec/nmatrix_yale_spec.rb +286 -0
  176. data/spec/plugins/lapacke/lapacke_spec.rb +303 -0
  177. data/spec/rspec_monkeys.rb +56 -0
  178. data/spec/rspec_spec.rb +34 -0
  179. data/spec/shortcuts_spec.rb +310 -0
  180. data/spec/slice_set_spec.rb +157 -0
  181. data/spec/spec_helper.rb +140 -0
  182. data/spec/stat_spec.rb +203 -0
  183. data/spec/test.pcd +20 -0
  184. data/spec/utm5940.mtx +83844 -0
  185. metadata +262 -0
@@ -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
@@ -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