nmatrix 0.2.0 → 0.2.1
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.
- checksums.yaml +4 -4
- data/ext/nmatrix/data/complex.h +183 -159
- data/ext/nmatrix/data/data.cpp +113 -112
- data/ext/nmatrix/data/data.h +306 -292
- data/ext/nmatrix/data/ruby_object.h +193 -193
- data/ext/nmatrix/extconf.rb +11 -9
- data/ext/nmatrix/math.cpp +9 -11
- data/ext/nmatrix/math/math.h +3 -2
- data/ext/nmatrix/math/trsm.h +152 -152
- data/ext/nmatrix/nmatrix.h +30 -0
- data/ext/nmatrix/ruby_constants.cpp +67 -67
- data/ext/nmatrix/ruby_constants.h +35 -35
- data/ext/nmatrix/ruby_nmatrix.c +168 -183
- data/ext/nmatrix/storage/common.h +4 -3
- data/ext/nmatrix/storage/dense/dense.cpp +50 -50
- data/ext/nmatrix/storage/dense/dense.h +8 -7
- data/ext/nmatrix/storage/list/list.cpp +16 -16
- data/ext/nmatrix/storage/list/list.h +7 -6
- data/ext/nmatrix/storage/storage.cpp +32 -32
- data/ext/nmatrix/storage/storage.h +12 -11
- data/ext/nmatrix/storage/yale/class.h +2 -2
- data/ext/nmatrix/storage/yale/iterators/base.h +2 -1
- data/ext/nmatrix/storage/yale/iterators/iterator.h +2 -1
- data/ext/nmatrix/storage/yale/iterators/row.h +2 -1
- data/ext/nmatrix/storage/yale/iterators/row_stored.h +2 -1
- data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +1 -0
- data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +2 -1
- data/ext/nmatrix/storage/yale/yale.cpp +27 -27
- data/ext/nmatrix/storage/yale/yale.h +7 -6
- data/ext/nmatrix/ttable_helper.rb +10 -10
- data/ext/nmatrix/types.h +3 -2
- data/ext/nmatrix/util/io.cpp +7 -7
- data/ext/nmatrix/util/sl_list.cpp +26 -26
- data/ext/nmatrix/util/sl_list.h +19 -18
- data/lib/nmatrix/blas.rb +7 -7
- data/lib/nmatrix/io/mat5_reader.rb +30 -30
- data/lib/nmatrix/math.rb +73 -17
- data/lib/nmatrix/nmatrix.rb +10 -8
- data/lib/nmatrix/shortcuts.rb +3 -3
- data/lib/nmatrix/version.rb +3 -3
- data/spec/00_nmatrix_spec.rb +6 -0
- data/spec/math_spec.rb +77 -0
- data/spec/spec_helper.rb +9 -0
- metadata +2 -2
data/ext/nmatrix/nmatrix.h
CHANGED
@@ -57,6 +57,33 @@
|
|
57
57
|
#include "nm_memory.h"
|
58
58
|
#endif
|
59
59
|
|
60
|
+
#ifndef FIX_CONST_VALUE_PTR
|
61
|
+
# if defined(__fcc__) || defined(__fcc_version) || \
|
62
|
+
defined(__FCC__) || defined(__FCC_VERSION)
|
63
|
+
/* workaround for old version of Fujitsu C Compiler (fcc) */
|
64
|
+
# define FIX_CONST_VALUE_PTR(x) ((const VALUE *)(x))
|
65
|
+
# else
|
66
|
+
# define FIX_CONST_VALUE_PTR(x) (x)
|
67
|
+
# endif
|
68
|
+
#endif
|
69
|
+
|
70
|
+
#ifndef HAVE_RB_ARRAY_CONST_PTR
|
71
|
+
static inline const VALUE *
|
72
|
+
rb_array_const_ptr(VALUE a)
|
73
|
+
{
|
74
|
+
return FIX_CONST_VALUE_PTR((RBASIC(a)->flags & RARRAY_EMBED_FLAG) ?
|
75
|
+
RARRAY(a)->as.ary : RARRAY(a)->as.heap.ptr);
|
76
|
+
}
|
77
|
+
#endif
|
78
|
+
|
79
|
+
#ifndef RARRAY_CONST_PTR
|
80
|
+
# define RARRAY_CONST_PTR(a) rb_array_const_ptr(a)
|
81
|
+
#endif
|
82
|
+
|
83
|
+
#ifndef RARRAY_AREF
|
84
|
+
# define RARRAY_AREF(a, i) (RARRAY_CONST_PTR(a)[i])
|
85
|
+
#endif
|
86
|
+
|
60
87
|
/*
|
61
88
|
* Macros
|
62
89
|
*/
|
@@ -323,7 +350,10 @@ NM_DEF_STRUCT_POST(NM_GC_HOLDER); // };
|
|
323
350
|
#define NM_SHAPE1(val) (NM_STORAGE(val)->shape[1])
|
324
351
|
#define NM_DEFAULT_VAL(val) (NM_STORAGE_LIST(val)->default_val)
|
325
352
|
|
353
|
+
// Number of elements in a dense nmatrix.
|
326
354
|
#define NM_DENSE_COUNT(val) (nm_storage_count_max_elements(NM_STORAGE_DENSE(val)))
|
355
|
+
|
356
|
+
// Get a pointer to the array that stores elements in a dense matrix.
|
327
357
|
#define NM_DENSE_ELEMENTS(val) (NM_STORAGE_DENSE(val)->elements)
|
328
358
|
#define NM_SIZEOF_DTYPE(val) (DTYPE_SIZES[NM_DTYPE(val)])
|
329
359
|
#define NM_REF(val,slice) (RefFuncs[NM_STYPE(val)]( NM_STORAGE(val), slice, NM_SIZEOF_DTYPE(val) ))
|
@@ -35,21 +35,21 @@
|
|
35
35
|
* Global Variables
|
36
36
|
*/
|
37
37
|
|
38
|
-
ID
|
38
|
+
ID nm_rb_dtype,
|
39
39
|
nm_rb_stype,
|
40
40
|
|
41
41
|
nm_rb_capacity,
|
42
42
|
nm_rb_default,
|
43
43
|
|
44
44
|
nm_rb_real,
|
45
|
-
|
45
|
+
nm_rb_imag,
|
46
46
|
|
47
|
-
|
48
|
-
|
47
|
+
nm_rb_numer,
|
48
|
+
nm_rb_denom,
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
nm_rb_complex_conjugate,
|
51
|
+
nm_rb_transpose,
|
52
|
+
nm_rb_no_transpose,
|
53
53
|
nm_rb_left,
|
54
54
|
nm_rb_right,
|
55
55
|
nm_rb_upper,
|
@@ -57,41 +57,41 @@ ID nm_rb_dtype,
|
|
57
57
|
nm_rb_unit,
|
58
58
|
nm_rb_nonunit,
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
nm_rb_dense,
|
61
|
+
nm_rb_list,
|
62
|
+
nm_rb_yale,
|
63
63
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
64
|
+
nm_rb_row,
|
65
|
+
nm_rb_column,
|
66
|
+
nm_rb_add,
|
67
|
+
nm_rb_sub,
|
68
|
+
nm_rb_mul,
|
69
|
+
nm_rb_div,
|
70
70
|
nm_rb_both,
|
71
71
|
nm_rb_none,
|
72
72
|
|
73
|
-
|
73
|
+
nm_rb_negate,
|
74
74
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
75
|
+
nm_rb_percent,
|
76
|
+
nm_rb_gt,
|
77
|
+
nm_rb_lt,
|
78
|
+
nm_rb_eql,
|
79
|
+
nm_rb_neql,
|
80
|
+
nm_rb_gte,
|
81
|
+
nm_rb_lte,
|
82
82
|
|
83
|
-
|
83
|
+
nm_rb_hash;
|
84
84
|
|
85
85
|
VALUE cNMatrix,
|
86
86
|
cNMatrix_IO,
|
87
87
|
cNMatrix_IO_Matlab,
|
88
|
-
|
88
|
+
cNMatrix_YaleFunctions,
|
89
89
|
|
90
90
|
cNMatrix_GC_holder,
|
91
91
|
|
92
|
-
|
92
|
+
nm_eDataTypeError,
|
93
93
|
nm_eConvergenceError,
|
94
|
-
|
94
|
+
nm_eStorageTypeError,
|
95
95
|
nm_eShapeError,
|
96
96
|
nm_eNotInvertibleError;
|
97
97
|
|
@@ -106,45 +106,45 @@ void nm_init_ruby_constants(void) {
|
|
106
106
|
nm_rb_capacity = rb_intern("capacity");
|
107
107
|
nm_rb_default = rb_intern("default");
|
108
108
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
109
|
+
nm_rb_real = rb_intern("real");
|
110
|
+
nm_rb_imag = rb_intern("imag");
|
111
|
+
|
112
|
+
nm_rb_numer = rb_intern("numerator");
|
113
|
+
nm_rb_denom = rb_intern("denominator");
|
114
|
+
|
115
|
+
nm_rb_complex_conjugate = rb_intern("complex_conjugate");
|
116
|
+
nm_rb_transpose = rb_intern("transpose");
|
117
|
+
nm_rb_no_transpose = rb_intern("no_transpose");
|
118
|
+
|
119
|
+
nm_rb_dense = rb_intern("dense");
|
120
|
+
nm_rb_list = rb_intern("list");
|
121
|
+
nm_rb_yale = rb_intern("yale");
|
122
|
+
|
123
|
+
nm_rb_add = rb_intern("+");
|
124
|
+
nm_rb_sub = rb_intern("-");
|
125
|
+
nm_rb_mul = rb_intern("*");
|
126
|
+
nm_rb_div = rb_intern("/");
|
127
|
+
|
128
|
+
nm_rb_negate = rb_intern("-@");
|
129
|
+
|
130
|
+
nm_rb_percent = rb_intern("%");
|
131
|
+
nm_rb_gt = rb_intern(">");
|
132
|
+
nm_rb_lt = rb_intern("<");
|
133
|
+
nm_rb_eql = rb_intern("==");
|
134
|
+
nm_rb_neql = rb_intern("!=");
|
135
|
+
nm_rb_gte = rb_intern(">=");
|
136
|
+
nm_rb_lte = rb_intern("<=");
|
137
|
+
|
138
|
+
nm_rb_left = rb_intern("left");
|
139
|
+
nm_rb_right = rb_intern("right");
|
140
|
+
nm_rb_upper = rb_intern("upper");
|
141
|
+
nm_rb_lower = rb_intern("lower");
|
142
|
+
nm_rb_unit = rb_intern("unit");
|
143
|
+
nm_rb_nonunit = rb_intern("nonunit");
|
144
|
+
nm_rb_hash = rb_intern("hash");
|
145
|
+
|
146
|
+
nm_rb_column = rb_intern("column");
|
147
|
+
nm_rb_row = rb_intern("row");
|
148
148
|
|
149
149
|
nm_rb_both = rb_intern("both");
|
150
150
|
nm_rb_none = rb_intern("none");
|
@@ -45,57 +45,57 @@ extern ID nm_rb_dtype,
|
|
45
45
|
nm_rb_default,
|
46
46
|
|
47
47
|
nm_rb_real,
|
48
|
-
|
48
|
+
nm_rb_imag,
|
49
49
|
|
50
|
-
|
51
|
-
|
50
|
+
nm_rb_numer,
|
51
|
+
nm_rb_denom,
|
52
52
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
53
|
+
nm_rb_complex_conjugate,
|
54
|
+
nm_rb_transpose,
|
55
|
+
nm_rb_no_transpose,
|
56
|
+
nm_rb_left,
|
57
|
+
nm_rb_right,
|
58
|
+
nm_rb_upper,
|
59
|
+
nm_rb_lower,
|
60
|
+
nm_rb_unit,
|
61
|
+
nm_rb_nonunit,
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
63
|
+
nm_rb_dense,
|
64
|
+
nm_rb_list,
|
65
|
+
nm_rb_yale,
|
66
66
|
|
67
67
|
nm_rb_row,
|
68
68
|
nm_rb_column,
|
69
69
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
70
|
+
nm_rb_add,
|
71
|
+
nm_rb_sub,
|
72
|
+
nm_rb_mul,
|
73
|
+
nm_rb_div,
|
74
74
|
|
75
|
-
|
75
|
+
nm_rb_negate,
|
76
76
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
77
|
+
nm_rb_percent,
|
78
|
+
nm_rb_gt,
|
79
|
+
nm_rb_lt,
|
80
|
+
nm_rb_eql,
|
81
|
+
nm_rb_neql,
|
82
|
+
nm_rb_gte,
|
83
|
+
nm_rb_lte,
|
84
84
|
|
85
|
-
|
85
|
+
nm_rb_hash;
|
86
86
|
|
87
|
-
extern VALUE
|
87
|
+
extern VALUE cNMatrix,
|
88
88
|
cNMatrix_IO,
|
89
89
|
cNMatrix_IO_Matlab,
|
90
|
-
|
90
|
+
cNMatrix_YaleFunctions,
|
91
91
|
|
92
|
-
|
92
|
+
cNMatrix_GC_holder,
|
93
93
|
|
94
|
-
|
94
|
+
nm_eDataTypeError,
|
95
95
|
nm_eConvergenceError,
|
96
|
-
|
97
|
-
|
98
|
-
|
96
|
+
nm_eStorageTypeError,
|
97
|
+
nm_eShapeError,
|
98
|
+
nm_eNotInvertibleError;
|
99
99
|
|
100
100
|
/*
|
101
101
|
* Functions
|
data/ext/nmatrix/ruby_nmatrix.c
CHANGED
@@ -159,13 +159,12 @@ static VALUE nm_hessenberg(VALUE self, VALUE a);
|
|
159
159
|
static VALUE nm_inverse(VALUE self, VALUE inverse, VALUE bang);
|
160
160
|
static VALUE nm_inverse_exact(VALUE self, VALUE inverse, VALUE lda, VALUE ldb);
|
161
161
|
static VALUE nm_complex_conjugate_bang(VALUE self);
|
162
|
-
static VALUE nm_complex_conjugate(VALUE self);
|
163
162
|
static VALUE nm_reshape_bang(VALUE self, VALUE arg);
|
164
163
|
|
165
|
-
static nm::dtype_t
|
166
|
-
static void*
|
167
|
-
static size_t*
|
168
|
-
static nm::stype_t
|
164
|
+
static nm::dtype_t interpret_dtype(int argc, VALUE* argv, nm::stype_t stype);
|
165
|
+
static void* interpret_initial_value(VALUE arg, nm::dtype_t dtype);
|
166
|
+
static size_t* interpret_shape(VALUE arg, size_t* dim);
|
167
|
+
static nm::stype_t interpret_stype(VALUE arg);
|
169
168
|
|
170
169
|
/* Singleton methods */
|
171
170
|
static VALUE nm_upcast(VALUE self, VALUE t1, VALUE t2);
|
@@ -182,28 +181,28 @@ static double get_time(void);
|
|
182
181
|
void Init_nmatrix() {
|
183
182
|
|
184
183
|
|
185
|
-
|
186
|
-
|
187
|
-
|
184
|
+
///////////////////////
|
185
|
+
// Class Definitions //
|
186
|
+
///////////////////////
|
188
187
|
|
189
|
-
|
188
|
+
cNMatrix = rb_define_class("NMatrix", rb_cObject);
|
190
189
|
|
191
|
-
|
190
|
+
// Special exceptions
|
192
191
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
192
|
+
/*
|
193
|
+
* Exception raised when there's a problem with data.
|
194
|
+
*/
|
195
|
+
nm_eDataTypeError = rb_define_class("DataTypeError", rb_eStandardError);
|
197
196
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
197
|
+
/*
|
198
|
+
* Exception raised when something goes wrong with the storage of a matrix.
|
199
|
+
*/
|
200
|
+
nm_eStorageTypeError = rb_define_class("StorageTypeError", rb_eStandardError);
|
202
201
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
202
|
+
/*
|
203
|
+
* Exception raise when the matrix shape is not appropriate for a given operation.
|
204
|
+
*/
|
205
|
+
nm_eShapeError = rb_define_class("ShapeError", rb_eStandardError);
|
207
206
|
|
208
207
|
/*
|
209
208
|
* Exception raise when an inverse is requested but the matrix is not invertible.
|
@@ -217,57 +216,56 @@ void Init_nmatrix() {
|
|
217
216
|
cNMatrix_GC_holder = rb_define_class("NMGCHolder", rb_cObject);
|
218
217
|
|
219
218
|
|
220
|
-
|
221
|
-
|
222
|
-
|
219
|
+
///////////////////
|
220
|
+
// Class Methods //
|
221
|
+
///////////////////
|
223
222
|
|
224
|
-
|
223
|
+
rb_define_alloc_func(cNMatrix, nm_alloc);
|
225
224
|
|
226
|
-
|
225
|
+
///////////////////////
|
227
226
|
// Singleton Methods //
|
228
227
|
///////////////////////
|
229
228
|
|
230
|
-
|
231
|
-
|
232
|
-
|
229
|
+
rb_define_singleton_method(cNMatrix, "upcast", (METHOD)nm_upcast, 2); /* in ext/nmatrix/nmatrix.cpp */
|
230
|
+
rb_define_singleton_method(cNMatrix, "guess_dtype", (METHOD)nm_guess_dtype, 1);
|
231
|
+
rb_define_singleton_method(cNMatrix, "min_dtype", (METHOD)nm_min_dtype, 1);
|
233
232
|
|
234
|
-
|
235
|
-
|
236
|
-
|
233
|
+
//////////////////////
|
234
|
+
// Instance Methods //
|
235
|
+
//////////////////////
|
237
236
|
|
238
|
-
|
239
|
-
|
240
|
-
|
237
|
+
rb_define_method(cNMatrix, "initialize", (METHOD)nm_init, -1);
|
238
|
+
rb_define_method(cNMatrix, "initialize_copy", (METHOD)nm_init_copy, 1);
|
239
|
+
rb_define_singleton_method(cNMatrix, "read", (METHOD)nm_read, -1);
|
241
240
|
|
242
|
-
|
241
|
+
rb_define_method(cNMatrix, "write", (METHOD)nm_write, -1);
|
243
242
|
|
244
|
-
|
245
|
-
|
243
|
+
// Technically, the following function is a copy constructor.
|
244
|
+
rb_define_protected_method(cNMatrix, "clone_transpose", (METHOD)nm_init_transposed, 0);
|
246
245
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
246
|
+
rb_define_method(cNMatrix, "dtype", (METHOD)nm_dtype, 0);
|
247
|
+
rb_define_method(cNMatrix, "stype", (METHOD)nm_stype, 0);
|
248
|
+
rb_define_method(cNMatrix, "cast_full", (METHOD)nm_cast, 3);
|
249
|
+
rb_define_method(cNMatrix, "default_value", (METHOD)nm_default_value, 0);
|
250
|
+
rb_define_protected_method(cNMatrix, "__list_default_value__", (METHOD)nm_list_default_value, 0);
|
251
|
+
rb_define_protected_method(cNMatrix, "__yale_default_value__", (METHOD)nm_yale_default_value, 0);
|
253
252
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
253
|
+
rb_define_method(cNMatrix, "[]", (METHOD)nm_mref, -1);
|
254
|
+
rb_define_method(cNMatrix, "slice", (METHOD)nm_mget, -1);
|
255
|
+
rb_define_method(cNMatrix, "[]=", (METHOD)nm_mset, -1);
|
256
|
+
rb_define_method(cNMatrix, "is_ref?", (METHOD)nm_is_ref, 0);
|
257
|
+
rb_define_method(cNMatrix, "dimensions", (METHOD)nm_dim, 0);
|
258
|
+
rb_define_method(cNMatrix, "effective_dimensions", (METHOD)nm_effective_dim, 0);
|
260
259
|
|
261
|
-
|
260
|
+
rb_define_protected_method(cNMatrix, "__list_to_hash__", (METHOD)nm_to_hash, 0); // handles list and dense, which are n-dimensional
|
262
261
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
262
|
+
rb_define_method(cNMatrix, "shape", (METHOD)nm_shape, 0);
|
263
|
+
rb_define_method(cNMatrix, "supershape", (METHOD)nm_supershape, 0);
|
264
|
+
rb_define_method(cNMatrix, "offset", (METHOD)nm_offset, 0);
|
265
|
+
rb_define_method(cNMatrix, "det_exact", (METHOD)nm_det_exact, 0);
|
267
266
|
rb_define_method(cNMatrix, "complex_conjugate!", (METHOD)nm_complex_conjugate_bang, 0);
|
268
|
-
rb_define_method(cNMatrix, "complex_conjugate", (METHOD)nm_complex_conjugate, 0);
|
269
267
|
|
270
|
-
|
268
|
+
rb_define_protected_method(cNMatrix, "reshape_bang", (METHOD)nm_reshape_bang, 1);
|
271
269
|
|
272
270
|
// Iterators public methods
|
273
271
|
rb_define_method(cNMatrix, "each_with_indices", (METHOD)nm_each_with_indices, 0);
|
@@ -276,22 +274,22 @@ void Init_nmatrix() {
|
|
276
274
|
rb_define_method(cNMatrix, "each_ordered_stored_with_indices", (METHOD)nm_each_ordered_stored_with_indices, 0);
|
277
275
|
|
278
276
|
// Iterators protected methods
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
rb_define_method(cNMatrix, "*",
|
294
|
-
|
277
|
+
rb_define_protected_method(cNMatrix, "__dense_each__", (METHOD)nm_dense_each, 0);
|
278
|
+
rb_define_protected_method(cNMatrix, "__dense_map__", (METHOD)nm_dense_map, 0);
|
279
|
+
rb_define_protected_method(cNMatrix, "__dense_map_pair__", (METHOD)nm_dense_map_pair, 1);
|
280
|
+
rb_define_protected_method(cNMatrix, "__list_map_merged_stored__", (METHOD)nm_list_map_merged_stored, 2);
|
281
|
+
rb_define_protected_method(cNMatrix, "__list_map_stored__", (METHOD)nm_list_map_stored, 1);
|
282
|
+
rb_define_protected_method(cNMatrix, "__yale_map_merged_stored__", (METHOD)nm_yale_map_merged_stored, 2);
|
283
|
+
rb_define_protected_method(cNMatrix, "__yale_map_stored__", (METHOD)nm_yale_map_stored, 0);
|
284
|
+
rb_define_protected_method(cNMatrix, "__yale_stored_diagonal_each_with_indices__", (METHOD)nm_yale_stored_diagonal_each_with_indices, 0);
|
285
|
+
rb_define_protected_method(cNMatrix, "__yale_stored_nondiagonal_each_with_indices__", (METHOD)nm_yale_stored_nondiagonal_each_with_indices, 0);
|
286
|
+
|
287
|
+
rb_define_method(cNMatrix, "==", (METHOD)nm_eqeq, 1);
|
288
|
+
|
289
|
+
rb_define_method(cNMatrix, "+", (METHOD)nm_ew_add, 1);
|
290
|
+
rb_define_method(cNMatrix, "-", (METHOD)nm_ew_subtract, 1);
|
291
|
+
rb_define_method(cNMatrix, "*", (METHOD)nm_ew_multiply, 1);
|
292
|
+
rb_define_method(cNMatrix, "/", (METHOD)nm_ew_divide, 1);
|
295
293
|
rb_define_method(cNMatrix, "**", (METHOD)nm_ew_power, 1);
|
296
294
|
rb_define_method(cNMatrix, "%", (METHOD)nm_ew_mod, 1);
|
297
295
|
|
@@ -326,25 +324,25 @@ void Init_nmatrix() {
|
|
326
324
|
rb_define_method(cNMatrix, "round", (METHOD)nm_unary_round, -1);
|
327
325
|
|
328
326
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
327
|
+
rb_define_method(cNMatrix, "=~", (METHOD)nm_ew_eqeq, 1);
|
328
|
+
rb_define_method(cNMatrix, "!~", (METHOD)nm_ew_neq, 1);
|
329
|
+
rb_define_method(cNMatrix, "<=", (METHOD)nm_ew_leq, 1);
|
330
|
+
rb_define_method(cNMatrix, ">=", (METHOD)nm_ew_geq, 1);
|
331
|
+
rb_define_method(cNMatrix, "<", (METHOD)nm_ew_lt, 1);
|
332
|
+
rb_define_method(cNMatrix, ">", (METHOD)nm_ew_gt, 1);
|
335
333
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
334
|
+
/////////////////////////////
|
335
|
+
// Helper Instance Methods //
|
336
|
+
/////////////////////////////
|
337
|
+
rb_define_protected_method(cNMatrix, "__yale_vector_set__", (METHOD)nm_vector_set, -1);
|
340
338
|
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
339
|
+
/////////////////////////
|
340
|
+
// Matrix Math Methods //
|
341
|
+
/////////////////////////
|
342
|
+
rb_define_method(cNMatrix, "dot", (METHOD)nm_multiply, 1);
|
343
|
+
rb_define_method(cNMatrix, "symmetric?", (METHOD)nm_symmetric, 0);
|
344
|
+
rb_define_method(cNMatrix, "hermitian?", (METHOD)nm_hermitian, 0);
|
345
|
+
rb_define_method(cNMatrix, "capacity", (METHOD)nm_capacity, 0);
|
348
346
|
|
349
347
|
// protected methods
|
350
348
|
rb_define_protected_method(cNMatrix, "__inverse__", (METHOD)nm_inverse, 2);
|
@@ -353,46 +351,46 @@ void Init_nmatrix() {
|
|
353
351
|
// private methods
|
354
352
|
rb_define_private_method(cNMatrix, "__hessenberg__", (METHOD)nm_hessenberg, 1);
|
355
353
|
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
354
|
+
/////////////////
|
355
|
+
// FFI Methods //
|
356
|
+
/////////////////
|
357
|
+
rb_define_method(cNMatrix, "data_pointer", (METHOD)nm_data_pointer, 0);
|
360
358
|
|
361
|
-
|
362
|
-
|
363
|
-
|
359
|
+
/////////////
|
360
|
+
// Aliases //
|
361
|
+
/////////////
|
364
362
|
|
365
|
-
|
366
|
-
|
367
|
-
|
363
|
+
rb_define_alias(cNMatrix, "dim", "dimensions");
|
364
|
+
rb_define_alias(cNMatrix, "effective_dim", "effective_dimensions");
|
365
|
+
rb_define_alias(cNMatrix, "equal?", "eql?");
|
368
366
|
|
369
|
-
|
370
|
-
|
371
|
-
|
367
|
+
///////////////////////
|
368
|
+
// Symbol Generation //
|
369
|
+
///////////////////////
|
372
370
|
|
373
|
-
|
371
|
+
nm_init_ruby_constants();
|
374
372
|
|
375
|
-
|
376
|
-
|
377
|
-
|
373
|
+
//////////////////////////
|
374
|
+
// YaleFunctions module //
|
375
|
+
//////////////////////////
|
378
376
|
|
379
|
-
|
377
|
+
nm_init_yale_functions();
|
380
378
|
|
381
|
-
|
382
|
-
|
383
|
-
|
379
|
+
/////////////////
|
380
|
+
// BLAS module //
|
381
|
+
/////////////////
|
384
382
|
|
385
|
-
|
383
|
+
nm_math_init_blas();
|
386
384
|
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
385
|
+
///////////////
|
386
|
+
// IO module //
|
387
|
+
///////////////
|
388
|
+
nm_init_io();
|
391
389
|
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
390
|
+
/////////////////////////////////////////////////
|
391
|
+
// Force compilation of necessary constructors //
|
392
|
+
/////////////////////////////////////////////////
|
393
|
+
nm_init_data();
|
396
394
|
}
|
397
395
|
|
398
396
|
|
@@ -1083,19 +1081,6 @@ static VALUE nm_complex_conjugate_bang(VALUE self) {
|
|
1083
1081
|
return self;
|
1084
1082
|
}
|
1085
1083
|
|
1086
|
-
/*
|
1087
|
-
* call-seq:
|
1088
|
-
* complex_conjugate -> NMatrix
|
1089
|
-
*
|
1090
|
-
* Transform the matrix (non-in-place) to its complex conjugate. Only works on complex matrices.
|
1091
|
-
*
|
1092
|
-
*/
|
1093
|
-
static VALUE nm_complex_conjugate(VALUE self) {
|
1094
|
-
VALUE copy;
|
1095
|
-
return nm_complex_conjugate_bang(nm_init_copy(copy,self));
|
1096
|
-
}
|
1097
|
-
|
1098
|
-
|
1099
1084
|
/*
|
1100
1085
|
* call-seq:
|
1101
1086
|
* __reshape!__ -> NMatrix
|
@@ -1231,7 +1216,7 @@ static VALUE nm_init_new_version(int argc, VALUE* argv, VALUE self) {
|
|
1231
1216
|
|
1232
1217
|
if (!NIL_P(initial_ary)) {
|
1233
1218
|
|
1234
|
-
if (TYPE(initial_ary) == T_ARRAY)
|
1219
|
+
if (TYPE(initial_ary) == T_ARRAY) v_size = RARRAY_LEN(initial_ary);
|
1235
1220
|
else v_size = 1;
|
1236
1221
|
|
1237
1222
|
v = interpret_initial_value(initial_ary, dtype);
|
@@ -1373,7 +1358,7 @@ static VALUE nm_init(int argc, VALUE* argv, VALUE nm) {
|
|
1373
1358
|
if (argc <= 3) { // Call the new constructor unless all four arguments are given (or the 7-arg version is given)
|
1374
1359
|
NM_CONSERVATIVE(nm_unregister_values(argv, argc));
|
1375
1360
|
NM_CONSERVATIVE(nm_unregister_value(&nm));
|
1376
|
-
|
1361
|
+
return nm_init_new_version(argc, argv, nm);
|
1377
1362
|
}
|
1378
1363
|
|
1379
1364
|
/* First, determine stype (dense by default) */
|
@@ -1413,36 +1398,36 @@ static VALUE nm_init(int argc, VALUE* argv, VALUE nm) {
|
|
1413
1398
|
size_t init_cap = 0, init_val_len = 0;
|
1414
1399
|
void* init_val = NULL;
|
1415
1400
|
if (!SYMBOL_P(argv[1+offset]) || TYPE(argv[1+offset]) == T_ARRAY) {
|
1416
|
-
|
1401
|
+
// Initial value provided (could also be initial capacity, if yale).
|
1417
1402
|
|
1418
1403
|
if (stype == nm::YALE_STORE && NM_RUBYVAL_IS_NUMERIC(argv[1+offset])) {
|
1419
1404
|
init_cap = FIX2UINT(argv[1+offset]);
|
1420
1405
|
|
1421
1406
|
} else {
|
1422
|
-
|
1407
|
+
// 4: initial value / dtype
|
1423
1408
|
init_val = interpret_initial_value(argv[1+offset], dtype);
|
1424
1409
|
|
1425
|
-
if (TYPE(argv[1+offset]) == T_ARRAY)
|
1410
|
+
if (TYPE(argv[1+offset]) == T_ARRAY) init_val_len = RARRAY_LEN(argv[1+offset]);
|
1426
1411
|
else init_val_len = 1;
|
1427
1412
|
}
|
1428
1413
|
|
1429
1414
|
} else {
|
1430
|
-
|
1415
|
+
// DType is RUBYOBJ.
|
1431
1416
|
|
1432
1417
|
if (stype == nm::DENSE_STORE) {
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1418
|
+
/*
|
1419
|
+
* No need to initialize dense with any kind of default value unless it's
|
1420
|
+
* an RUBYOBJ matrix.
|
1421
|
+
*/
|
1437
1422
|
if (dtype == nm::RUBYOBJ) {
|
1438
|
-
|
1439
|
-
|
1423
|
+
// Pretend [nil] was passed for RUBYOBJ.
|
1424
|
+
init_val = NM_ALLOC(VALUE);
|
1440
1425
|
*(VALUE*)init_val = Qnil;
|
1441
1426
|
|
1442
1427
|
init_val_len = 1;
|
1443
1428
|
|
1444
1429
|
} else {
|
1445
|
-
|
1430
|
+
init_val = NULL;
|
1446
1431
|
}
|
1447
1432
|
} else if (stype == nm::LIST_STORE) {
|
1448
1433
|
init_val = NM_ALLOC_N(char, DTYPE_SIZES[dtype]);
|
@@ -2281,7 +2266,7 @@ static VALUE nm_xslice(int argc, VALUE* argv, void* (*slice_func)(const STORAGE*
|
|
2281
2266
|
};
|
2282
2267
|
|
2283
2268
|
if (NM_DTYPE(self) == nm::RUBYOBJ) result = *reinterpret_cast<VALUE*>( ttable[NM_STYPE(self)](s, slice) );
|
2284
|
-
else result = rubyobj_from_cval( ttable[NM_STYPE(self)](s, slice), NM_DTYPE(self) ).rval;
|
2269
|
+
else result = nm::rubyobj_from_cval( ttable[NM_STYPE(self)](s, slice), NM_DTYPE(self) ).rval;
|
2285
2270
|
|
2286
2271
|
} else {
|
2287
2272
|
|
@@ -2471,9 +2456,9 @@ static VALUE noncom_elementwise_op(nm::noncom_ewop_t op, VALUE self, VALUE other
|
|
2471
2456
|
sym = "__list_elementwise_" + nm::NONCOM_EWOP_NAMES[op] + "__";
|
2472
2457
|
break;
|
2473
2458
|
default:
|
2474
|
-
|
2475
|
-
|
2476
|
-
|
2459
|
+
NM_CONSERVATIVE(nm_unregister_value(&self));
|
2460
|
+
NM_CONSERVATIVE(nm_unregister_value(&other));
|
2461
|
+
rb_raise(rb_eNotImpError, "unknown storage type requested element-wise operation");
|
2477
2462
|
}
|
2478
2463
|
NM_CONSERVATIVE(nm_unregister_value(&self));
|
2479
2464
|
NM_CONSERVATIVE(nm_unregister_value(&other));
|
@@ -2645,13 +2630,13 @@ nm::dtype_t nm_dtype_guess(VALUE v) {
|
|
2645
2630
|
#endif
|
2646
2631
|
|
2647
2632
|
case T_ARRAY:
|
2648
|
-
|
2649
|
-
|
2633
|
+
/*
|
2634
|
+
* May be passed for dense -- for now, just look at the first element.
|
2650
2635
|
*
|
2651
|
-
|
2652
|
-
|
2636
|
+
* TODO: Look at entire array for most specific type.
|
2637
|
+
*/
|
2653
2638
|
|
2654
|
-
return nm_dtype_guess(
|
2639
|
+
return nm_dtype_guess(RARRAY_AREF(v, 0));
|
2655
2640
|
|
2656
2641
|
default:
|
2657
2642
|
RB_P(v);
|
@@ -2772,30 +2757,30 @@ static nm::dtype_t interpret_dtype(int argc, VALUE* argv, nm::stype_t stype) {
|
|
2772
2757
|
int offset;
|
2773
2758
|
|
2774
2759
|
switch (argc) {
|
2775
|
-
|
2776
|
-
|
2777
|
-
|
2760
|
+
case 1:
|
2761
|
+
offset = 0;
|
2762
|
+
break;
|
2778
2763
|
|
2779
|
-
|
2780
|
-
|
2781
|
-
|
2764
|
+
case 2:
|
2765
|
+
offset = 1;
|
2766
|
+
break;
|
2782
2767
|
|
2783
|
-
|
2784
|
-
|
2785
|
-
|
2768
|
+
default:
|
2769
|
+
rb_raise(rb_eArgError, "Need an initial value or a dtype.");
|
2770
|
+
break;
|
2786
2771
|
}
|
2787
2772
|
|
2788
2773
|
if (SYMBOL_P(argv[offset])) {
|
2789
|
-
|
2774
|
+
return nm_dtype_from_rbsymbol(argv[offset]);
|
2790
2775
|
|
2791
2776
|
} else if (TYPE(argv[offset]) == T_STRING) {
|
2792
|
-
|
2777
|
+
return nm_dtype_from_rbstring(StringValue(argv[offset]));
|
2793
2778
|
|
2794
2779
|
} else if (stype == nm::YALE_STORE) {
|
2795
|
-
|
2780
|
+
rb_raise(rb_eArgError, "Yale storage class requires a dtype.");
|
2796
2781
|
|
2797
2782
|
} else {
|
2798
|
-
|
2783
|
+
return nm_dtype_guess(argv[0]);
|
2799
2784
|
}
|
2800
2785
|
}
|
2801
2786
|
|
@@ -2809,15 +2794,15 @@ static void* interpret_initial_value(VALUE arg, nm::dtype_t dtype) {
|
|
2809
2794
|
void* init_val;
|
2810
2795
|
|
2811
2796
|
if (TYPE(arg) == T_ARRAY) {
|
2812
|
-
|
2797
|
+
// Array
|
2813
2798
|
init_val = NM_ALLOC_N(char, DTYPE_SIZES[dtype] * RARRAY_LEN(arg));
|
2814
2799
|
NM_CHECK_ALLOC(init_val);
|
2815
2800
|
for (index = 0; index < RARRAY_LEN(arg); ++index) {
|
2816
|
-
|
2801
|
+
rubyval_to_cval(RARRAY_AREF(arg, index), dtype, (char*)init_val + (index * DTYPE_SIZES[dtype]));
|
2817
2802
|
}
|
2818
2803
|
|
2819
2804
|
} else {
|
2820
|
-
|
2805
|
+
// Single value
|
2821
2806
|
init_val = rubyobj_to_cval(arg, dtype);
|
2822
2807
|
}
|
2823
2808
|
|
@@ -2840,7 +2825,7 @@ static size_t* interpret_shape(VALUE arg, size_t* dim) {
|
|
2840
2825
|
shape = NM_ALLOC_N(size_t, *dim);
|
2841
2826
|
|
2842
2827
|
for (size_t index = 0; index < *dim; ++index) {
|
2843
|
-
shape[index] = FIX2UINT(
|
2828
|
+
shape[index] = FIX2UINT( RARRAY_AREF(arg, index) );
|
2844
2829
|
}
|
2845
2830
|
|
2846
2831
|
} else if (FIXNUM_P(arg)) {
|
@@ -2864,13 +2849,13 @@ static size_t* interpret_shape(VALUE arg, size_t* dim) {
|
|
2864
2849
|
*/
|
2865
2850
|
static nm::stype_t interpret_stype(VALUE arg) {
|
2866
2851
|
if (SYMBOL_P(arg)) {
|
2867
|
-
|
2852
|
+
return nm_stype_from_rbsymbol(arg);
|
2868
2853
|
|
2869
2854
|
} else if (TYPE(arg) == T_STRING) {
|
2870
|
-
|
2855
|
+
return nm_stype_from_rbstring(StringValue(arg));
|
2871
2856
|
|
2872
2857
|
} else {
|
2873
|
-
|
2858
|
+
rb_raise(rb_eArgError, "Expected storage type");
|
2874
2859
|
}
|
2875
2860
|
}
|
2876
2861
|
|
@@ -3062,7 +3047,7 @@ static VALUE nm_det_exact(VALUE self) {
|
|
3062
3047
|
if (dtype == nm::RUBYOBJ) {
|
3063
3048
|
nm_register_values(reinterpret_cast<VALUE*>(result), 1);
|
3064
3049
|
}
|
3065
|
-
VALUE to_return = rubyobj_from_cval(result, NM_DTYPE(self)).rval;
|
3050
|
+
VALUE to_return = nm::rubyobj_from_cval(result, NM_DTYPE(self)).rval;
|
3066
3051
|
if (dtype == nm::RUBYOBJ) {
|
3067
3052
|
nm_unregister_values(reinterpret_cast<VALUE*>(result), 1);
|
3068
3053
|
}
|
@@ -3116,14 +3101,14 @@ VALUE rb_nmatrix_dense_create(nm::dtype_t dtype, size_t* shape, size_t dim, void
|
|
3116
3101
|
|
3117
3102
|
// Do not allow a dim of 1. Treat it as a column or row matrix.
|
3118
3103
|
if (dim == 1) {
|
3119
|
-
nm_dim
|
3120
|
-
shape_copy
|
3121
|
-
shape_copy[0]
|
3122
|
-
shape_copy[1]
|
3104
|
+
nm_dim = 2;
|
3105
|
+
shape_copy = NM_ALLOC_N(size_t, nm_dim);
|
3106
|
+
shape_copy[0] = shape[0];
|
3107
|
+
shape_copy[1] = 1;
|
3123
3108
|
|
3124
3109
|
} else {
|
3125
|
-
nm_dim
|
3126
|
-
shape_copy
|
3110
|
+
nm_dim = dim;
|
3111
|
+
shape_copy = NM_ALLOC_N(size_t, nm_dim);
|
3127
3112
|
memcpy(shape_copy, shape, sizeof(size_t)*nm_dim);
|
3128
3113
|
}
|
3129
3114
|
|