nmatrix-gemv 0.0.3
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 +7 -0
- data/.gitignore +29 -0
- data/.rspec +2 -0
- data/.travis.yml +14 -0
- data/Gemfile +7 -0
- data/README.md +29 -0
- data/Rakefile +225 -0
- data/ext/nmatrix_gemv/binary_format.txt +53 -0
- data/ext/nmatrix_gemv/data/complex.h +399 -0
- data/ext/nmatrix_gemv/data/data.cpp +298 -0
- data/ext/nmatrix_gemv/data/data.h +771 -0
- data/ext/nmatrix_gemv/data/meta.h +70 -0
- data/ext/nmatrix_gemv/data/rational.h +436 -0
- data/ext/nmatrix_gemv/data/ruby_object.h +471 -0
- data/ext/nmatrix_gemv/extconf.rb +254 -0
- data/ext/nmatrix_gemv/math.cpp +1639 -0
- data/ext/nmatrix_gemv/math/asum.h +143 -0
- data/ext/nmatrix_gemv/math/geev.h +82 -0
- data/ext/nmatrix_gemv/math/gemm.h +271 -0
- data/ext/nmatrix_gemv/math/gemv.h +212 -0
- data/ext/nmatrix_gemv/math/ger.h +96 -0
- data/ext/nmatrix_gemv/math/gesdd.h +80 -0
- data/ext/nmatrix_gemv/math/gesvd.h +78 -0
- data/ext/nmatrix_gemv/math/getf2.h +86 -0
- data/ext/nmatrix_gemv/math/getrf.h +240 -0
- data/ext/nmatrix_gemv/math/getri.h +108 -0
- data/ext/nmatrix_gemv/math/getrs.h +129 -0
- data/ext/nmatrix_gemv/math/idamax.h +86 -0
- data/ext/nmatrix_gemv/math/inc.h +47 -0
- data/ext/nmatrix_gemv/math/laswp.h +165 -0
- data/ext/nmatrix_gemv/math/long_dtype.h +52 -0
- data/ext/nmatrix_gemv/math/math.h +1069 -0
- data/ext/nmatrix_gemv/math/nrm2.h +181 -0
- data/ext/nmatrix_gemv/math/potrs.h +129 -0
- data/ext/nmatrix_gemv/math/rot.h +141 -0
- data/ext/nmatrix_gemv/math/rotg.h +115 -0
- data/ext/nmatrix_gemv/math/scal.h +73 -0
- data/ext/nmatrix_gemv/math/swap.h +73 -0
- data/ext/nmatrix_gemv/math/trsm.h +387 -0
- data/ext/nmatrix_gemv/nm_memory.h +60 -0
- data/ext/nmatrix_gemv/nmatrix_gemv.cpp +90 -0
- data/ext/nmatrix_gemv/nmatrix_gemv.h +374 -0
- data/ext/nmatrix_gemv/ruby_constants.cpp +153 -0
- data/ext/nmatrix_gemv/ruby_constants.h +107 -0
- data/ext/nmatrix_gemv/ruby_nmatrix.c +84 -0
- data/ext/nmatrix_gemv/ttable_helper.rb +122 -0
- data/ext/nmatrix_gemv/types.h +54 -0
- data/ext/nmatrix_gemv/util/util.h +78 -0
- data/lib/nmatrix-gemv.rb +43 -0
- data/lib/nmatrix_gemv/blas.rb +85 -0
- data/lib/nmatrix_gemv/nmatrix_gemv.rb +35 -0
- data/lib/nmatrix_gemv/rspec.rb +75 -0
- data/nmatrix-gemv.gemspec +31 -0
- data/spec/blas_spec.rb +154 -0
- data/spec/spec_helper.rb +128 -0
- metadata +186 -0
@@ -0,0 +1,212 @@
|
|
1
|
+
/////////////////////////////////////////////////////////////////////
|
2
|
+
// = NMatrix
|
3
|
+
//
|
4
|
+
// A linear algebra library for scientific computation in Ruby.
|
5
|
+
// NMatrix is part of SciRuby.
|
6
|
+
//
|
7
|
+
// NMatrix was originally inspired by and derived from NArray, by
|
8
|
+
// Masahiro Tanaka: http://narray.rubyforge.org
|
9
|
+
//
|
10
|
+
// == Copyright Information
|
11
|
+
//
|
12
|
+
// SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
|
13
|
+
// NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
|
14
|
+
//
|
15
|
+
// Please see LICENSE.txt for additional copyright notices.
|
16
|
+
//
|
17
|
+
// == Contributing
|
18
|
+
//
|
19
|
+
// By contributing source code to SciRuby, you agree to be bound by
|
20
|
+
// our Contributor Agreement:
|
21
|
+
//
|
22
|
+
// * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
|
23
|
+
//
|
24
|
+
// == gemv.h
|
25
|
+
//
|
26
|
+
// Header file for interface with ATLAS's CBLAS gemv functions and
|
27
|
+
// native templated version of LAPACK's gemv function.
|
28
|
+
//
|
29
|
+
|
30
|
+
#ifndef GEMV_H
|
31
|
+
# define GEMV_H
|
32
|
+
|
33
|
+
extern "C" { // These need to be in an extern "C" block or you'll get all kinds of undefined symbol errors.
|
34
|
+
#if defined HAVE_CBLAS_H
|
35
|
+
#include <cblas.h>
|
36
|
+
#elif defined HAVE_ATLAS_CBLAS_H
|
37
|
+
#include <atlas/cblas.h>
|
38
|
+
#endif
|
39
|
+
}
|
40
|
+
|
41
|
+
|
42
|
+
namespace nm { namespace math {
|
43
|
+
|
44
|
+
/*
|
45
|
+
* GEneral Matrix-Vector multiplication: based on dgemv.f from Netlib.
|
46
|
+
*
|
47
|
+
* This is an extremely inefficient algorithm. Recommend using ATLAS' version instead.
|
48
|
+
*
|
49
|
+
* Template parameters: LT -- long version of type T. Type T is the matrix dtype.
|
50
|
+
*/
|
51
|
+
template <typename DType>
|
52
|
+
inline bool gemv(const enum CBLAS_TRANSPOSE Trans, const int M, const int N, const DType* alpha, const DType* A, const int lda,
|
53
|
+
const DType* X, const int incX, const DType* beta, DType* Y, const int incY) {
|
54
|
+
int lenX, lenY, i, j;
|
55
|
+
int kx, ky, iy, jx, jy, ix;
|
56
|
+
|
57
|
+
typename LongDType<DType>::type temp;
|
58
|
+
|
59
|
+
// Test the input parameters
|
60
|
+
if (Trans < 111 || Trans > 113) {
|
61
|
+
rb_raise(rb_eArgError, "GEMV: TransA must be CblasNoTrans, CblasTrans, or CblasConjTrans");
|
62
|
+
return false;
|
63
|
+
} else if (lda < std::max(1, N)) {
|
64
|
+
fprintf(stderr, "GEMV: N = %d; got lda=%d", N, lda);
|
65
|
+
rb_raise(rb_eArgError, "GEMV: Expected lda >= max(1, N)");
|
66
|
+
return false;
|
67
|
+
} else if (incX == 0) {
|
68
|
+
rb_raise(rb_eArgError, "GEMV: Expected incX != 0\n");
|
69
|
+
return false;
|
70
|
+
} else if (incY == 0) {
|
71
|
+
rb_raise(rb_eArgError, "GEMV: Expected incY != 0\n");
|
72
|
+
return false;
|
73
|
+
}
|
74
|
+
|
75
|
+
// Quick return if possible
|
76
|
+
if (!M or !N or (*alpha == 0 and *beta == 1)) return true;
|
77
|
+
|
78
|
+
if (Trans == CblasNoTrans) {
|
79
|
+
lenX = N;
|
80
|
+
lenY = M;
|
81
|
+
} else {
|
82
|
+
lenX = M;
|
83
|
+
lenY = N;
|
84
|
+
}
|
85
|
+
|
86
|
+
if (incX > 0) kx = 0;
|
87
|
+
else kx = (lenX - 1) * -incX;
|
88
|
+
|
89
|
+
if (incY > 0) ky = 0;
|
90
|
+
else ky = (lenY - 1) * -incY;
|
91
|
+
|
92
|
+
// Start the operations. In this version, the elements of A are accessed sequentially with one pass through A.
|
93
|
+
if (*beta != 1) {
|
94
|
+
if (incY == 1) {
|
95
|
+
if (*beta == 0) {
|
96
|
+
for (i = 0; i < lenY; ++i) {
|
97
|
+
Y[i] = 0;
|
98
|
+
}
|
99
|
+
} else {
|
100
|
+
for (i = 0; i < lenY; ++i) {
|
101
|
+
Y[i] *= *beta;
|
102
|
+
}
|
103
|
+
}
|
104
|
+
} else {
|
105
|
+
iy = ky;
|
106
|
+
if (*beta == 0) {
|
107
|
+
for (i = 0; i < lenY; ++i) {
|
108
|
+
Y[iy] = 0;
|
109
|
+
iy += incY;
|
110
|
+
}
|
111
|
+
} else {
|
112
|
+
for (i = 0; i < lenY; ++i) {
|
113
|
+
Y[iy] *= *beta;
|
114
|
+
iy += incY;
|
115
|
+
}
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
if (*alpha == 0) return false;
|
121
|
+
|
122
|
+
if (Trans == CblasNoTrans) {
|
123
|
+
|
124
|
+
// Form y := alpha*A*x + y.
|
125
|
+
jx = kx;
|
126
|
+
if (incY == 1) {
|
127
|
+
for (j = 0; j < N; ++j) {
|
128
|
+
if (X[jx] != 0) {
|
129
|
+
temp = *alpha * X[jx];
|
130
|
+
for (i = 0; i < M; ++i) {
|
131
|
+
Y[i] += A[j+i*lda] * temp;
|
132
|
+
}
|
133
|
+
}
|
134
|
+
jx += incX;
|
135
|
+
}
|
136
|
+
} else {
|
137
|
+
for (j = 0; j < N; ++j) {
|
138
|
+
if (X[jx] != 0) {
|
139
|
+
temp = *alpha * X[jx];
|
140
|
+
iy = ky;
|
141
|
+
for (i = 0; i < M; ++i) {
|
142
|
+
Y[iy] += A[j+i*lda] * temp;
|
143
|
+
iy += incY;
|
144
|
+
}
|
145
|
+
}
|
146
|
+
jx += incX;
|
147
|
+
}
|
148
|
+
}
|
149
|
+
|
150
|
+
} else { // TODO: Check that indices are correct! They're switched for C.
|
151
|
+
|
152
|
+
// Form y := alpha*A**DType*x + y.
|
153
|
+
jy = ky;
|
154
|
+
|
155
|
+
if (incX == 1) {
|
156
|
+
for (j = 0; j < N; ++j) {
|
157
|
+
temp = 0;
|
158
|
+
for (i = 0; i < M; ++i) {
|
159
|
+
temp += A[j+i*lda]*X[j];
|
160
|
+
}
|
161
|
+
Y[jy] += *alpha * temp;
|
162
|
+
jy += incY;
|
163
|
+
}
|
164
|
+
} else {
|
165
|
+
for (j = 0; j < N; ++j) {
|
166
|
+
temp = 0;
|
167
|
+
ix = kx;
|
168
|
+
for (i = 0; i < M; ++i) {
|
169
|
+
temp += A[j+i*lda] * X[ix];
|
170
|
+
ix += incX;
|
171
|
+
}
|
172
|
+
|
173
|
+
Y[jy] += *alpha * temp;
|
174
|
+
jy += incY;
|
175
|
+
}
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
return true;
|
180
|
+
} // end of GEMV
|
181
|
+
|
182
|
+
template <>
|
183
|
+
inline bool gemv(const enum CBLAS_TRANSPOSE Trans, const int M, const int N, const float* alpha, const float* A, const int lda,
|
184
|
+
const float* X, const int incX, const float* beta, float* Y, const int incY) {
|
185
|
+
cblas_sgemv(CblasRowMajor, Trans, M, N, *alpha, A, lda, X, incX, *beta, Y, incY);
|
186
|
+
return true;
|
187
|
+
}
|
188
|
+
|
189
|
+
template <>
|
190
|
+
inline bool gemv(const enum CBLAS_TRANSPOSE Trans, const int M, const int N, const double* alpha, const double* A, const int lda,
|
191
|
+
const double* X, const int incX, const double* beta, double* Y, const int incY) {
|
192
|
+
cblas_dgemv(CblasRowMajor, Trans, M, N, *alpha, A, lda, X, incX, *beta, Y, incY);
|
193
|
+
return true;
|
194
|
+
}
|
195
|
+
|
196
|
+
template <>
|
197
|
+
inline bool gemv(const enum CBLAS_TRANSPOSE Trans, const int M, const int N, const Complex64* alpha, const Complex64* A, const int lda,
|
198
|
+
const Complex64* X, const int incX, const Complex64* beta, Complex64* Y, const int incY) {
|
199
|
+
cblas_cgemv(CblasRowMajor, Trans, M, N, alpha, A, lda, X, incX, beta, Y, incY);
|
200
|
+
return true;
|
201
|
+
}
|
202
|
+
|
203
|
+
template <>
|
204
|
+
inline bool gemv(const enum CBLAS_TRANSPOSE Trans, const int M, const int N, const Complex128* alpha, const Complex128* A, const int lda,
|
205
|
+
const Complex128* X, const int incX, const Complex128* beta, Complex128* Y, const int incY) {
|
206
|
+
cblas_zgemv(CblasRowMajor, Trans, M, N, alpha, A, lda, X, incX, beta, Y, incY);
|
207
|
+
return true;
|
208
|
+
}
|
209
|
+
|
210
|
+
}} // end of namespace nm::math
|
211
|
+
|
212
|
+
#endif // GEMM_H
|
@@ -0,0 +1,96 @@
|
|
1
|
+
/////////////////////////////////////////////////////////////////////
|
2
|
+
// = NMatrix
|
3
|
+
//
|
4
|
+
// A linear algebra library for scientific computation in Ruby.
|
5
|
+
// NMatrix is part of SciRuby.
|
6
|
+
//
|
7
|
+
// NMatrix was originally inspired by and derived from NArray, by
|
8
|
+
// Masahiro Tanaka: http://narray.rubyforge.org
|
9
|
+
//
|
10
|
+
// == Copyright Information
|
11
|
+
//
|
12
|
+
// SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
|
13
|
+
// NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
|
14
|
+
//
|
15
|
+
// Please see LICENSE.txt for additional copyright notices.
|
16
|
+
//
|
17
|
+
// == Contributing
|
18
|
+
//
|
19
|
+
// By contributing source code to SciRuby, you agree to be bound by
|
20
|
+
// our Contributor Agreement:
|
21
|
+
//
|
22
|
+
// * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
|
23
|
+
//
|
24
|
+
// == ger.h
|
25
|
+
//
|
26
|
+
// BLAS level-2 ger function in native C++.
|
27
|
+
//
|
28
|
+
|
29
|
+
#ifndef GER_H
|
30
|
+
#define GER_H
|
31
|
+
|
32
|
+
namespace nm { namespace math {
|
33
|
+
|
34
|
+
template <typename DType>
|
35
|
+
inline int ger(int m, int n, DType alpha, DType* x, int incx, DType* y, int incy, DType* a, int lda) {
|
36
|
+
|
37
|
+
// FIXME: Call BLAS ger if available
|
38
|
+
|
39
|
+
if (m < 0) {
|
40
|
+
return 1;
|
41
|
+
} else if (n < 0) {
|
42
|
+
return 2;
|
43
|
+
} else if (incx == 0) {
|
44
|
+
return 5;
|
45
|
+
} else if (incy == 0) {
|
46
|
+
return 7;
|
47
|
+
} else if (lda < std::max(1,m)) {
|
48
|
+
return 9;
|
49
|
+
}
|
50
|
+
|
51
|
+
if (m == 0 || n == 0 || alpha == 0) return 0; /* Quick return if possible. */
|
52
|
+
|
53
|
+
/* Start the operations. In this version the elements of A are */
|
54
|
+
/* accessed sequentially with one pass through A. */
|
55
|
+
|
56
|
+
// FIXME: These have been unrolled in a way that the compiler can handle. Collapse into a single case, or optimize
|
57
|
+
// FIXME: in a more modern way.
|
58
|
+
|
59
|
+
int jy = incy > 0 ? 0 : -(n-1) * incy;
|
60
|
+
|
61
|
+
if (incx == 1) {
|
62
|
+
|
63
|
+
for (size_t j = 0; j < n; ++j, jy += incy) {
|
64
|
+
if (y[jy] != 0) {
|
65
|
+
DType temp = alpha * y[jy];
|
66
|
+
for (size_t i = 0; i < m; ++i) {
|
67
|
+
a[i + j * lda] += x[i] * temp;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
} else {
|
73
|
+
|
74
|
+
int kx = incx > 0 ? 0 : -(m-1) * incx;
|
75
|
+
|
76
|
+
for (size_t j = 0; j < n; ++j, jy += incy) {
|
77
|
+
if (y[jy] != 0) {
|
78
|
+
DType temp = alpha * y[jy];
|
79
|
+
|
80
|
+
for (size_t i = 0, ix = kx; i < m; ++i, ix += incx) {
|
81
|
+
a[i + j * lda] += x[ix] * temp;
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
}
|
87
|
+
|
88
|
+
return 0;
|
89
|
+
|
90
|
+
/* End of DGER . */
|
91
|
+
|
92
|
+
} /* dger_ */
|
93
|
+
|
94
|
+
}} // end nm::math
|
95
|
+
|
96
|
+
#endif // GER_H
|
@@ -0,0 +1,80 @@
|
|
1
|
+
/////////////////////////////////////////////////////////////////////
|
2
|
+
// = NMatrix
|
3
|
+
//
|
4
|
+
// A linear algebra library for scientific computation in Ruby.
|
5
|
+
// NMatrix is part of SciRuby.
|
6
|
+
//
|
7
|
+
// NMatrix was originally inspired by and derived from NArray, by
|
8
|
+
// Masahiro Tanaka: http://narray.rubyforge.org
|
9
|
+
//
|
10
|
+
// == Copyright Information
|
11
|
+
//
|
12
|
+
// SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
|
13
|
+
// NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
|
14
|
+
//
|
15
|
+
// Please see LICENSE.txt for additional copyright notices.
|
16
|
+
//
|
17
|
+
// == Contributing
|
18
|
+
//
|
19
|
+
// By contributing source code to SciRuby, you agree to be bound by
|
20
|
+
// our Contributor Agreement:
|
21
|
+
//
|
22
|
+
// * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
|
23
|
+
//
|
24
|
+
// == gesdd.h
|
25
|
+
//
|
26
|
+
// Header file for interface with LAPACK's xGESDD functions.
|
27
|
+
//
|
28
|
+
|
29
|
+
#ifndef GESDD_H
|
30
|
+
# define GESDD_H
|
31
|
+
|
32
|
+
extern "C" {
|
33
|
+
|
34
|
+
void sgesdd_(char*, int*, int*, float*, int*, float*, float*, int*, float*, int*, float*, int*, int*, int*);
|
35
|
+
void dgesdd_(char*, int*, int*, double*, int*, double*, double*, int*, double*, int*, double*, int*, int*, int*);
|
36
|
+
void cgesdd_(char*, int*, int*, nm::Complex64*, int*, nm::Complex64*, nm::Complex64*, int*, nm::Complex64*, int*, nm::Complex64*, int*, float*, int*, int*);
|
37
|
+
void zgesdd_(char*, int*, int*, nm::Complex128*, int*, nm::Complex128*, nm::Complex128*, int*, nm::Complex128*, int*, nm::Complex128*, int*, double*, int*, int*);
|
38
|
+
}
|
39
|
+
|
40
|
+
namespace nm {
|
41
|
+
namespace math {
|
42
|
+
|
43
|
+
template <typename DType, typename CType>
|
44
|
+
inline int gesdd(char jobz, int m, int n, DType* a, int lda, DType* s, DType* u, int ldu, DType* vt, int ldvt, DType* work, int lwork, int* iwork, CType* rwork) {
|
45
|
+
rb_raise(rb_eNotImpError, "not yet implemented for non-BLAS dtypes");
|
46
|
+
return -1;
|
47
|
+
}
|
48
|
+
|
49
|
+
template <>
|
50
|
+
inline int gesdd(char jobz, int m, int n, float* a, int lda, float* s, float* u, int ldu, float* vt, int ldvt, float* work, int lwork, int* iwork, float* rwork) {
|
51
|
+
int info;
|
52
|
+
sgesdd_(&jobz, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, iwork, &info);
|
53
|
+
return info;
|
54
|
+
}
|
55
|
+
|
56
|
+
template <>
|
57
|
+
inline int gesdd(char jobz, int m, int n, double* a, int lda, double* s, double* u, int ldu, double* vt, int ldvt, double* work, int lwork, int* iwork, double* rwork) {
|
58
|
+
int info;
|
59
|
+
dgesdd_(&jobz, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, iwork, &info);
|
60
|
+
return info;
|
61
|
+
}
|
62
|
+
|
63
|
+
template <>
|
64
|
+
inline int gesdd(char jobz, int m, int n, nm::Complex64* a, int lda, nm::Complex64* s, nm::Complex64* u, int ldu, nm::Complex64* vt, int ldvt, nm::Complex64* work, int lwork, int* iwork, float* rwork) {
|
65
|
+
int info;
|
66
|
+
cgesdd_(&jobz, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, rwork, iwork, &info);
|
67
|
+
return info;
|
68
|
+
}
|
69
|
+
|
70
|
+
template <>
|
71
|
+
inline int gesdd(char jobz, int m, int n, nm::Complex128* a, int lda, nm::Complex128* s, nm::Complex128* u, int ldu, nm::Complex128* vt, int ldvt, nm::Complex128* work, int lwork, int* iwork, double* rwork) {
|
72
|
+
int info;
|
73
|
+
zgesdd_(&jobz, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, rwork, iwork, &info);
|
74
|
+
return info;
|
75
|
+
}
|
76
|
+
|
77
|
+
} // end of namespace math
|
78
|
+
} // end of namespace nm
|
79
|
+
|
80
|
+
#endif // GESDD_H
|
@@ -0,0 +1,78 @@
|
|
1
|
+
/////////////////////////////////////////////////////////////////////
|
2
|
+
// = NMatrix
|
3
|
+
//
|
4
|
+
// A linear algebra library for scientific computation in Ruby.
|
5
|
+
// NMatrix is part of SciRuby.
|
6
|
+
//
|
7
|
+
// NMatrix was originally inspired by and derived from NArray, by
|
8
|
+
// Masahiro Tanaka: http://narray.rubyforge.org
|
9
|
+
//
|
10
|
+
// == Copyright Information
|
11
|
+
//
|
12
|
+
// SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
|
13
|
+
// NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
|
14
|
+
//
|
15
|
+
// Please see LICENSE.txt for additional copyright notices.
|
16
|
+
//
|
17
|
+
// == Contributing
|
18
|
+
//
|
19
|
+
// By contributing source code to SciRuby, you agree to be bound by
|
20
|
+
// our Contributor Agreement:
|
21
|
+
//
|
22
|
+
// * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
|
23
|
+
//
|
24
|
+
// == gesvd.h
|
25
|
+
//
|
26
|
+
// Header file for interface with LAPACK's xGESVD functions.
|
27
|
+
//
|
28
|
+
|
29
|
+
#ifndef GESVD_H
|
30
|
+
# define GESVD_H
|
31
|
+
|
32
|
+
extern "C" {
|
33
|
+
void sgesvd_(char*, char*, int*, int*, float*, int*, float*, float*, int*, float*, int*, float*, int*, int*);
|
34
|
+
void dgesvd_(char*, char*, int*, int*, double*, int*, double*, double*, int*, double*, int*, double*, int*, int*);
|
35
|
+
void cgesvd_(char*, char*, int*, int*, nm::Complex64*, int*, nm::Complex64*, nm::Complex64*, int*, nm::Complex64*, int*, nm::Complex64*, int*, float*, int*);
|
36
|
+
void zgesvd_(char*, char*, int*, int*, nm::Complex128*, int*, nm::Complex128*, nm::Complex128*, int*, nm::Complex128*, int*, nm::Complex128*, int*, double*, int*);
|
37
|
+
}
|
38
|
+
|
39
|
+
namespace nm {
|
40
|
+
namespace math {
|
41
|
+
|
42
|
+
template <typename DType, typename CType>
|
43
|
+
inline int gesvd(char jobu, char jobvt, int m, int n, DType* a, int lda, DType* s, DType* u, int ldu, DType* vt, int ldvt, DType* work, int lwork, CType* rwork) {
|
44
|
+
rb_raise(rb_eNotImpError, "not yet implemented for non-BLAS dtypes");
|
45
|
+
return -1;
|
46
|
+
}
|
47
|
+
|
48
|
+
template <>
|
49
|
+
inline int gesvd(char jobu, char jobvt, int m, int n, float* a, int lda, float* s, float* u, int ldu, float* vt, int ldvt, float* work, int lwork, float* rwork) {
|
50
|
+
int info;
|
51
|
+
sgesvd_(&jobu, &jobvt, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, &info);
|
52
|
+
return info;
|
53
|
+
}
|
54
|
+
|
55
|
+
template <>
|
56
|
+
inline int gesvd(char jobu, char jobvt, int m, int n, double* a, int lda, double* s, double* u, int ldu, double* vt, int ldvt, double* work, int lwork, double* rwork) {
|
57
|
+
int info;
|
58
|
+
dgesvd_(&jobu, &jobvt, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, &info);
|
59
|
+
return info;
|
60
|
+
}
|
61
|
+
|
62
|
+
template <>
|
63
|
+
inline int gesvd(char jobu, char jobvt, int m, int n, nm::Complex64* a, int lda, nm::Complex64* s, nm::Complex64* u, int ldu, nm::Complex64* vt, int ldvt, nm::Complex64* work, int lwork, float* rwork) {
|
64
|
+
int info;
|
65
|
+
cgesvd_(&jobu, &jobvt, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, rwork, &info);
|
66
|
+
return info;
|
67
|
+
}
|
68
|
+
|
69
|
+
template <>
|
70
|
+
inline int gesvd(char jobu, char jobvt, int m, int n, nm::Complex128* a, int lda, nm::Complex128* s, nm::Complex128* u, int ldu, nm::Complex128* vt, int ldvt, nm::Complex128* work, int lwork, double* rwork) {
|
71
|
+
int info;
|
72
|
+
zgesvd_(&jobu, &jobvt, &m, &n, a, &lda, s, u, &ldu, vt, &ldvt, work, &lwork, rwork, &info);
|
73
|
+
return info;
|
74
|
+
}
|
75
|
+
|
76
|
+
} // end of namespace math
|
77
|
+
} // end of namespace nm
|
78
|
+
#endif // GESVD_H
|