nmatrix-fftw 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/ext/nmatrix/data/complex.h +388 -0
  3. data/ext/nmatrix/data/data.h +652 -0
  4. data/ext/nmatrix/data/meta.h +64 -0
  5. data/ext/nmatrix/data/ruby_object.h +389 -0
  6. data/ext/nmatrix/math/asum.h +120 -0
  7. data/ext/nmatrix/math/cblas_enums.h +36 -0
  8. data/ext/nmatrix/math/cblas_templates_core.h +507 -0
  9. data/ext/nmatrix/math/gemm.h +241 -0
  10. data/ext/nmatrix/math/gemv.h +178 -0
  11. data/ext/nmatrix/math/getrf.h +255 -0
  12. data/ext/nmatrix/math/getrs.h +121 -0
  13. data/ext/nmatrix/math/imax.h +79 -0
  14. data/ext/nmatrix/math/laswp.h +165 -0
  15. data/ext/nmatrix/math/long_dtype.h +49 -0
  16. data/ext/nmatrix/math/math.h +745 -0
  17. data/ext/nmatrix/math/nrm2.h +160 -0
  18. data/ext/nmatrix/math/rot.h +117 -0
  19. data/ext/nmatrix/math/rotg.h +106 -0
  20. data/ext/nmatrix/math/scal.h +71 -0
  21. data/ext/nmatrix/math/trsm.h +332 -0
  22. data/ext/nmatrix/math/util.h +148 -0
  23. data/ext/nmatrix/nm_memory.h +60 -0
  24. data/ext/nmatrix/nmatrix.h +438 -0
  25. data/ext/nmatrix/ruby_constants.h +106 -0
  26. data/ext/nmatrix/storage/common.h +177 -0
  27. data/ext/nmatrix/storage/dense/dense.h +129 -0
  28. data/ext/nmatrix/storage/list/list.h +138 -0
  29. data/ext/nmatrix/storage/storage.h +99 -0
  30. data/ext/nmatrix/storage/yale/class.h +1139 -0
  31. data/ext/nmatrix/storage/yale/iterators/base.h +143 -0
  32. data/ext/nmatrix/storage/yale/iterators/iterator.h +131 -0
  33. data/ext/nmatrix/storage/yale/iterators/row.h +450 -0
  34. data/ext/nmatrix/storage/yale/iterators/row_stored.h +140 -0
  35. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +169 -0
  36. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +124 -0
  37. data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
  38. data/ext/nmatrix/storage/yale/yale.h +203 -0
  39. data/ext/nmatrix/types.h +55 -0
  40. data/ext/nmatrix/util/io.h +115 -0
  41. data/ext/nmatrix/util/sl_list.h +144 -0
  42. data/ext/nmatrix/util/util.h +78 -0
  43. data/ext/nmatrix_fftw/extconf.rb +122 -0
  44. data/ext/nmatrix_fftw/nmatrix_fftw.cpp +274 -0
  45. data/lib/nmatrix/fftw.rb +343 -0
  46. data/spec/00_nmatrix_spec.rb +736 -0
  47. data/spec/01_enum_spec.rb +190 -0
  48. data/spec/02_slice_spec.rb +389 -0
  49. data/spec/03_nmatrix_monkeys_spec.rb +78 -0
  50. data/spec/2x2_dense_double.mat +0 -0
  51. data/spec/4x4_sparse.mat +0 -0
  52. data/spec/4x5_dense.mat +0 -0
  53. data/spec/blas_spec.rb +193 -0
  54. data/spec/elementwise_spec.rb +303 -0
  55. data/spec/homogeneous_spec.rb +99 -0
  56. data/spec/io/fortran_format_spec.rb +88 -0
  57. data/spec/io/harwell_boeing_spec.rb +98 -0
  58. data/spec/io/test.rua +9 -0
  59. data/spec/io_spec.rb +149 -0
  60. data/spec/lapack_core_spec.rb +482 -0
  61. data/spec/leakcheck.rb +16 -0
  62. data/spec/math_spec.rb +807 -0
  63. data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
  64. data/spec/nmatrix_yale_spec.rb +286 -0
  65. data/spec/plugins/fftw/fftw_spec.rb +348 -0
  66. data/spec/rspec_monkeys.rb +56 -0
  67. data/spec/rspec_spec.rb +34 -0
  68. data/spec/shortcuts_spec.rb +310 -0
  69. data/spec/slice_set_spec.rb +157 -0
  70. data/spec/spec_helper.rb +149 -0
  71. data/spec/stat_spec.rb +203 -0
  72. data/spec/test.pcd +20 -0
  73. data/spec/utm5940.mtx +83844 -0
  74. metadata +151 -0
@@ -0,0 +1,332 @@
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
+ // == trsm.h
25
+ //
26
+ // trsm function in native C++.
27
+ //
28
+ /*
29
+ * Automatically Tuned Linear Algebra Software v3.8.4
30
+ * (C) Copyright 1999 R. Clint Whaley
31
+ *
32
+ * Redistribution and use in source and binary forms, with or without
33
+ * modification, are permitted provided that the following conditions
34
+ * are met:
35
+ * 1. Redistributions of source code must retain the above copyright
36
+ * notice, this list of conditions and the following disclaimer.
37
+ * 2. Redistributions in binary form must reproduce the above copyright
38
+ * notice, this list of conditions, and the following disclaimer in the
39
+ * documentation and/or other materials provided with the distribution.
40
+ * 3. The name of the ATLAS group or the names of its contributers may
41
+ * not be used to endorse or promote products derived from this
42
+ * software without specific written permission.
43
+ *
44
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
45
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
46
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
47
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ATLAS GROUP OR ITS CONTRIBUTORS
48
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
49
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
50
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
51
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
52
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
54
+ * POSSIBILITY OF SUCH DAMAGE.
55
+ *
56
+ */
57
+
58
+ #ifndef TRSM_H
59
+ #define TRSM_H
60
+
61
+
62
+ namespace nm { namespace math {
63
+
64
+
65
+ /*
66
+ * This version of trsm doesn't do any error checks and only works on column-major matrices.
67
+ *
68
+ * For row major, call trsm<DType> instead. That will handle necessary changes-of-variables
69
+ * and parameter checks.
70
+ *
71
+ * Note that some of the boundary conditions here may be incorrect. Very little has been tested!
72
+ * This was converted directly from dtrsm.f using f2c, and then rewritten more cleanly.
73
+ */
74
+ template <typename DType>
75
+ inline void trsm_nothrow(const enum CBLAS_SIDE side, const enum CBLAS_UPLO uplo,
76
+ const enum CBLAS_TRANSPOSE trans_a, const enum CBLAS_DIAG diag,
77
+ const int m, const int n, const DType alpha, const DType* a,
78
+ const int lda, DType* b, const int ldb)
79
+ {
80
+
81
+ // (row-major) trsm: left upper trans nonunit m=3 n=1 1/1 a 3 b 3
82
+
83
+ if (m == 0 || n == 0) return; /* Quick return if possible. */
84
+
85
+ if (alpha == 0) { // Handle alpha == 0
86
+ for (int j = 0; j < n; ++j) {
87
+ for (int i = 0; i < m; ++i) {
88
+ b[i + j * ldb] = 0;
89
+ }
90
+ }
91
+ return;
92
+ }
93
+
94
+ if (side == CblasLeft) {
95
+ if (trans_a == CblasNoTrans) {
96
+
97
+ /* Form B := alpha*inv( A )*B. */
98
+ if (uplo == CblasUpper) {
99
+ for (int j = 0; j < n; ++j) {
100
+ if (alpha != 1) {
101
+ for (int i = 0; i < m; ++i) {
102
+ b[i + j * ldb] = alpha * b[i + j * ldb];
103
+ }
104
+ }
105
+ for (int k = m-1; k >= 0; --k) {
106
+ if (b[k + j * ldb] != 0) {
107
+ if (diag == CblasNonUnit) {
108
+ b[k + j * ldb] /= a[k + k * lda];
109
+ }
110
+
111
+ for (int i = 0; i < k-1; ++i) {
112
+ b[i + j * ldb] -= b[k + j * ldb] * a[i + k * lda];
113
+ }
114
+ }
115
+ }
116
+ }
117
+ } else {
118
+ for (int j = 0; j < n; ++j) {
119
+ if (alpha != 1) {
120
+ for (int i = 0; i < m; ++i) {
121
+ b[i + j * ldb] = alpha * b[i + j * ldb];
122
+ }
123
+ }
124
+ for (int k = 0; k < m; ++k) {
125
+ if (b[k + j * ldb] != 0.) {
126
+ if (diag == CblasNonUnit) {
127
+ b[k + j * ldb] /= a[k + k * lda];
128
+ }
129
+ for (int i = k+1; i < m; ++i) {
130
+ b[i + j * ldb] -= b[k + j * ldb] * a[i + k * lda];
131
+ }
132
+ }
133
+ }
134
+ }
135
+ }
136
+ } else { // CblasTrans
137
+
138
+ /* Form B := alpha*inv( A**T )*B. */
139
+ if (uplo == CblasUpper) {
140
+ for (int j = 0; j < n; ++j) {
141
+ for (int i = 0; i < m; ++i) {
142
+ DType temp = alpha * b[i + j * ldb];
143
+ for (int k = 0; k < i; ++k) { // limit was i-1. Lots of similar bugs in this code, probably.
144
+ temp -= a[k + i * lda] * b[k + j * ldb];
145
+ }
146
+ if (diag == CblasNonUnit) {
147
+ temp /= a[i + i * lda];
148
+ }
149
+ b[i + j * ldb] = temp;
150
+ }
151
+ }
152
+ } else {
153
+ for (int j = 0; j < n; ++j) {
154
+ for (int i = m-1; i >= 0; --i) {
155
+ DType temp= alpha * b[i + j * ldb];
156
+ for (int k = i+1; k < m; ++k) {
157
+ temp -= a[k + i * lda] * b[k + j * ldb];
158
+ }
159
+ if (diag == CblasNonUnit) {
160
+ temp /= a[i + i * lda];
161
+ }
162
+ b[i + j * ldb] = temp;
163
+ }
164
+ }
165
+ }
166
+ }
167
+ } else { // right side
168
+
169
+ if (trans_a == CblasNoTrans) {
170
+
171
+ /* Form B := alpha*B*inv( A ). */
172
+
173
+ if (uplo == CblasUpper) {
174
+ for (int j = 0; j < n; ++j) {
175
+ if (alpha != 1) {
176
+ for (int i = 0; i < m; ++i) {
177
+ b[i + j * ldb] = alpha * b[i + j * ldb];
178
+ }
179
+ }
180
+ for (int k = 0; k < j-1; ++k) {
181
+ if (a[k + j * lda] != 0) {
182
+ for (int i = 0; i < m; ++i) {
183
+ b[i + j * ldb] -= a[k + j * lda] * b[i + k * ldb];
184
+ }
185
+ }
186
+ }
187
+ if (diag == CblasNonUnit) {
188
+ DType temp = 1 / a[j + j * lda];
189
+ for (int i = 0; i < m; ++i) {
190
+ b[i + j * ldb] = temp * b[i + j * ldb];
191
+ }
192
+ }
193
+ }
194
+ } else {
195
+ for (int j = n-1; j >= 0; --j) {
196
+ if (alpha != 1) {
197
+ for (int i = 0; i < m; ++i) {
198
+ b[i + j * ldb] = alpha * b[i + j * ldb];
199
+ }
200
+ }
201
+
202
+ for (int k = j+1; k < n; ++k) {
203
+ if (a[k + j * lda] != 0.) {
204
+ for (int i = 0; i < m; ++i) {
205
+ b[i + j * ldb] -= a[k + j * lda] * b[i + k * ldb];
206
+ }
207
+ }
208
+ }
209
+ if (diag == CblasNonUnit) {
210
+ DType temp = 1 / a[j + j * lda];
211
+
212
+ for (int i = 0; i < m; ++i) {
213
+ b[i + j * ldb] = temp * b[i + j * ldb];
214
+ }
215
+ }
216
+ }
217
+ }
218
+ } else { // CblasTrans
219
+
220
+ /* Form B := alpha*B*inv( A**T ). */
221
+
222
+ if (uplo == CblasUpper) {
223
+ for (int k = n-1; k >= 0; --k) {
224
+ if (diag == CblasNonUnit) {
225
+ DType temp= 1 / a[k + k * lda];
226
+ for (int i = 0; i < m; ++i) {
227
+ b[i + k * ldb] = temp * b[i + k * ldb];
228
+ }
229
+ }
230
+ for (int j = 0; j < k-1; ++j) {
231
+ if (a[j + k * lda] != 0.) {
232
+ DType temp= a[j + k * lda];
233
+ for (int i = 0; i < m; ++i) {
234
+ b[i + j * ldb] -= temp * b[i + k * ldb];
235
+ }
236
+ }
237
+ }
238
+ if (alpha != 1) {
239
+ for (int i = 0; i < m; ++i) {
240
+ b[i + k * ldb] = alpha * b[i + k * ldb];
241
+ }
242
+ }
243
+ }
244
+ } else {
245
+ for (int k = 0; k < n; ++k) {
246
+ if (diag == CblasNonUnit) {
247
+ DType temp = 1 / a[k + k * lda];
248
+ for (int i = 0; i < m; ++i) {
249
+ b[i + k * ldb] = temp * b[i + k * ldb];
250
+ }
251
+ }
252
+ for (int j = k+1; j < n; ++j) {
253
+ if (a[j + k * lda] != 0.) {
254
+ DType temp = a[j + k * lda];
255
+ for (int i = 0; i < m; ++i) {
256
+ b[i + j * ldb] -= temp * b[i + k * ldb];
257
+ }
258
+ }
259
+ }
260
+ if (alpha != 1) {
261
+ for (int i = 0; i < m; ++i) {
262
+ b[i + k * ldb] = alpha * b[i + k * ldb];
263
+ }
264
+ }
265
+ }
266
+ }
267
+ }
268
+ }
269
+ }
270
+
271
+ /*
272
+ * BLAS' DTRSM function, generalized.
273
+ */
274
+ template <typename DType, typename = typename std::enable_if<!std::is_integral<DType>::value>::type>
275
+ inline void trsm(const enum CBLAS_ORDER order,
276
+ const enum CBLAS_SIDE side, const enum CBLAS_UPLO uplo,
277
+ const enum CBLAS_TRANSPOSE trans_a, const enum CBLAS_DIAG diag,
278
+ const int m, const int n, const DType alpha, const DType* a,
279
+ const int lda, DType* b, const int ldb)
280
+ {
281
+ /*using std::cerr;
282
+ using std::endl;*/
283
+
284
+ int num_rows_a = n;
285
+ if (side == CblasLeft) num_rows_a = m;
286
+
287
+ if (lda < std::max(1,num_rows_a)) {
288
+ fprintf(stderr, "TRSM: num_rows_a = %d; got lda=%d\n", num_rows_a, lda);
289
+ rb_raise(rb_eArgError, "TRSM: Expected lda >= max(1, num_rows_a)");
290
+ }
291
+
292
+ // Test the input parameters.
293
+ if (order == CblasRowMajor) {
294
+ if (ldb < std::max(1,n)) {
295
+ fprintf(stderr, "TRSM: M=%d; got ldb=%d\n", m, ldb);
296
+ rb_raise(rb_eArgError, "TRSM: Expected ldb >= max(1,N)");
297
+ }
298
+
299
+ // For row major, need to switch side and uplo
300
+ enum CBLAS_SIDE side_ = side == CblasLeft ? CblasRight : CblasLeft;
301
+ enum CBLAS_UPLO uplo_ = uplo == CblasUpper ? CblasLower : CblasUpper;
302
+
303
+ /*
304
+ cerr << "(row-major) trsm: " << (side_ == CblasLeft ? "left " : "right ")
305
+ << (uplo_ == CblasUpper ? "upper " : "lower ")
306
+ << (trans_a == CblasTrans ? "trans " : "notrans ")
307
+ << (diag == CblasNonUnit ? "nonunit " : "unit ")
308
+ << n << " " << m << " " << alpha << " a " << lda << " b " << ldb << endl;
309
+ */
310
+ trsm_nothrow<DType>(side_, uplo_, trans_a, diag, n, m, alpha, a, lda, b, ldb);
311
+
312
+ } else { // CblasColMajor
313
+
314
+ if (ldb < std::max(1,m)) {
315
+ fprintf(stderr, "TRSM: M=%d; got ldb=%d\n", m, ldb);
316
+ rb_raise(rb_eArgError, "TRSM: Expected ldb >= max(1,M)");
317
+ }
318
+ /*
319
+ cerr << "(col-major) trsm: " << (side == CblasLeft ? "left " : "right ")
320
+ << (uplo == CblasUpper ? "upper " : "lower ")
321
+ << (trans_a == CblasTrans ? "trans " : "notrans ")
322
+ << (diag == CblasNonUnit ? "nonunit " : "unit ")
323
+ << m << " " << n << " " << alpha << " a " << lda << " b " << ldb << endl;
324
+ */
325
+ trsm_nothrow<DType>(side, uplo, trans_a, diag, m, n, alpha, a, lda, b, ldb);
326
+
327
+ }
328
+
329
+ }
330
+
331
+ } } // namespace nm::math
332
+ #endif // TRSM_H
@@ -0,0 +1,148 @@
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
+ // == util.h
25
+ //
26
+ // Collect a few utility functions which convert ruby symbols into arguments
27
+ // that CBLAS or LAPACK can understand: either enum's for CBLAS or char's
28
+ // for LAPACK.
29
+ //
30
+
31
+ #ifndef UTIL_H
32
+ #define UTIL_H
33
+
34
+ /* Interprets cblas argument which could be any of false/:no_transpose, :transpose, or :complex_conjugate,
35
+ * into an enum recognized by cblas.
36
+ *
37
+ * Called by nm_cblas_gemm -- basically inline.
38
+ *
39
+ */
40
+ static inline enum CBLAS_TRANSPOSE blas_transpose_sym(VALUE op) {
41
+ if (op == Qfalse || rb_to_id(op) == nm_rb_no_transpose) return CblasNoTrans;
42
+ else if (rb_to_id(op) == nm_rb_transpose) return CblasTrans;
43
+ else if (rb_to_id(op) == nm_rb_complex_conjugate) return CblasConjTrans;
44
+ else rb_raise(rb_eArgError, "Expected false, :transpose, or :complex_conjugate");
45
+ return CblasNoTrans;
46
+ }
47
+
48
+ /* Interprets transpose argument which could be any of false/:no_transpose, :transpose, or :complex_conjugate,
49
+ * into an character recognized by LAPACKE. LAPACKE uses a different system than CBLAS for this.
50
+ *
51
+ */
52
+ static inline char lapacke_transpose_sym(VALUE op) {
53
+ if (op == Qfalse || rb_to_id(op) == nm_rb_no_transpose) return 'N';
54
+ else if (rb_to_id(op) == nm_rb_transpose) return 'T';
55
+ else if (rb_to_id(op) == nm_rb_complex_conjugate) return 'C';
56
+ else rb_raise(rb_eArgError, "Expected false, :transpose, or :complex_conjugate");
57
+ return 'N';
58
+ }
59
+
60
+ /*
61
+ * Interprets cblas argument which could be :left or :right
62
+ *
63
+ * Called by nm_cblas_trsm -- basically inline
64
+ */
65
+ static inline enum CBLAS_SIDE blas_side_sym(VALUE op) {
66
+ ID op_id = rb_to_id(op);
67
+ if (op_id == nm_rb_left) return CblasLeft;
68
+ if (op_id == nm_rb_right) return CblasRight;
69
+ rb_raise(rb_eArgError, "Expected :left or :right for side argument");
70
+ return CblasLeft;
71
+ }
72
+
73
+ /*
74
+ * Interprets cblas argument which could be :upper or :lower
75
+ *
76
+ * Called by nm_cblas_trsm -- basically inline
77
+ */
78
+ static inline enum CBLAS_UPLO blas_uplo_sym(VALUE op) {
79
+ ID op_id = rb_to_id(op);
80
+ if (op_id == nm_rb_upper) return CblasUpper;
81
+ if (op_id == nm_rb_lower) return CblasLower;
82
+ rb_raise(rb_eArgError, "Expected :upper or :lower for uplo argument");
83
+ return CblasUpper;
84
+ }
85
+
86
+ /*
87
+ * Interprets argument which could be :upper or :lower for LAPACKE
88
+ *
89
+ * Called by nm_cblas_trsm -- basically inline
90
+ */
91
+ static inline char lapacke_uplo_sym(VALUE op) {
92
+ ID op_id = rb_to_id(op);
93
+ if (op_id == nm_rb_upper) return 'U';
94
+ if (op_id == nm_rb_lower) return 'L';
95
+ rb_raise(rb_eArgError, "Expected :upper or :lower for uplo argument");
96
+ return 'U';
97
+ }
98
+
99
+ /*
100
+ * Interprets cblas argument which could be :unit (true) or :nonunit (false or anything other than true/:unit)
101
+ *
102
+ * Called by nm_cblas_trsm -- basically inline
103
+ */
104
+ static inline enum CBLAS_DIAG blas_diag_sym(VALUE op) {
105
+ if (rb_to_id(op) == nm_rb_unit || op == Qtrue) return CblasUnit;
106
+ return CblasNonUnit;
107
+ }
108
+
109
+ /*
110
+ * Interprets cblas argument which could be :row or :col
111
+ *
112
+ * This function, unlike the other ones, works for LAPACKE as well as for CBLAS/CLAPACK.
113
+ * Although LAPACKE calls this an int instead of a enum, the magic values are the same
114
+ * (101 for row-major, 102 for column-major).
115
+ */
116
+ static inline enum CBLAS_ORDER blas_order_sym(VALUE op) {
117
+ if (rb_to_id(op) == rb_intern("row") || rb_to_id(op) == rb_intern("row_major")) return CblasRowMajor;
118
+ else if (rb_to_id(op) == rb_intern("col") || rb_to_id(op) == rb_intern("col_major") ||
119
+ rb_to_id(op) == rb_intern("column") || rb_to_id(op) == rb_intern("column_major")) return CblasColMajor;
120
+ rb_raise(rb_eArgError, "Expected :row or :col for order argument");
121
+ return CblasRowMajor;
122
+ }
123
+
124
+ /*
125
+ * Interprets lapack jobu and jobvt arguments, for which LAPACK needs character values A, S, O, or N.
126
+ *
127
+ * Called by lapack_gesvd -- basically inline. svd stands for singular value decomposition.
128
+ */
129
+ static inline char lapack_svd_job_sym(VALUE op) {
130
+ if (rb_to_id(op) == rb_intern("all") || rb_to_id(op) == rb_intern("a")) return 'A';
131
+ else if (rb_to_id(op) == rb_intern("return") || rb_to_id(op) == rb_intern("s")) return 'S';
132
+ else if (rb_to_id(op) == rb_intern("overwrite") || rb_to_id(op) == rb_intern("o")) return 'O';
133
+ else if (rb_to_id(op) == rb_intern("none") || rb_to_id(op) == rb_intern("n")) return 'N';
134
+ else rb_raise(rb_eArgError, "Expected :all, :return, :overwrite, :none (or :a, :s, :o, :n, respectively)");
135
+ return 'a';
136
+ }
137
+
138
+ /*
139
+ * Interprets lapack jobvl and jobvr arguments, for which LAPACK needs character values N or V.
140
+ *
141
+ * Called by lapack_geev -- basically inline. evd stands for eigenvalue decomposition.
142
+ */
143
+ static inline char lapack_evd_job_sym(VALUE op) {
144
+ if (op == Qfalse || op == Qnil || rb_to_id(op) == rb_intern("n")) return 'N';
145
+ else return 'V';
146
+ }
147
+
148
+ #endif