nmatrix 0.2.3 → 0.2.4
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/ruby_object.h +1 -1
- data/ext/nmatrix/math.cpp +274 -33
- data/ext/nmatrix/math/math.h +8 -2
- data/ext/nmatrix/ruby_nmatrix.c +81 -65
- data/lib/nmatrix/blas.rb +6 -2
- data/lib/nmatrix/cruby/math.rb +744 -0
- data/lib/nmatrix/enumerate.rb +3 -2
- data/lib/nmatrix/jruby/decomposition.rb +24 -0
- data/lib/nmatrix/jruby/enumerable.rb +13 -0
- data/lib/nmatrix/jruby/error.rb +4 -0
- data/lib/nmatrix/jruby/math.rb +501 -0
- data/lib/nmatrix/jruby/nmatrix_java.rb +840 -0
- data/lib/nmatrix/jruby/operators.rb +283 -0
- data/lib/nmatrix/jruby/slice.rb +264 -0
- data/lib/nmatrix/math.rb +233 -635
- data/lib/nmatrix/mkmf.rb +6 -9
- data/lib/nmatrix/monkeys.rb +2 -4
- data/lib/nmatrix/nmatrix.rb +62 -32
- data/lib/nmatrix/shortcuts.rb +8 -3
- data/lib/nmatrix/version.rb +1 -1
- data/spec/00_nmatrix_spec.rb +110 -3
- data/spec/01_enum_spec.rb +7 -1
- data/spec/02_slice_spec.rb +19 -1
- data/spec/03_nmatrix_monkeys_spec.rb +2 -0
- data/spec/elementwise_spec.rb +10 -2
- data/spec/homogeneous_spec.rb +1 -0
- data/spec/io_spec.rb +11 -1
- data/spec/math_spec.rb +346 -102
- data/spec/rspec_spec.rb +1 -0
- data/spec/shortcuts_spec.rb +47 -23
- data/spec/slice_set_spec.rb +7 -2
- data/spec/stat_spec.rb +11 -0
- metadata +20 -41
- data/ext/nmatrix/ttable_helper.rb +0 -115
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f0860add5c9502fe90139d362beaf61c116b07a9
|
4
|
+
data.tar.gz: c3880411c97cdf56a9bff9e2b35df05cf218f2c7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9e8f203ce54fb5a53fef9011b6ba6fed3b4080e0d28364625ef63892cb5381153cb0aef6e5e6d1ad9d286f0df588f591263cd9f50872df543fba146da58ce73
|
7
|
+
data.tar.gz: 0c4e726871ca3c69d4b522acd9c5c05caba55bcce54339330762ca39d100c9159730ae16430f3319e9042e09b9a76b6d7cb54cb1b0bdfe77e1d25ad1f1693e79
|
@@ -110,7 +110,7 @@ class RubyObject {
|
|
110
110
|
inline operator VALUE() const { return rval; }
|
111
111
|
//inline operator uint32_t() const { return NUM2ULONG(this->rval); }
|
112
112
|
inline operator int64_t() const { RETURN_OBJ2NUM(NUM2LONG) }
|
113
|
-
inline operator uint64_t() const { RETURN_OBJ2NUM(NUM2ULONG) }
|
113
|
+
//inline operator uint64_t() const { RETURN_OBJ2NUM(NUM2ULONG) }
|
114
114
|
inline operator double() const { RETURN_OBJ2NUM(NUM2DBL) }
|
115
115
|
inline operator float() const { RETURN_OBJ2NUM(NUM2DBL) }
|
116
116
|
|
data/ext/nmatrix/math.cpp
CHANGED
@@ -188,14 +188,14 @@ extern "C" {
|
|
188
188
|
// Math Functions //
|
189
189
|
////////////////////
|
190
190
|
|
191
|
-
namespace nm {
|
191
|
+
namespace nm {
|
192
192
|
namespace math {
|
193
193
|
|
194
194
|
/*
|
195
195
|
* Calculate the determinant for a dense matrix (A [elements]) of size 2 or 3. Return the result.
|
196
196
|
*/
|
197
197
|
template <typename DType>
|
198
|
-
void
|
198
|
+
void det_exact_from_dense(const int M, const void* A_elements, const int lda, void* result_arg) {
|
199
199
|
DType* result = reinterpret_cast<DType*>(result_arg);
|
200
200
|
const DType* A = reinterpret_cast<const DType*>(A_elements);
|
201
201
|
|
@@ -203,7 +203,6 @@ namespace nm {
|
|
203
203
|
|
204
204
|
if (M == 2) {
|
205
205
|
*result = A[0] * A[lda+1] - A[1] * A[lda];
|
206
|
-
|
207
206
|
} else if (M == 3) {
|
208
207
|
x = A[lda+1] * A[2*lda+2] - A[lda+2] * A[2*lda+1]; // ei - fh
|
209
208
|
y = A[lda] * A[2*lda+2] - A[lda+2] * A[2*lda]; // fg - di
|
@@ -220,9 +219,99 @@ namespace nm {
|
|
220
219
|
|
221
220
|
//we can't do det_exact on byte, because it will want to return a byte (unsigned), but determinants can be negative, even if all elements of the matrix are positive
|
222
221
|
template <>
|
223
|
-
void
|
222
|
+
void det_exact_from_dense<uint8_t>(const int M, const void* A_elements, const int lda, void* result_arg) {
|
224
223
|
rb_raise(nm_eDataTypeError, "cannot call det_exact on unsigned type");
|
225
224
|
}
|
225
|
+
/*
|
226
|
+
* Calculate the determinant for a yale matrix (storage) of size 2 or 3. Return the result.
|
227
|
+
*/
|
228
|
+
template <typename DType>
|
229
|
+
void det_exact_from_yale(const int M, const YALE_STORAGE* storage, const int lda, void* result_arg) {
|
230
|
+
DType* result = reinterpret_cast<DType*>(result_arg);
|
231
|
+
IType* ija = reinterpret_cast<IType *>(storage->ija);
|
232
|
+
DType* a = reinterpret_cast<DType*>(storage->a);
|
233
|
+
IType col_pos = storage->shape[0] + 1;
|
234
|
+
if (M == 2) {
|
235
|
+
if (ija[2] - ija[0] == 2) {
|
236
|
+
*result = a[0] * a[1] - a[col_pos] * a[col_pos+1];
|
237
|
+
}
|
238
|
+
else { *result = a[0] * a[1]; }
|
239
|
+
} else if (M == 3) {
|
240
|
+
DType m[3][3];
|
241
|
+
for (int i = 0; i < 3; ++i) {
|
242
|
+
m[i][i] = a[i];
|
243
|
+
switch(ija[i+1] - ija[i]) {
|
244
|
+
case 2:
|
245
|
+
m[i][ija[col_pos]] = a[col_pos];
|
246
|
+
m[i][ija[col_pos+1]] = a[col_pos+1];
|
247
|
+
col_pos += 2;
|
248
|
+
break;
|
249
|
+
case 1:
|
250
|
+
m[i][(i+1)%3] = m[i][(i+2)%3] = 0;
|
251
|
+
m[i][ija[col_pos]] = a[col_pos];
|
252
|
+
++col_pos;
|
253
|
+
break;
|
254
|
+
case 0:
|
255
|
+
m[i][(i+1)%3] = m[i][(i+2)%3] = 0;
|
256
|
+
break;
|
257
|
+
default:
|
258
|
+
rb_raise(rb_eArgError, "some value in IJA is incorrect!");
|
259
|
+
}
|
260
|
+
}
|
261
|
+
*result =
|
262
|
+
m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + m[0][2] * m[1][0] * m[2][1]
|
263
|
+
- m[0][0] * m[1][2] * m[2][1] - m[0][1] * m[1][0] * m[2][2] - m[0][2] * m[1][1] * m[2][0];
|
264
|
+
|
265
|
+
} else if (M < 2) {
|
266
|
+
rb_raise(rb_eArgError, "can only calculate exact determinant of a square matrix of size 2 or larger");
|
267
|
+
} else {
|
268
|
+
rb_raise(rb_eNotImpError, "exact determinant calculation needed for matrices larger than 3x3");
|
269
|
+
}
|
270
|
+
}
|
271
|
+
|
272
|
+
/*
|
273
|
+
* Solve a system of linear equations using forward-substution followed by
|
274
|
+
* back substution from the LU factorization of the matrix of co-efficients.
|
275
|
+
* Replaces x_elements with the result. Works only with non-integer, non-object
|
276
|
+
* data types.
|
277
|
+
*
|
278
|
+
* args - r -> The number of rows of the matrix.
|
279
|
+
* lu_elements -> Elements of the LU decomposition of the co-efficients
|
280
|
+
* matrix, as a contiguos array.
|
281
|
+
* b_elements -> Elements of the the right hand sides, as a contiguous array.
|
282
|
+
* x_elements -> The array that will contain the results of the computation.
|
283
|
+
* pivot -> Positions of permuted rows.
|
284
|
+
*/
|
285
|
+
template <typename DType>
|
286
|
+
void solve(const int r, const void* lu_elements, const void* b_elements, void* x_elements, const int* pivot) {
|
287
|
+
int ii = 0, ip;
|
288
|
+
DType sum;
|
289
|
+
|
290
|
+
const DType* matrix = reinterpret_cast<const DType*>(lu_elements);
|
291
|
+
const DType* b = reinterpret_cast<const DType*>(b_elements);
|
292
|
+
DType* x = reinterpret_cast<DType*>(x_elements);
|
293
|
+
|
294
|
+
for (int i = 0; i < r; ++i) { x[i] = b[i]; }
|
295
|
+
for (int i = 0; i < r; ++i) { // forward substitution loop
|
296
|
+
ip = pivot[i];
|
297
|
+
sum = x[ip];
|
298
|
+
x[ip] = x[i];
|
299
|
+
|
300
|
+
if (ii != 0) {
|
301
|
+
for (int j = ii - 1;j < i; ++j) { sum = sum - matrix[i * r + j] * x[j]; }
|
302
|
+
}
|
303
|
+
else if (sum != 0.0) {
|
304
|
+
ii = i + 1;
|
305
|
+
}
|
306
|
+
x[i] = sum;
|
307
|
+
}
|
308
|
+
|
309
|
+
for (int i = r - 1; i >= 0; --i) { // back substitution loop
|
310
|
+
sum = x[i];
|
311
|
+
for (int j = i + 1; j < r; j++) { sum = sum - matrix[i * r + j] * x[j]; }
|
312
|
+
x[i] = sum/matrix[i * r + i];
|
313
|
+
}
|
314
|
+
}
|
226
315
|
|
227
316
|
/*
|
228
317
|
* Calculates in-place inverse of A_elements. Uses Gauss-Jordan elimination technique.
|
@@ -246,18 +335,18 @@ namespace nm {
|
|
246
335
|
for (int row = k + 1; row < M; ++row) {
|
247
336
|
typename MagnitudeDType<DType>::type big;
|
248
337
|
big = magnitude( matrix[M*row + k] ); // element below the temp pivot
|
249
|
-
|
338
|
+
|
250
339
|
if ( big > akk ) {
|
251
340
|
interchange = row;
|
252
|
-
akk = big;
|
341
|
+
akk = big;
|
253
342
|
}
|
254
|
-
}
|
343
|
+
}
|
255
344
|
|
256
345
|
if (interchange != k) { // check if rows need flipping
|
257
346
|
DType temp;
|
258
347
|
|
259
348
|
for (int col = 0; col < M; ++col) {
|
260
|
-
NM_SWAP(matrix[interchange*M + col], matrix[k*M + col], temp);
|
349
|
+
NM_SWAP(matrix[interchange*M + col], matrix[k*M + col], temp);
|
261
350
|
}
|
262
351
|
}
|
263
352
|
|
@@ -271,7 +360,7 @@ namespace nm {
|
|
271
360
|
DType pivot = matrix[k * (M + 1)];
|
272
361
|
matrix[k * (M + 1)] = (DType)(1); // set diagonal as 1 for in-place inversion
|
273
362
|
|
274
|
-
for (int col = 0; col < M; ++col) {
|
363
|
+
for (int col = 0; col < M; ++col) {
|
275
364
|
// divide each element in the kth row with the pivot
|
276
365
|
matrix[k*M + col] = matrix[k*M + col] / pivot;
|
277
366
|
}
|
@@ -280,7 +369,7 @@ namespace nm {
|
|
280
369
|
if (kk == k) continue;
|
281
370
|
|
282
371
|
DType dum = matrix[k + M*kk];
|
283
|
-
matrix[k + M*kk] = (DType)(0); // prepare for inplace inversion
|
372
|
+
matrix[k + M*kk] = (DType)(0); // prepare for inplace inversion
|
284
373
|
for (int col = 0; col < M; ++col) {
|
285
374
|
matrix[M*kk + col] = matrix[M*kk + col] - matrix[M*k + col] * dum;
|
286
375
|
}
|
@@ -295,7 +384,7 @@ namespace nm {
|
|
295
384
|
|
296
385
|
for (int row = 0; row < M; ++row) {
|
297
386
|
NM_SWAP(matrix[row * M + row_index[k]], matrix[row * M + col_index[k]],
|
298
|
-
temp);
|
387
|
+
temp);
|
299
388
|
}
|
300
389
|
}
|
301
390
|
}
|
@@ -321,14 +410,14 @@ namespace nm {
|
|
321
410
|
DType sum_of_squares, *p_row, *psubdiag, *p_a, scale, innerproduct;
|
322
411
|
int i, k, col;
|
323
412
|
|
324
|
-
// For each column use a Householder transformation to zero all entries
|
413
|
+
// For each column use a Householder transformation to zero all entries
|
325
414
|
// below the subdiagonal.
|
326
|
-
for (psubdiag = a + nrows, col = 0; col < nrows - 2; psubdiag += nrows + 1,
|
415
|
+
for (psubdiag = a + nrows, col = 0; col < nrows - 2; psubdiag += nrows + 1,
|
327
416
|
col++) {
|
328
417
|
// Calculate the signed square root of the sum of squares of the
|
329
418
|
// elements below the diagonal.
|
330
419
|
|
331
|
-
for (p_a = psubdiag, sum_of_squares = 0.0, i = col + 1; i < nrows;
|
420
|
+
for (p_a = psubdiag, sum_of_squares = 0.0, i = col + 1; i < nrows;
|
332
421
|
p_a += nrows, i++) {
|
333
422
|
sum_of_squares += *p_a * *p_a;
|
334
423
|
}
|
@@ -358,7 +447,7 @@ namespace nm {
|
|
358
447
|
*p_a -= u[k] * innerproduct;
|
359
448
|
}
|
360
449
|
}
|
361
|
-
|
450
|
+
|
362
451
|
// Postmultiply QA by Q
|
363
452
|
for (p_row = a, i = 0; i < nrows; p_row += nrows, i++) {
|
364
453
|
for (innerproduct = 0.0, k = col + 1; k < nrows; k++) {
|
@@ -375,33 +464,34 @@ namespace nm {
|
|
375
464
|
delete[] u;
|
376
465
|
}
|
377
466
|
|
467
|
+
void raise_not_invertible_error() {
|
468
|
+
rb_raise(nm_eNotInvertibleError,
|
469
|
+
"matrix must have non-zero determinant to be invertible (not getting this error does not mean matrix is invertible if you're dealing with floating points)");
|
470
|
+
}
|
471
|
+
|
378
472
|
/*
|
379
473
|
* Calculate the exact inverse for a dense matrix (A [elements]) of size 2 or 3. Places the result in B_elements.
|
380
474
|
*/
|
381
475
|
template <typename DType>
|
382
|
-
void
|
476
|
+
void inverse_exact_from_dense(const int M, const void* A_elements,
|
477
|
+
const int lda, void* B_elements, const int ldb) {
|
478
|
+
|
383
479
|
const DType* A = reinterpret_cast<const DType*>(A_elements);
|
384
480
|
DType* B = reinterpret_cast<DType*>(B_elements);
|
385
481
|
|
386
482
|
if (M == 2) {
|
387
483
|
DType det = A[0] * A[lda+1] - A[1] * A[lda];
|
388
|
-
if (det == 0) {
|
389
|
-
rb_raise(nm_eNotInvertibleError,
|
390
|
-
"matrix must have non-zero determinant to be invertible (not getting this error does not mean matrix is invertible if you're dealing with floating points)");
|
391
|
-
}
|
484
|
+
if (det == 0) { raise_not_invertible_error(); }
|
392
485
|
B[0] = A[lda+1] / det;
|
393
486
|
B[1] = -A[1] / det;
|
394
487
|
B[ldb] = -A[lda] / det;
|
395
|
-
B[ldb+1] =
|
488
|
+
B[ldb+1] = A[0] / det;
|
396
489
|
|
397
490
|
} else if (M == 3) {
|
398
491
|
// Calculate the exact determinant.
|
399
492
|
DType det;
|
400
|
-
|
401
|
-
if (det == 0) {
|
402
|
-
rb_raise(nm_eNotInvertibleError,
|
403
|
-
"matrix must have non-zero determinant to be invertible (not getting this error does not mean matrix is invertible if you're dealing with floating points)");
|
404
|
-
}
|
493
|
+
det_exact_from_dense<DType>(M, A_elements, lda, reinterpret_cast<void*>(&det));
|
494
|
+
if (det == 0) { raise_not_invertible_error(); }
|
405
495
|
|
406
496
|
B[0] = ( A[lda+1] * A[2*lda+2] - A[lda+2] * A[2*lda+1]) / det; // A = ei - fh
|
407
497
|
B[1] = (- A[1] * A[2*lda+2] + A[2] * A[2*lda+1]) / det; // D = -bi + ch
|
@@ -419,6 +509,113 @@ namespace nm {
|
|
419
509
|
}
|
420
510
|
}
|
421
511
|
|
512
|
+
template <typename DType>
|
513
|
+
void inverse_exact_from_yale(const int M, const YALE_STORAGE* storage,
|
514
|
+
const int lda, YALE_STORAGE* inverse, const int ldb) {
|
515
|
+
|
516
|
+
// inverse is a clone of storage
|
517
|
+
const DType* a = reinterpret_cast<const DType*>(storage->a);
|
518
|
+
const IType* ija = reinterpret_cast<const IType *>(storage->ija);
|
519
|
+
DType* b = reinterpret_cast<DType*>(inverse->a);
|
520
|
+
IType* ijb = reinterpret_cast<IType *>(inverse->ija);
|
521
|
+
IType col_pos = storage->shape[0] + 1;
|
522
|
+
// Calculate the exact determinant.
|
523
|
+
DType det;
|
524
|
+
|
525
|
+
if (M == 2) {
|
526
|
+
IType ndnz = ija[2] - ija[0];
|
527
|
+
if (ndnz == 2) {
|
528
|
+
det = a[0] * a[1] - a[col_pos] * a[col_pos+1];
|
529
|
+
}
|
530
|
+
else { det = a[0] * a[1]; }
|
531
|
+
if (det == 0) { raise_not_invertible_error(); }
|
532
|
+
b[0] = a[1] / det;
|
533
|
+
b[1] = a[0] / det;
|
534
|
+
if (ndnz == 2) {
|
535
|
+
b[col_pos] = -a[col_pos] / det;
|
536
|
+
b[col_pos+1] = -a[col_pos+1] / det;
|
537
|
+
}
|
538
|
+
else if (ndnz == 1) {
|
539
|
+
b[col_pos] = -a[col_pos] / det;
|
540
|
+
}
|
541
|
+
|
542
|
+
} else if (M == 3) {
|
543
|
+
DType *A = new DType[lda*3];
|
544
|
+
for (int i = 0; i < lda; ++i) {
|
545
|
+
A[i*3+i] = a[i];
|
546
|
+
switch (ija[i+1] - ija[i]) {
|
547
|
+
case 2:
|
548
|
+
A[i*3 + ija[col_pos]] = a[col_pos];
|
549
|
+
A[i*3 + ija[col_pos+1]] = a[col_pos+1];
|
550
|
+
col_pos += 2;
|
551
|
+
break;
|
552
|
+
case 1:
|
553
|
+
A[i*3 + (i+1)%3] = A[i*3 + (i+2)%3] = 0;
|
554
|
+
A[i*3 + ija[col_pos]] = a[col_pos];
|
555
|
+
col_pos += 1;
|
556
|
+
break;
|
557
|
+
case 0:
|
558
|
+
A[i*3 + (i+1)%3] = A[i*3 + (i+2)%3] = 0;
|
559
|
+
break;
|
560
|
+
default:
|
561
|
+
rb_raise(rb_eArgError, "some value in IJA is incorrect!");
|
562
|
+
}
|
563
|
+
}
|
564
|
+
det =
|
565
|
+
A[0] * A[lda+1] * A[2*lda+2] + A[1] * A[lda+2] * A[2*lda] + A[2] * A[lda] * A[2*lda+1]
|
566
|
+
- A[0] * A[lda+2] * A[2*lda+1] - A[1] * A[lda] * A[2*lda+2] - A[2] * A[lda+1] * A[2*lda];
|
567
|
+
if (det == 0) { raise_not_invertible_error(); }
|
568
|
+
|
569
|
+
DType *B = new DType[3*ldb];
|
570
|
+
B[0] = ( A[lda+1] * A[2*lda+2] - A[lda+2] * A[2*lda+1]) / det; // A = ei - fh
|
571
|
+
B[1] = (- A[1] * A[2*lda+2] + A[2] * A[2*lda+1]) / det; // D = -bi + ch
|
572
|
+
B[2] = ( A[1] * A[lda+2] - A[2] * A[lda+1]) / det; // G = bf - ce
|
573
|
+
B[ldb] = (- A[lda] * A[2*lda+2] + A[lda+2] * A[2*lda]) / det; // B = -di + fg
|
574
|
+
B[ldb+1] = ( A[0] * A[2*lda+2] - A[2] * A[2*lda]) / det; // E = ai - cg
|
575
|
+
B[ldb+2] = (- A[0] * A[lda+2] + A[2] * A[lda]) / det; // H = -af + cd
|
576
|
+
B[2*ldb] = ( A[lda] * A[2*lda+1] - A[lda+1] * A[2*lda]) / det; // C = dh - eg
|
577
|
+
B[2*ldb+1]= ( -A[0] * A[2*lda+1] + A[1] * A[2*lda]) / det; // F = -ah + bg
|
578
|
+
B[2*ldb+2]= ( A[0] * A[lda+1] - A[1] * A[lda]) / det; // I = ae - bd
|
579
|
+
|
580
|
+
// Calculate the size of ijb and b, then reallocate them.
|
581
|
+
IType ndnz = 0;
|
582
|
+
for (int i = 0; i < 3; ++i) {
|
583
|
+
for (int j = 0; j < 3; ++j) {
|
584
|
+
if (j != i && B[i*ldb + j] != 0) { ++ndnz; }
|
585
|
+
}
|
586
|
+
}
|
587
|
+
inverse->ndnz = ndnz;
|
588
|
+
col_pos = 4; // shape[0] + 1
|
589
|
+
inverse->capacity = 4 + ndnz;
|
590
|
+
NM_REALLOC_N(inverse->a, DType, 4 + ndnz);
|
591
|
+
NM_REALLOC_N(inverse->ija, IType, 4 + ndnz);
|
592
|
+
b = reinterpret_cast<DType*>(inverse->a);
|
593
|
+
ijb = reinterpret_cast<IType *>(inverse->ija);
|
594
|
+
|
595
|
+
for (int i = 0; i < 3; ++i) {
|
596
|
+
ijb[i] = col_pos;
|
597
|
+
for (int j = 0; j < 3; ++j) {
|
598
|
+
if (j == i) {
|
599
|
+
b[i] = B[i*ldb + j];
|
600
|
+
}
|
601
|
+
else if (B[i*ldb + j] != 0) {
|
602
|
+
b[col_pos] = B[i*ldb + j];
|
603
|
+
ijb[col_pos] = j;
|
604
|
+
++col_pos;
|
605
|
+
}
|
606
|
+
}
|
607
|
+
}
|
608
|
+
b[3] = 0;
|
609
|
+
ijb[3] = col_pos;
|
610
|
+
delete [] B;
|
611
|
+
delete [] A;
|
612
|
+
} else if (M == 1) {
|
613
|
+
b[0] = 1 / a[0];
|
614
|
+
} else {
|
615
|
+
rb_raise(rb_eNotImpError, "exact inverse calculation needed for matrices larger than 3x3");
|
616
|
+
}
|
617
|
+
}
|
618
|
+
|
422
619
|
/*
|
423
620
|
* Function signature conversion for calling CBLAS' gemm functions as directly as possible.
|
424
621
|
*
|
@@ -1068,14 +1265,43 @@ static VALUE nm_clapack_laswp(VALUE self, VALUE n, VALUE a, VALUE lda, VALUE k1,
|
|
1068
1265
|
|
1069
1266
|
|
1070
1267
|
/*
|
1071
|
-
* C accessor for calculating an exact determinant.
|
1268
|
+
* C accessor for calculating an exact determinant. Dense matrix version.
|
1072
1269
|
*/
|
1073
|
-
void
|
1074
|
-
|
1270
|
+
void nm_math_det_exact_from_dense(const int M, const void* elements, const int lda,
|
1271
|
+
nm::dtype_t dtype, void* result) {
|
1272
|
+
NAMED_DTYPE_TEMPLATE_TABLE(ttable, nm::math::det_exact_from_dense, void, const int M,
|
1273
|
+
const void* A_elements, const int lda, void* result_arg);
|
1075
1274
|
|
1076
1275
|
ttable[dtype](M, elements, lda, result);
|
1077
1276
|
}
|
1078
1277
|
|
1278
|
+
/*
|
1279
|
+
* C accessor for calculating an exact determinant. Yale matrix version.
|
1280
|
+
*/
|
1281
|
+
void nm_math_det_exact_from_yale(const int M, const YALE_STORAGE* storage, const int lda,
|
1282
|
+
nm::dtype_t dtype, void* result) {
|
1283
|
+
NAMED_DTYPE_TEMPLATE_TABLE(ttable, nm::math::det_exact_from_yale, void, const int M,
|
1284
|
+
const YALE_STORAGE* storage, const int lda, void* result_arg);
|
1285
|
+
|
1286
|
+
ttable[dtype](M, storage, lda, result);
|
1287
|
+
}
|
1288
|
+
|
1289
|
+
/*
|
1290
|
+
* C accessor for solving a system of linear equations.
|
1291
|
+
*/
|
1292
|
+
void nm_math_solve(VALUE lu, VALUE b, VALUE x, VALUE ipiv) {
|
1293
|
+
int* pivot = new int[RARRAY_LEN(ipiv)];
|
1294
|
+
|
1295
|
+
for (int i = 0; i < RARRAY_LEN(ipiv); ++i) {
|
1296
|
+
pivot[i] = FIX2INT(rb_ary_entry(ipiv, i));
|
1297
|
+
}
|
1298
|
+
|
1299
|
+
NAMED_DTYPE_TEMPLATE_TABLE(ttable, nm::math::solve, void, const int, const void*, const void*, void*, const int*);
|
1300
|
+
|
1301
|
+
ttable[NM_DTYPE(x)](NM_SHAPE0(b), NM_STORAGE_DENSE(lu)->elements,
|
1302
|
+
NM_STORAGE_DENSE(b)->elements, NM_STORAGE_DENSE(x)->elements, pivot);
|
1303
|
+
}
|
1304
|
+
|
1079
1305
|
/*
|
1080
1306
|
* C accessor for reducing a matrix to hessenberg form.
|
1081
1307
|
*/
|
@@ -1087,7 +1313,7 @@ void nm_math_hessenberg(VALUE a) {
|
|
1087
1313
|
NULL, NULL, // does not support Complex
|
1088
1314
|
NULL // no support for Ruby Object
|
1089
1315
|
};
|
1090
|
-
|
1316
|
+
|
1091
1317
|
ttable[NM_DTYPE(a)](NM_SHAPE0(a), NM_STORAGE_DENSE(a)->elements);
|
1092
1318
|
}
|
1093
1319
|
/*
|
@@ -1100,14 +1326,29 @@ void nm_math_inverse(const int M, void* a_elements, nm::dtype_t dtype) {
|
|
1100
1326
|
}
|
1101
1327
|
|
1102
1328
|
/*
|
1103
|
-
* C accessor for calculating an exact inverse.
|
1329
|
+
* C accessor for calculating an exact inverse. Dense matrix version.
|
1104
1330
|
*/
|
1105
|
-
void
|
1106
|
-
|
1331
|
+
void nm_math_inverse_exact_from_dense(const int M, const void* A_elements,
|
1332
|
+
const int lda, void* B_elements, const int ldb, nm::dtype_t dtype) {
|
1333
|
+
|
1334
|
+
NAMED_DTYPE_TEMPLATE_TABLE(ttable, nm::math::inverse_exact_from_dense, void,
|
1335
|
+
const int, const void*, const int, void*, const int);
|
1107
1336
|
|
1108
1337
|
ttable[dtype](M, A_elements, lda, B_elements, ldb);
|
1109
1338
|
}
|
1110
1339
|
|
1340
|
+
/*
|
1341
|
+
* C accessor for calculating an exact inverse. Yale matrix version.
|
1342
|
+
*/
|
1343
|
+
void nm_math_inverse_exact_from_yale(const int M, const YALE_STORAGE* storage,
|
1344
|
+
const int lda, YALE_STORAGE* inverse, const int ldb, nm::dtype_t dtype) {
|
1345
|
+
|
1346
|
+
NAMED_DTYPE_TEMPLATE_TABLE(ttable, nm::math::inverse_exact_from_yale, void,
|
1347
|
+
const int, const YALE_STORAGE*, const int, YALE_STORAGE*, const int);
|
1348
|
+
|
1349
|
+
ttable[dtype](M, storage, lda, inverse, ldb);
|
1350
|
+
}
|
1351
|
+
|
1111
1352
|
/*
|
1112
1353
|
* Transpose an array of elements that represent a row-major dense matrix. Does not allocate anything, only does an memcpy.
|
1113
1354
|
*/
|