nmatrix 0.1.0.rc5 → 0.1.0
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/.travis.yml +0 -1
- data/Gemfile +0 -2
- data/History.txt +39 -4
- data/LICENSE.txt +3 -1
- data/Manifest.txt +2 -0
- data/README.rdoc +6 -14
- data/Rakefile +4 -1
- data/ext/nmatrix/data/data.cpp +1 -1
- data/ext/nmatrix/data/data.h +2 -1
- data/ext/nmatrix/data/rational.h +230 -226
- data/ext/nmatrix/extconf.rb +7 -4
- data/ext/nmatrix/math.cpp +259 -172
- data/ext/nmatrix/math/getri.h +2 -2
- data/ext/nmatrix/math/math.h +1 -1
- data/ext/nmatrix/ruby_constants.cpp +0 -1
- data/ext/nmatrix/ruby_nmatrix.c +55 -32
- data/ext/nmatrix/storage/dense/dense.cpp +1 -0
- data/ext/nmatrix/storage/yale/yale.cpp +12 -14
- data/ext/nmatrix/ttable_helper.rb +0 -1
- data/lib/nmatrix.rb +5 -0
- data/lib/nmatrix/homogeneous.rb +98 -0
- data/lib/nmatrix/io/fortran_format.rb +135 -0
- data/lib/nmatrix/io/harwell_boeing.rb +220 -0
- data/lib/nmatrix/io/market.rb +18 -8
- data/lib/nmatrix/io/mat5_reader.rb +16 -111
- data/lib/nmatrix/io/mat_reader.rb +3 -5
- data/lib/nmatrix/io/point_cloud.rb +27 -28
- data/lib/nmatrix/lapack.rb +3 -1
- data/lib/nmatrix/math.rb +112 -43
- data/lib/nmatrix/monkeys.rb +67 -11
- data/lib/nmatrix/nmatrix.rb +56 -33
- data/lib/nmatrix/rspec.rb +2 -2
- data/lib/nmatrix/shortcuts.rb +42 -25
- data/lib/nmatrix/version.rb +4 -4
- data/nmatrix.gemspec +4 -3
- data/spec/03_nmatrix_monkeys_spec.rb +72 -0
- data/spec/blas_spec.rb +4 -0
- data/spec/homogeneous_spec.rb +12 -4
- data/spec/io/fortran_format_spec.rb +88 -0
- data/spec/io/harwell_boeing_spec.rb +98 -0
- data/spec/io/test.rua +9 -0
- data/spec/math_spec.rb +51 -9
- metadata +38 -9
data/ext/nmatrix/extconf.rb
CHANGED
@@ -71,7 +71,6 @@ def create_conf_h(file) #:nodoc:
|
|
71
71
|
|
72
72
|
# FIXME: Find a better way to do this:
|
73
73
|
hfile.puts "#define RUBY_2 1" if RUBY_VERSION >= '2.0'
|
74
|
-
hfile.puts "#define OLD_RB_SCAN_ARGS" if RUBY_VERSION < '1.9.3'
|
75
74
|
|
76
75
|
for line in $defs
|
77
76
|
line =~ /^-D(.*)/
|
@@ -123,7 +122,7 @@ def find_newer_gplusplus #:nodoc:
|
|
123
122
|
false
|
124
123
|
end
|
125
124
|
|
126
|
-
def gplusplus_version
|
125
|
+
def gplusplus_version
|
127
126
|
cxxvar = proc { |n| `#{CONFIG['CXX']} -E -dM - </dev/null | grep #{n}`.chomp.split(' ')[2] }
|
128
127
|
major = cxxvar.call('__GNUC__')
|
129
128
|
minor = cxxvar.call('__GNUC_MINOR__')
|
@@ -209,8 +208,12 @@ else
|
|
209
208
|
end
|
210
209
|
|
211
210
|
|
212
|
-
have_func
|
213
|
-
|
211
|
+
# Although have_func is supposed to take a list as its second argument, I find that it simply
|
212
|
+
# applies a :to_s to the second arg and doesn't actually check each one. We may want to put
|
213
|
+
# have_func calls inside an :each block which checks atlas/clapack.h, cblas.h, clapack.h, and
|
214
|
+
# lastly lapack.h. On Ubuntu, it only works if I use atlas/clapack.h. --@mohawkjohn 8/20/14
|
215
|
+
have_func("clapack_dgetrf", "atlas/clapack.h")
|
216
|
+
have_func("clapack_dgetri", "atlas/clapack.h")
|
214
217
|
have_func("dgesvd_", "clapack.h") # This may not do anything. dgesvd_ seems to be in LAPACK, not CLAPACK.
|
215
218
|
|
216
219
|
have_func("cblas_dgemm", "cblas.h")
|
data/ext/nmatrix/math.cpp
CHANGED
@@ -115,6 +115,7 @@
|
|
115
115
|
|
116
116
|
#include <algorithm>
|
117
117
|
#include <limits>
|
118
|
+
#include <cmath>
|
118
119
|
|
119
120
|
#include "math/inc.h"
|
120
121
|
#include "data/data.h"
|
@@ -199,185 +200,263 @@ extern "C" {
|
|
199
200
|
// Math Functions //
|
200
201
|
////////////////////
|
201
202
|
|
202
|
-
namespace nm {
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
}
|
203
|
+
namespace nm {
|
204
|
+
namespace math {
|
205
|
+
|
206
|
+
/*
|
207
|
+
* Calculate the determinant for a dense matrix (A [elements]) of size 2 or 3. Return the result.
|
208
|
+
*/
|
209
|
+
template <typename DType>
|
210
|
+
void det_exact(const int M, const void* A_elements, const int lda, void* result_arg) {
|
211
|
+
DType* result = reinterpret_cast<DType*>(result_arg);
|
212
|
+
const DType* A = reinterpret_cast<const DType*>(A_elements);
|
213
|
+
|
214
|
+
typename LongDType<DType>::type x, y;
|
215
|
+
|
216
|
+
if (M == 2) {
|
217
|
+
*result = A[0] * A[lda+1] - A[1] * A[lda];
|
218
|
+
|
219
|
+
} else if (M == 3) {
|
220
|
+
x = A[lda+1] * A[2*lda+2] - A[lda+2] * A[2*lda+1]; // ei - fh
|
221
|
+
y = A[lda] * A[2*lda+2] - A[lda+2] * A[2*lda]; // fg - di
|
222
|
+
x = A[0]*x - A[1]*y ; // a*(ei-fh) - b*(fg-di)
|
223
|
+
|
224
|
+
y = A[lda] * A[2*lda+1] - A[lda+1] * A[2*lda]; // dh - eg
|
225
|
+
*result = A[2]*y + x; // c*(dh-eg) + _
|
226
|
+
} else if (M < 2) {
|
227
|
+
rb_raise(rb_eArgError, "can only calculate exact determinant of a square matrix of size 2 or larger");
|
228
|
+
} else {
|
229
|
+
rb_raise(rb_eNotImpError, "exact determinant calculation needed for matrices larger than 3x3");
|
230
|
+
}
|
231
|
+
}
|
230
232
|
|
231
233
|
|
232
|
-
/*
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
234
|
+
/*
|
235
|
+
* Calculates in-place inverse of A_elements. Uses Gauss-Jordan elimination technique.
|
236
|
+
* In-place inversion of the matrix saves on memory and time.
|
237
|
+
*
|
238
|
+
* args - M - Shape of the matrix
|
239
|
+
* a_elements - A duplicate of the original expressed as a contiguos array
|
240
|
+
*/
|
241
|
+
template <typename DType>
|
242
|
+
void inverse(const int M, void* a_elements) {
|
243
|
+
DType* matrix = reinterpret_cast<DType*>(a_elements);
|
244
|
+
int* row_index = new int[M]; // arrays for keeping track of column scrambling
|
245
|
+
int* col_index = new int[M];
|
246
|
+
|
247
|
+
for (int k = 0;k < M; ++k) {
|
248
|
+
DType akk = std::abs( matrix[k * (M + 1)] ) ; // diagonal element
|
249
|
+
int interchange = k;
|
250
|
+
|
251
|
+
for (int row = k + 1; row < M; ++row) {
|
252
|
+
DType big = std::abs( matrix[M*row + k] ); // element below the temp pivot
|
253
|
+
|
254
|
+
if ( big > akk ) {
|
255
|
+
interchange = row;
|
256
|
+
akk = big;
|
257
|
+
}
|
258
|
+
}
|
259
|
+
|
260
|
+
if (interchange != k) { // check if rows need flipping
|
261
|
+
DType temp;
|
262
|
+
|
263
|
+
for (int col = 0; col < M; ++col) {
|
264
|
+
NM_SWAP(matrix[interchange*M + col], matrix[k*M + col], temp);
|
265
|
+
}
|
266
|
+
}
|
267
|
+
|
268
|
+
row_index[k] = interchange;
|
269
|
+
col_index[k] = k;
|
270
|
+
|
271
|
+
if (matrix[k * (M + 1)] == (DType)(0)) {
|
272
|
+
rb_raise(rb_eZeroDivError, "Expected Non-Singular Matrix.");
|
273
|
+
}
|
274
|
+
|
275
|
+
DType pivot = matrix[k * (M + 1)];
|
276
|
+
matrix[k * (M + 1)] = (DType)(1); // set diagonal as 1 for in-place inversion
|
277
|
+
|
278
|
+
for (int col = 0; col < M; ++col) {
|
279
|
+
// divide each element in the kth row with the pivot
|
280
|
+
matrix[k*M + col] = matrix[k*M + col] / pivot;
|
281
|
+
}
|
282
|
+
|
283
|
+
for (int kk = 0; kk < M; ++kk) { // iterate and reduce all rows
|
284
|
+
if (kk == k) continue;
|
285
|
+
|
286
|
+
DType dum = matrix[k + M*kk];
|
287
|
+
matrix[k + M*kk] = (DType)(0); // prepare for inplace inversion
|
288
|
+
for (int col = 0; col < M; ++col) {
|
289
|
+
matrix[M*kk + col] = matrix[M*kk + col] - matrix[M*k + col] * dum;
|
290
|
+
}
|
291
|
+
}
|
292
|
+
}
|
293
|
+
|
294
|
+
// Unscramble columns
|
295
|
+
DType temp;
|
296
|
+
|
297
|
+
for (int k = M - 1; k >= 0; --k) {
|
298
|
+
if (row_index[k] != col_index[k]) {
|
299
|
+
|
300
|
+
for (int row = 0; row < M; ++row) {
|
301
|
+
NM_SWAP(matrix[row * M + row_index[k]], matrix[row * M + col_index[k]],
|
302
|
+
temp);
|
303
|
+
}
|
304
|
+
}
|
305
|
+
}
|
306
|
+
|
307
|
+
delete[] row_index;
|
308
|
+
delete[] col_index;
|
253
309
|
}
|
254
310
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
311
|
+
/*
|
312
|
+
* Calculate the exact inverse for a dense matrix (A [elements]) of size 2 or 3. Places the result in B_elements.
|
313
|
+
*/
|
314
|
+
template <typename DType>
|
315
|
+
void inverse_exact(const int M, const void* A_elements, const int lda, void* B_elements, const int ldb) {
|
316
|
+
const DType* A = reinterpret_cast<const DType*>(A_elements);
|
317
|
+
DType* B = reinterpret_cast<DType*>(B_elements);
|
318
|
+
|
319
|
+
if (M == 2) {
|
320
|
+
DType det = A[0] * A[lda+1] - A[1] * A[lda];
|
321
|
+
B[0] = A[lda+1] / det;
|
322
|
+
B[1] = -A[1] / det;
|
323
|
+
B[ldb] = -A[lda] / det;
|
324
|
+
B[ldb+1] = -A[0] / det;
|
325
|
+
|
326
|
+
} else if (M == 3) {
|
327
|
+
// Calculate the exact determinant.
|
328
|
+
DType det;
|
329
|
+
det_exact<DType>(M, A_elements, lda, reinterpret_cast<void*>(&det));
|
330
|
+
if (det == 0) {
|
331
|
+
rb_raise(nm_eNotInvertibleError, "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)");
|
332
|
+
}
|
333
|
+
|
334
|
+
B[0] = ( A[lda+1] * A[2*lda+2] - A[lda+2] * A[2*lda+1]) / det; // A = ei - fh
|
335
|
+
B[1] = (- A[1] * A[2*lda+2] + A[2] * A[2*lda+1]) / det; // D = -bi + ch
|
336
|
+
B[2] = ( A[1] * A[lda+2] - A[2] * A[lda+1]) / det; // G = bf - ce
|
337
|
+
B[ldb] = (- A[lda] * A[2*lda+2] + A[lda+2] * A[2*lda]) / det; // B = -di + fg
|
338
|
+
B[ldb+1] = ( A[0] * A[2*lda+2] - A[2] * A[2*lda]) / det; // E = ai - cg
|
339
|
+
B[ldb+2] = (- A[0] * A[lda+2] + A[2] * A[lda]) / det; // H = -af + cd
|
340
|
+
B[2*ldb] = ( A[lda] * A[2*lda+1] - A[lda+1] * A[2*lda]) / det; // C = dh - eg
|
341
|
+
B[2*ldb+1]= ( -A[0] * A[2*lda+1] + A[1] * A[2*lda]) / det; // F = -ah + bg
|
342
|
+
B[2*ldb+2]= ( A[0] * A[lda+1] - A[1] * A[lda]) / det; // I = ae - bd
|
343
|
+
} else if (M == 1) {
|
344
|
+
B[0] = 1 / A[0];
|
345
|
+
} else {
|
346
|
+
rb_raise(rb_eNotImpError, "exact inverse calculation needed for matrices larger than 3x3");
|
347
|
+
}
|
348
|
+
}
|
271
349
|
|
272
|
-
/*
|
273
|
-
|
274
|
-
|
275
|
-
template <typename DType, typename CType>
|
276
|
-
inline static int lapack_gesvd(char jobu, char jobvt, int m, int n, void* a, int lda, void* s, void* u, int ldu, void* vt, int ldvt, void* work, int lwork, void* rwork) {
|
277
|
-
|
278
|
-
}
|
350
|
+
/*
|
351
|
+
* Function signature conversion for calling CBLAS' gesvd functions as directly as possible.
|
352
|
+
*/
|
353
|
+
template <typename DType, typename CType>
|
354
|
+
inline static int lapack_gesvd(char jobu, char jobvt, int m, int n, void* a, int lda, void* s, void* u, int ldu, void* vt, int ldvt, void* work, int lwork, void* rwork) {
|
355
|
+
return gesvd<DType,CType>(jobu, jobvt, m, n, reinterpret_cast<DType*>(a), lda, reinterpret_cast<DType*>(s), reinterpret_cast<DType*>(u), ldu, reinterpret_cast<DType*>(vt), ldvt, reinterpret_cast<DType*>(work), lwork, reinterpret_cast<CType*>(rwork));
|
356
|
+
}
|
279
357
|
|
280
|
-
/*
|
281
|
-
|
282
|
-
|
283
|
-
template <typename DType, typename CType>
|
284
|
-
inline static int lapack_gesdd(char jobz, int m, int n, void* a, int lda, void* s, void* u, int ldu, void* vt, int ldvt, void* work, int lwork, int* iwork, void* rwork) {
|
285
|
-
|
286
|
-
}
|
358
|
+
/*
|
359
|
+
* Function signature conversion for calling CBLAS' gesvd functions as directly as possible.
|
360
|
+
*/
|
361
|
+
template <typename DType, typename CType>
|
362
|
+
inline static int lapack_gesdd(char jobz, int m, int n, void* a, int lda, void* s, void* u, int ldu, void* vt, int ldvt, void* work, int lwork, int* iwork, void* rwork) {
|
363
|
+
return gesdd<DType,CType>(jobz, m, n, reinterpret_cast<DType*>(a), lda, reinterpret_cast<DType*>(s), reinterpret_cast<DType*>(u), ldu, reinterpret_cast<DType*>(vt), ldvt, reinterpret_cast<DType*>(work), lwork, iwork, reinterpret_cast<CType*>(rwork));
|
364
|
+
}
|
287
365
|
|
288
|
-
/*
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
template <typename DType>
|
294
|
-
inline static void cblas_gemm(const enum CBLAS_ORDER order,
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
{
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
}
|
366
|
+
/*
|
367
|
+
* Function signature conversion for calling CBLAS' gemm functions as directly as possible.
|
368
|
+
*
|
369
|
+
* For documentation: http://www.netlib.org/blas/dgemm.f
|
370
|
+
*/
|
371
|
+
template <typename DType>
|
372
|
+
inline static void cblas_gemm(const enum CBLAS_ORDER order,
|
373
|
+
const enum CBLAS_TRANSPOSE trans_a, const enum CBLAS_TRANSPOSE trans_b,
|
374
|
+
int m, int n, int k,
|
375
|
+
void* alpha,
|
376
|
+
void* a, int lda,
|
377
|
+
void* b, int ldb,
|
378
|
+
void* beta,
|
379
|
+
void* c, int ldc)
|
380
|
+
{
|
381
|
+
gemm<DType>(order, trans_a, trans_b, m, n, k, reinterpret_cast<DType*>(alpha),
|
382
|
+
reinterpret_cast<DType*>(a), lda,
|
383
|
+
reinterpret_cast<DType*>(b), ldb, reinterpret_cast<DType*>(beta),
|
384
|
+
reinterpret_cast<DType*>(c), ldc);
|
385
|
+
}
|
308
386
|
|
309
387
|
|
310
|
-
/*
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
template <typename DType>
|
316
|
-
inline static bool cblas_gemv(const enum CBLAS_TRANSPOSE trans,
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
{
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
}
|
388
|
+
/*
|
389
|
+
* Function signature conversion for calling CBLAS's gemv functions as directly as possible.
|
390
|
+
*
|
391
|
+
* For documentation: http://www.netlib.org/lapack/double/dgetrf.f
|
392
|
+
*/
|
393
|
+
template <typename DType>
|
394
|
+
inline static bool cblas_gemv(const enum CBLAS_TRANSPOSE trans,
|
395
|
+
const int m, const int n,
|
396
|
+
const void* alpha,
|
397
|
+
const void* a, const int lda,
|
398
|
+
const void* x, const int incx,
|
399
|
+
const void* beta,
|
400
|
+
void* y, const int incy)
|
401
|
+
{
|
402
|
+
return gemv<DType>(trans,
|
403
|
+
m, n, reinterpret_cast<const DType*>(alpha),
|
404
|
+
reinterpret_cast<const DType*>(a), lda,
|
405
|
+
reinterpret_cast<const DType*>(x), incx, reinterpret_cast<const DType*>(beta),
|
406
|
+
reinterpret_cast<DType*>(y), incy);
|
407
|
+
}
|
330
408
|
|
331
409
|
|
332
|
-
/*
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
template <typename DType>
|
338
|
-
inline static void cblas_trsm(const enum CBLAS_ORDER order, const enum CBLAS_SIDE side, const enum CBLAS_UPLO uplo,
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
{
|
343
|
-
|
344
|
-
|
345
|
-
}
|
410
|
+
/*
|
411
|
+
* Function signature conversion for calling CBLAS' trsm functions as directly as possible.
|
412
|
+
*
|
413
|
+
* For documentation: http://www.netlib.org/blas/dtrsm.f
|
414
|
+
*/
|
415
|
+
template <typename DType>
|
416
|
+
inline static void cblas_trsm(const enum CBLAS_ORDER order, const enum CBLAS_SIDE side, const enum CBLAS_UPLO uplo,
|
417
|
+
const enum CBLAS_TRANSPOSE trans_a, const enum CBLAS_DIAG diag,
|
418
|
+
const int m, const int n, const void* alpha, const void* a,
|
419
|
+
const int lda, void* b, const int ldb)
|
420
|
+
{
|
421
|
+
trsm<DType>(order, side, uplo, trans_a, diag, m, n, *reinterpret_cast<const DType*>(alpha),
|
422
|
+
reinterpret_cast<const DType*>(a), lda, reinterpret_cast<DType*>(b), ldb);
|
423
|
+
}
|
346
424
|
|
347
425
|
|
348
|
-
/*
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
template <typename DType>
|
354
|
-
inline static void cblas_trmm(const enum CBLAS_ORDER order, const enum CBLAS_SIDE side, const enum CBLAS_UPLO uplo,
|
355
|
-
|
356
|
-
|
357
|
-
{
|
358
|
-
|
359
|
-
|
360
|
-
}
|
426
|
+
/*
|
427
|
+
* Function signature conversion for calling CBLAS' trmm functions as directly as possible.
|
428
|
+
*
|
429
|
+
* For documentation: http://www.netlib.org/blas/dtrmm.f
|
430
|
+
*/
|
431
|
+
template <typename DType>
|
432
|
+
inline static void cblas_trmm(const enum CBLAS_ORDER order, const enum CBLAS_SIDE side, const enum CBLAS_UPLO uplo,
|
433
|
+
const enum CBLAS_TRANSPOSE ta, const enum CBLAS_DIAG diag, const int m, const int n, const void* alpha,
|
434
|
+
const void* A, const int lda, void* B, const int ldb)
|
435
|
+
{
|
436
|
+
trmm<DType>(order, side, uplo, ta, diag, m, n, reinterpret_cast<const DType*>(alpha),
|
437
|
+
reinterpret_cast<const DType*>(A), lda, reinterpret_cast<DType*>(B), ldb);
|
438
|
+
}
|
361
439
|
|
362
440
|
|
363
|
-
/*
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
template <typename DType>
|
369
|
-
inline static void cblas_syrk(const enum CBLAS_ORDER order, const enum CBLAS_UPLO uplo, const enum CBLAS_TRANSPOSE trans,
|
370
|
-
|
371
|
-
|
372
|
-
{
|
373
|
-
|
374
|
-
|
375
|
-
}
|
441
|
+
/*
|
442
|
+
* Function signature conversion for calling CBLAS' syrk functions as directly as possible.
|
443
|
+
*
|
444
|
+
* For documentation: http://www.netlib.org/blas/dsyrk.f
|
445
|
+
*/
|
446
|
+
template <typename DType>
|
447
|
+
inline static void cblas_syrk(const enum CBLAS_ORDER order, const enum CBLAS_UPLO uplo, const enum CBLAS_TRANSPOSE trans,
|
448
|
+
const int n, const int k, const void* alpha,
|
449
|
+
const void* A, const int lda, const void* beta, void* C, const int ldc)
|
450
|
+
{
|
451
|
+
syrk<DType>(order, uplo, trans, n, k, reinterpret_cast<const DType*>(alpha),
|
452
|
+
reinterpret_cast<const DType*>(A), lda, reinterpret_cast<const DType*>(beta), reinterpret_cast<DType*>(C), ldc);
|
453
|
+
}
|
376
454
|
|
377
455
|
|
378
456
|
|
379
457
|
|
380
|
-
}
|
458
|
+
}
|
459
|
+
} // end of namespace nm::math
|
381
460
|
|
382
461
|
|
383
462
|
extern "C" {
|
@@ -1268,7 +1347,7 @@ static VALUE nm_clapack_lauum(VALUE self, VALUE order, VALUE uplo, VALUE n, VALU
|
|
1268
1347
|
NULL, NULL, NULL, NULL, NULL,
|
1269
1348
|
nm::math::clapack_lauum<false, float>,
|
1270
1349
|
nm::math::clapack_lauum<false, double>,
|
1271
|
-
#
|
1350
|
+
#if defined (HAVE_CLAPACK_H) || defined (HAVE_ATLAS_CLAPACK_H)
|
1272
1351
|
clapack_clauum, clapack_zlauum, // call directly, same function signature!
|
1273
1352
|
#else // Especially important for Mac OS, which doesn't seem to include the ATLAS clapack interface.
|
1274
1353
|
nm::math::clapack_lauum<true, nm::Complex64>,
|
@@ -1323,7 +1402,7 @@ static VALUE nm_clapack_getrf(VALUE self, VALUE order, VALUE m, VALUE n, VALUE a
|
|
1323
1402
|
NULL, NULL, NULL, NULL, NULL, // integers not allowed due to division
|
1324
1403
|
nm::math::clapack_getrf<float>,
|
1325
1404
|
nm::math::clapack_getrf<double>,
|
1326
|
-
#
|
1405
|
+
#if defined (HAVE_CLAPACK_H) || defined (HAVE_ATLAS_CLAPACK_H)
|
1327
1406
|
clapack_cgetrf, clapack_zgetrf, // call directly, same function signature!
|
1328
1407
|
#else // Especially important for Mac OS, which doesn't seem to include the ATLAS clapack interface.
|
1329
1408
|
nm::math::clapack_getrf<nm::Complex64>,
|
@@ -1370,7 +1449,7 @@ static VALUE nm_clapack_getrf(VALUE self, VALUE order, VALUE m, VALUE n, VALUE a
|
|
1370
1449
|
* Returns an array giving the pivot indices (normally these are argument #5).
|
1371
1450
|
*/
|
1372
1451
|
static VALUE nm_clapack_potrf(VALUE self, VALUE order, VALUE uplo, VALUE n, VALUE a, VALUE lda) {
|
1373
|
-
#
|
1452
|
+
#if !defined(HAVE_CLAPACK_H) && !defined(HAVE_ATLAS_CLAPACK_H)
|
1374
1453
|
rb_raise(rb_eNotImpError, "potrf currently requires CLAPACK");
|
1375
1454
|
#endif
|
1376
1455
|
|
@@ -1378,7 +1457,7 @@ static VALUE nm_clapack_potrf(VALUE self, VALUE order, VALUE uplo, VALUE n, VALU
|
|
1378
1457
|
NULL, NULL, NULL, NULL, NULL, // integers not allowed due to division
|
1379
1458
|
nm::math::clapack_potrf<float>,
|
1380
1459
|
nm::math::clapack_potrf<double>,
|
1381
|
-
#
|
1460
|
+
#if defined (HAVE_CLAPACK_H) || defined (HAVE_ATLAS_CLAPACK_H)
|
1382
1461
|
clapack_cpotrf, clapack_zpotrf, // call directly, same function signature!
|
1383
1462
|
#else // Especially important for Mac OS, which doesn't seem to include the ATLAS clapack interface.
|
1384
1463
|
nm::math::clapack_potrf<nm::Complex64>,
|
@@ -1414,7 +1493,7 @@ static VALUE nm_clapack_getrs(VALUE self, VALUE order, VALUE trans, VALUE n, VAL
|
|
1414
1493
|
NULL, NULL, NULL, NULL, NULL, // integers not allowed due to division
|
1415
1494
|
nm::math::clapack_getrs<float>,
|
1416
1495
|
nm::math::clapack_getrs<double>,
|
1417
|
-
#
|
1496
|
+
#if defined (HAVE_CLAPACK_H) || defined (HAVE_ATLAS_CLAPACK_H)
|
1418
1497
|
clapack_cgetrs, clapack_zgetrs, // call directly, same function signature!
|
1419
1498
|
#else // Especially important for Mac OS, which doesn't seem to include the ATLAS clapack interface.
|
1420
1499
|
nm::math::clapack_getrs<nm::Complex64>,
|
@@ -1460,7 +1539,7 @@ static VALUE nm_clapack_potrs(VALUE self, VALUE order, VALUE uplo, VALUE n, VALU
|
|
1460
1539
|
NULL, NULL, NULL, NULL, NULL, // integers not allowed due to division
|
1461
1540
|
nm::math::clapack_potrs<float,false>,
|
1462
1541
|
nm::math::clapack_potrs<double,false>,
|
1463
|
-
#
|
1542
|
+
#if defined (HAVE_CLAPACK_H) || defined (HAVE_ATLAS_CLAPACK_H)
|
1464
1543
|
clapack_cpotrs, clapack_zpotrs, // call directly, same function signature!
|
1465
1544
|
#else // Especially important for Mac OS, which doesn't seem to include the ATLAS clapack interface.
|
1466
1545
|
nm::math::clapack_potrs<nm::Complex64,true>,
|
@@ -1492,7 +1571,7 @@ static VALUE nm_clapack_potrs(VALUE self, VALUE order, VALUE uplo, VALUE n, VALU
|
|
1492
1571
|
* having to wait around for an exception to be thrown.
|
1493
1572
|
*/
|
1494
1573
|
static VALUE nm_has_clapack(VALUE self) {
|
1495
|
-
#
|
1574
|
+
#if defined (HAVE_CLAPACK_H) || defined (HAVE_ATLAS_CLAPACK_H)
|
1496
1575
|
return Qfalse;
|
1497
1576
|
#else
|
1498
1577
|
return Qtrue;
|
@@ -1511,7 +1590,7 @@ static VALUE nm_has_clapack(VALUE self) {
|
|
1511
1590
|
* Returns an array giving the pivot indices (normally these are argument #5).
|
1512
1591
|
*/
|
1513
1592
|
static VALUE nm_clapack_getri(VALUE self, VALUE order, VALUE n, VALUE a, VALUE lda, VALUE ipiv) {
|
1514
|
-
#
|
1593
|
+
#if !defined (HAVE_CLAPACK_H) && !defined (HAVE_ATLAS_CLAPACK_H)
|
1515
1594
|
rb_raise(rb_eNotImpError, "getri currently requires CLAPACK");
|
1516
1595
|
#endif
|
1517
1596
|
|
@@ -1519,7 +1598,7 @@ static VALUE nm_clapack_getri(VALUE self, VALUE order, VALUE n, VALUE a, VALUE l
|
|
1519
1598
|
NULL, NULL, NULL, NULL, NULL, // integers not allowed due to division
|
1520
1599
|
nm::math::clapack_getri<float>,
|
1521
1600
|
nm::math::clapack_getri<double>,
|
1522
|
-
#
|
1601
|
+
#if defined (HAVE_CLAPACK_H) || defined (HAVE_ATLAS_CLAPACK_H)
|
1523
1602
|
clapack_cgetri, clapack_zgetri, // call directly, same function signature!
|
1524
1603
|
#else // Especially important for Mac OS, which doesn't seem to include the ATLAS clapack interface.
|
1525
1604
|
nm::math::clapack_getri<nm::Complex64>,
|
@@ -1567,7 +1646,7 @@ static VALUE nm_clapack_getri(VALUE self, VALUE order, VALUE n, VALUE a, VALUE l
|
|
1567
1646
|
* Returns an array giving the pivot indices (normally these are argument #5).
|
1568
1647
|
*/
|
1569
1648
|
static VALUE nm_clapack_potri(VALUE self, VALUE order, VALUE uplo, VALUE n, VALUE a, VALUE lda) {
|
1570
|
-
#
|
1649
|
+
#if !defined (HAVE_CLAPACK_H) && !defined (HAVE_ATLAS_CLAPACK_H)
|
1571
1650
|
rb_raise(rb_eNotImpError, "getri currently requires CLAPACK");
|
1572
1651
|
#endif
|
1573
1652
|
|
@@ -1575,7 +1654,7 @@ static VALUE nm_clapack_potri(VALUE self, VALUE order, VALUE uplo, VALUE n, VALU
|
|
1575
1654
|
NULL, NULL, NULL, NULL, NULL, // integers not allowed due to division
|
1576
1655
|
nm::math::clapack_potri<float>,
|
1577
1656
|
nm::math::clapack_potri<double>,
|
1578
|
-
#
|
1657
|
+
#if defined (HAVE_CLAPACK_H) || defined (HAVE_ATLAS_CLAPACK_H)
|
1579
1658
|
clapack_cpotri, clapack_zpotri, // call directly, same function signature!
|
1580
1659
|
#else // Especially important for Mac OS, which doesn't seem to include the ATLAS clapack interface.
|
1581
1660
|
nm::math::clapack_potri<nm::Complex64>,
|
@@ -1656,6 +1735,15 @@ void nm_math_det_exact(const int M, const void* elements, const int lda, nm::dty
|
|
1656
1735
|
ttable[dtype](M, elements, lda, result);
|
1657
1736
|
}
|
1658
1737
|
|
1738
|
+
/*
|
1739
|
+
* C accessor for calculating an in-place inverse.
|
1740
|
+
*/
|
1741
|
+
void nm_math_inverse(const int M, void* a_elements, nm::dtype_t dtype) {
|
1742
|
+
NAMED_DTYPE_TEMPLATE_TABLE(ttable, nm::math::inverse, void, const int, void*);
|
1743
|
+
|
1744
|
+
ttable[dtype](M, a_elements);
|
1745
|
+
}
|
1746
|
+
|
1659
1747
|
/*
|
1660
1748
|
* C accessor for calculating an exact inverse.
|
1661
1749
|
*/
|
@@ -1665,7 +1753,6 @@ void nm_math_inverse_exact(const int M, const void* A_elements, const int lda, v
|
|
1665
1753
|
ttable[dtype](M, A_elements, lda, B_elements, ldb);
|
1666
1754
|
}
|
1667
1755
|
|
1668
|
-
|
1669
1756
|
/*
|
1670
1757
|
* Transpose an array of elements that represent a row-major dense matrix. Does not allocate anything, only does an memcpy.
|
1671
1758
|
*/
|