nmatrix-atlas 0.2.0
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/ext/nmatrix/data/complex.h +364 -0
- data/ext/nmatrix/data/data.h +638 -0
- data/ext/nmatrix/data/meta.h +64 -0
- data/ext/nmatrix/data/ruby_object.h +389 -0
- data/ext/nmatrix/math/asum.h +120 -0
- data/ext/nmatrix/math/cblas_enums.h +36 -0
- data/ext/nmatrix/math/cblas_templates_core.h +507 -0
- data/ext/nmatrix/math/gemm.h +241 -0
- data/ext/nmatrix/math/gemv.h +178 -0
- data/ext/nmatrix/math/getrf.h +255 -0
- data/ext/nmatrix/math/getrs.h +121 -0
- data/ext/nmatrix/math/imax.h +79 -0
- data/ext/nmatrix/math/laswp.h +165 -0
- data/ext/nmatrix/math/long_dtype.h +49 -0
- data/ext/nmatrix/math/math.h +744 -0
- data/ext/nmatrix/math/nrm2.h +160 -0
- data/ext/nmatrix/math/rot.h +117 -0
- data/ext/nmatrix/math/rotg.h +106 -0
- data/ext/nmatrix/math/scal.h +71 -0
- data/ext/nmatrix/math/trsm.h +332 -0
- data/ext/nmatrix/math/util.h +148 -0
- data/ext/nmatrix/nm_memory.h +60 -0
- data/ext/nmatrix/nmatrix.h +408 -0
- data/ext/nmatrix/ruby_constants.h +106 -0
- data/ext/nmatrix/storage/common.h +176 -0
- data/ext/nmatrix/storage/dense/dense.h +128 -0
- data/ext/nmatrix/storage/list/list.h +137 -0
- data/ext/nmatrix/storage/storage.h +98 -0
- data/ext/nmatrix/storage/yale/class.h +1139 -0
- data/ext/nmatrix/storage/yale/iterators/base.h +142 -0
- data/ext/nmatrix/storage/yale/iterators/iterator.h +130 -0
- data/ext/nmatrix/storage/yale/iterators/row.h +449 -0
- data/ext/nmatrix/storage/yale/iterators/row_stored.h +139 -0
- data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +168 -0
- data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +123 -0
- data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
- data/ext/nmatrix/storage/yale/yale.h +202 -0
- data/ext/nmatrix/types.h +54 -0
- data/ext/nmatrix/util/io.h +115 -0
- data/ext/nmatrix/util/sl_list.h +143 -0
- data/ext/nmatrix/util/util.h +78 -0
- data/ext/nmatrix_atlas/extconf.rb +250 -0
- data/ext/nmatrix_atlas/math_atlas.cpp +1206 -0
- data/ext/nmatrix_atlas/math_atlas/cblas_templates_atlas.h +72 -0
- data/ext/nmatrix_atlas/math_atlas/clapack_templates.h +332 -0
- data/ext/nmatrix_atlas/math_atlas/geev.h +82 -0
- data/ext/nmatrix_atlas/math_atlas/gesdd.h +83 -0
- data/ext/nmatrix_atlas/math_atlas/gesvd.h +81 -0
- data/ext/nmatrix_atlas/math_atlas/inc.h +47 -0
- data/ext/nmatrix_atlas/nmatrix_atlas.cpp +44 -0
- data/lib/nmatrix/atlas.rb +213 -0
- data/lib/nmatrix/lapack_ext_common.rb +69 -0
- data/spec/00_nmatrix_spec.rb +730 -0
- data/spec/01_enum_spec.rb +190 -0
- data/spec/02_slice_spec.rb +389 -0
- data/spec/03_nmatrix_monkeys_spec.rb +78 -0
- data/spec/2x2_dense_double.mat +0 -0
- data/spec/4x4_sparse.mat +0 -0
- data/spec/4x5_dense.mat +0 -0
- data/spec/blas_spec.rb +193 -0
- data/spec/elementwise_spec.rb +303 -0
- data/spec/homogeneous_spec.rb +99 -0
- data/spec/io/fortran_format_spec.rb +88 -0
- data/spec/io/harwell_boeing_spec.rb +98 -0
- data/spec/io/test.rua +9 -0
- data/spec/io_spec.rb +149 -0
- data/spec/lapack_core_spec.rb +482 -0
- data/spec/leakcheck.rb +16 -0
- data/spec/math_spec.rb +730 -0
- data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
- data/spec/nmatrix_yale_spec.rb +286 -0
- data/spec/plugins/atlas/atlas_spec.rb +242 -0
- data/spec/rspec_monkeys.rb +56 -0
- data/spec/rspec_spec.rb +34 -0
- data/spec/shortcuts_spec.rb +310 -0
- data/spec/slice_set_spec.rb +157 -0
- data/spec/spec_helper.rb +140 -0
- data/spec/stat_spec.rb +203 -0
- data/spec/test.pcd +20 -0
- data/spec/utm5940.mtx +83844 -0
- metadata +159 -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
|