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