numo-linalg 0.1.2 → 0.1.3

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +7 -3
  3. data/ext/numo/linalg/blas/extconf.rb +1 -2
  4. data/ext/numo/linalg/blas/numo_blas.h +6 -0
  5. data/ext/numo/linalg/blas/tmpl/mv.c +3 -2
  6. data/ext/numo/linalg/lapack/gen/spec.rb +5 -0
  7. data/ext/numo/linalg/lapack/lapack.c +29 -0
  8. data/ext/numo/linalg/lapack/numo_lapack.h +3 -0
  9. data/ext/numo/linalg/lapack/tmpl/gqr.c +1 -1
  10. data/ext/numo/linalg/lapack/tmpl/sygvx.c +130 -0
  11. data/ext/numo/linalg/mkmf_linalg.rb +2 -19
  12. data/lib/numo/linalg/function.rb +168 -77
  13. data/lib/numo/linalg/loader.rb +6 -14
  14. data/lib/numo/linalg/version.rb +1 -1
  15. data/numo-linalg.gemspec +2 -1
  16. data/spec/linalg/autoloader_spec.rb +27 -0
  17. data/spec/linalg/function/cho_fact_spec.rb +31 -0
  18. data/spec/linalg/function/cho_inv_spec.rb +39 -0
  19. data/spec/linalg/function/cho_solve_spec.rb +66 -0
  20. data/spec/linalg/function/cholesky_spec.rb +43 -0
  21. data/spec/linalg/function/cond_spec.rb +57 -0
  22. data/spec/linalg/function/det_spec.rb +21 -0
  23. data/spec/linalg/function/dot_spec.rb +84 -0
  24. data/spec/linalg/function/eig_spec.rb +53 -0
  25. data/spec/linalg/function/eigh_spec.rb +81 -0
  26. data/spec/linalg/function/eigvals_spec.rb +27 -0
  27. data/spec/linalg/function/eigvalsh_spec.rb +60 -0
  28. data/spec/linalg/function/inv_spec.rb +57 -0
  29. data/spec/linalg/function/ldl_spec.rb +51 -0
  30. data/spec/linalg/function/lstsq_spec.rb +80 -0
  31. data/spec/linalg/function/lu_fact_spec.rb +34 -0
  32. data/spec/linalg/function/lu_inv_spec.rb +21 -0
  33. data/spec/linalg/function/lu_solve_spec.rb +40 -0
  34. data/spec/linalg/function/lu_spec.rb +46 -0
  35. data/spec/linalg/function/matmul_spec.rb +41 -0
  36. data/spec/linalg/function/matrix_power_spec.rb +31 -0
  37. data/spec/linalg/function/matrix_rank_spec.rb +33 -0
  38. data/spec/linalg/function/norm_spec.rb +81 -0
  39. data/spec/linalg/function/pinv_spec.rb +48 -0
  40. data/spec/linalg/function/qr_spec.rb +82 -0
  41. data/spec/linalg/function/slogdet_spec.rb +21 -0
  42. data/spec/linalg/function/solve_spec.rb +98 -0
  43. data/spec/linalg/function/svd_spec.rb +88 -0
  44. data/spec/linalg/function/svdvals_spec.rb +40 -0
  45. data/spec/spec_helper.rb +55 -0
  46. metadata +79 -6
  47. data/spec/lapack_spec.rb +0 -13
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Numo::Linalg do
6
+ describe 'svd' do
7
+ let(:m) { 5 }
8
+ let(:n) { 3 }
9
+ let(:mat_a) { rand_rect_real_mat(m, n) }
10
+ let(:mat_b) { rand_rect_complex_mat(m, n) }
11
+
12
+ it 'raises ArgumentError given a invalid driver option' do
13
+ expect { described_class.svd(mat_a, driver: 'foo') }.to raise_error(ArgumentError)
14
+ end
15
+
16
+ it 'raises ArgumentError given a invalid job option' do
17
+ expect { described_class.svd(mat_a, job: '@') }.to raise_error(ArgumentError)
18
+ end
19
+
20
+ it 'perfoms the singular value decomposition of a rectangular real matrix' do
21
+ s, u, vt = described_class.svd(mat_a, driver: 'svd')
22
+ expect((u.transpose.dot(u) - Numo::DFloat.eye(m)).abs.max).to be < ERR_TOL
23
+ expect((vt.dot(vt.transpose) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
24
+ mat_a_rec = u.dot(Numo::NArray.vstack([s.diag.dot(vt), Numo::DFloat.zeros(m - n, n)]))
25
+ expect((mat_a - mat_a_rec).abs.max).to be < ERR_TOL
26
+ end
27
+
28
+ it 'perfoms the singular value decomposition of a rectangular complex matrix' do
29
+ s, u, vt = described_class.svd(mat_b, driver: 'svd')
30
+ expect((u.transpose.conj.dot(u) - Numo::DFloat.eye(m)).abs.max).to be < ERR_TOL
31
+ expect((vt.dot(vt.transpose.conj) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
32
+ mat_b_rec = u.dot(Numo::NArray.vstack([s.diag.dot(vt), Numo::DFloat.zeros(m - n, n)]))
33
+ expect((mat_b - mat_b_rec).abs.max).to be < ERR_TOL
34
+ end
35
+
36
+ it 'perfoms the singular value decomposition of a rectangular real matrix with S job option' do
37
+ s, u, vt = described_class.svd(mat_a, driver: 'svd', job: 'S')
38
+ expect(u.shape[0]).to eq(m)
39
+ expect(u.shape[1]).to eq(n)
40
+ expect((u.transpose.dot(u) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
41
+ expect((vt.dot(vt.transpose) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
42
+ mat_a_rec = u.dot(s.diag.dot(vt))
43
+ expect((mat_a - mat_a_rec).abs.max).to be < ERR_TOL
44
+ end
45
+
46
+ it 'perfoms the singular value decomposition of a rectangular complex matrix with S job option' do
47
+ s, u, vt = described_class.svd(mat_b, driver: 'svd', job: 'S')
48
+ expect(u.shape[0]).to eq(m)
49
+ expect(u.shape[1]).to eq(n)
50
+ expect((u.transpose.conj.dot(u) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
51
+ expect((vt.dot(vt.transpose.conj) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
52
+ mat_b_rec = u.dot(s.diag.dot(vt))
53
+ expect((mat_b - mat_b_rec).abs.max).to be < ERR_TOL
54
+ end
55
+
56
+ it 'calculates the singular values of a rectangular real matrix' do
57
+ s1, = described_class.svd(mat_a, driver: 'svd')
58
+ s2, u, vt = described_class.svd(mat_a, driver: 'svd', job: 'N')
59
+ expect(u).to be_nil
60
+ expect(vt).to be_nil
61
+ expect((s1 - s2).abs.max).to be < ERR_TOL
62
+ end
63
+
64
+ it 'calculates the singular values of a rectangular complex matrix' do
65
+ s1, = described_class.svd(mat_b, driver: 'svd')
66
+ s2, u, vt = described_class.svd(mat_b, driver: 'svd', job: 'N')
67
+ expect(u).to be_nil
68
+ expect(vt).to be_nil
69
+ expect((s1 - s2).abs.max).to be < ERR_TOL
70
+ end
71
+
72
+ it 'perfoms the singular value decomposition of a rectangular real matrix with divide and conquer algorithm' do
73
+ s, u, vt = described_class.svd(mat_a, driver: 'sdd')
74
+ mat_a_rec = u.dot(Numo::NArray.vstack([s.diag.dot(vt), Numo::DFloat.zeros(m - n, n)]))
75
+ expect((u.dot(u.transpose) - Numo::DFloat.eye(m)).abs.max).to be < ERR_TOL
76
+ expect((vt.transpose.dot(vt) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
77
+ expect((mat_a - mat_a_rec).abs.max).to be < ERR_TOL
78
+ end
79
+
80
+ it 'perfoms the singular value decomposition of a rectangular complex matrix with divide and conquer algorithm' do
81
+ s, u, vt = described_class.svd(mat_b, driver: 'sdd')
82
+ mat_b_rec = u.dot(Numo::NArray.vstack([s.diag.dot(vt), Numo::DFloat.zeros(m - n, n)]))
83
+ expect((u.dot(u.transpose.conj) - Numo::DFloat.eye(m)).abs.max).to be < ERR_TOL
84
+ expect((vt.transpose.conj.dot(vt) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
85
+ expect((mat_b - mat_b_rec).abs.max).to be < ERR_TOL
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Numo::Linalg do
6
+ describe 'svdvals' do
7
+ let(:m) { 5 }
8
+ let(:n) { 3 }
9
+ let(:mat_a) { rand_rect_real_mat(m, n) }
10
+ let(:mat_b) { rand_rect_complex_mat(m, n) }
11
+
12
+ it 'raises ArgumentError given a invalid driver option' do
13
+ expect { described_class.svdvals(mat_a, driver: 'foo') }.to raise_error(ArgumentError)
14
+ end
15
+
16
+ it 'calculates the singular values of a rectangular real matrix' do
17
+ s1, = described_class.svd(mat_a, driver: 'svd', job: 'N')
18
+ s2 = described_class.svdvals(mat_a, driver: 'svd')
19
+ expect((s1 - s2).abs.max).to be < ERR_TOL
20
+ end
21
+
22
+ it 'calculates the singular values of a rectangular complex matrix' do
23
+ s1, = described_class.svd(mat_b, driver: 'svd', job: 'N')
24
+ s2 = described_class.svdvals(mat_b, driver: 'svd')
25
+ expect((s1 - s2).abs.max).to be < ERR_TOL
26
+ end
27
+
28
+ it 'calculates the singular values of a rectangular real matrix with divide and conquer algorithm' do
29
+ s1, = described_class.svd(mat_a, driver: 'sdd', job: 'N')
30
+ s2 = described_class.svdvals(mat_a, driver: 'sdd')
31
+ expect((s1 - s2).abs.max).to be < ERR_TOL
32
+ end
33
+
34
+ it 'calculates the singular values of a rectangular complex matrix with divide and conquer algorithm' do
35
+ s1, = described_class.svd(mat_b, driver: 'sdd', job: 'N')
36
+ s2 = described_class.svdvals(mat_b, driver: 'sdd')
37
+ expect((s1 - s2).abs.max).to be < ERR_TOL
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'numo/linalg/autoloader'
4
+
5
+ ERR_TOL = 1e-6
6
+
7
+ def rand_symmetric_mat(n)
8
+ a = Numo::DFloat.new(n, n).rand
9
+ 0.5 * (a + a.transpose) - 0.5
10
+ end
11
+
12
+ def rand_hermitian_mat(n)
13
+ a = rand_symmetric_mat(n)
14
+ b = Numo::DFloat.new(n, n).rand
15
+ b = 0.5 * (b + b.transpose)
16
+ b = (b.triu - b.tril)
17
+ b[b.diag_indices] = 0.0
18
+ a + b * Complex::I
19
+ end
20
+
21
+ def rand_square_real_mat(m)
22
+ Numo::DFloat.new(m, m).rand - 0.5
23
+ end
24
+
25
+ def rand_square_complex_mat(m)
26
+ rand_rect_real_mat(m, m) + Complex::I * (rand_rect_real_mat(m, m) - 0.5)
27
+ end
28
+
29
+ def rand_rect_real_mat(m, n)
30
+ Numo::DFloat.new(m, n).rand - 0.5
31
+ end
32
+
33
+ def rand_rect_complex_mat(m, n)
34
+ rand_rect_real_mat(m, n) + Complex::I * (rand_rect_real_mat(m, n) - 0.5)
35
+ end
36
+
37
+ def rand_real_vec(m)
38
+ Numo::DFloat.new(m).rand - 0.5
39
+ end
40
+
41
+ def rand_complex_vec(m)
42
+ rand_real_vec(m) + Complex::I * (rand_real_vec(m) - 0.5)
43
+ end
44
+
45
+ RSpec.configure do |config|
46
+ # Enable flags like --only-failures and --next-failure
47
+ config.example_status_persistence_file_path = '.rspec_status'
48
+
49
+ # Disable RSpec exposing methods globally on `Module` and `main`
50
+ config.disable_monkey_patching!
51
+
52
+ config.expect_with :rspec do |c|
53
+ c.syntax = :expect
54
+ end
55
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: numo-linalg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahiro TANAKA
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-03-25 00:00:00.000000000 Z
12
+ date: 2018-08-23 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -31,14 +31,28 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: '0'
34
+ version: '12.0'
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: '0'
41
+ version: '12.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rspec
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '3.0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '3.0'
42
56
  - !ruby/object:Gem::Dependency
43
57
  name: numo-narray
44
58
  requirement: !ruby/object:Gem::Requirement
@@ -133,6 +147,7 @@ files:
133
147
  - ext/numo/linalg/lapack/tmpl/module.c
134
148
  - ext/numo/linalg/lapack/tmpl/syev.c
135
149
  - ext/numo/linalg/lapack/tmpl/sygv.c
150
+ - ext/numo/linalg/lapack/tmpl/sygvx.c
136
151
  - ext/numo/linalg/lapack/tmpl/trf.c
137
152
  - ext/numo/linalg/mkmf_linalg.rb
138
153
  - ext/numo/linalg/numo_linalg.h
@@ -147,7 +162,36 @@ files:
147
162
  - lib/numo/linalg/use/openblas.rb
148
163
  - lib/numo/linalg/version.rb
149
164
  - numo-linalg.gemspec
150
- - spec/lapack_spec.rb
165
+ - spec/linalg/autoloader_spec.rb
166
+ - spec/linalg/function/cho_fact_spec.rb
167
+ - spec/linalg/function/cho_inv_spec.rb
168
+ - spec/linalg/function/cho_solve_spec.rb
169
+ - spec/linalg/function/cholesky_spec.rb
170
+ - spec/linalg/function/cond_spec.rb
171
+ - spec/linalg/function/det_spec.rb
172
+ - spec/linalg/function/dot_spec.rb
173
+ - spec/linalg/function/eig_spec.rb
174
+ - spec/linalg/function/eigh_spec.rb
175
+ - spec/linalg/function/eigvals_spec.rb
176
+ - spec/linalg/function/eigvalsh_spec.rb
177
+ - spec/linalg/function/inv_spec.rb
178
+ - spec/linalg/function/ldl_spec.rb
179
+ - spec/linalg/function/lstsq_spec.rb
180
+ - spec/linalg/function/lu_fact_spec.rb
181
+ - spec/linalg/function/lu_inv_spec.rb
182
+ - spec/linalg/function/lu_solve_spec.rb
183
+ - spec/linalg/function/lu_spec.rb
184
+ - spec/linalg/function/matmul_spec.rb
185
+ - spec/linalg/function/matrix_power_spec.rb
186
+ - spec/linalg/function/matrix_rank_spec.rb
187
+ - spec/linalg/function/norm_spec.rb
188
+ - spec/linalg/function/pinv_spec.rb
189
+ - spec/linalg/function/qr_spec.rb
190
+ - spec/linalg/function/slogdet_spec.rb
191
+ - spec/linalg/function/solve_spec.rb
192
+ - spec/linalg/function/svd_spec.rb
193
+ - spec/linalg/function/svdvals_spec.rb
194
+ - spec/spec_helper.rb
151
195
  homepage: https://github.com/ruby-numo/numo-linalg
152
196
  licenses:
153
197
  - BSD-3-Clause
@@ -173,4 +217,33 @@ signing_key:
173
217
  specification_version: 4
174
218
  summary: Ruby/Numo Linear Algebra library with BLAS/LAPACK
175
219
  test_files:
176
- - spec/lapack_spec.rb
220
+ - spec/linalg/autoloader_spec.rb
221
+ - spec/linalg/function/cho_fact_spec.rb
222
+ - spec/linalg/function/cho_inv_spec.rb
223
+ - spec/linalg/function/cho_solve_spec.rb
224
+ - spec/linalg/function/cholesky_spec.rb
225
+ - spec/linalg/function/cond_spec.rb
226
+ - spec/linalg/function/det_spec.rb
227
+ - spec/linalg/function/dot_spec.rb
228
+ - spec/linalg/function/eig_spec.rb
229
+ - spec/linalg/function/eigh_spec.rb
230
+ - spec/linalg/function/eigvals_spec.rb
231
+ - spec/linalg/function/eigvalsh_spec.rb
232
+ - spec/linalg/function/inv_spec.rb
233
+ - spec/linalg/function/ldl_spec.rb
234
+ - spec/linalg/function/lstsq_spec.rb
235
+ - spec/linalg/function/lu_fact_spec.rb
236
+ - spec/linalg/function/lu_inv_spec.rb
237
+ - spec/linalg/function/lu_solve_spec.rb
238
+ - spec/linalg/function/lu_spec.rb
239
+ - spec/linalg/function/matmul_spec.rb
240
+ - spec/linalg/function/matrix_power_spec.rb
241
+ - spec/linalg/function/matrix_rank_spec.rb
242
+ - spec/linalg/function/norm_spec.rb
243
+ - spec/linalg/function/pinv_spec.rb
244
+ - spec/linalg/function/qr_spec.rb
245
+ - spec/linalg/function/slogdet_spec.rb
246
+ - spec/linalg/function/solve_spec.rb
247
+ - spec/linalg/function/svd_spec.rb
248
+ - spec/linalg/function/svdvals_spec.rb
249
+ - spec/spec_helper.rb
@@ -1,13 +0,0 @@
1
- require 'numo/narray'
2
- require File.join(File.dirname(__FILE__), "../ext/numo/lapack/lapack")
3
- #Numo::NArray.debug = true
4
-
5
- RSpec.configure do |config|
6
- config.filter_run :focus
7
- config.run_all_when_everything_filtered = true
8
- end
9
- #context :focus=>true do ... end
10
-
11
- describe 'something' do
12
- it{expect(Numo::LAPACK).to be_a(Module)}
13
- end