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.
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