pnmatrix 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/ext/nmatrix/binary_format.txt +53 -0
  3. data/ext/nmatrix/data/complex.h +388 -0
  4. data/ext/nmatrix/data/data.cpp +274 -0
  5. data/ext/nmatrix/data/data.h +651 -0
  6. data/ext/nmatrix/data/meta.h +64 -0
  7. data/ext/nmatrix/data/ruby_object.h +386 -0
  8. data/ext/nmatrix/extconf.rb +70 -0
  9. data/ext/nmatrix/math/asum.h +99 -0
  10. data/ext/nmatrix/math/cblas_enums.h +36 -0
  11. data/ext/nmatrix/math/cblas_templates_core.h +507 -0
  12. data/ext/nmatrix/math/gemm.h +241 -0
  13. data/ext/nmatrix/math/gemv.h +178 -0
  14. data/ext/nmatrix/math/getrf.h +255 -0
  15. data/ext/nmatrix/math/getrs.h +121 -0
  16. data/ext/nmatrix/math/imax.h +82 -0
  17. data/ext/nmatrix/math/laswp.h +165 -0
  18. data/ext/nmatrix/math/long_dtype.h +62 -0
  19. data/ext/nmatrix/math/magnitude.h +54 -0
  20. data/ext/nmatrix/math/math.h +751 -0
  21. data/ext/nmatrix/math/nrm2.h +165 -0
  22. data/ext/nmatrix/math/rot.h +117 -0
  23. data/ext/nmatrix/math/rotg.h +106 -0
  24. data/ext/nmatrix/math/scal.h +71 -0
  25. data/ext/nmatrix/math/trsm.h +336 -0
  26. data/ext/nmatrix/math/util.h +162 -0
  27. data/ext/nmatrix/math.cpp +1368 -0
  28. data/ext/nmatrix/nm_memory.h +60 -0
  29. data/ext/nmatrix/nmatrix.cpp +285 -0
  30. data/ext/nmatrix/nmatrix.h +476 -0
  31. data/ext/nmatrix/ruby_constants.cpp +151 -0
  32. data/ext/nmatrix/ruby_constants.h +106 -0
  33. data/ext/nmatrix/ruby_nmatrix.c +3130 -0
  34. data/ext/nmatrix/storage/common.cpp +77 -0
  35. data/ext/nmatrix/storage/common.h +183 -0
  36. data/ext/nmatrix/storage/dense/dense.cpp +1096 -0
  37. data/ext/nmatrix/storage/dense/dense.h +129 -0
  38. data/ext/nmatrix/storage/list/list.cpp +1628 -0
  39. data/ext/nmatrix/storage/list/list.h +138 -0
  40. data/ext/nmatrix/storage/storage.cpp +730 -0
  41. data/ext/nmatrix/storage/storage.h +99 -0
  42. data/ext/nmatrix/storage/yale/class.h +1139 -0
  43. data/ext/nmatrix/storage/yale/iterators/base.h +143 -0
  44. data/ext/nmatrix/storage/yale/iterators/iterator.h +131 -0
  45. data/ext/nmatrix/storage/yale/iterators/row.h +450 -0
  46. data/ext/nmatrix/storage/yale/iterators/row_stored.h +140 -0
  47. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +169 -0
  48. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +124 -0
  49. data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
  50. data/ext/nmatrix/storage/yale/yale.cpp +2074 -0
  51. data/ext/nmatrix/storage/yale/yale.h +203 -0
  52. data/ext/nmatrix/types.h +55 -0
  53. data/ext/nmatrix/util/io.cpp +279 -0
  54. data/ext/nmatrix/util/io.h +115 -0
  55. data/ext/nmatrix/util/sl_list.cpp +627 -0
  56. data/ext/nmatrix/util/sl_list.h +144 -0
  57. data/ext/nmatrix/util/util.h +78 -0
  58. data/lib/nmatrix/blas.rb +378 -0
  59. data/lib/nmatrix/cruby/math.rb +744 -0
  60. data/lib/nmatrix/enumerate.rb +253 -0
  61. data/lib/nmatrix/homogeneous.rb +241 -0
  62. data/lib/nmatrix/io/fortran_format.rb +138 -0
  63. data/lib/nmatrix/io/harwell_boeing.rb +221 -0
  64. data/lib/nmatrix/io/market.rb +263 -0
  65. data/lib/nmatrix/io/point_cloud.rb +189 -0
  66. data/lib/nmatrix/jruby/decomposition.rb +24 -0
  67. data/lib/nmatrix/jruby/enumerable.rb +13 -0
  68. data/lib/nmatrix/jruby/error.rb +4 -0
  69. data/lib/nmatrix/jruby/math.rb +501 -0
  70. data/lib/nmatrix/jruby/nmatrix_java.rb +840 -0
  71. data/lib/nmatrix/jruby/operators.rb +283 -0
  72. data/lib/nmatrix/jruby/slice.rb +264 -0
  73. data/lib/nmatrix/lapack_core.rb +181 -0
  74. data/lib/nmatrix/lapack_plugin.rb +44 -0
  75. data/lib/nmatrix/math.rb +953 -0
  76. data/lib/nmatrix/mkmf.rb +100 -0
  77. data/lib/nmatrix/monkeys.rb +137 -0
  78. data/lib/nmatrix/nmatrix.rb +1172 -0
  79. data/lib/nmatrix/rspec.rb +75 -0
  80. data/lib/nmatrix/shortcuts.rb +1163 -0
  81. data/lib/nmatrix/version.rb +39 -0
  82. data/lib/nmatrix/yale_functions.rb +118 -0
  83. data/lib/nmatrix.rb +28 -0
  84. data/spec/00_nmatrix_spec.rb +892 -0
  85. data/spec/01_enum_spec.rb +196 -0
  86. data/spec/02_slice_spec.rb +407 -0
  87. data/spec/03_nmatrix_monkeys_spec.rb +80 -0
  88. data/spec/2x2_dense_double.mat +0 -0
  89. data/spec/4x4_sparse.mat +0 -0
  90. data/spec/4x5_dense.mat +0 -0
  91. data/spec/blas_spec.rb +215 -0
  92. data/spec/elementwise_spec.rb +311 -0
  93. data/spec/homogeneous_spec.rb +100 -0
  94. data/spec/io/fortran_format_spec.rb +88 -0
  95. data/spec/io/harwell_boeing_spec.rb +98 -0
  96. data/spec/io/test.rua +9 -0
  97. data/spec/io_spec.rb +159 -0
  98. data/spec/lapack_core_spec.rb +482 -0
  99. data/spec/leakcheck.rb +16 -0
  100. data/spec/math_spec.rb +1363 -0
  101. data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
  102. data/spec/nmatrix_yale_spec.rb +286 -0
  103. data/spec/rspec_monkeys.rb +56 -0
  104. data/spec/rspec_spec.rb +35 -0
  105. data/spec/shortcuts_spec.rb +474 -0
  106. data/spec/slice_set_spec.rb +162 -0
  107. data/spec/spec_helper.rb +172 -0
  108. data/spec/stat_spec.rb +214 -0
  109. data/spec/test.pcd +20 -0
  110. data/spec/utm5940.mtx +83844 -0
  111. metadata +295 -0
@@ -0,0 +1,336 @@
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
+ // Apply necessary offset
86
+ a -= 1 + lda;
87
+ b -= 1 + ldb;
88
+
89
+ if (alpha == 0) { // Handle alpha == 0
90
+ for (int j = 1; j <= n; ++j) {
91
+ for (int i = 1; i <= m; ++i) {
92
+ b[i + j * ldb] = 0;
93
+ }
94
+ }
95
+ return;
96
+ }
97
+
98
+ if (side == CblasLeft) {
99
+ if (trans_a == CblasNoTrans) {
100
+
101
+ /* Form B := alpha*inv( A )*B. */
102
+ if (uplo == CblasUpper) {
103
+ for (int j = 1; j <= n; ++j) {
104
+ if (alpha != 1) {
105
+ for (int i = 1; i <= m; ++i) {
106
+ b[i + j * ldb] = alpha * b[i + j * ldb];
107
+ }
108
+ }
109
+ for (int k = m; k >= 1; --k) {
110
+ if (b[k + j * ldb] != 0) {
111
+ if (diag == CblasNonUnit) {
112
+ b[k + j * ldb] /= a[k + k * lda];
113
+ }
114
+
115
+ for (int i = 1; i <= k-1; ++i) {
116
+ b[i + j * ldb] -= b[k + j * ldb] * a[i + k * lda];
117
+ }
118
+ }
119
+ }
120
+ }
121
+ } else {
122
+ for (int j = 1; j <= n; ++j) {
123
+ if (alpha != 1) {
124
+ for (int i = 1; i <= m; ++i) {
125
+ b[i + j * ldb] = alpha * b[i + j * ldb];
126
+ }
127
+ }
128
+ for (int k = 1; k <= m; ++k) {
129
+ if (b[k + j * ldb] != 0.) {
130
+ if (diag == CblasNonUnit) {
131
+ b[k + j * ldb] /= a[k + k * lda];
132
+ }
133
+ for (int i = k+1; i <= m; ++i) {
134
+ b[i + j * ldb] -= b[k + j * ldb] * a[i + k * lda];
135
+ }
136
+ }
137
+ }
138
+ }
139
+ }
140
+ } else { // CblasTrans
141
+
142
+ /* Form B := alpha*inv( A**T )*B. */
143
+ if (uplo == CblasUpper) {
144
+ for (int j = 1; j <= n; ++j) {
145
+ for (int i = 1; i <= m; ++i) {
146
+ DType temp = alpha * b[i + j * ldb];
147
+ for (int k = 1; k <= i-1; ++k) { // limit was i-1. Lots of similar bugs in this code, probably.
148
+ temp -= a[k + i * lda] * b[k + j * ldb];
149
+ }
150
+ if (diag == CblasNonUnit) {
151
+ temp /= a[i + i * lda];
152
+ }
153
+ b[i + j * ldb] = temp;
154
+ }
155
+ }
156
+ } else {
157
+ for (int j = 1; j <= n; ++j) {
158
+ for (int i = m; i >= 1; --i) {
159
+ DType temp= alpha * b[i + j * ldb];
160
+ for (int k = i+1; k <= m; ++k) {
161
+ temp -= a[k + i * lda] * b[k + j * ldb];
162
+ }
163
+ if (diag == CblasNonUnit) {
164
+ temp /= a[i + i * lda];
165
+ }
166
+ b[i + j * ldb] = temp;
167
+ }
168
+ }
169
+ }
170
+ }
171
+ } else { // right side
172
+
173
+ if (trans_a == CblasNoTrans) {
174
+
175
+ /* Form B := alpha*B*inv( A ). */
176
+
177
+ if (uplo == CblasUpper) {
178
+ for (int j = 1; j <= n; ++j) {
179
+ if (alpha != 1) {
180
+ for (int i = 1; i <= m; ++i) {
181
+ b[i + j * ldb] = alpha * b[i + j * ldb];
182
+ }
183
+ }
184
+ for (int k = 1; k <= j-1; ++k) {
185
+ if (a[k + j * lda] != 0) {
186
+ for (int i = 1; i <= m; ++i) {
187
+ b[i + j * ldb] -= a[k + j * lda] * b[i + k * ldb];
188
+ }
189
+ }
190
+ }
191
+ if (diag == CblasNonUnit) {
192
+ DType temp = 1 / a[j + j * lda];
193
+ for (int i = 1; i <= m; ++i) {
194
+ b[i + j * ldb] = temp * b[i + j * ldb];
195
+ }
196
+ }
197
+ }
198
+ } else {
199
+ for (int j = n; j >= 1; --j) {
200
+ if (alpha != 1) {
201
+ for (int i = 1; i <= m; ++i) {
202
+ b[i + j * ldb] = alpha * b[i + j * ldb];
203
+ }
204
+ }
205
+
206
+ for (int k = j+1; k <= n; ++k) {
207
+ if (a[k + j * lda] != 0.) {
208
+ for (int i = 1; i <= m; ++i) {
209
+ b[i + j * ldb] -= a[k + j * lda] * b[i + k * ldb];
210
+ }
211
+ }
212
+ }
213
+ if (diag == CblasNonUnit) {
214
+ DType temp = 1 / a[j + j * lda];
215
+
216
+ for (int i = 1; i <= m; ++i) {
217
+ b[i + j * ldb] = temp * b[i + j * ldb];
218
+ }
219
+ }
220
+ }
221
+ }
222
+ } else { // CblasTrans
223
+
224
+ /* Form B := alpha*B*inv( A**T ). */
225
+
226
+ if (uplo == CblasUpper) {
227
+ for (int k = n; k >= 1; --k) {
228
+ if (diag == CblasNonUnit) {
229
+ DType temp= 1 / a[k + k * lda];
230
+ for (int i = 1; i <= m; ++i) {
231
+ b[i + k * ldb] = temp * b[i + k * ldb];
232
+ }
233
+ }
234
+ for (int j = 1; j <= k-1; ++j) {
235
+ if (a[j + k * lda] != 0.) {
236
+ DType temp= a[j + k * lda];
237
+ for (int i = 1; i <= m; ++i) {
238
+ b[i + j * ldb] -= temp * b[i + k * ldb];
239
+ }
240
+ }
241
+ }
242
+ if (alpha != 1) {
243
+ for (int i = 1; i <= m; ++i) {
244
+ b[i + k * ldb] = alpha * b[i + k * ldb];
245
+ }
246
+ }
247
+ }
248
+ } else {
249
+ for (int k = 1; k <= n; ++k) {
250
+ if (diag == CblasNonUnit) {
251
+ DType temp = 1 / a[k + k * lda];
252
+ for (int i = 1; i <= m; ++i) {
253
+ b[i + k * ldb] = temp * b[i + k * ldb];
254
+ }
255
+ }
256
+ for (int j = k+1; j <= n; ++j) {
257
+ if (a[j + k * lda] != 0.) {
258
+ DType temp = a[j + k * lda];
259
+ for (int i = 1; i <= m; ++i) {
260
+ b[i + j * ldb] -= temp * b[i + k * ldb];
261
+ }
262
+ }
263
+ }
264
+ if (alpha != 1) {
265
+ for (int i = 1; i <= m; ++i) {
266
+ b[i + k * ldb] = alpha * b[i + k * ldb];
267
+ }
268
+ }
269
+ }
270
+ }
271
+ }
272
+ }
273
+ }
274
+
275
+ /*
276
+ * BLAS' DTRSM function, generalized.
277
+ */
278
+ template <typename DType, typename = typename std::enable_if<!std::is_integral<DType>::value>::type>
279
+ inline void trsm(const enum CBLAS_ORDER order,
280
+ const enum CBLAS_SIDE side, const enum CBLAS_UPLO uplo,
281
+ const enum CBLAS_TRANSPOSE trans_a, const enum CBLAS_DIAG diag,
282
+ const int m, const int n, const DType alpha, const DType* a,
283
+ const int lda, DType* b, const int ldb)
284
+ {
285
+ /*using std::cerr;
286
+ using std::endl;*/
287
+
288
+ int num_rows_a = n;
289
+ if (side == CblasLeft) num_rows_a = m;
290
+
291
+ if (lda < std::max(1,num_rows_a)) {
292
+ fprintf(stderr, "TRSM: num_rows_a = %d; got lda=%d\n", num_rows_a, lda);
293
+ rb_raise(rb_eArgError, "TRSM: Expected lda >= max(1, num_rows_a)");
294
+ }
295
+
296
+ // Test the input parameters.
297
+ if (order == CblasRowMajor) {
298
+ if (ldb < std::max(1,n)) {
299
+ fprintf(stderr, "TRSM: M=%d; got ldb=%d\n", m, ldb);
300
+ rb_raise(rb_eArgError, "TRSM: Expected ldb >= max(1,N)");
301
+ }
302
+
303
+ // For row major, need to switch side and uplo
304
+ enum CBLAS_SIDE side_ = side == CblasLeft ? CblasRight : CblasLeft;
305
+ enum CBLAS_UPLO uplo_ = uplo == CblasUpper ? CblasLower : CblasUpper;
306
+
307
+ /*
308
+ cerr << "(row-major) trsm: " << (side_ == CblasLeft ? "left " : "right ")
309
+ << (uplo_ == CblasUpper ? "upper " : "lower ")
310
+ << (trans_a == CblasTrans ? "trans " : "notrans ")
311
+ << (diag == CblasNonUnit ? "nonunit " : "unit ")
312
+ << n << " " << m << " " << alpha << " a " << lda << " b " << ldb << endl;
313
+ */
314
+ trsm_nothrow<DType>(side_, uplo_, trans_a, diag, n, m, alpha, a, lda, b, ldb);
315
+
316
+ } else { // CblasColMajor
317
+
318
+ if (ldb < std::max(1,m)) {
319
+ fprintf(stderr, "TRSM: M=%d; got ldb=%d\n", m, ldb);
320
+ rb_raise(rb_eArgError, "TRSM: Expected ldb >= max(1,M)");
321
+ }
322
+ /*
323
+ cerr << "(col-major) trsm: " << (side == CblasLeft ? "left " : "right ")
324
+ << (uplo == CblasUpper ? "upper " : "lower ")
325
+ << (trans_a == CblasTrans ? "trans " : "notrans ")
326
+ << (diag == CblasNonUnit ? "nonunit " : "unit ")
327
+ << m << " " << n << " " << alpha << " a " << lda << " b " << ldb << endl;
328
+ */
329
+ trsm_nothrow<DType>(side, uplo, trans_a, diag, m, n, alpha, a, lda, b, ldb);
330
+
331
+ }
332
+
333
+ }
334
+
335
+ } } // namespace nm::math
336
+ #endif // TRSM_H
@@ -0,0 +1,162 @@
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 the LAPACK side argument which could be :left or :right
75
+ *
76
+ * Related to obtaining Q in QR factorization after calling lapack_geqrf
77
+ */
78
+
79
+ static inline char lapacke_side_sym(VALUE op) {
80
+ ID op_id = rb_to_id(op);
81
+ if (op_id == nm_rb_left) return 'L';
82
+ if (op_id == nm_rb_right) return 'R';
83
+ else rb_raise(rb_eArgError, "Expected :left or :right for side argument");
84
+ return 'L';
85
+ }
86
+
87
+ /*
88
+ * Interprets cblas argument which could be :upper or :lower
89
+ *
90
+ * Called by nm_cblas_trsm -- basically inline
91
+ */
92
+ static inline enum CBLAS_UPLO blas_uplo_sym(VALUE op) {
93
+ ID op_id = rb_to_id(op);
94
+ if (op_id == nm_rb_upper) return CblasUpper;
95
+ if (op_id == nm_rb_lower) return CblasLower;
96
+ rb_raise(rb_eArgError, "Expected :upper or :lower for uplo argument");
97
+ return CblasUpper;
98
+ }
99
+
100
+ /*
101
+ * Interprets argument which could be :upper or :lower for LAPACKE
102
+ *
103
+ * Called by nm_cblas_trsm -- basically inline
104
+ */
105
+ static inline char lapacke_uplo_sym(VALUE op) {
106
+ ID op_id = rb_to_id(op);
107
+ if (op_id == nm_rb_upper) return 'U';
108
+ if (op_id == nm_rb_lower) return 'L';
109
+ rb_raise(rb_eArgError, "Expected :upper or :lower for uplo argument");
110
+ return 'U';
111
+ }
112
+
113
+ /*
114
+ * Interprets cblas argument which could be :unit (true) or :nonunit (false or anything other than true/:unit)
115
+ *
116
+ * Called by nm_cblas_trsm -- basically inline
117
+ */
118
+ static inline enum CBLAS_DIAG blas_diag_sym(VALUE op) {
119
+ if (rb_to_id(op) == nm_rb_unit || op == Qtrue) return CblasUnit;
120
+ return CblasNonUnit;
121
+ }
122
+
123
+ /*
124
+ * Interprets cblas argument which could be :row or :col
125
+ *
126
+ * This function, unlike the other ones, works for LAPACKE as well as for CBLAS/CLAPACK.
127
+ * Although LAPACKE calls this an int instead of a enum, the magic values are the same
128
+ * (101 for row-major, 102 for column-major).
129
+ */
130
+ static inline enum CBLAS_ORDER blas_order_sym(VALUE op) {
131
+ if (rb_to_id(op) == rb_intern("row") || rb_to_id(op) == rb_intern("row_major")) return CblasRowMajor;
132
+ else if (rb_to_id(op) == rb_intern("col") || rb_to_id(op) == rb_intern("col_major") ||
133
+ rb_to_id(op) == rb_intern("column") || rb_to_id(op) == rb_intern("column_major")) return CblasColMajor;
134
+ rb_raise(rb_eArgError, "Expected :row or :col for order argument");
135
+ return CblasRowMajor;
136
+ }
137
+
138
+ /*
139
+ * Interprets lapack jobu and jobvt arguments, for which LAPACK needs character values A, S, O, or N.
140
+ *
141
+ * Called by lapack_gesvd -- basically inline. svd stands for singular value decomposition.
142
+ */
143
+ static inline char lapack_svd_job_sym(VALUE op) {
144
+ if (rb_to_id(op) == rb_intern("all") || rb_to_id(op) == rb_intern("a")) return 'A';
145
+ else if (rb_to_id(op) == rb_intern("return") || rb_to_id(op) == rb_intern("s")) return 'S';
146
+ else if (rb_to_id(op) == rb_intern("overwrite") || rb_to_id(op) == rb_intern("o")) return 'O';
147
+ else if (rb_to_id(op) == rb_intern("none") || rb_to_id(op) == rb_intern("n")) return 'N';
148
+ else rb_raise(rb_eArgError, "Expected :all, :return, :overwrite, :none (or :a, :s, :o, :n, respectively)");
149
+ return 'a';
150
+ }
151
+
152
+ /*
153
+ * Interprets lapack jobvl and jobvr arguments, for which LAPACK needs character values N or V.
154
+ *
155
+ * Called by lapack_geev -- basically inline. evd stands for eigenvalue decomposition.
156
+ */
157
+ static inline char lapack_evd_job_sym(VALUE op) {
158
+ if (op == Qfalse || op == Qnil || rb_to_id(op) == rb_intern("n")) return 'N';
159
+ else return 'V';
160
+ }
161
+
162
+ #endif