nulin 0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/doc/BSDL +22 -0
- data/doc/COPYING +10 -0
- data/doc/README.en +31 -0
- data/doc/README.ja +36 -0
- data/ext/extconf.rb +33 -0
- data/ext/nulin_native.c +637 -0
- data/lib/narray_extext.rb +113 -0
- data/lib/nulin.rb +51 -0
- data/lib/nulin/cholesky.rb +62 -0
- data/lib/nulin/det.rb +17 -0
- data/lib/nulin/eigensystem.rb +191 -0
- data/lib/nulin/gemm.rb +53 -0
- data/lib/nulin/lls.rb +133 -0
- data/lib/nulin/qr.rb +68 -0
- data/lib/nulin/svd.rb +84 -0
- data/tests/run_test.rb +17 -0
- data/tests/test_cholesky.rb +39 -0
- data/tests/test_det.rb +11 -0
- data/tests/test_eigensystem.rb +71 -0
- data/tests/test_gemm.rb +57 -0
- data/tests/test_lls.rb +51 -0
- data/tests/test_narray.rb +100 -0
- data/tests/test_qr.rb +56 -0
- data/tests/test_svd.rb +51 -0
- metadata +108 -0
data/tests/test_lls.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'test-unit'
|
2
|
+
require 'nulin'
|
3
|
+
require 'complex'
|
4
|
+
|
5
|
+
class TestNuLin_lls < Test::Unit::TestCase
|
6
|
+
def test_lls
|
7
|
+
a = NMatrix[[0.4, 0.1],
|
8
|
+
[-1.2, 0.9],
|
9
|
+
[0.1, -0.6]]
|
10
|
+
b = NVector[0.7,-1.0,0.4]
|
11
|
+
|
12
|
+
lls = NuLin.lls(a, b)
|
13
|
+
assert_equal([2], lls.solution.shape)
|
14
|
+
assert_narray_in_delta((a.transpose*a).inverse * a.transpose * b, lls.solution)
|
15
|
+
|
16
|
+
lls = NuLin.lls(a, b, algorithm: :svd)
|
17
|
+
assert_equal([2], lls.solution.shape)
|
18
|
+
assert_narray_in_delta((a.transpose*a).inverse * a.transpose * b, lls.solution)
|
19
|
+
assert_narray_in_delta(NuLin.svd(a).singular_values, lls.singular_values)
|
20
|
+
assert_equal(2, lls.rank)
|
21
|
+
|
22
|
+
b = NVector[[0.7,-1.0,0.4], [1.2, 0.8, -0.1]]
|
23
|
+
lls = NuLin.lls(a, b)
|
24
|
+
|
25
|
+
assert_narray_in_delta((a.transpose*a).inverse * a.transpose * b[true, 0],
|
26
|
+
lls.solution[true, 0])
|
27
|
+
assert_narray_in_delta((a.transpose*a).inverse * a.transpose * b[true, 1],
|
28
|
+
lls.solution[true, 1])
|
29
|
+
|
30
|
+
lls = NuLin.lls(a, b, algorithm: :svd)
|
31
|
+
assert_narray_in_delta((a.transpose*a).inverse * a.transpose * b[true, 0],
|
32
|
+
lls.solution[true, 0])
|
33
|
+
assert_narray_in_delta((a.transpose*a).inverse * a.transpose * b[true, 1],
|
34
|
+
lls.solution[true, 1])
|
35
|
+
|
36
|
+
a = NMatrix[[Complex(1.2, 0.2), Complex(0.1, -0.1)],
|
37
|
+
[Complex(-1.2, -0.2), Complex(-0.9, 1.0)],
|
38
|
+
[Complex(0.34, 0.1), Complex(-0.1, -0.1)]]
|
39
|
+
b = NVector[Complex(0.7), -1.0, Complex(0.1, 0.4)]
|
40
|
+
|
41
|
+
lls = NuLin.lls(a, b)
|
42
|
+
assert_narray_in_delta((a.adjoint*a).inverse * a.adjoint * b, lls.solution)
|
43
|
+
|
44
|
+
lls = NuLin.lls(a, b, algorithm: :svd)
|
45
|
+
assert_narray_in_delta((a.adjoint*a).inverse * a.adjoint * b, lls.solution)
|
46
|
+
|
47
|
+
a = NMatrix.float(2, 3); b = NVector.float(2)
|
48
|
+
assert_raise(NuLin::DimensionError){ NuLin.lls(a, b) }
|
49
|
+
assert_raise(NuLin::DimensionError){ NuLin.lls(a, b, algorithm: :svd) }
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'test-unit'
|
2
|
+
require 'nulin'
|
3
|
+
require 'complex'
|
4
|
+
|
5
|
+
class TestNArray < Test::Unit::TestCase
|
6
|
+
def test_square_p
|
7
|
+
assert(NArray[[1, 2], [3, 4]].square?)
|
8
|
+
assert(NArray[[1.0]].square?)
|
9
|
+
assert(!NArray.float(3, 3, 3).square?)
|
10
|
+
assert(!NArray.float(2, 3).square?)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_column_vector
|
14
|
+
m = NMatrix.int(3, 3); m.indgen(0, 1)
|
15
|
+
assert_equal(m.column_vector(0), NVector[0, 3, 6])
|
16
|
+
m = NMatrix.int(3, 3, 3); m.indgen!
|
17
|
+
assert_equal(m.column_vector(0), NVector[[0, 3, 6], [9, 12, 15], [18, 21, 24]])
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_row_vector
|
21
|
+
m = NMatrix.int(3, 3); m.indgen(0, 1)
|
22
|
+
assert_equal(m.row_vector(0), NVector[0, 1, 2])
|
23
|
+
m = NMatrix.int(3, 3, 3); m.indgen!
|
24
|
+
assert_equal(m.row_vector(0), NVector[[0, 1, 2], [9, 10, 11], [18, 19, 20]])
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_adjoint
|
28
|
+
m = NMatrix.int(3, 3); m.indgen(0, 1)
|
29
|
+
assert_equal(NMatrix[[0, 3, 6], [1, 4, 7], [2, 5, 8]] , m.adjoint)
|
30
|
+
m = NMatrix[[Complex(1, 2), 0], [Complex(0, -2), Complex(-1, 4)]]
|
31
|
+
assert_equal(NMatrix[[Complex(1, -2), Complex(0, 2)], [0, Complex(-1, -4)]],
|
32
|
+
m.adjoint)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_row_vectors
|
36
|
+
m = NMatrix.int(2, 3); m.indgen(0, 1)
|
37
|
+
assert_equal([NVector[0,1], NVector[2,3], NVector[4,5]], m.row_vectors)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_column_vectors
|
41
|
+
m = NMatrix.int(2, 3); m.indgen(0, 1)
|
42
|
+
assert_equal([NVector[0,2,4], NVector[1,3,5]], m.column_vectors)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_as_vector
|
46
|
+
assert_equal(NVector[1, 2], NMatrix[[1, 2]].as_vector)
|
47
|
+
assert_equal(NVector[1, 2], NMatrix[[1],[2]].as_vector)
|
48
|
+
assert_raise(ArgumentError){ NMatrix[[1,2],[3,4]].as_vector }
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_I
|
52
|
+
m = NMatrix.I(3)
|
53
|
+
assert_equal(NArray::DFLOAT, m.typecode)
|
54
|
+
assert_narray_in_delta(NMatrix[[1.0, 0.0, 0.0],
|
55
|
+
[0.0, 1.0, 0.0],
|
56
|
+
[0.0, 0.0, 1.0]], m)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_diagonal
|
60
|
+
diag = NVector[1.0, 2.0, 3.0]
|
61
|
+
m = NMatrix.diagonal(diag)
|
62
|
+
assert_equal(NArray::DFLOAT, m.typecode)
|
63
|
+
assert_narray_in_delta(NMatrix[[1.0, 0.0, 0.0],
|
64
|
+
[0.0, 2.0, 0.0],
|
65
|
+
[0.0, 0.0, 3.0]], m)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_build
|
69
|
+
m = NMatrix.build(NArray::DFLOAT, 2, 3){|m, n| m*4 + n }
|
70
|
+
assert_equal(NArray::DFLOAT, m.typecode)
|
71
|
+
assert_narray_in_delta(NMatrix[[0.0, 4.0],[1.0, 5.0], [2.0, 6.0]], m)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_each_with_index
|
75
|
+
m = NMatrix.build(NArray::INT, 2, 3){|m, n| (m + n*2)*2 }
|
76
|
+
r = []
|
77
|
+
m.each_with_index{|*k| r << k }
|
78
|
+
assert_equal([[0, 0, 0], [2, 1, 0],
|
79
|
+
[4, 0, 1], [6, 1, 1],
|
80
|
+
[8, 0, 2], [10, 1, 2]], r)
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_filled
|
85
|
+
m = NArray.filled(NArray::FLOAT, 4.0, 2, 3)
|
86
|
+
assert_equal(NArray::FLOAT, m.typecode)
|
87
|
+
assert_equal([2, 3], m.shape)
|
88
|
+
m.each{|v| assert_equal(4.0, v) }
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_norm
|
92
|
+
assert_in_delta(5.0, NVector[3.0, 4.0].norm)
|
93
|
+
assert_in_delta(5.0, NVector[3.i, 4].norm)
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_normalize
|
97
|
+
assert_narray_in_delta(NVector[3.0/5.0, 4.0/5.0],
|
98
|
+
NVector[3.0, 4.0].normalize)
|
99
|
+
end
|
100
|
+
end
|
data/tests/test_qr.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'nulin'
|
2
|
+
require 'test-unit'
|
3
|
+
|
4
|
+
|
5
|
+
class TestNuLin_qr < Test::Unit::TestCase
|
6
|
+
def test_qr
|
7
|
+
m = NMatrix[[-0.8, 1.2, 0.9, 0.2],
|
8
|
+
[0.0, 0.3, -0.7, 0.4],
|
9
|
+
[0.1, -0.3, 0.7, -0.4],
|
10
|
+
[0.2, 0.4, -0.1, 0.5]]
|
11
|
+
check_qr_for(m, NArray::DFLOAT)
|
12
|
+
|
13
|
+
sm = NMatrix.sfloat(4, 4); sm[] = m
|
14
|
+
check_qr_for(sm, NArray::SFLOAT)
|
15
|
+
|
16
|
+
m = NMatrix[[-0.8, 1.2, 0.9, 0.2],
|
17
|
+
[0.0, 0.3, -0.7, 0.4],
|
18
|
+
[0.2, 0.4, -0.1, 0.5]]
|
19
|
+
check_qr_for(m, NArray::DFLOAT)
|
20
|
+
|
21
|
+
m = NMatrix[[-0.8, 1.2, 0.9],
|
22
|
+
[0.0, 0.3, -0.7],
|
23
|
+
[0.1, -0.3, 0.7],
|
24
|
+
[0.2, 0.4, -0.1]]
|
25
|
+
check_qr_for(m, NArray::DFLOAT)
|
26
|
+
|
27
|
+
re = NMatrix[[-0.8, 1.2, 0.9, 0.2],
|
28
|
+
[0.0, 0.3, -0.7, 0.4],
|
29
|
+
[0.1, -0.3, 0.7, -0.4],
|
30
|
+
[0.2, 0.4, -0.1, 0.5]]
|
31
|
+
imag = NMatrix[[ 0.277778, 0.347718, 1.25833, 0.257209 ],
|
32
|
+
[ 0.159667, -0.0683527, 1.60072, 0.479529 ],
|
33
|
+
[ 0.537662, -1.08895, -0.815658, -0.247471 ],
|
34
|
+
[ -2.0635, 0.201613, 3.78139, -1.52979 ]]
|
35
|
+
m = NMatrix.complex(4, 4); m[] = re; m.imag = imag
|
36
|
+
check_qr_for(m, NArray::DCOMPLEX)
|
37
|
+
|
38
|
+
m = NMatrix.scomplex(4, 4); m[] = re; m.imag = imag
|
39
|
+
check_qr_for(m, NArray::SCOMPLEX)
|
40
|
+
end
|
41
|
+
|
42
|
+
def check_qr_for(m, typecode)
|
43
|
+
qr = NuLin.qr(m)
|
44
|
+
|
45
|
+
assert_equal(typecode, qr.Q.typecode)
|
46
|
+
assert_equal(typecode, qr.R.typecode)
|
47
|
+
assert_narray_in_delta(NMatrix.I(qr.Q.shape[0], typecode), qr.Q * qr.Qt)
|
48
|
+
assert_narray_in_delta(m, qr.Q * qr.R)
|
49
|
+
qr.R.each_with_index do |v, i, j|
|
50
|
+
if i < j
|
51
|
+
assert(v.abs < 0.0001)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
assert(qr.Q.adjoint == qr.Qt)
|
55
|
+
end
|
56
|
+
end
|
data/tests/test_svd.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'test-unit'
|
2
|
+
require 'nulin'
|
3
|
+
|
4
|
+
class TestNuLin_svd < Test::Unit::TestCase
|
5
|
+
REAL_MATRIX = NMatrix[[1.2, 0.8, -1.9, 0.4],
|
6
|
+
[0.0, -2.1, 0.2, -0.12],
|
7
|
+
[-0.2, 0.48, 1.02, 0.09]]
|
8
|
+
|
9
|
+
COMPLEX_MATRIX = NMatrix[[Complex(1,2), Complex(3,4), Complex(5,6)],
|
10
|
+
[Complex(7,8), Complex(9,10), Complex(11, 12)],
|
11
|
+
[Complex(-6, -5), Complex(-4, -3), Complex(-2, -1)],
|
12
|
+
[Complex(0,1), Complex(2,3), Complex(4,5)]]
|
13
|
+
def test_svd_dfloat
|
14
|
+
check_svd(REAL_MATRIX, 4, 3, NArray::FLOAT, NArray::FLOAT)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_svd_sfloat
|
18
|
+
m = NMatrix.sfloat(4, 3); m[] = REAL_MATRIX
|
19
|
+
check_svd(m, 4, 3, NArray::SFLOAT, NArray::SFLOAT)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_svd_dcomplex
|
23
|
+
check_svd(COMPLEX_MATRIX, 3, 4, NArray::DCOMPLEX, NArray::DFLOAT)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_svd_scomplex
|
27
|
+
m = NMatrix.scomplex(3, 4); m[] = COMPLEX_MATRIX
|
28
|
+
check_svd(m, 3, 4, NArray::SCOMPLEX, NArray::SFLOAT)
|
29
|
+
end
|
30
|
+
|
31
|
+
def check_svd(matrix, rows, columns, typecode, sv_typecode)
|
32
|
+
assert_equal([rows, columns], matrix.shape)
|
33
|
+
|
34
|
+
svd = NuLin.svd(matrix, full_matrix: true)
|
35
|
+
|
36
|
+
assert_equal([columns, columns], svd.U.shape)
|
37
|
+
assert_equal([rows, rows], svd.V.shape)
|
38
|
+
assert_equal([rows, rows], svd.Vt.shape)
|
39
|
+
assert_equal([rows, columns], svd.sigma.shape)
|
40
|
+
assert_equal([[columns,rows].min], svd.singular_values.shape)
|
41
|
+
assert_equal(typecode, svd.U.typecode)
|
42
|
+
assert_equal(typecode, svd.Vt.typecode)
|
43
|
+
assert_equal(sv_typecode, svd.singular_values.typecode)
|
44
|
+
assert_equal(typecode, svd.sigma.typecode)
|
45
|
+
|
46
|
+
assert_narray_in_delta(matrix, svd.U * svd.sigma * svd.V.transpose)
|
47
|
+
([rows, columns].min - 1).times do |n|
|
48
|
+
assert(svd.singular_values[n] > svd.singular_values[n+1])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nulin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.2'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ippei Obayashi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: narray
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.6.0.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.6.0.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: test-unit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: |
|
42
|
+
A linear algebra library cooperating with NArray.
|
43
|
+
This library calls blas and lapack routines for fast computations.
|
44
|
+
This library has following functionalities.
|
45
|
+
|
46
|
+
* xGEMM (multiply two matrices and add other matrix)
|
47
|
+
* Solve LLS(Least Square Sum) problems
|
48
|
+
* Computing determinant (using QR decomposition)
|
49
|
+
* Solve eigenproblems (compute eigenvalues and eigenvectors)
|
50
|
+
* (Pivoted) LU decompotision
|
51
|
+
* SVD(Singular value decomposition)
|
52
|
+
* QR decomposition
|
53
|
+
* Cholesky decomposition
|
54
|
+
email: ohai@kmc.gr.jp
|
55
|
+
executables: []
|
56
|
+
extensions:
|
57
|
+
- ext/extconf.rb
|
58
|
+
extra_rdoc_files: []
|
59
|
+
files:
|
60
|
+
- lib/narray_extext.rb
|
61
|
+
- lib/nulin.rb
|
62
|
+
- lib/nulin/qr.rb
|
63
|
+
- lib/nulin/eigensystem.rb
|
64
|
+
- lib/nulin/gemm.rb
|
65
|
+
- lib/nulin/svd.rb
|
66
|
+
- lib/nulin/cholesky.rb
|
67
|
+
- lib/nulin/det.rb
|
68
|
+
- lib/nulin/lls.rb
|
69
|
+
- tests/run_test.rb
|
70
|
+
- tests/test_det.rb
|
71
|
+
- tests/test_narray.rb
|
72
|
+
- tests/test_qr.rb
|
73
|
+
- tests/test_gemm.rb
|
74
|
+
- tests/test_svd.rb
|
75
|
+
- tests/test_lls.rb
|
76
|
+
- tests/test_cholesky.rb
|
77
|
+
- tests/test_eigensystem.rb
|
78
|
+
- doc/BSDL
|
79
|
+
- doc/COPYING
|
80
|
+
- doc/README.en
|
81
|
+
- doc/README.ja
|
82
|
+
- ext/extconf.rb
|
83
|
+
- ext/nulin_native.c
|
84
|
+
homepage: http://www.kmc.gr.jp/~ohai/nulin/
|
85
|
+
licenses:
|
86
|
+
- 2-clause BSDL
|
87
|
+
metadata: {}
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 2.0.14
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: Linear algebra library cooperating with NArray
|
108
|
+
test_files: []
|