nmatrix-lapacke 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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,190 @@
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
+ # == 01_enum_spec.rb
24
+ #
25
+ # Enumerator tests for NMatrix. These should load early, as they
26
+ # test functionality essential to matrix printing.
27
+ #
28
+ require 'spec_helper'
29
+
30
+ describe "NMatrix enumeration for" do
31
+ [:dense, :yale, :list].each do |stype|
32
+ context stype do
33
+ let(:n) { create_rectangular_matrix(stype) }
34
+ let(:m) { n[1..4,1..3] }
35
+
36
+ if stype == :yale
37
+ it "should iterate properly along each row of a slice" do
38
+ vv = []
39
+ ii = []
40
+ jj = []
41
+ m.extend NMatrix::YaleFunctions
42
+ m.each_row do |row|
43
+ row.each_with_indices do |v,i,j|
44
+ vv << v
45
+ ii << i
46
+ jj << j
47
+ end
48
+ end
49
+
50
+ expect(vv).to eq([7,8,9, 12,13,0, 0,0,0, 0,17,18])
51
+ expect(ii).to eq([0]*12)
52
+ expect(jj).to eq([0,1,2]*4)
53
+ end
54
+
55
+ it "should iterate along diagonal portion of A array" do
56
+ vv = []
57
+ ii = []
58
+ jj = []
59
+ n.send :__yale_stored_diagonal_each_with_indices__ do |v,i,j|
60
+ vv << v
61
+ ii << i
62
+ jj << j
63
+ end
64
+ expect(vv).to eq([1,7,13,0,19])
65
+ expect(ii).to eq([0,1,2,3,4])
66
+ expect(jj).to eq(ii)
67
+ end
68
+
69
+ it "should iterate along non-diagonal portion of A array" do
70
+ vv = []
71
+ ii = []
72
+ jj = []
73
+ n.send :__yale_stored_nondiagonal_each_with_indices__ do |v,i,j|
74
+ vv << v
75
+ ii << i
76
+ jj << j
77
+ end
78
+
79
+ expect(vv).to eq([2,3,4,5, 6,8,9,10, 11,12,14,15, 16,17,18,20])
80
+ expect(ii).to eq([[0]*4, [1]*4, [2]*4, [4]*4].flatten)
81
+ expect(jj).to eq([1,2,3,4, 0,2,3,5, 0,1,4,5, 0,2,3,5])
82
+ end
83
+
84
+ it "should iterate along a sliced diagonal portion of an A array" do
85
+ m = n[0..3,1..3]
86
+ vv = []
87
+ ii = []
88
+ jj = []
89
+ m.send :__yale_stored_diagonal_each_with_indices__ do |v,i,j|
90
+ vv << v
91
+ ii << i
92
+ jj << j
93
+ end
94
+ expect(vv).to eq([7,13,0])
95
+ expect(ii).to eq([1,2,3])
96
+ expect(jj).to eq([0,1,2])
97
+ end
98
+
99
+ it "should iterate along a sliced non-diagonal portion of a sliced A array" do
100
+ vv = []
101
+ ii = []
102
+ jj = []
103
+ n.extend NMatrix::YaleFunctions
104
+ m.extend NMatrix::YaleFunctions
105
+ m.send :__yale_stored_nondiagonal_each_with_indices__ do |v,i,j|
106
+ vv << v
107
+ ii << i
108
+ jj << j
109
+ end
110
+
111
+ expect(ii).to eq([0,0, 1, 3,3 ])
112
+ expect(jj).to eq([1,2, 0, 1,2 ])
113
+ expect(vv).to eq([8,9, 12, 17,18])
114
+ end
115
+
116
+ it "should visit each stored element of the matrix in order by indices" do
117
+ vv = []
118
+ ii = []
119
+ jj = []
120
+ n.each_ordered_stored_with_indices do |v,i,j|
121
+ vv << v
122
+ ii << i
123
+ jj << j
124
+ end
125
+
126
+ expect(vv).to eq([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 16, 17, 18, 19, 20])
127
+ expect(ii).to eq([[0]*5, [1]*5, [2]*5, [3]*1, [4]*5].flatten)
128
+ expect(jj).to eq([0,1,2,3,4, 0,1,2,3,5, 0,1,2,4,5, 3, 0,2,3,4,5])
129
+ end
130
+
131
+ it "should visit each stored element of the slice in order by indices" do
132
+
133
+ vv = []
134
+ ii = []
135
+ jj = []
136
+ m.each_ordered_stored_with_indices do |v,i,j|
137
+ vv << v
138
+ ii << i
139
+ jj << j
140
+ end
141
+ expect(ii).to eq([0,0,0, 1,1, 2, 3,3 ])
142
+ expect(jj).to eq([0,1,2, 0,1, 2, 1,2 ])
143
+ expect(vv).to eq([7,8,9, 12,13, 0, 17,18 ])
144
+ end
145
+ end
146
+
147
+ it "should visit each cell in the matrix as if dense, making indices available" do
148
+ vv = []
149
+ ii = []
150
+ jj = []
151
+ n.each_with_indices do |v,i,j|
152
+ vv << v
153
+ ii << i
154
+ jj << j
155
+ end
156
+
157
+ expect(vv).to eq([1,2,3,4,5,0,6,7,8,9,0,10,11,12,13,0,14,15,0,0,0,0,0,0,16,0,17,18,19,20])
158
+ expect(ii).to eq([[0]*6, [1]*6, [2]*6, [3]*6, [4]*6].flatten)
159
+ expect(jj).to eq([0,1,2,3,4,5]*5)
160
+ end
161
+
162
+ it "should visit each cell in the slice as if dense, making indices available" do
163
+ vv = []
164
+ ii = []
165
+ jj = []
166
+ m.each_with_indices do |v,i,j|
167
+ vv << v
168
+ ii << i
169
+ jj << j
170
+ end
171
+ expect(jj).to eq([0,1,2]*4)
172
+ expect(ii).to eq([[0]*3, [1]*3, [2]*3, [3]*3].flatten)
173
+ expect(vv).to eq([7,8,9,12,13,0,0,0,0,0,17,18])
174
+
175
+ end
176
+
177
+ if stype == :list or stype == :dense then
178
+ it "should correctly map to a matrix with a single element" do
179
+ nm = N.new([1], [2.0], stype: stype)
180
+ expect(nm.map { |e| e**2 }).to eq N.new([1], [4.0], stype: stype)
181
+ end
182
+
183
+ it "should correctly map to a matrix with multiple elements" do
184
+ nm = N.new([2], [2.0, 2.0], stype: stype)
185
+ expect(nm.map { |e| e**2 }).to eq N.new([2], [4.0, 4.0], stype: stype)
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,389 @@
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
+ # == 02_slice_spec.rb
24
+ #
25
+ # Test of slice operations. High priority tests since reference
26
+ # slicing is needed for pretty_print.
27
+ #
28
+ require 'spec_helper'
29
+
30
+ describe "Slice operation" do
31
+ include RSpec::Longrun::DSL
32
+
33
+ [:dense, :list, :yale].each do |stype|
34
+ context "for #{stype}" do
35
+ #GC.start # don't have to do this, but it helps to make sure we've cleaned up our pointers properly.
36
+ let(:stype_matrix) { create_matrix(stype) }
37
+
38
+ it "should correctly return a row of a reference-slice" do
39
+ n = create_rectangular_matrix(stype)
40
+ stype_matrix = n[1..4,1..3]
41
+ expect(stype_matrix.row(1, :copy)).to eq(stype_matrix.row(1, :reference))
42
+ expect(stype_matrix.row(1, :copy).to_flat_array).to eq([12,13,0])
43
+ end
44
+
45
+ if stype == :yale
46
+ it "should binary search for the left boundary of a partial row of stored indices correctly" do
47
+ n = NMatrix.new(10, stype: :yale, dtype: :int32)
48
+ n[3,0] = 1
49
+ #n[3,2] = 2
50
+ n[3,3] = 3
51
+ n[3,4] = 4
52
+ n[3,6] = 5
53
+ n[3,8] = 6
54
+ n[3,9] = 7
55
+ vs = []
56
+ is = []
57
+ js = []
58
+
59
+ n[3,1..9].each_stored_with_indices do |v,i,j|
60
+ vs << v
61
+ is << i
62
+ js << j
63
+ end
64
+
65
+ expect(vs).to eq([3,4,5,6,7])
66
+ expect(js).to eq([2,3,5,7,8])
67
+ expect(is).to eq([0,0,0,0,0])
68
+ end
69
+ elsif stype == :list
70
+ it "should iterate across a partial row of stored indices" do
71
+ vs = []
72
+ is = []
73
+ js = []
74
+
75
+ STDERR.puts("now") if stype == :yale
76
+ stype_matrix[2,1..2].each_stored_with_indices do |v,i,j|
77
+ vs << v
78
+ is << i
79
+ js << j
80
+ end
81
+
82
+ expect(vs).to eq([7,8])
83
+ expect(is).to eq([0,0])
84
+ expect(js).to eq([0,1])
85
+ end
86
+ end
87
+
88
+ unless stype == :dense
89
+ it "should iterate across a row of stored indices" do
90
+
91
+ vs = []
92
+ is = []
93
+ js = []
94
+ stype_matrix[2,0..2].each_stored_with_indices do |v,i,j|
95
+ vs << v
96
+ is << i
97
+ js << j
98
+ end
99
+ expect(vs).to eq(stype == :yale ? [8,6,7] : [6,7,8])
100
+ expect(is).to eq([0,0,0])
101
+ expect(js).to eq(stype == :yale ? [2,0,1] : [0,1,2])
102
+ end
103
+
104
+ it "should iterate across a submatrix of stored indices" do
105
+ vs = []
106
+ is = []
107
+ js = []
108
+ stype_matrix[0..1,1..2].each_stored_with_indices do |v,i,j|
109
+ vs << v
110
+ is << i
111
+ js << j
112
+ end
113
+
114
+ expect(vs).to eq(stype == :yale ? [4,1,2,5] : [1,2,4,5])
115
+ expect(is).to eq(stype == :yale ? [1,0,0,1] : [0,0,1,1])
116
+ expect(js).to eq(stype == :yale ? [0,0,1,1] : [0,1,0,1])
117
+ end
118
+ end
119
+
120
+ it "should return correct supershape" do
121
+ x = NMatrix.random([10,12])
122
+ y = x[0...8,5...12]
123
+ expect(y.shape).to eq([8,7])
124
+ expect(y.supershape).to eq([10,12])
125
+ end
126
+
127
+ it "should have #is_ref? method" do
128
+ a = stype_matrix[0..1, 0..1]
129
+ b = stype_matrix.slice(0..1, 0..1)
130
+ expect(stype_matrix.is_ref?).to be_false
131
+ expect(a.is_ref?).to be_true
132
+ expect(b.is_ref?).to be_false
133
+ end
134
+
135
+ it "reference should compare with non-reference" do
136
+ expect(stype_matrix.slice(1..2,0..1)).to eq(stype_matrix[1..2, 0..1])
137
+ expect(stype_matrix[1..2,0..1]).to eq(stype_matrix.slice(1..2, 0..1))
138
+ expect(stype_matrix[1..2,0..1]).to eq(stype_matrix[1..2, 0..1])
139
+ end
140
+
141
+ context "with copying" do
142
+ it 'should return an NMatrix' do
143
+ n = stype_matrix.slice(0..1,0..1)
144
+ expect(nm_eql(n, NMatrix.new([2,2], [0,1,3,4], dtype: :int32))).to be_true
145
+ end
146
+
147
+ it 'should return a copy of 2x2 matrix to self elements' do
148
+ n = stype_matrix.slice(1..2,0..1)
149
+ expect(n.shape).to eql([2,2])
150
+
151
+ expect(n[1,1]).to eq(stype_matrix[2,1])
152
+ n[1,1] = -9
153
+ expect(stype_matrix[2,1]).to eql(7)
154
+ end
155
+
156
+ it 'should return a 1x2 matrix without refs to self elements' do
157
+ n = stype_matrix.slice(0,1..2)
158
+ expect(n.shape).to eql([1,2])
159
+
160
+ expect(n[0]).to eq(stype_matrix[0,1])
161
+ expect(n[1]).to eq(stype_matrix[0,2])
162
+ n[0] = -9
163
+ expect(stype_matrix[0,1]).to eql(1)
164
+ expect(stype_matrix[0,2]).to eql(2)
165
+ end
166
+
167
+ it 'should return a 2x1 matrix without refs to self elements' do
168
+ stype_matrix.extend NMatrix::YaleFunctions
169
+
170
+ n = stype_matrix.slice(0..1,1)
171
+ expect(n.shape).to eql([2,1])
172
+
173
+ expect(n[0]).to eq(stype_matrix[0,1])
174
+ expect(n[1]).to eq(stype_matrix[1,1])
175
+ n[0] = -9
176
+ expect(stype_matrix[0,1]).to eql(1)
177
+ expect(stype_matrix[1,1]).to eql(4)
178
+ end
179
+
180
+ it 'should be correct slice for range 0..2 and 0...3' do
181
+ expect(stype_matrix.slice(0..2,0..2)).to eq(stype_matrix.slice(0...3,0...3))
182
+ end
183
+
184
+ [:dense, :list, :yale].each do |cast_type|
185
+ it "should cast copied slice from #{stype.upcase} to #{cast_type.upcase}" do
186
+ expect(nm_eql(stype_matrix.slice(1..2, 1..2).cast(cast_type, :int32), stype_matrix.slice(1..2,1..2))).to be_true
187
+ expect(nm_eql(stype_matrix.slice(0..1, 1..2).cast(cast_type, :int32), stype_matrix.slice(0..1,1..2))).to be_true
188
+ expect(nm_eql(stype_matrix.slice(1..2, 0..1).cast(cast_type, :int32), stype_matrix.slice(1..2,0..1))).to be_true
189
+ expect(nm_eql(stype_matrix.slice(0..1, 0..1).cast(cast_type, :int32), stype_matrix.slice(0..1,0..1))).to be_true
190
+
191
+ # Non square
192
+ expect(nm_eql(stype_matrix.slice(0..2, 1..2).cast(cast_type, :int32), stype_matrix.slice(0..2,1..2))).to be_true
193
+ #require 'pry'
194
+ #binding.pry if cast_type == :yale
195
+ expect(nm_eql(stype_matrix.slice(1..2, 0..2).cast(cast_type, :int32), stype_matrix.slice(1..2,0..2))).to be_true
196
+
197
+ # Full
198
+ expect(nm_eql(stype_matrix.slice(0..2, 0..2).cast(cast_type, :int32), stype_matrix)).to be_true
199
+ end
200
+ end
201
+ end
202
+
203
+ # Yale:
204
+ #context "by copy" do
205
+ #it "should correctly preserve zeros" do
206
+ # stype_matrix = NMatrix.new(:yale, 3, :int64)
207
+ # column_slice = stype_matrix.column(2, :copy)
208
+ # column_slice[0].should == 0
209
+ # column_slice[1].should == 0
210
+ # column_slice[2].should == 0
211
+ #end
212
+ #end
213
+
214
+ context "by reference" do
215
+ it 'should return an NMatrix' do
216
+ n = stype_matrix[0..1,0..1]
217
+ expect(nm_eql(n, NMatrix.new([2,2], [0,1,3,4], dtype: :int32))).to be_true
218
+ end
219
+
220
+ it 'should return a 2x2 matrix with refs to self elements' do
221
+ n = stype_matrix[1..2,0..1]
222
+ expect(n.shape).to eql([2,2])
223
+
224
+ expect(n[0,0]).to eq(stype_matrix[1,0])
225
+ n[0,0] = -9
226
+ expect(stype_matrix[1,0]).to eql(-9)
227
+ end
228
+
229
+ it 'should return a 1x2 vector with refs to self elements' do
230
+ n = stype_matrix[0,1..2]
231
+ expect(n.shape).to eql([1,2])
232
+
233
+ expect(n[0]).to eq(stype_matrix[0,1])
234
+ n[0] = -9
235
+ expect(stype_matrix[0,1]).to eql(-9)
236
+ end
237
+
238
+ it 'should return a 2x1 vector with refs to self elements' do
239
+ n = stype_matrix[0..1,1]
240
+ expect(n.shape).to eql([2,1])
241
+
242
+ expect(n[0]).to eq(stype_matrix[0,1])
243
+ n[0] = -9
244
+ expect(stype_matrix[0,1]).to eql(-9)
245
+ end
246
+
247
+ it 'should slice again' do
248
+ n = stype_matrix[1..2, 1..2]
249
+ expect(nm_eql(n[1,0..1], NVector.new(2, [7,8], dtype: :int32).transpose)).to be_true
250
+ end
251
+
252
+ it 'should be correct slice for range 0..2 and 0...3' do
253
+ expect(stype_matrix[0..2,0..2]).to eq(stype_matrix[0...3,0...3])
254
+ end
255
+
256
+ it 'should correctly handle :* slice notation' do
257
+ expect(stype_matrix[:*,0]).to eq stype_matrix[0...stype_matrix.shape[0], 0]
258
+ end
259
+
260
+ if stype == :dense
261
+ [:byte,:int8,:int16,:int32,:int64,:float32,:float64].each do |left_dtype|
262
+ [:byte,:int8,:int16,:int32,:int64,:float32,:float64].each do |right_dtype|
263
+
264
+ # Won't work if they're both 1-byte, due to overflow.
265
+ next if [:byte,:int8].include?(left_dtype) && [:byte,:int8].include?(right_dtype)
266
+
267
+ # For now, don't bother testing int-int mult.
268
+ #next if [:int8,:int16,:int32,:int64].include?(left_dtype) && [:int8,:int16,:int32,:int64].include?(right_dtype)
269
+ it "handles #{left_dtype.to_s} dot #{right_dtype.to_s} matrix multiplication" do
270
+ #STDERR.puts "dtype=#{dtype.to_s}"
271
+ #STDERR.puts "2"
272
+
273
+ nary = if left_dtype.to_s =~ /complex/
274
+ COMPLEX_MATRIX43A_ARRAY
275
+ else
276
+ MATRIX43A_ARRAY
277
+ end
278
+
279
+ mary = if right_dtype.to_s =~ /complex/
280
+ COMPLEX_MATRIX32A_ARRAY
281
+ else
282
+ MATRIX32A_ARRAY
283
+ end
284
+
285
+ n = NMatrix.new([4,3], nary, dtype: left_dtype)[1..3,1..2]
286
+ m = NMatrix.new([3,2], mary, dtype: right_dtype)[1..2,0..1]
287
+
288
+ r = n.dot m
289
+ expect(r.shape).to eql([3,2])
290
+
291
+ expect(r[0,0]).to eq(219.0)
292
+ expect(r[0,1]).to eq(185.0)
293
+ expect(r[1,0]).to eq(244.0)
294
+ expect(r[1,1]).to eq(205.0)
295
+ expect(r[2,0]).to eq(42.0)
296
+ expect(r[2,1]).to eq(35.0)
297
+
298
+ end
299
+ end
300
+ end
301
+
302
+ context "operations" do
303
+
304
+ it "correctly transposes slices" do
305
+ expect(stype_matrix[0...3,0].transpose).to eq NMatrix[[0, 3, 6]]
306
+ expect(stype_matrix[0...3,1].transpose).to eq NMatrix[[1, 4, 7]]
307
+ expect(stype_matrix[0...3,2].transpose).to eq NMatrix[[2, 5, 8]]
308
+ expect(stype_matrix[0,0...3].transpose).to eq NMatrix[[0], [1], [2]]
309
+ expect(stype_matrix[1,0...3].transpose).to eq NMatrix[[3], [4], [5]]
310
+ expect(stype_matrix[2,0...3].transpose).to eq NMatrix[[6], [7], [8]]
311
+ expect(stype_matrix[1..2,1..2].transpose).to eq NMatrix[[4, 7], [5, 8]]
312
+ end
313
+
314
+ it "adds slices" do
315
+ expect(NMatrix[[0,0,0]] + stype_matrix[1,0..2]).to eq NMatrix[[3, 4, 5]]
316
+ end
317
+
318
+ it "scalar adds to slices" do
319
+ expect(stype_matrix[1,0..2]+1).to eq NMatrix[[4, 5, 6]]
320
+ end
321
+
322
+ it "compares slices to scalars" do
323
+ (stype_matrix[1, 0..2] > 2).each { |e| expect(e != 0).to be_true }
324
+ end
325
+
326
+ it "iterates only over elements in the slice" do
327
+ els = []
328
+ stype_matrix[1, 0..2].each { |e| els << e }
329
+ expect(els.size).to eq 3
330
+ expect(els[0]).to eq 3
331
+ expect(els[1]).to eq 4
332
+ expect(els[2]).to eq 5
333
+ end
334
+
335
+ it "iterates with index only over elements in the slice" do
336
+ els = []
337
+ stype_matrix[1, 0..2].each_stored_with_indices { |a| els << a }
338
+ expect(els.size).to eq 3
339
+ expect(els[0]).to eq [3, 0, 0]
340
+ expect(els[1]).to eq [4, 0, 1]
341
+ expect(els[2]).to eq [5, 0, 2]
342
+ end
343
+
344
+ end
345
+
346
+ end
347
+
348
+ example 'should be cleaned up by garbage collector without errors' do
349
+ step "reference slice" do
350
+ 1.times do
351
+ n = stype_matrix[1..2,0..1]
352
+ end
353
+ GC.start
354
+ end
355
+
356
+ step "reference slice of casted-copy" do
357
+ expect(stype_matrix).to eq(NMatrix.new([3,3], (0..9).to_a, dtype: :int32).cast(stype, :int32))
358
+ n = nil
359
+ 1.times do
360
+ m = NMatrix.new([2,2], [1,2,3,4]).cast(stype, :int32)
361
+ n = m[0..1,0..1]
362
+ end
363
+ GC.start
364
+ expect(n).to eq(NMatrix.new([2,2], [1,2,3,4]).cast(stype, :int32))
365
+ end
366
+ end
367
+
368
+ [:dense, :list, :yale].each do |cast_type|
369
+ it "should cast a square reference-slice from #{stype.upcase} to #{cast_type.upcase}" do
370
+ expect(nm_eql(stype_matrix[1..2, 1..2].cast(cast_type), stype_matrix[1..2,1..2])).to be_true
371
+ expect(nm_eql(stype_matrix[0..1, 1..2].cast(cast_type), stype_matrix[0..1,1..2])).to be_true
372
+ expect(nm_eql(stype_matrix[1..2, 0..1].cast(cast_type), stype_matrix[1..2,0..1])).to be_true
373
+ expect(nm_eql(stype_matrix[0..1, 0..1].cast(cast_type), stype_matrix[0..1,0..1])).to be_true
374
+ end
375
+
376
+ it "should cast a rectangular reference-slice from #{stype.upcase} to #{cast_type.upcase}" do
377
+ # Non square
378
+ expect(nm_eql(stype_matrix[0..2, 1..2].cast(cast_type), stype_matrix[0..2,1..2])).to be_true # FIXME: memory problem.
379
+ expect(nm_eql(stype_matrix[1..2, 0..2].cast(cast_type), stype_matrix[1..2,0..2])).to be_true # this one is fine
380
+ end
381
+
382
+ it "should cast a square full-matrix reference-slice from #{stype.upcase} to #{cast_type.upcase}" do
383
+ expect(nm_eql(stype_matrix[0..2, 0..2].cast(cast_type), stype_matrix)).to be_true
384
+ end
385
+ end
386
+ end
387
+ end
388
+ end
389
+ end