nmatrix-gemv 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +29 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +14 -0
  5. data/Gemfile +7 -0
  6. data/README.md +29 -0
  7. data/Rakefile +225 -0
  8. data/ext/nmatrix_gemv/binary_format.txt +53 -0
  9. data/ext/nmatrix_gemv/data/complex.h +399 -0
  10. data/ext/nmatrix_gemv/data/data.cpp +298 -0
  11. data/ext/nmatrix_gemv/data/data.h +771 -0
  12. data/ext/nmatrix_gemv/data/meta.h +70 -0
  13. data/ext/nmatrix_gemv/data/rational.h +436 -0
  14. data/ext/nmatrix_gemv/data/ruby_object.h +471 -0
  15. data/ext/nmatrix_gemv/extconf.rb +254 -0
  16. data/ext/nmatrix_gemv/math.cpp +1639 -0
  17. data/ext/nmatrix_gemv/math/asum.h +143 -0
  18. data/ext/nmatrix_gemv/math/geev.h +82 -0
  19. data/ext/nmatrix_gemv/math/gemm.h +271 -0
  20. data/ext/nmatrix_gemv/math/gemv.h +212 -0
  21. data/ext/nmatrix_gemv/math/ger.h +96 -0
  22. data/ext/nmatrix_gemv/math/gesdd.h +80 -0
  23. data/ext/nmatrix_gemv/math/gesvd.h +78 -0
  24. data/ext/nmatrix_gemv/math/getf2.h +86 -0
  25. data/ext/nmatrix_gemv/math/getrf.h +240 -0
  26. data/ext/nmatrix_gemv/math/getri.h +108 -0
  27. data/ext/nmatrix_gemv/math/getrs.h +129 -0
  28. data/ext/nmatrix_gemv/math/idamax.h +86 -0
  29. data/ext/nmatrix_gemv/math/inc.h +47 -0
  30. data/ext/nmatrix_gemv/math/laswp.h +165 -0
  31. data/ext/nmatrix_gemv/math/long_dtype.h +52 -0
  32. data/ext/nmatrix_gemv/math/math.h +1069 -0
  33. data/ext/nmatrix_gemv/math/nrm2.h +181 -0
  34. data/ext/nmatrix_gemv/math/potrs.h +129 -0
  35. data/ext/nmatrix_gemv/math/rot.h +141 -0
  36. data/ext/nmatrix_gemv/math/rotg.h +115 -0
  37. data/ext/nmatrix_gemv/math/scal.h +73 -0
  38. data/ext/nmatrix_gemv/math/swap.h +73 -0
  39. data/ext/nmatrix_gemv/math/trsm.h +387 -0
  40. data/ext/nmatrix_gemv/nm_memory.h +60 -0
  41. data/ext/nmatrix_gemv/nmatrix_gemv.cpp +90 -0
  42. data/ext/nmatrix_gemv/nmatrix_gemv.h +374 -0
  43. data/ext/nmatrix_gemv/ruby_constants.cpp +153 -0
  44. data/ext/nmatrix_gemv/ruby_constants.h +107 -0
  45. data/ext/nmatrix_gemv/ruby_nmatrix.c +84 -0
  46. data/ext/nmatrix_gemv/ttable_helper.rb +122 -0
  47. data/ext/nmatrix_gemv/types.h +54 -0
  48. data/ext/nmatrix_gemv/util/util.h +78 -0
  49. data/lib/nmatrix-gemv.rb +43 -0
  50. data/lib/nmatrix_gemv/blas.rb +85 -0
  51. data/lib/nmatrix_gemv/nmatrix_gemv.rb +35 -0
  52. data/lib/nmatrix_gemv/rspec.rb +75 -0
  53. data/nmatrix-gemv.gemspec +31 -0
  54. data/spec/blas_spec.rb +154 -0
  55. data/spec/spec_helper.rb +128 -0
  56. 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