nmatrix 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|