nmatrix 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/History.txt +31 -3
- data/Manifest.txt +5 -0
- data/README.rdoc +29 -27
- data/ext/nmatrix/binary_format.txt +53 -0
- data/ext/nmatrix/data/data.cpp +18 -18
- data/ext/nmatrix/data/data.h +38 -7
- data/ext/nmatrix/data/rational.h +13 -0
- data/ext/nmatrix/data/ruby_object.h +10 -0
- data/ext/nmatrix/extconf.rb +2 -0
- data/ext/nmatrix/nmatrix.cpp +655 -103
- data/ext/nmatrix/nmatrix.h +26 -14
- data/ext/nmatrix/ruby_constants.cpp +4 -0
- data/ext/nmatrix/ruby_constants.h +2 -0
- data/ext/nmatrix/storage/dense.cpp +99 -41
- data/ext/nmatrix/storage/dense.h +3 -3
- data/ext/nmatrix/storage/list.cpp +36 -14
- data/ext/nmatrix/storage/list.h +4 -4
- data/ext/nmatrix/storage/storage.cpp +19 -19
- data/ext/nmatrix/storage/storage.h +11 -11
- data/ext/nmatrix/storage/yale.cpp +17 -20
- data/ext/nmatrix/storage/yale.h +13 -11
- data/ext/nmatrix/util/io.cpp +25 -23
- data/ext/nmatrix/util/io.h +5 -5
- data/ext/nmatrix/util/math.cpp +634 -17
- data/ext/nmatrix/util/math.h +958 -9
- data/ext/nmatrix/util/sl_list.cpp +7 -7
- data/ext/nmatrix/util/sl_list.h +2 -2
- data/lib/nmatrix.rb +9 -0
- data/lib/nmatrix/blas.rb +4 -4
- data/lib/nmatrix/io/market.rb +227 -0
- data/lib/nmatrix/io/mat_reader.rb +7 -7
- data/lib/nmatrix/lapack.rb +80 -0
- data/lib/nmatrix/nmatrix.rb +78 -52
- data/lib/nmatrix/shortcuts.rb +486 -0
- data/lib/nmatrix/version.rb +1 -1
- data/spec/2x2_dense_double.mat +0 -0
- data/spec/blas_spec.rb +59 -9
- data/spec/elementwise_spec.rb +25 -12
- data/spec/io_spec.rb +69 -1
- data/spec/lapack_spec.rb +53 -4
- data/spec/math_spec.rb +9 -0
- data/spec/nmatrix_list_spec.rb +95 -0
- data/spec/nmatrix_spec.rb +10 -53
- data/spec/nmatrix_yale_spec.rb +17 -15
- data/spec/shortcuts_spec.rb +154 -0
- metadata +22 -15
data/Gemfile
CHANGED
data/History.txt
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
=== 0.0.2 / 2012-09-21
|
8
8
|
|
9
|
-
*
|
9
|
+
* 15 major enhancements
|
10
10
|
|
11
11
|
* Second alpha release
|
12
12
|
|
@@ -14,7 +14,7 @@
|
|
14
14
|
|
15
15
|
* Added preliminary C API
|
16
16
|
|
17
|
-
* Slicing and referencing support for dense and list matrices
|
17
|
+
* Slicing and referencing support for dense and list matrices (by @flipback)
|
18
18
|
|
19
19
|
* BLAS level-3 xTRSM algorithm added for rationals and BLAS types
|
20
20
|
|
@@ -36,4 +36,32 @@
|
|
36
36
|
|
37
37
|
* Sped up list storage item deletion, fixed bugs
|
38
38
|
|
39
|
-
*
|
39
|
+
* List matrix-to-hash conversion with `to_h`
|
40
|
+
|
41
|
+
* Note: Element-wise list operations current disabled
|
42
|
+
|
43
|
+
=== 0.0.3 / 2013-01-18
|
44
|
+
|
45
|
+
* 8 major enhancements
|
46
|
+
|
47
|
+
* Matrix-scalar operations (dense, list)
|
48
|
+
|
49
|
+
* Shortcuts for matrix creation (by @agarie)
|
50
|
+
|
51
|
+
* Access to most ATLAS-implemented LAPACK functions for those with ATLAS' CLAPACK interface: xGETRF, xGETRI, xGETRS, xGESV, xPOTRF, xPOTRI, xPOTRS, xPOSV, xLASWP, xSCAL, xLAUUM
|
52
|
+
|
53
|
+
* Access to additional ATLAS-implemented BLAS functions: xTRMM, xSYRK, xHERK, xROT, xROTG
|
54
|
+
|
55
|
+
* Non-ATLAS versions of CLAPACK functions: xLASWP, xSCAL, xLAUUM, xROT
|
56
|
+
|
57
|
+
* Matrix inversion (LU and Cholesky; requires CLAPACK)
|
58
|
+
|
59
|
+
* LU factoring with and without CLAPACK
|
60
|
+
|
61
|
+
* Native matrix I/O for dense (supporting upper, lower, hermitian, skew, symmetric, and general) and yale (general only); excludes Ruby objects currently
|
62
|
+
|
63
|
+
* 2 bug fixes:
|
64
|
+
|
65
|
+
* Yale-to-list casting
|
66
|
+
|
67
|
+
* Now requires packable-1.3.5 or higher, fixing a problem with MATLAB .mat v5 file I/O (specific to doubles)
|
data/Manifest.txt
CHANGED
@@ -8,20 +8,25 @@ Guardfile
|
|
8
8
|
spec/io_spec.rb
|
9
9
|
spec/math_spec.rb
|
10
10
|
spec/nmatrix_spec.rb
|
11
|
+
spec/nmatrix_list_spec.rb
|
11
12
|
spec/nmatrix_yale_spec.rb
|
12
13
|
spec/nvector_spec.rb
|
13
14
|
spec/slice_spec.rb
|
15
|
+
spec/shortcuts_spec.rb
|
14
16
|
spec/elementwise_spec.rb
|
15
17
|
spec/blas_spec.rb
|
16
18
|
spec/lapack_spec.rb
|
17
19
|
spec/spec_helper.rb
|
18
20
|
lib/nmatrix.rb
|
21
|
+
lib/nmatrix/io/market.rb
|
19
22
|
lib/nmatrix/io/mat5_reader.rb
|
20
23
|
lib/nmatrix/io/mat_reader.rb
|
21
24
|
lib/nmatrix/blas.rb
|
25
|
+
lib/nmatrix/lapack.rb
|
22
26
|
lib/nmatrix/monkeys.rb
|
23
27
|
lib/nmatrix/nmatrix.rb
|
24
28
|
lib/nmatrix/nvector.rb
|
29
|
+
lib/nmatrix/shortcuts.rb
|
25
30
|
lib/nmatrix/version.rb
|
26
31
|
ext/nmatrix/data/complex.h
|
27
32
|
ext/nmatrix/data/data.cpp
|
data/README.rdoc
CHANGED
@@ -27,49 +27,49 @@ are working on a {patch for Ruby/GSL}[https://github.com/SciRuby/rb-gsl].
|
|
27
27
|
|
28
28
|
== Features
|
29
29
|
|
30
|
-
The following features exist in the version of NMatrix (0.0.2)
|
31
|
-
0.0.1 (the current gem):
|
30
|
+
The following features exist in the current version of NMatrix (0.0.2):
|
32
31
|
|
33
32
|
* Matrix storage containers: dense, yale, list (more to come)
|
34
33
|
* Data types: uint8, int8, int16, int32, int64, float32, float64, complex64, complex128, rational64, rational128
|
35
34
|
(incomplete)
|
36
35
|
* Conversion between storage and data types (except from-complex, and from-float-to-rational)
|
37
|
-
* Element-wise operations and comparisons
|
36
|
+
* Element-wise operations and comparisons for dense and yale
|
38
37
|
* Matrix-matrix multiplication for dense (using ATLAS) and yale
|
39
38
|
* Matrix-vector multiplication for dense (using ATLAS)
|
40
39
|
* Dense and list matrix slicing and referencing
|
40
|
+
* Native reading and writing of dense and yale matrices
|
41
|
+
* Optional compression for dense matrices with symmetry or triangularity: symmetric, skew, hermitian, upper, lower
|
41
42
|
* Matlab .MAT v5 file input
|
42
43
|
* C and C++ API
|
43
|
-
*
|
44
|
-
*
|
45
|
-
*
|
44
|
+
* BLAS internal implementations (no library) and ATLAS (with library) access:
|
45
|
+
* Level 1: xROT, xROTG (BLAS dtypes only)
|
46
|
+
* Level 2: xGEMV
|
47
|
+
* Level 3: xGEMM, xTRSM
|
46
48
|
* LAPACK ATLAS access:
|
47
|
-
* xGETRF (
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
These features will exist in our second alpha release, 0.0.2 (incomplete, thus not yet available as a gem):
|
52
|
-
|
53
|
-
* Yale matrix slicing and referencing
|
54
|
-
* LU decomposition
|
55
|
-
* LAPACK internal implementations (no library needed):
|
49
|
+
* xGETRF, xGETRI, xGETRS, xGESV (Gaussian elimination)
|
50
|
+
* xPOTRF, xPOTRI, xPOTRS, xPOSV (Cholesky factorization)
|
51
|
+
* xLASWP, xSCAL, xLAUUM
|
52
|
+
* LAPACK-less internal implementations (no LAPACK needed and working on non-BLAS dtypes):
|
56
53
|
* xGETRF
|
57
|
-
|
58
|
-
|
54
|
+
* xLASWP, xSCAL
|
55
|
+
* xLAUUM (no LAPACK needed, but BLAS dtypes only)
|
56
|
+
* LU decomposition
|
57
|
+
* Matrix inversions (requires LAPACK; BLAS dtypes only)
|
58
|
+
* Determinant calculation for BLAS dtypes
|
59
59
|
|
60
60
|
=== Planned Features (Short-to-Medium Term)
|
61
61
|
|
62
62
|
These are features planned for NMatrix 0.1.0, our first beta.
|
63
63
|
|
64
|
-
* calculation of determinant, trace, and eigenvalues (characteristic polynomial) (0.1.0)
|
65
|
-
* Gaussian elimination
|
64
|
+
* calculation of determinant (LAPACK-free), trace, and eigenvalues (characteristic polynomial) (0.1.0)
|
66
65
|
* exponentials and square roots
|
67
|
-
* matrix inversions
|
66
|
+
* matrix inversions (LAPACK-free)
|
68
67
|
* matrix decomposition/factorization
|
69
68
|
* calculation of norms
|
70
69
|
* tensor products
|
71
70
|
* principal component analysis (PCA)
|
72
71
|
* improved file I/O
|
72
|
+
* compression of yale symmetries in I/O
|
73
73
|
* operation scheduling
|
74
74
|
* parallelization of some types of operations
|
75
75
|
* optimization of non-BLAS data types on BLAS-like operations (e.g., matrix multiplication for rational numbers)
|
@@ -83,30 +83,32 @@ For full instructions, please see sciruby.com/nmatrix. Generally, you should be
|
|
83
83
|
|
84
84
|
However, you will need to install ATLAS with CBLAS first. Those directions can be found at our website.
|
85
85
|
|
86
|
-
|
87
|
-
following sequence of commands:
|
86
|
+
You can typically get the developer's build using the following sequence of commands:
|
88
87
|
|
89
88
|
git clone https://github.com/SciRuby/nmatrix.git
|
90
89
|
cd nmatrix/
|
91
90
|
rake compile
|
92
91
|
rake repackage
|
93
|
-
gem install pkg/nmatrix-0.0.
|
92
|
+
gem install pkg/nmatrix-0.0.4.gem
|
94
93
|
|
95
94
|
If you get errors about clapack.h or cblas.h, figure out where your ATLAS headers are using:
|
96
95
|
|
97
|
-
locate clapack.h
|
96
|
+
locate clapack.h # If you're a Mac user, we recommend you search for cblas.h instead.
|
98
97
|
|
99
98
|
Then, tell your system:
|
100
99
|
|
101
100
|
export C_INCLUDE_PATH=/usr/local/atlas/include
|
101
|
+
export CPLUS_INCLUDE_PATH=/usr/local/atlas/include
|
102
102
|
|
103
103
|
Finally, try compiling again.
|
104
104
|
|
105
105
|
== REQUIREMENTS:
|
106
106
|
|
107
|
-
* ATLAS
|
108
|
-
*
|
107
|
+
* ATLAS
|
108
|
+
* LAPACK, probably
|
109
|
+
* GCC 4.3
|
109
110
|
* Ruby 1.9
|
111
|
+
* {packable}[http://github.com/marcandre/packable] 1.3.5 (used for I/O)
|
110
112
|
|
111
113
|
== INSTALLATION:
|
112
114
|
|
@@ -126,7 +128,7 @@ Before commiting any code, you *MUST* read our
|
|
126
128
|
|
127
129
|
== LICENSE:
|
128
130
|
|
129
|
-
Copyright (c) 2012, The Ruby Science Foundation.
|
131
|
+
Copyright (c) 2012--13, The Ruby Science Foundation.
|
130
132
|
|
131
133
|
All rights reserved.
|
132
134
|
|
@@ -0,0 +1,53 @@
|
|
1
|
+
This is the proposed binary format for saving and loading NMatrix objects.
|
2
|
+
|
3
|
+
Order is little-endian.
|
4
|
+
|
5
|
+
List matrices should be converted to dense or yale matrices. There should be no serious need to load or save
|
6
|
+
linked-list matrices, since these exist primarily in order to construct efficient yale matrices.
|
7
|
+
|
8
|
+
|
9
|
+
First 64-bit block:
|
10
|
+
* ui16 major (version)
|
11
|
+
* ui16 minor
|
12
|
+
* ui16 release
|
13
|
+
* i16 NULL
|
14
|
+
|
15
|
+
|
16
|
+
Second 64-bit block:
|
17
|
+
* ui8 dtype
|
18
|
+
* ui8 stype
|
19
|
+
* ui8 itype # ui32 for dense
|
20
|
+
* ui8 symm
|
21
|
+
* i16 NULL
|
22
|
+
* ui16 dim # if 1, NVector; otherwise, NMatrix
|
23
|
+
|
24
|
+
|
25
|
+
3rd - nth 64-bit block: shape
|
26
|
+
|
27
|
+
itype sets the number of bytes allocated for each shape entry. Since only yale uses itype, dense will pretty
|
28
|
+
much always be the UINT32 itype (see nmatrix.h). If the total number of bytes occupied by the shape array is
|
29
|
+
less than 8, the rest of the 64-bit block will be padded with zeros.
|
30
|
+
|
31
|
+
|
32
|
+
(n+1)th 64-bit block: depends on stype, symm
|
33
|
+
|
34
|
+
symm is designed to reduce file size by allowing us to not save certain elements in symmetric, hermitian, skew-
|
35
|
+
symmetric, and triangular matrices. These values will be defined in nmatrix.h; 0 indicates standard (no symmetry).
|
36
|
+
In later versions, additional patterns may be defined which might even have less to do with symmetry than
|
37
|
+
upper/lower do.
|
38
|
+
|
39
|
+
When storing a symmetric matrix, we will only store the upper portion. If the matrix is lower triangular, only the
|
40
|
+
lower portion will be stored.
|
41
|
+
|
42
|
+
For dense, we simply store the contents of the matrix exactly as in memory (or just the upper-triangular part if
|
43
|
+
symm is set).
|
44
|
+
|
45
|
+
For yale, we store:
|
46
|
+
* ui32 ndnz
|
47
|
+
* ui32 length (AKA size, the number of elements in A/IJA that aren't nil/undefined)
|
48
|
+
|
49
|
+
The latter will serve as the capacity when we read a Yale matrix.
|
50
|
+
|
51
|
+
Then we store the a array, again padding with zeros so it's a multiple of 8 bytes.
|
52
|
+
|
53
|
+
Then we store the ija array, padding with zeros so it's a multiple of 8 bytes.
|
data/ext/nmatrix/data/data.cpp
CHANGED
@@ -95,20 +95,20 @@ const size_t ITYPE_SIZES[nm::NUM_ITYPES] = {
|
|
95
95
|
sizeof(uint64_t),
|
96
96
|
};
|
97
97
|
|
98
|
-
const dtype_t Upcast[nm::NUM_DTYPES][nm::NUM_DTYPES] = {
|
99
|
-
{ BYTE, INT8, INT16, INT32, INT64, FLOAT32, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL32, RATIONAL64, RATIONAL128, RUBYOBJ},
|
100
|
-
{ INT8, INT8, INT16, INT32, INT64, FLOAT32, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL32, RATIONAL64, RATIONAL128, RUBYOBJ},
|
101
|
-
{ INT16, INT16, INT16, INT32, INT64, FLOAT32, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL32, RATIONAL64, RATIONAL128, RUBYOBJ},
|
102
|
-
{ INT32, INT32, INT32, INT32, INT64, FLOAT32, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL32, RATIONAL64, RATIONAL128, RUBYOBJ},
|
103
|
-
{ INT64, INT64, INT64, INT64, INT64, FLOAT32, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL32, RATIONAL64, RATIONAL128, RUBYOBJ},
|
104
|
-
{ FLOAT32, FLOAT32, FLOAT32, FLOAT32, FLOAT32, FLOAT32, FLOAT64, COMPLEX64, COMPLEX128, FLOAT64, FLOAT64, FLOAT64, RUBYOBJ},
|
105
|
-
{ FLOAT64, FLOAT64, FLOAT64, FLOAT64, FLOAT64, FLOAT64, FLOAT64, COMPLEX128, COMPLEX128, FLOAT64, FLOAT64, FLOAT64, RUBYOBJ},
|
106
|
-
{ COMPLEX64, COMPLEX64, COMPLEX64, COMPLEX64, COMPLEX64, COMPLEX64, COMPLEX128, COMPLEX64, COMPLEX128, COMPLEX64, COMPLEX64, COMPLEX64, RUBYOBJ},
|
107
|
-
{ COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, RUBYOBJ},
|
108
|
-
{ RATIONAL32, RATIONAL32, RATIONAL32, RATIONAL32, RATIONAL32, FLOAT64, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL32, RATIONAL64, RATIONAL128, RUBYOBJ},
|
109
|
-
{ RATIONAL64, RATIONAL64, RATIONAL64, RATIONAL64, RATIONAL64, FLOAT64, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL64, RATIONAL64, RATIONAL128, RUBYOBJ},
|
110
|
-
{ RATIONAL128, RATIONAL128, RATIONAL128, RATIONAL128, RATIONAL128, FLOAT64, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL128, RATIONAL128, RATIONAL128, RUBYOBJ},
|
111
|
-
{ RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ}
|
98
|
+
const nm::dtype_t Upcast[nm::NUM_DTYPES][nm::NUM_DTYPES] = {
|
99
|
+
{ nm::BYTE, nm::INT8, nm::INT16, nm::INT32, nm::INT64, nm::FLOAT32, nm::FLOAT64, nm::COMPLEX64, nm::COMPLEX128, nm::RATIONAL32, nm::RATIONAL64, nm::RATIONAL128, nm::RUBYOBJ},
|
100
|
+
{ nm::INT8, nm::INT8, nm::INT16, nm::INT32, nm::INT64, nm::FLOAT32, nm::FLOAT64, nm::COMPLEX64, nm::COMPLEX128, nm::RATIONAL32, nm::RATIONAL64, nm::RATIONAL128, nm::RUBYOBJ},
|
101
|
+
{ nm::INT16, nm::INT16, nm::INT16, nm::INT32, nm::INT64, nm::FLOAT32, nm::FLOAT64, nm::COMPLEX64, nm::COMPLEX128, nm::RATIONAL32, nm::RATIONAL64, nm::RATIONAL128, nm::RUBYOBJ},
|
102
|
+
{ nm::INT32, nm::INT32, nm::INT32, nm::INT32, nm::INT64, nm::FLOAT32, nm::FLOAT64, nm::COMPLEX64, nm::COMPLEX128, nm::RATIONAL32, nm::RATIONAL64, nm::RATIONAL128, nm::RUBYOBJ},
|
103
|
+
{ nm::INT64, nm::INT64, nm::INT64, nm::INT64, nm::INT64, nm::FLOAT32, nm::FLOAT64, nm::COMPLEX64, nm::COMPLEX128, nm::RATIONAL32, nm::RATIONAL64, nm::RATIONAL128, nm::RUBYOBJ},
|
104
|
+
{ nm::FLOAT32, nm::FLOAT32, nm::FLOAT32, nm::FLOAT32, nm::FLOAT32, nm::FLOAT32, nm::FLOAT64, nm::COMPLEX64, nm::COMPLEX128, nm::FLOAT64, nm::FLOAT64, nm::FLOAT64, nm::RUBYOBJ},
|
105
|
+
{ nm::FLOAT64, nm::FLOAT64, nm::FLOAT64, nm::FLOAT64, nm::FLOAT64, nm::FLOAT64, nm::FLOAT64, nm::COMPLEX128, nm::COMPLEX128, nm::FLOAT64, nm::FLOAT64, nm::FLOAT64, nm::RUBYOBJ},
|
106
|
+
{ nm::COMPLEX64, nm::COMPLEX64, nm::COMPLEX64, nm::COMPLEX64, nm::COMPLEX64, nm::COMPLEX64, nm::COMPLEX128, nm::COMPLEX64, nm::COMPLEX128, nm::COMPLEX64, nm::COMPLEX64, nm::COMPLEX64, nm::RUBYOBJ},
|
107
|
+
{ nm::COMPLEX128, nm::COMPLEX128, nm::COMPLEX128, nm::COMPLEX128, nm::COMPLEX128, nm::COMPLEX128, nm::COMPLEX128, nm::COMPLEX128, nm::COMPLEX128, nm::COMPLEX128, nm::COMPLEX128, nm::COMPLEX128, nm::RUBYOBJ},
|
108
|
+
{ nm::RATIONAL32, nm::RATIONAL32, nm::RATIONAL32, nm::RATIONAL32, nm::RATIONAL32, nm::FLOAT64, nm::FLOAT64, nm::COMPLEX64, nm::COMPLEX128, nm::RATIONAL32, nm::RATIONAL64, nm::RATIONAL128, nm::RUBYOBJ},
|
109
|
+
{ nm::RATIONAL64, nm::RATIONAL64, nm::RATIONAL64, nm::RATIONAL64, nm::RATIONAL64, nm::FLOAT64, nm::FLOAT64, nm::COMPLEX64, nm::COMPLEX128, nm::RATIONAL64, nm::RATIONAL64, nm::RATIONAL128, nm::RUBYOBJ},
|
110
|
+
{ nm::RATIONAL128, nm::RATIONAL128, nm::RATIONAL128, nm::RATIONAL128, nm::RATIONAL128, nm::FLOAT64, nm::FLOAT64, nm::COMPLEX64, nm::COMPLEX128, nm::RATIONAL128, nm::RATIONAL128, nm::RATIONAL128, nm::RUBYOBJ},
|
111
|
+
{ nm::RUBYOBJ, nm::RUBYOBJ, nm::RUBYOBJ, nm::RUBYOBJ, nm::RUBYOBJ, nm::RUBYOBJ, nm::RUBYOBJ, nm::RUBYOBJ, nm::RUBYOBJ, nm::RUBYOBJ, nm::RUBYOBJ, nm::RUBYOBJ, nm::RUBYOBJ}
|
112
112
|
};
|
113
113
|
|
114
114
|
|
@@ -123,7 +123,7 @@ const dtype_t Upcast[nm::NUM_DTYPES][nm::NUM_DTYPES] = {
|
|
123
123
|
/*
|
124
124
|
* Converts a RubyObject
|
125
125
|
*/
|
126
|
-
void rubyval_to_cval(VALUE val, dtype_t dtype, void* loc) {
|
126
|
+
void rubyval_to_cval(VALUE val, nm::dtype_t dtype, void* loc) {
|
127
127
|
using namespace nm;
|
128
128
|
switch (dtype) {
|
129
129
|
case BYTE:
|
@@ -189,7 +189,7 @@ void rubyval_to_cval(VALUE val, dtype_t dtype, void* loc) {
|
|
189
189
|
* Create a RubyObject from a regular C value (given a dtype). Does not return a VALUE! To get a VALUE, you need to
|
190
190
|
* look at the rval property of what this function returns.
|
191
191
|
*/
|
192
|
-
nm::RubyObject rubyobj_from_cval(void* val, dtype_t dtype) {
|
192
|
+
nm::RubyObject rubyobj_from_cval(void* val, nm::dtype_t dtype) {
|
193
193
|
using namespace nm;
|
194
194
|
switch (dtype) {
|
195
195
|
case BYTE:
|
@@ -238,7 +238,7 @@ nm::RubyObject rubyobj_from_cval(void* val, dtype_t dtype) {
|
|
238
238
|
/*
|
239
239
|
* Convert from itype instead of dtype
|
240
240
|
*/
|
241
|
-
nm::RubyObject rubyobj_from_cval_by_itype(void* val, itype_t itype) {
|
241
|
+
nm::RubyObject rubyobj_from_cval_by_itype(void* val, nm::itype_t itype) {
|
242
242
|
using namespace nm;
|
243
243
|
switch (itype) {
|
244
244
|
case UINT8:
|
@@ -263,7 +263,7 @@ nm::RubyObject rubyobj_from_cval_by_itype(void* val, itype_t itype) {
|
|
263
263
|
* Allocate and return a piece of data of the correct dtype, converted from a
|
264
264
|
* given RubyObject.
|
265
265
|
*/
|
266
|
-
void* rubyobj_to_cval(VALUE val, dtype_t dtype) {
|
266
|
+
void* rubyobj_to_cval(VALUE val, nm::dtype_t dtype) {
|
267
267
|
size_t size = DTYPE_SIZES[dtype];
|
268
268
|
void* ret_val = ALLOC_N(char, size);
|
269
269
|
|
data/ext/nmatrix/data/data.h
CHANGED
@@ -82,7 +82,7 @@ namespace nm {
|
|
82
82
|
};
|
83
83
|
|
84
84
|
#define STYPE_CAST_COPY_TABLE(name) \
|
85
|
-
static STORAGE* (*(name)[nm::NUM_STYPES][nm::NUM_STYPES])(const STORAGE*, dtype_t) = { \
|
85
|
+
static STORAGE* (*(name)[nm::NUM_STYPES][nm::NUM_STYPES])(const STORAGE*, nm::dtype_t) = { \
|
86
86
|
{ nm_dense_storage_cast_copy, nm_dense_storage_from_list, nm_dense_storage_from_yale }, \
|
87
87
|
{ nm_list_storage_from_dense, nm_list_storage_cast_copy, nm_list_storage_from_yale }, \
|
88
88
|
{ nm_yale_storage_from_dense, nm_yale_storage_from_list, nm_yale_storage_cast_copy } \
|
@@ -95,6 +95,22 @@ namespace nm {
|
|
95
95
|
#define DTYPE_TEMPLATE_TABLE(fun, ret, ...) NAMED_DTYPE_TEMPLATE_TABLE(ttable, fun, ret, __VA_ARGS__)
|
96
96
|
|
97
97
|
#define NAMED_DTYPE_TEMPLATE_TABLE(name, fun, ret, ...) \
|
98
|
+
static ret (*(name)[nm::NUM_DTYPES])(__VA_ARGS__) = { \
|
99
|
+
fun<uint8_t>, \
|
100
|
+
fun<int8_t>, \
|
101
|
+
fun<int16_t>, \
|
102
|
+
fun<int32_t>, \
|
103
|
+
fun<int64_t>, \
|
104
|
+
fun<float32_t>, \
|
105
|
+
fun<float64_t>, \
|
106
|
+
fun<nm::Complex64>, \
|
107
|
+
fun<nm::Complex128>, \
|
108
|
+
fun<nm::Rational32>, \
|
109
|
+
fun<nm::Rational64>, \
|
110
|
+
fun<nm::Rational128> \
|
111
|
+
};
|
112
|
+
|
113
|
+
#define NAMED_DTYPE_TEMPLATE_TABLE_NO_ROBJ(name, fun, ret, ...) \
|
98
114
|
static ret (*(name)[nm::NUM_DTYPES])(__VA_ARGS__) = { \
|
99
115
|
fun<uint8_t>, \
|
100
116
|
fun<int8_t>, \
|
@@ -108,7 +124,6 @@ namespace nm {
|
|
108
124
|
fun<nm::Rational32>, \
|
109
125
|
fun<nm::Rational64>, \
|
110
126
|
fun<nm::Rational128>, \
|
111
|
-
fun<nm::RubyObject> \
|
112
127
|
};
|
113
128
|
|
114
129
|
/*
|
@@ -674,6 +689,22 @@ static ret (*(name)[nm::NUM_DTYPES][nm::NUM_DTYPES][nm::NUM_ITYPES])(__VA_ARGS__
|
|
674
689
|
{ fun<nm::RubyObject,uint8_t>,fun<nm::RubyObject,uint16_t>,fun<nm::RubyObject,uint32_t>,fun<nm::RubyObject,uint64_t>} \
|
675
690
|
};
|
676
691
|
|
692
|
+
#define NAMED_LI_DTYPE_TEMPLATE_TABLE_NO_ROBJ(name, fun, ret, ...) \
|
693
|
+
static ret (*(name)[nm::NUM_DTYPES][nm::NUM_ITYPES])(__VA_ARGS__) = { \
|
694
|
+
{ fun<uint8_t,uint8_t>,fun<uint8_t,uint16_t>,fun<uint8_t,uint32_t>,fun<uint8_t,uint64_t> }, \
|
695
|
+
{ fun<int8_t,uint8_t>,fun<int8_t,uint16_t>,fun<int8_t,uint32_t>,fun<int8_t,uint64_t> }, \
|
696
|
+
{ fun<int16_t,uint8_t>,fun<int16_t,uint16_t>,fun<int16_t,uint32_t>,fun<int16_t,uint64_t> }, \
|
697
|
+
{ fun<int32_t,uint8_t>,fun<int32_t,uint16_t>,fun<int32_t,uint32_t>,fun<int32_t,uint64_t> }, \
|
698
|
+
{ fun<int64_t,uint8_t>,fun<int64_t,uint16_t>,fun<int64_t,uint32_t>,fun<int64_t,uint64_t> }, \
|
699
|
+
{ fun<float32_t,uint8_t>,fun<float32_t,uint16_t>,fun<float32_t,uint32_t>,fun<float32_t,uint64_t> }, \
|
700
|
+
{ fun<float64_t,uint8_t>,fun<float64_t,uint16_t>,fun<float64_t,uint32_t>,fun<float64_t,uint64_t> }, \
|
701
|
+
{ fun<nm::Complex64,uint8_t>,fun<nm::Complex64,uint16_t>,fun<nm::Complex64,uint32_t>,fun<nm::Complex64,uint64_t> }, \
|
702
|
+
{ fun<nm::Complex128,uint8_t>,fun<nm::Complex128,uint16_t>,fun<nm::Complex128,uint32_t>,fun<nm::Complex128,uint64_t> }, \
|
703
|
+
{ fun<nm::Rational32,uint8_t>,fun<nm::Rational32,uint16_t>,fun<nm::Rational32,uint32_t>,fun<nm::Rational32,uint64_t> }, \
|
704
|
+
{ fun<nm::Rational64,uint8_t>,fun<nm::Rational64,uint16_t>,fun<nm::Rational64,uint32_t>,fun<nm::Rational64,uint64_t> }, \
|
705
|
+
{ fun<nm::Rational128,uint8_t>,fun<nm::Rational128,uint16_t>,fun<nm::Rational128,uint32_t>,fun<nm::Rational128,uint64_t> } \
|
706
|
+
};
|
707
|
+
|
677
708
|
|
678
709
|
extern "C" {
|
679
710
|
|
@@ -690,17 +721,17 @@ extern const size_t DTYPE_SIZES[nm::NUM_DTYPES];
|
|
690
721
|
extern const char* const ITYPE_NAMES[nm::NUM_ITYPES];
|
691
722
|
extern const size_t ITYPE_SIZES[nm::NUM_ITYPES];
|
692
723
|
|
693
|
-
extern const dtype_t
|
724
|
+
extern const nm::dtype_t Upcast[nm::NUM_DTYPES][nm::NUM_DTYPES];
|
694
725
|
|
695
726
|
/*
|
696
727
|
* Functions
|
697
728
|
*/
|
698
729
|
|
699
730
|
|
700
|
-
void* rubyobj_to_cval(VALUE val, dtype_t dtype);
|
701
|
-
void rubyval_to_cval(VALUE val, dtype_t dtype, void* loc);
|
702
|
-
nm::RubyObject rubyobj_from_cval(void* val, dtype_t dtype);
|
703
|
-
nm::RubyObject rubyobj_from_cval_by_itype(void* val, itype_t itype);
|
731
|
+
void* rubyobj_to_cval(VALUE val, nm::dtype_t dtype);
|
732
|
+
void rubyval_to_cval(VALUE val, nm::dtype_t dtype, void* loc);
|
733
|
+
nm::RubyObject rubyobj_from_cval(void* val, nm::dtype_t dtype);
|
734
|
+
nm::RubyObject rubyobj_from_cval_by_itype(void* val, nm::itype_t itype);
|
704
735
|
|
705
736
|
} // end of extern "C" block
|
706
737
|
|
data/ext/nmatrix/data/rational.h
CHANGED
@@ -304,6 +304,12 @@ class Rational {
|
|
304
304
|
}
|
305
305
|
};
|
306
306
|
|
307
|
+
// Negative operator
|
308
|
+
template <typename Type, typename = typename std::enable_if<std::is_integral<Type>::value>::type>
|
309
|
+
inline Rational<Type> operator-(const Rational<Type>& rhs) {
|
310
|
+
return Rational<Type>(-rhs.n, rhs.d);
|
311
|
+
}
|
312
|
+
|
307
313
|
////////////////////////////////
|
308
314
|
// Native-Rational Operations //
|
309
315
|
////////////////////////////////
|
@@ -416,6 +422,13 @@ namespace std {
|
|
416
422
|
if (value.n >= 0) return value;
|
417
423
|
return nm::Rational<IntType>(-value.n, value.d);
|
418
424
|
}
|
425
|
+
|
426
|
+
template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
427
|
+
nm::Rational<IntType> sqrt(const nm::Rational<IntType>& value) {
|
428
|
+
nm::Rational<IntType> result(std::sqrt(value.n), std::sqrt(value.d));
|
429
|
+
if (value * value == result) return result;
|
430
|
+
else rb_raise(rb_eArgError, "square root of the given rational is not rational");
|
431
|
+
}
|
419
432
|
}
|
420
433
|
|
421
434
|
#endif // RATIONAL_H
|
@@ -319,6 +319,11 @@ class RubyObject {
|
|
319
319
|
}
|
320
320
|
};
|
321
321
|
|
322
|
+
// Negative operator
|
323
|
+
inline RubyObject operator-(const RubyObject& rhs) {
|
324
|
+
return RubyObject(rb_funcall(rhs.rval, nm_rb_negate, 0));
|
325
|
+
}
|
326
|
+
|
322
327
|
|
323
328
|
////////////////////////////
|
324
329
|
// NATIVE-RUBY OPERATIONS //
|
@@ -441,6 +446,11 @@ namespace std {
|
|
441
446
|
inline nm::RubyObject abs(const nm::RubyObject& obj) {
|
442
447
|
return obj.abs();
|
443
448
|
}
|
449
|
+
|
450
|
+
inline nm::RubyObject sqrt(const nm::RubyObject& obj) {
|
451
|
+
VALUE cMath = rb_const_get(rb_cObject, rb_intern("Math"));
|
452
|
+
return nm::RubyObject(rb_funcall(cMath, rb_intern("sqrt"), 1, obj.rval));
|
453
|
+
}
|
444
454
|
}
|
445
455
|
|
446
456
|
#endif // RUBY_OBJECT_H
|