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,78 @@
1
+ require 'spec_helper'
2
+
3
+ describe NMatrix do
4
+ describe "#to_a" do
5
+ it "creates an Array with the same dimensions" do
6
+ n = NMatrix.seq([3,2])
7
+ expect(n.to_a).to eq([[0, 1], [2, 3], [4, 5]])
8
+ end
9
+
10
+ it "creates an Array with the proper element type" do
11
+ n = NMatrix.seq([3,2], dtype: :float64)
12
+ expect(n.to_a).to eq([[0.0, 1.0], [2.0, 3.0], [4.0, 5.0]])
13
+ end
14
+
15
+ it "properly interprets list matrices" do
16
+ n = NMatrix.seq([3,2], stype: :list)
17
+ expect(n.to_a).to eq([[0, 1], [2, 3], [4, 5]])
18
+ end
19
+
20
+ it "properly interprets yale matrices" do
21
+ n = NMatrix.seq([3,2], stype: :yale)
22
+ expect(n.to_a).to eq([[0, 1], [2, 3], [4, 5]])
23
+ end
24
+ end
25
+ end
26
+
27
+ describe Array do
28
+ describe "#to_nm" do
29
+ # [0, 1, 2, 3, 4, 5]
30
+ let(:a) {(0..5).to_a}
31
+
32
+ it "uses a given shape and type" do
33
+ expect(a.to_nm([3,2]).dtype).to eq :int64
34
+ expect(a.to_nm([3,2])).to eq(NMatrix.seq([3,2]))
35
+ end
36
+
37
+ it "guesses dtype based on first element" do
38
+ a[0] = 0.0
39
+ expect(a.to_nm([3,2]).dtype).to eq :float64
40
+ end
41
+
42
+ it "defaults to dtype :object if necessary" do
43
+ a = %w(this is an array of strings)
44
+ expect(a.to_nm([3,2]).dtype).to eq :object
45
+ expect(a.to_nm([3,2])).to eq(NMatrix.new([3,2], a, dtype: :object))
46
+ end
47
+
48
+ it "attempts to intuit the shape of the Array" do
49
+ a = [[0, 1], [2, 3], [4, 5]]
50
+ expect(a.to_nm).to eq(NMatrix.new([3,2], a.flatten))
51
+ expect(a.to_nm.dtype).to eq :int64
52
+ end
53
+
54
+ it "creates an object Array for inconsistent dimensions" do
55
+ a = [[0, 1, 2], [3], [4, 5]]
56
+ expect(a.to_nm).to eq(NMatrix.new([3], a, dtype: :object))
57
+ expect(a.to_nm.dtype).to eq :object
58
+ end
59
+
60
+ it "intuits shape of Array into multiple dimensions" do
61
+ a = [[[0], [1]], [[2], [3]], [[4], [5]]]
62
+ expect(a.to_nm).to eq(NMatrix.new([3,2,1], a.flatten))
63
+ expect(a).to eq(a.to_nm.to_a)
64
+ end
65
+
66
+ it "is reflective with NMatrix#to_a" do
67
+ a = [[0, 1, 2], [3], [4, 5]]
68
+ expect(a).to eq(a.to_nm.to_a)
69
+ end
70
+
71
+ it "does not permanently alter the Array" do
72
+ a = [[0, 1], [2, 3], [4, 5]]
73
+ expect(a.to_nm).to eq(NMatrix.new([3,2], a.flatten))
74
+ expect(a).to eq([[0, 1], [2, 3], [4, 5]])
75
+ end
76
+ end
77
+ end
78
+
Binary file
Binary file
Binary file
@@ -0,0 +1,193 @@
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
+ # == blas_spec.rb
24
+ #
25
+ # Tests for properly exposed BLAS functions.
26
+ #
27
+
28
+ require 'spec_helper'
29
+
30
+ describe NMatrix::BLAS do
31
+ [:byte, :int8, :int16, :int32, :int64,
32
+ :float32, :float64, :complex64, :complex128,
33
+ :object
34
+ ].each do |dtype|
35
+ context dtype do
36
+ it "exposes cblas_scal" do
37
+ x = NMatrix.new([3, 1], [1, 2, 3], dtype: dtype)
38
+ NMatrix::BLAS.cblas_scal(3, 2, x, 1)
39
+ expect(x).to eq(NMatrix.new([3, 1], [2, 4, 6], dtype: dtype))
40
+ end
41
+
42
+ it "exposes cblas_imax" do
43
+ u = NMatrix.new([3,1], [1, 4, 3], dtype: dtype)
44
+ index = NMatrix::BLAS.cblas_imax(3, u, 1)
45
+ expect(index).to eq(1)
46
+ end
47
+ end
48
+ end
49
+
50
+ [:float32, :float64, :complex64, :complex128].each do |dtype|
51
+ context dtype do
52
+ # This is not the same as "exposes cblas trsm", which would be for a version defined in blas.rb (which
53
+ # would greatly simplify the calling of cblas_trsm in terms of arguments, and which would be accessible
54
+ # as NMatrix::BLAS::trsm)
55
+ it "exposes unfriendly cblas_trsm" do
56
+ a = NMatrix.new(3, [4,-1.0/2, -3.0/4, -2, 2, -1.0/4, -4, -2, -1.0/2], dtype: dtype)
57
+ b = NMatrix.new([3,1], [-1, 17, -9], dtype: dtype)
58
+ NMatrix::BLAS::cblas_trsm(:row, :right, :lower, :transpose, :nonunit, 1, 3, 1.0, a, 3, b, 3)
59
+
60
+ # These test results all come from actually running a matrix through BLAS. We use them to ensure that NMatrix's
61
+ # version of these functions give similar results.
62
+
63
+ expect(b[0]).to eq(-1.0/4)
64
+ expect(b[1]).to eq(33.0/4)
65
+ expect(b[2]).to eq(-13)
66
+
67
+ NMatrix::BLAS::cblas_trsm(:row, :right, :upper, :transpose, :unit, 1, 3, 1.0, a, 3, b, 3)
68
+
69
+ expect(b[0]).to eq(-15.0/2)
70
+ expect(b[1]).to eq(5)
71
+ expect(b[2]).to eq(-13)
72
+ end
73
+
74
+ # trmm multiplies two matrices, where one of the two is required to be
75
+ # triangular
76
+ it "exposes cblas_trmm" do
77
+ a = NMatrix.new([3,3], [1,1,1, 0,1,2, 0,0,-1], dtype: dtype)
78
+ b = NMatrix.new([3,3], [1,2,3, 4,5,6, 7,8,9], dtype: dtype)
79
+
80
+ begin
81
+ NMatrix::BLAS.cblas_trmm(:row, :left, :upper, false, :not_unit, 3, 3, 1, a, 3, b, 3)
82
+ rescue NotImplementedError => e
83
+ pending e.to_s
84
+ end
85
+
86
+ product = NMatrix.new([3,3], [12,15,18, 18,21,24, -7,-8,-9], dtype: dtype)
87
+ expect(b).to eq(product)
88
+ end
89
+ end
90
+ end
91
+
92
+ #should have a separate test for complex
93
+ [:float32, :float64, :complex64, :complex128, :object].each do |dtype|
94
+ context dtype do
95
+
96
+ it "exposes cblas rot" do
97
+ x = NMatrix.new([5,1], [1,2,3,4,5], dtype: dtype)
98
+ y = NMatrix.new([5,1], [-5,-4,-3,-2,-1], dtype: dtype)
99
+ x, y = NMatrix::BLAS::rot(x, y, 1.0/2, Math.sqrt(3)/2, -1)
100
+
101
+ expect(x).to be_within(1e-4).of(
102
+ NMatrix.new([5,1], [-0.3660254037844386, -0.7320508075688772, -1.098076211353316, -1.4641016151377544, -1.8301270189221928], dtype: dtype)
103
+ )
104
+
105
+ expect(y).to be_within(1e-4).of(
106
+ NMatrix.new([5,1], [-6.830127018922193, -5.464101615137754, -4.098076211353316, -2.732050807568877, -1.3660254037844386], dtype: dtype)
107
+ )
108
+ end
109
+
110
+ end
111
+ end
112
+
113
+ [:float32, :float64, :complex64, :complex128, :object].each do |dtype|
114
+ context dtype do
115
+
116
+ it "exposes cblas rotg" do
117
+ pending("broken for :object") if dtype == :object
118
+
119
+ ab = NMatrix.new([2,1], [6,-8], dtype: dtype)
120
+ begin
121
+ c,s = NMatrix::BLAS::rotg(ab)
122
+ rescue NotImplementedError => e
123
+ pending e.to_s
124
+ end
125
+
126
+ if [:float32, :float64].include?(dtype)
127
+ expect(ab[0]).to be_within(1e-6).of(-10)
128
+ expect(ab[1]).to be_within(1e-6).of(-5.0/3)
129
+ expect(c).to be_within(1e-6).of(-3.0/5)
130
+ else
131
+ pending "need correct test cases"
132
+ expect(ab[0]).to be_within(1e-6).of(10)
133
+ expect(ab[1]).to be_within(1e-6).of(5.0/3)
134
+ expect(c).to be_within(1e-6).of(3.0/5)
135
+ end
136
+ expect(s).to be_within(1e-6).of(4.0/5)
137
+ end
138
+
139
+ # Note: this exposes gemm, not cblas_gemm (which is the unfriendly CBLAS no-error-checking version)
140
+ it "exposes gemm" do
141
+ n = NMatrix.new([4,3], [14.0,9.0,3.0, 2.0,11.0,15.0, 0.0,12.0,17.0, 5.0,2.0,3.0], dtype: dtype)
142
+ m = NMatrix.new([3,2], [12.0,25.0, 9.0,10.0, 8.0,5.0], dtype: dtype)
143
+
144
+ #c = NMatrix.new([4,2], dtype)
145
+ r = NMatrix::BLAS.gemm(n, m) #, c)
146
+ #c.should equal(r) # check that both are same memory address
147
+
148
+ expect(r).to eq(NMatrix.new([4,2], [273,455,243,235,244,205,102,160], dtype: dtype))
149
+ end
150
+
151
+ it "exposes gemv" do
152
+ a = 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: dtype)
153
+ x = NMatrix.new([3,1], [2.0, 1.0, 0.0], dtype: dtype)
154
+ y = NMatrix::BLAS.gemv(a, x)
155
+ expect(y).to eq(NMatrix.new([4,1],[4.0,13.0,22.0,31.0],dtype: dtype))
156
+ end
157
+
158
+ it "exposes asum" do
159
+ pending("broken for :object") if dtype == :object
160
+
161
+ x = NMatrix.new([4,1], [-1,2,3,4], dtype: dtype)
162
+ expect(NMatrix::BLAS.asum(x)).to eq(10)
163
+ end
164
+
165
+ it "exposes asum for single element" do
166
+ if [:complex64,:complex128].include?(dtype)
167
+ x = NMatrix.new([1], [Complex(-3,2)], dtype: dtype)
168
+ expect(x.asum).to eq(5.0)
169
+ else
170
+ x = NMatrix.new([1], [-1], dtype: dtype)
171
+ expect(x.asum).to eq(1.0)
172
+ end
173
+ end
174
+
175
+ it "exposes nrm2" do
176
+ pending("broken for :object") if dtype == :object
177
+ pending("Temporarily disable because the internal implementation of nrm2 is broken -WL 2015-05-17") if dtype == :complex64 || dtype == :complex128
178
+
179
+ x = NMatrix.new([4,1], [2,-4,3,5], dtype: dtype)
180
+ err = case dtype
181
+ when :float32, :complex64
182
+ 1e-6
183
+ when :float64, :complex128
184
+ 1e-14
185
+ else
186
+ 1e-14
187
+ end
188
+ expect(NMatrix::BLAS.nrm2(x, 1, 3)).to be_within(err).of(5.385164807134504)
189
+ end
190
+
191
+ end
192
+ end
193
+ 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
+ # == nmatrix_spec.rb
24
+ #
25
+ # Element-wise operation tests.
26
+ #
27
+
28
+ require 'spec_helper'
29
+
30
+ describe NMatrix do
31
+ context "yale" do
32
+ before :each do
33
+ @n = NMatrix.new(3, stype: :yale, dtype: :int64)
34
+ @n.extend NMatrix::YaleFunctions
35
+ @m = NMatrix.new(3, stype: :yale, dtype: :int64)
36
+ @n[0,0] = 52
37
+ @n[0,2] = 5
38
+ @n[1,1] = 40
39
+ @n[0,1] = 30
40
+ @n[2,0] = 6
41
+ @m[1,1] = -48
42
+ @m[0,2] = -5
43
+ @n.extend NMatrix::YaleFunctions
44
+ end
45
+
46
+ it "should perform scalar math" do
47
+ x = @n * 3
48
+ expect(x[0,0]).to eq(52 * 3)
49
+ expect(x[0,1]).to eq(30 * 3)
50
+ expect(x[0,2]).to eq(5 * 3)
51
+ expect(x[1,1]).to eq(40 * 3)
52
+ expect(x[2,0]).to eq(6 * 3)
53
+
54
+ r = NMatrix.new(3, stype: :yale, dtype: :int64)
55
+ y = r + 3
56
+ expect(y[0,0]).to eq(3)
57
+ end
58
+
59
+ it "should refuse to perform a dot operation on a yale with non-zero default" do
60
+ r = NMatrix.new(3, stype: :yale, dtype: :int64)
61
+ y = r + 3
62
+ expect { y.dot(r) }.to raise_error
63
+ expect { r.dot(y) }.to raise_error
64
+ end
65
+
66
+ it "should perform element-wise addition" do
67
+ expect(@n+@m).to eq(NMatrix.new(:dense, 3, [52,30,0,0,-8,0,6,0,0], :int64).cast(:yale, :int64))
68
+ end
69
+
70
+ it "should perform element-wise subtraction" do
71
+ expect(@n-@m).to eq(NMatrix.new(:dense, 3, [52,30,10,0,88,0,6,0,0], :int64).cast(:yale, :int64))
72
+ end
73
+
74
+ it "should perform element-wise multiplication" do
75
+ r = NMatrix.new(:dense, 3, [0,0,-25,0,-1920,0,0,0,0], :int64).cast(:yale, :int64)
76
+ m = NMatrix.new(2, stype: :yale, dtype: :int64)
77
+ expect(@n*@m).to eq(r)
78
+ end
79
+
80
+ it "should perform element-wise division" do
81
+ r = NMatrix.new(:dense, 3, [52, 30, -2, 0, -1, 0, 6, 0, 0], :int64).cast(:yale, :int64)
82
+ expect(@n/(@m+1)).to eq(r)
83
+ end
84
+
85
+ it "should perform element-wise modulo" do
86
+ m = NMatrix.new(3, stype: :yale, dtype: :int64, default: 0) + 5
87
+ expect(@n % m).to eq(NMatrix.new(:dense, 3, [2,0,0,0,0,0,1,0,0], :int64).cast(:yale, :int64))
88
+ end
89
+
90
+ it "should handle element-wise equality (=~)" do
91
+ expect(@n =~ @m).to eq(NMatrix.new(:dense, 3, [false,false,false,true,false,true,false,true,true], :object).cast(:yale, :object, false))
92
+ end
93
+
94
+ it "should handle element-wise inequality (!~)" do
95
+ expect(@n !~ @m).to eq(NMatrix.new(:dense, 3, [true,true,true,false,true,false,true,false,false], :object).cast(:yale, :object, true))
96
+ end
97
+
98
+ it "should handle element-wise less-than (<)" do
99
+ expect(@m < @n).to eq(NMatrix.new(:dense, 3, [true,true,true,false,true,false,true,false,false], :object).cast(:yale, :object, true))
100
+ end
101
+
102
+ it "should handle element-wise greater-than (>)" do
103
+ expect(@n > @m).to eq(NMatrix.new(:dense, 3, [true,true,true,false,true,false,true,false,false], :object).cast(:yale, :object, false))
104
+ end
105
+
106
+ it "should handle element-wise greater-than-or-equals (>=)" do
107
+ expect(@n >= @m).to eq(NMatrix.new(:dense, 3, true, :object).cast(:yale,:object, true))
108
+ end
109
+
110
+ it "should handle element-wise less-than-or-equals (<=)" do
111
+ r = NMatrix.new(:dense, 3, [false,false,false,true,false,true,false,true,true], :object).cast(:yale, :object, false)
112
+ expect(@n <= @m).to eq(r)
113
+ end
114
+ end
115
+
116
+
117
+ context "list" do
118
+ before :each do
119
+ @n = NMatrix.new(:list, 2, 0, :int64)
120
+ @m = NMatrix.new(:list, 2, 0, :int64)
121
+ @n[0,0] = 52
122
+ @m[1,1] = -48
123
+ @n[1,1] = 40
124
+ end
125
+
126
+ it "should perform scalar math" do
127
+ x = @n * 3
128
+ expect(x[0,0]).to eq(52 * 3)
129
+ expect(x[1,1]).to eq(40 * 3)
130
+ expect(x[0,1]).to eq(0)
131
+
132
+ r = NMatrix.new(3, stype: :list, default: 1)
133
+ y = r + 3
134
+ expect(y[0,0]).to eq(4)
135
+ end
136
+
137
+ it "should perform element-wise addition" do
138
+ r = NMatrix.new(2, stype: :list, dtype: :int64, default: 0)
139
+ r[0,0] = 52
140
+ r[1,1] = -8
141
+ q = @n + @m
142
+ expect(q).to eq(r)
143
+ end
144
+
145
+ it "should perform element-wise subtraction" do
146
+ r = NMatrix.new(:dense, 2, [52, 0, 0, 88], :int64).cast(:list, :int64)
147
+ expect(@n-@m).to eq(r)
148
+ end
149
+
150
+ it "should perform element-wise multiplication" do
151
+ r = NMatrix.new(:dense, 2, [52, 0, 0, -1920], :int64).cast(:list, :int64)
152
+ m = NMatrix.new(:list, 2, 1, :int64)
153
+ m[1,1] = -48
154
+ expect(@n*m).to eq(r)
155
+ end
156
+
157
+ it "should perform element-wise division" do
158
+ m = NMatrix.new(:list, 2, 1, :int64)
159
+ m[1,1] = 2
160
+ r = NMatrix.new(:dense, 2, [52, 0, 0, 20], :int64).cast(:list, :int64)
161
+ expect(@n/m).to eq(r)
162
+ end
163
+
164
+ it "should perform element-wise modulo" do
165
+ m = NMatrix.new(:list, 2, 1, :int64)
166
+ m[0,0] = 50
167
+ m[1,1] = 40
168
+ (@n % m)
169
+ end
170
+
171
+ it "should handle element-wise equality (=~)" do
172
+ r = NMatrix.new(:list, 2, false, :object)
173
+ r[0,1] = true
174
+ r[1,0] = true
175
+
176
+ expect(@n =~ @m).to eq(r)
177
+ end
178
+
179
+ it "should handle element-wise inequality (!~)" do
180
+ r = NMatrix.new(:list, 2, false, :object)
181
+ r[0,0] = true
182
+ r[1,1] = true
183
+
184
+ expect(@n !~ @m).to eq(r)
185
+ end
186
+
187
+ it "should handle element-wise less-than (<)" do
188
+ expect(@n < @m).to eq(NMatrix.new(:list, 2, false, :object))
189
+ end
190
+
191
+ it "should handle element-wise greater-than (>)" do
192
+ r = NMatrix.new(:list, 2, false, :object)
193
+ r[0,0] = true
194
+ r[1,1] = true
195
+ expect(@n > @m).to eq(r)
196
+ end
197
+
198
+ it "should handle element-wise greater-than-or-equals (>=)" do
199
+ expect(@n >= @m).to eq(NMatrix.new(:list, 2, true, :object))
200
+ end
201
+
202
+ it "should handle element-wise less-than-or-equals (<=)" do
203
+ r = NMatrix.new(:list, 2, false, :object)
204
+ r[0,1] = true
205
+ r[1,0] = true
206
+ expect(@n <= @m).to eq(r)
207
+ end
208
+ end
209
+
210
+ context "dense" do
211
+ context "scalar arithmetic" do
212
+ before :each do
213
+ @n = NMatrix.new(:dense, 2, [1,2,3,4], :int64)
214
+ end
215
+
216
+ it "works for integers" do
217
+ expect(@n+1).to eq(NMatrix.new(:dense, 2, [2,3,4,5], :int64))
218
+ end
219
+
220
+ #it "works for complex64" do
221
+ # n = @n.cast(:dtype => :complex64)
222
+ # (n + 10.0).to_a.should == [Complex(11.0), Complex(12.0), Complex(13.0), Complex(14.0)]
223
+ #end
224
+ end
225
+
226
+ context "elementwise arithmetic" do
227
+ before :each do
228
+ @n = NMatrix.new(:dense, 2, [1,2,3,4], :int64)
229
+ @m = NMatrix.new(:dense, 2, [-4,-1,0,66], :int64)
230
+ end
231
+
232
+ it "adds" do
233
+ r = @n+@m
234
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [-3, 1, 3, 70], :int64))
235
+ end
236
+
237
+ it "subtracts" do
238
+ r = @n-@m
239
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [5, 3, 3, -62], :int64))
240
+ end
241
+
242
+ it "multiplies" do
243
+ r = @n*@m
244
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [-4, -2, 0, 264], :int64))
245
+ end
246
+
247
+ it "divides in the Ruby way" do
248
+ m = @m.clone
249
+ m[1,0] = 3
250
+ r = @n/m
251
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [-1, -2, 1, 0], :int64))
252
+ end
253
+
254
+ it "exponentiates" do
255
+ r = @n ** 2
256
+ # TODO: We might have problems with the dtype.
257
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [1, 4, 9, 16], :int64))
258
+ end
259
+
260
+ it "modulo" do
261
+ expect(@n % (@m + 2)).to eq(NMatrix.new(:dense, [2,2], [-1, 0, 1, 4], :int64))
262
+ end
263
+ end
264
+
265
+ context "elementwise comparisons" do
266
+ before :each do
267
+ @n = NMatrix.new(:dense, 2, [1,2,3,4], :int64)
268
+ @m = NMatrix.new(:dense, 2, [-4,-1,3,2], :int64)
269
+ end
270
+
271
+ it "equals" do
272
+ r = @n =~ @m
273
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [false, false, true, false], :object))
274
+ end
275
+
276
+ it "is not equal" do
277
+ r = @n !~ @m
278
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [true, true, false, true], :object))
279
+ end
280
+
281
+ it "is less than" do
282
+ r = @n < @m
283
+ expect(r).to eq(NMatrix.new(:dense, [2,2], false, :object))
284
+ end
285
+
286
+ it "is greater than" do
287
+ r = @n > @m
288
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [true, true, false, true], :object))
289
+ end
290
+
291
+ it "is less than or equal to" do
292
+ r = @n <= @m
293
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [false, false, true, false], :object))
294
+ end
295
+
296
+ it "is greater than or equal to" do
297
+ n = NMatrix.new(:dense, [2,2], [1, 2, 2, 4], :int64)
298
+ r = n >= @m
299
+ expect(r).to eq(NMatrix.new(:dense, [2,2], [true, true, false, true], :object))
300
+ end
301
+ end
302
+ end
303
+ end