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,286 @@
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
+ # == nmatrix_yale_spec.rb
24
+ #
25
+ # Basic tests for NMatrix's Yale storage type.
26
+ #
27
+ require 'spec_helper'
28
+ require "./lib/nmatrix"
29
+
30
+ describe NMatrix do
31
+ context :yale do
32
+
33
+ it "compares two empty matrices" do
34
+ n = NMatrix.new(4, stype: :yale, dtype: :float64)
35
+ m = NMatrix.new(4, stype: :yale, dtype: :float64)
36
+ expect(n).to eq(m)
37
+ end
38
+
39
+ it "compares two matrices following basic assignments" do
40
+ n = NMatrix.new(2, stype: :yale, dtype: :float64)
41
+ m = NMatrix.new(2, stype: :yale, dtype: :float64)
42
+
43
+ m[0,0] = 1
44
+ m[0,1] = 1
45
+ expect(n).not_to eq(m)
46
+ n[0,0] = 1
47
+ expect(n).not_to eq(m)
48
+ n[0,1] = 1
49
+ expect(n).to eq(m)
50
+ end
51
+
52
+ it "compares two matrices following elementwise operations" do
53
+ n = NMatrix.new(2, stype: :yale, dtype: :float64)
54
+ m = NMatrix.new(2, stype: :yale, dtype: :float64)
55
+ n[0,1] = 1
56
+ m[0,1] = -1
57
+ x = n+m
58
+ expect(n+m).to eq(NMatrix.new(2, 0.0, stype: :yale))
59
+ end
60
+
61
+ it "sets diagonal values" do
62
+ n = NMatrix.new([2,3], stype: :yale, dtype: :float64)
63
+ n.extend(NMatrix::YaleFunctions)
64
+ n[1,1] = 0.1
65
+ n[0,0] = 0.2
66
+ expect(n.yale_d).to eq([0.2, 0.1])
67
+ end
68
+
69
+ it "gets non-diagonal rows as hashes" do
70
+ n = NMatrix.new([4,6], stype: :yale, dtype: :float64)
71
+ n.extend(NMatrix::YaleFunctions)
72
+ n[0,0] = 0.1
73
+ n[0,2] = 0.2
74
+ n[0,3] = 0.3
75
+ n[1,5] = 0.4
76
+ h = n.yale_nd_row(0, :hash)
77
+ expect(h).to eq({2 => 0.2, 3 => 0.3})
78
+ end
79
+
80
+ it "gets non-diagonal occupied column indices for a given row" do
81
+ n = NMatrix.new([4,6], stype: :yale, dtype: :float64)
82
+ n.extend(NMatrix::YaleFunctions)
83
+ n[0,0] = 0.1
84
+ n[0,2] = 0.2
85
+ n[0,3] = 0.3
86
+ n[1,5] = 0.4
87
+ a = n.yale_nd_row(0, :array)
88
+ expect(a).to eq([2,3])
89
+ end
90
+
91
+ it "does not resize until necessary" do
92
+ n = NMatrix.new([2,3], stype: :yale, dtype: :float64)
93
+ n.extend(NMatrix::YaleFunctions)
94
+ expect(n.yale_size).to eq(3)
95
+ expect(n.capacity).to eq(5)
96
+ n[0,0] = 0.1
97
+ n[0,1] = 0.2
98
+ n[1,0] = 0.3
99
+ expect(n.yale_size).to eq(5)
100
+ expect(n.capacity).to eq(5)
101
+ end
102
+
103
+
104
+ it "sets when not resizing" do
105
+ n = NMatrix.new([2,3], stype: :yale, dtype: :float64)
106
+ n.extend(NMatrix::YaleFunctions)
107
+ n[0,0] = 0.1
108
+ n[0,1] = 0.2
109
+ n[1,0] = 0.3
110
+ expect(n.yale_a).to eq([0.1, 0.0, 0.0, 0.2, 0.3])
111
+ expect(n.yale_ija).to eq([3,4,5,1,0])
112
+ end
113
+
114
+ it "sets when resizing" do
115
+ n = NMatrix.new([2,3], stype: :yale, dtype: :float64)
116
+ n.extend(NMatrix::YaleFunctions)
117
+ n[0,0] = 0.01
118
+ n[1,1] = 0.1
119
+ n[0,1] = 0.2
120
+ n[1,0] = 0.3
121
+ n[1,2] = 0.4
122
+ expect(n.yale_d).to eq([0.01, 0.1])
123
+ expect(n.yale_ia).to eq([3,4,6])
124
+ expect(n.yale_ja).to eq([1,0,2,nil])
125
+ expect(n.yale_lu).to eq([0.2, 0.3, 0.4, nil])
126
+ end
127
+
128
+ it "resizes without erasing values" do
129
+ require 'yaml'
130
+
131
+ associations = File.open('spec/nmatrix_yale_resize_test_associations.yaml') { |y| YAML::load(y) }
132
+
133
+ n = NMatrix.new([618,2801], stype: :yale, dtype: :byte, capacity: associations.size)
134
+ #n = NMatrix.new(:yale, [618, 2801], associations.size, :byte)
135
+
136
+ associations.each_pair do |j,i|
137
+ n[i,j] = 1
138
+ expect(n[i,j]).to be(1), "Value at #{i},#{j} not inserted correctly!"
139
+ end
140
+
141
+ associations.each_pair do |j,i|
142
+ expect(n[i,j]).to be(1), "Value at #{i},#{j} erased during resize!"
143
+ end
144
+ end
145
+
146
+ it "sets values within rows" do
147
+ n = NMatrix.new([3,20], stype: :yale, dtype: :float64)
148
+ n.extend(NMatrix::YaleFunctions)
149
+ n[2,1] = 1.0
150
+ n[2,0] = 1.5
151
+ n[2,15] = 2.0
152
+ expect(n.yale_lu).to eq([1.5, 1.0, 2.0])
153
+ expect(n.yale_ja).to eq([0, 1, 15])
154
+ end
155
+
156
+ it "gets values within rows" do
157
+ n = NMatrix.new([3,20], stype: :yale, dtype: :float64)
158
+ n[2,1] = 1.0
159
+ n[2,0] = 1.5
160
+ n[2,15] = 2.0
161
+ expect(n[2,1]).to eq(1.0)
162
+ expect(n[2,0]).to eq(1.5)
163
+ expect(n[2,15]).to eq(2.0)
164
+ end
165
+
166
+ it "sets values within large rows" do
167
+ n = NMatrix.new([10,300], stype: :yale, dtype: :float64)
168
+ n.extend(NMatrix::YaleFunctions)
169
+ n[5,1] = 1.0
170
+ n[5,0] = 1.5
171
+ n[5,15] = 2.0
172
+ n[5,291] = 3.0
173
+ n[5,292] = 4.0
174
+ n[5,289] = 5.0
175
+ n[5,290] = 6.0
176
+ n[5,293] = 2.0
177
+ n[5,299] = 7.0
178
+ n[5,100] = 8.0
179
+ expect(n.yale_lu).to eq([1.5, 1.0, 2.0, 8.0, 5.0, 6.0, 3.0, 4.0, 2.0, 7.0])
180
+ expect(n.yale_ja).to eq([0, 1, 15, 100, 289, 290, 291, 292, 293, 299])
181
+ end
182
+
183
+ it "gets values within large rows" do
184
+ n = NMatrix.new([10,300], stype: :yale, dtype: :float64)
185
+ n.extend(NMatrix::YaleFunctions)
186
+ n[5,1] = 1.0
187
+ n[5,0] = 1.5
188
+ n[5,15] = 2.0
189
+ n[5,291] = 3.0
190
+ n[5,292] = 4.0
191
+ n[5,289] = 5.0
192
+ n[5,290] = 6.0
193
+ n[5,293] = 2.0
194
+ n[5,299] = 7.0
195
+ n[5,100] = 8.0
196
+
197
+ n.yale_ja.each_index do |idx|
198
+ j = n.yale_ja[idx]
199
+ expect(n[5,j]).to eq(n.yale_lu[idx])
200
+ end
201
+ end
202
+
203
+ it "dots two identical matrices" do
204
+ a = NMatrix.new(4, stype: :yale, dtype: :float64)
205
+ a[0,1] = 4.0
206
+ a[1,2] = 1.0
207
+ a[1,3] = 1.0
208
+ a[3,1] = 2.0
209
+
210
+ b = a.dup
211
+ c = a.dot b
212
+
213
+ d = NMatrix.new(4, [0,0,4,4, 0,2,0,0, 0,0,0,0, 0,0,2,2], dtype: :float64, stype: :yale)
214
+
215
+ expect(c).to eq(d)
216
+ end
217
+
218
+ it "dots two identical matrices where a positive and negative partial sum cancel on the diagonal" do
219
+ a = NMatrix.new(4, 0.0, stype: :yale)
220
+
221
+ a[0,0] = 1.0
222
+ a[0,1] = 4.0
223
+ a[1,2] = 2.0
224
+ a[1,3] = -4.0
225
+ a[3,1] = 4.0
226
+ a[3,3] = 4.0
227
+
228
+ b = a.dup
229
+ c = a.dot b
230
+
231
+ c.extend(NMatrix::YaleFunctions)
232
+
233
+ expect(c.yale_ija.reject { |i| i.nil? }).to eq([5,8,9,9,11,1,2,3,3,1,2])
234
+ expect(c.yale_a.reject { |i| i.nil? }).to eq([1.0, -16.0, 0.0, 0.0, 0.0, 4.0, 8.0, -16.0, -16.0, 16.0, 8.0])
235
+
236
+ end
237
+
238
+ it "dots two vectors" do
239
+ n = NMatrix.new([16,1], 0, stype: :yale)
240
+ m = NMatrix.new([1,16], 0, stype: :yale)
241
+
242
+ n[0] = m[0] = 1
243
+ n[1] = m[1] = 2
244
+ n[2] = m[2] = 3
245
+ n[3] = m[3] = 4
246
+ n[4] = m[4] = 5
247
+ n[5] = m[5] = 6
248
+ n[6] = m[6] = 7
249
+ n[7] = m[7] = 8
250
+ n[8] = m[8] = 9
251
+ n[15] = m[15] = 16
252
+
253
+ nm = n.dot(m)
254
+
255
+ # Perform the same multiplication with dense
256
+ nmr = n.cast(:dense, :int64).dot(m.cast(:dense, :int64)).cast(:yale, :int64)
257
+
258
+ nm.extend(NMatrix::YaleFunctions)
259
+ nmr.extend(NMatrix::YaleFunctions)
260
+
261
+ # We want to do a structure comparison to ensure multiplication is occurring properly, but more importantly, to
262
+ # ensure that insertion sort is occurring as it should. If the row has more than four entries, it'll run quicksort
263
+ # instead. Quicksort calls insertion sort for small rows, so we test both with this particular multiplication.
264
+ expect(nm.yale_ija[0...107]).to eq(nmr.yale_ija[0...107])
265
+ expect(nm.yale_a[0...107]).to eq(nmr.yale_a[0...107])
266
+
267
+ mn = m.dot(n)
268
+ expect(mn[0,0]).to eq(541)
269
+ end
270
+
271
+ it "calculates the row key intersections of two matrices" do
272
+ a = NMatrix.new([3,9], [0,1], stype: :yale, dtype: :byte, default: 0)
273
+ b = NMatrix.new([3,9], [0,0,1,0,1], stype: :yale, dtype: :byte, default: 0)
274
+ a.extend NMatrix::YaleFunctions
275
+ b.extend NMatrix::YaleFunctions
276
+
277
+ (0...3).each do |ai|
278
+ (0...3).each do |bi|
279
+ STDERR.puts (a.yale_ja_d_keys_at(ai) & b.yale_ja_d_keys_at(bi)).inspect
280
+ expect(a.yale_ja_d_keys_at(ai) & b.yale_ja_d_keys_at(bi)).to eq(a.yale_row_keys_intersection(ai, b, bi))
281
+ end
282
+ end
283
+
284
+ end
285
+ end
286
+ end
@@ -0,0 +1,303 @@
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
+ # == lapacke_spec.rb
24
+ #
25
+ # Tests for interfaces that are only exposed by nmatrix-lapacke
26
+ #
27
+
28
+ require 'spec_helper'
29
+ require "./lib/nmatrix/lapacke"
30
+
31
+ describe "NMatrix::LAPACK functions implemented with LAPACKE interface" do
32
+ [:float32, :float64, :complex64, :complex128].each do |dtype|
33
+ context dtype do
34
+ it "exposes lapacke_getrf" do
35
+ a = NMatrix.new([3,4], GETRF_EXAMPLE_ARRAY, dtype: dtype)
36
+ ipiv = NMatrix::LAPACK.lapacke_getrf(:row, 3, 4, a, 4)
37
+ b = NMatrix.new([3,4], GETRF_SOLUTION_ARRAY, dtype: dtype)
38
+ ipiv_true = [2,3,3]
39
+
40
+ # delta varies for different dtypes
41
+ err = case dtype
42
+ when :float32, :complex64
43
+ 1e-6
44
+ when :float64, :complex128
45
+ 1e-14
46
+ end
47
+
48
+ expect(a).to be_within(err).of(b)
49
+ expect(ipiv).to eq(ipiv_true)
50
+ end
51
+
52
+ it "exposes lapacke_getri" do
53
+ a = NMatrix.new(:dense, 3, [1,0,4,1,1,6,-3,0,-10], dtype)
54
+ ipiv = NMatrix::LAPACK::lapacke_getrf(:row, 3, 3, a, 3) # get pivot from getrf, use for getri
55
+
56
+ # delta varies for different dtypes
57
+ err = case dtype
58
+ when :float32, :complex64
59
+ 1e-5
60
+ when :float64, :complex128
61
+ 1e-14
62
+ end
63
+
64
+ NMatrix::LAPACK::lapacke_getri(:row, 3, a, 3, ipiv)
65
+
66
+ b = NMatrix.new(:dense, 3, [-5,0,-2,-4,1,-1,1.5,0,0.5], dtype)
67
+ expect(a).to be_within(err).of(b)
68
+ end
69
+
70
+ it "exposes lapacke_getrs with vector solutions" do
71
+ a = NMatrix.new(3, [-2,4,-3,3,-2,1,0,-4,3], dtype: dtype)
72
+ ipiv = NMatrix::LAPACK::lapacke_getrf(:row, 3, 3, a, 3)
73
+ b = NMatrix.new([3,1], [-1, 17, -9], dtype: dtype)
74
+
75
+ #be careful! the leading dimenension (lda,ldb) is the number of rows for row-major in LAPACKE. Different from CLAPACK convention!
76
+ NMatrix::LAPACK::lapacke_getrs(:row, false, 3, 1, a, 3, ipiv, b, 1)
77
+
78
+ # delta varies for different dtypes
79
+ err = case dtype
80
+ when :float32, :complex64
81
+ 1e-5
82
+ when :float64, :complex128
83
+ 1e-13
84
+ end
85
+
86
+ expect(b[0]).to be_within(err).of(5)
87
+ expect(b[1]).to be_within(err).of(-15.0/2)
88
+ expect(b[2]).to be_within(err).of(-13)
89
+ end
90
+
91
+ it "exposes lapacke_getrs with matrix solutions" do
92
+ a = NMatrix.new(3, [-2,4,-3,3,-2,1,0,-4,3], dtype: dtype)
93
+ ipiv = NMatrix::LAPACK::lapacke_getrf(:row, 3, 3, a, 3)
94
+ b = NMatrix.new([3,2], [-1, 2, 17, 10, -9, 1], dtype: dtype)
95
+
96
+ #be careful! the leading dimenension (lda,ldb) is the number of rows for row-major in LAPACKE. Different from CLAPACK convention!
97
+ NMatrix::LAPACK::lapacke_getrs(:row, false, 3, 2, a, 3, ipiv, b, 2)
98
+
99
+ # delta varies for different dtypes
100
+ err = case dtype
101
+ when :float32, :complex64
102
+ 1e-4
103
+ when :float64, :complex128
104
+ 1e-13
105
+ end
106
+
107
+ x = NMatrix.new([3,2], [5, -1.5, -7.5, -21.25, -13, -28], dtype: dtype)
108
+ expect(b).to be_within(err).of(x)
109
+ end
110
+
111
+ it "exposes lapacke_potrf" do
112
+ # first do upper
113
+ begin
114
+ a = NMatrix.new(:dense, 3, [25,15,-5, 0,18,0, 0,0,11], dtype)
115
+ NMatrix::LAPACK::lapacke_potrf(:row, :upper, 3, a, 3)
116
+ b = NMatrix.new(:dense, 3, [5,3,-1, 0,3,1, 0,0,3], dtype)
117
+ expect(a).to eq(b)
118
+ end
119
+
120
+ # then do lower
121
+ a = NMatrix.new(:dense, 3, [25,0,0, 15,18,0,-5,0,11], dtype)
122
+ NMatrix::LAPACK::lapacke_potrf(:row, :lower, 3, a, 3)
123
+ b = NMatrix.new(:dense, 3, [5,0,0, 3,3,0, -1,1,3], dtype)
124
+ expect(a).to eq(b)
125
+ end
126
+
127
+ it "exposes lapacke_potri" do
128
+ a = NMatrix.new(3, [4, 0,-1,
129
+ 0, 2, 1,
130
+ 0, 0, 1], dtype: dtype)
131
+ NMatrix::LAPACK::lapacke_potrf(:row, :upper, 3, a, 3)
132
+ NMatrix::LAPACK::lapacke_potri(:row, :upper, 3, a, 3)
133
+ b = NMatrix.new(3, [0.5, -0.5, 1, 0, 1.5, -2, 0, 0, 4], dtype: dtype)
134
+ err = case dtype
135
+ when :float32, :complex64
136
+ 1e-6
137
+ when :float64, :complex128
138
+ 1e-14
139
+ end
140
+ expect(a).to be_within(err).of(b)
141
+ end
142
+
143
+ it "exposes lapacke_potrs with vector solution" do
144
+ a = NMatrix.new(3, [4, 0,-1,
145
+ 0, 2, 1,
146
+ 0, 0, 1], dtype: dtype)
147
+ b = NMatrix.new([3,1], [3,0,2], dtype: dtype)
148
+
149
+ NMatrix::LAPACK::lapacke_potrf(:row, :upper, 3, a, 3)
150
+ #ldb is different from CLAPACK versions
151
+ NMatrix::LAPACK::lapacke_potrs(:row, :upper, 3, 1, a, 3, b, 1)
152
+
153
+ x = NMatrix.new([3,1], [3.5, -5.5, 11], dtype: dtype)
154
+
155
+ err = case dtype
156
+ when :float32, :complex64
157
+ 1e-5
158
+ when :float64, :complex128
159
+ 1e-14
160
+ end
161
+
162
+ expect(b).to be_within(err).of(x)
163
+ end
164
+
165
+ it "exposes lapacke_potrs with matrix solution" do
166
+ a = NMatrix.new(3, [4, 0,-1,
167
+ 0, 2, 1,
168
+ 0, 0, 1], dtype: dtype)
169
+ b = NMatrix.new([3,2], [3,4,
170
+ 0,4,
171
+ 2,0], dtype: dtype)
172
+
173
+ NMatrix::LAPACK::lapacke_potrf(:row, :upper, 3, a, 3)
174
+ #ldb is different from CLAPACK versions
175
+ NMatrix::LAPACK::lapacke_potrs(:row, :upper, 3, 2, a, 3, b, 2)
176
+
177
+ x = NMatrix.new([3,2], [3.5, 0,
178
+ -5.5, 4,
179
+ 11, -4], dtype: dtype)
180
+
181
+ err = case dtype
182
+ when :float32, :complex64
183
+ 1e-5
184
+ when :float64, :complex128
185
+ 1e-14
186
+ end
187
+
188
+ expect(b).to be_within(err).of(x)
189
+ end
190
+
191
+ it "calculates the singular value decomposition with lapacke_gesvd" do
192
+ #example from Wikipedia
193
+ m = 4
194
+ n = 5
195
+ mn_min = [m,n].min
196
+ a = NMatrix.new([m,n],[1,0,0,0,2, 0,0,3,0,0, 0,0,0,0,0, 0,4,0,0,0], dtype: dtype)
197
+ s = NMatrix.new([mn_min], 0, dtype: a.abs_dtype) #s is always real and always returned as float/double, never as complex
198
+ u = NMatrix.new([m,m], 0, dtype: dtype)
199
+ vt = NMatrix.new([n,n], 0, dtype: dtype)
200
+ superb = NMatrix.new([mn_min-1], dtype: a.abs_dtype)
201
+
202
+ NMatrix::LAPACK.lapacke_gesvd(:row, :a, :a, m, n, a, n, s, u, m, vt, n, superb)
203
+
204
+ s_true = NMatrix.new([mn_min], [4,3,Math.sqrt(5),0], dtype: a.abs_dtype)
205
+ u_true = NMatrix.new([m,m], [0,0,1,0, 0,1,0,0, 0,0,0,-1, 1,0,0,0], dtype: dtype)
206
+ vt_true = NMatrix.new([n,n], [0,1,0,0,0, 0,0,1,0,0, Math.sqrt(0.2),0,0,0,Math.sqrt(0.8), 0,0,0,1,0, -Math.sqrt(0.8),0,0,0,Math.sqrt(0.2)], dtype: dtype)
207
+
208
+ err = case dtype
209
+ when :float32, :complex64
210
+ 1e-5
211
+ when :float64, :complex128
212
+ 1e-14
213
+ end
214
+
215
+ expect(s).to be_within(err).of(s_true)
216
+ expect(u).to be_within(err).of(u_true)
217
+ expect(vt).to be_within(err).of(vt_true)
218
+ end
219
+
220
+ it "calculates the singular value decomposition with lapacke_gesdd" do
221
+ #example from Wikipedia
222
+ m = 4
223
+ n = 5
224
+ mn_min = [m,n].min
225
+ a = NMatrix.new([m,n],[1,0,0,0,2, 0,0,3,0,0, 0,0,0,0,0, 0,4,0,0,0], dtype: dtype)
226
+ s = NMatrix.new([mn_min], 0, dtype: a.abs_dtype) #s is always real and always returned as float/double, never as complex
227
+ u = NMatrix.new([m,m], 0, dtype: dtype)
228
+ vt = NMatrix.new([n,n], 0, dtype: dtype)
229
+
230
+ NMatrix::LAPACK.lapacke_gesdd(:row, :a, m, n, a, n, s, u, m, vt, n)
231
+
232
+ s_true = NMatrix.new([mn_min], [4,3,Math.sqrt(5),0], dtype: a.abs_dtype)
233
+ u_true = NMatrix.new([m,m], [0,0,1,0, 0,1,0,0, 0,0,0,-1, 1,0,0,0], dtype: dtype)
234
+ vt_true = NMatrix.new([n,n], [0,1,0,0,0, 0,0,1,0,0, Math.sqrt(0.2),0,0,0,Math.sqrt(0.8), 0,0,0,1,0, -Math.sqrt(0.8),0,0,0,Math.sqrt(0.2)], dtype: dtype)
235
+
236
+ err = case dtype
237
+ when :float32, :complex64
238
+ 1e-5
239
+ when :float64, :complex128
240
+ 1e-14
241
+ end
242
+
243
+ expect(s).to be_within(err).of(s_true)
244
+ expect(u).to be_within(err).of(u_true)
245
+ expect(vt).to be_within(err).of(vt_true)
246
+ end
247
+
248
+ it "calculates eigenvalues and eigenvectors using lapacke_geev" do
249
+ n = 3
250
+ a = NMatrix.new([n,n], [-1,0,0, 0,1,-2, 0,1,-1], dtype: dtype)
251
+ w = NMatrix.new([n], dtype: dtype)
252
+ if a.complex_dtype? #for real dtypes, imaginary parts of eigenvalues are stored in separate vector
253
+ wi = nil
254
+ else
255
+ wi = NMatrix.new([n], dtype: dtype)
256
+ end
257
+ vl = NMatrix.new([n,n], dtype: dtype)
258
+ vr = NMatrix.new([n,n], dtype: dtype)
259
+
260
+ NMatrix::LAPACK.lapacke_geev(:row, :t, :t, n, a, n, w, wi, vl, n, vr, n)
261
+
262
+ if !a.complex_dtype?
263
+ w = w + wi*Complex(0,1)
264
+ end
265
+
266
+ w_true = NMatrix.new([n], [Complex(0,1), -Complex(0,1), -1], dtype: NMatrix.upcast(dtype, :complex64))
267
+ if a.complex_dtype?
268
+ #For complex types the right/left eigenvectors are stored as columns
269
+ #of vr/vl.
270
+ vr_true = NMatrix.new([n,n],[0,0,1,
271
+ 2/Math.sqrt(6),2/Math.sqrt(6),0,
272
+ Complex(1,-1)/Math.sqrt(6),Complex(1,1)/Math.sqrt(6),0], dtype: dtype)
273
+ vl_true = NMatrix.new([n,n],[0,0,1,
274
+ Complex(-1,1)/Math.sqrt(6),Complex(-1,-1)/Math.sqrt(6),0,
275
+ 2/Math.sqrt(6),2/Math.sqrt(6),0], dtype: dtype)
276
+ else
277
+ #For real types, the real part of the first and second eigenvectors is
278
+ #stored in the first column, the imaginary part of the first (= the
279
+ #negative of the imaginary part of the second) eigenvector is stored
280
+ #in the second column, and the third eigenvector (purely real) is the
281
+ #third column.
282
+ vr_true = NMatrix.new([n,n],[0,0,1,
283
+ 2/Math.sqrt(6),0,0,
284
+ 1/Math.sqrt(6),-1/Math.sqrt(6),0], dtype: dtype)
285
+ vl_true = NMatrix.new([n,n],[0,0,1,
286
+ -1/Math.sqrt(6),1/Math.sqrt(6),0,
287
+ 2/Math.sqrt(6),0,0], dtype: dtype)
288
+ end
289
+
290
+ err = case dtype
291
+ when :float32, :complex64
292
+ 1e-6
293
+ when :float64, :complex128
294
+ 1e-15
295
+ end
296
+
297
+ expect(w).to be_within(err).of(w_true)
298
+ expect(vr).to be_within(err).of(vr_true)
299
+ expect(vl).to be_within(err).of(vl_true)
300
+ end
301
+ end
302
+ end
303
+ end