nmatrix 0.0.1 → 0.0.2

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 (91) hide show
  1. data/.gitignore +27 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +3 -5
  4. data/Guardfile +6 -0
  5. data/History.txt +33 -0
  6. data/Manifest.txt +41 -38
  7. data/README.rdoc +88 -11
  8. data/Rakefile +35 -53
  9. data/ext/nmatrix/data/complex.h +372 -0
  10. data/ext/nmatrix/data/data.cpp +275 -0
  11. data/ext/nmatrix/data/data.h +707 -0
  12. data/ext/nmatrix/data/rational.h +421 -0
  13. data/ext/nmatrix/data/ruby_object.h +446 -0
  14. data/ext/nmatrix/extconf.rb +101 -51
  15. data/ext/nmatrix/new_extconf.rb +56 -0
  16. data/ext/nmatrix/nmatrix.cpp +1609 -0
  17. data/ext/nmatrix/nmatrix.h +265 -849
  18. data/ext/nmatrix/ruby_constants.cpp +134 -0
  19. data/ext/nmatrix/ruby_constants.h +103 -0
  20. data/ext/nmatrix/storage/common.cpp +70 -0
  21. data/ext/nmatrix/storage/common.h +170 -0
  22. data/ext/nmatrix/storage/dense.cpp +665 -0
  23. data/ext/nmatrix/storage/dense.h +116 -0
  24. data/ext/nmatrix/storage/list.cpp +1088 -0
  25. data/ext/nmatrix/storage/list.h +129 -0
  26. data/ext/nmatrix/storage/storage.cpp +658 -0
  27. data/ext/nmatrix/storage/storage.h +99 -0
  28. data/ext/nmatrix/storage/yale.cpp +1601 -0
  29. data/ext/nmatrix/storage/yale.h +208 -0
  30. data/ext/nmatrix/ttable_helper.rb +126 -0
  31. data/ext/nmatrix/{yale/smmp1_header.template.c → types.h} +36 -9
  32. data/ext/nmatrix/util/io.cpp +295 -0
  33. data/ext/nmatrix/util/io.h +117 -0
  34. data/ext/nmatrix/util/lapack.h +1175 -0
  35. data/ext/nmatrix/util/math.cpp +557 -0
  36. data/ext/nmatrix/util/math.h +1363 -0
  37. data/ext/nmatrix/util/sl_list.cpp +475 -0
  38. data/ext/nmatrix/util/sl_list.h +255 -0
  39. data/ext/nmatrix/util/util.h +78 -0
  40. data/lib/nmatrix/blas.rb +70 -0
  41. data/lib/nmatrix/io/mat5_reader.rb +567 -0
  42. data/lib/nmatrix/io/mat_reader.rb +162 -0
  43. data/lib/{string.rb → nmatrix/monkeys.rb} +49 -2
  44. data/lib/nmatrix/nmatrix.rb +199 -0
  45. data/lib/nmatrix/nvector.rb +103 -0
  46. data/lib/nmatrix/version.rb +27 -0
  47. data/lib/nmatrix.rb +22 -230
  48. data/nmatrix.gemspec +59 -0
  49. data/scripts/mac-brew-gcc.sh +47 -0
  50. data/spec/4x4_sparse.mat +0 -0
  51. data/spec/4x5_dense.mat +0 -0
  52. data/spec/blas_spec.rb +47 -0
  53. data/spec/elementwise_spec.rb +164 -0
  54. data/spec/io_spec.rb +60 -0
  55. data/spec/lapack_spec.rb +52 -0
  56. data/spec/math_spec.rb +96 -0
  57. data/spec/nmatrix_spec.rb +93 -89
  58. data/spec/nmatrix_yale_spec.rb +52 -36
  59. data/spec/nvector_spec.rb +1 -1
  60. data/spec/slice_spec.rb +257 -0
  61. data/spec/spec_helper.rb +51 -0
  62. data/spec/utm5940.mtx +83844 -0
  63. metadata +113 -71
  64. data/.autotest +0 -23
  65. data/.gemtest +0 -0
  66. data/ext/nmatrix/cblas.c +0 -150
  67. data/ext/nmatrix/dense/blas_header.template.c +0 -52
  68. data/ext/nmatrix/dense/elementwise.template.c +0 -107
  69. data/ext/nmatrix/dense/gemm.template.c +0 -159
  70. data/ext/nmatrix/dense/gemv.template.c +0 -130
  71. data/ext/nmatrix/dense/rationalmath.template.c +0 -68
  72. data/ext/nmatrix/dense.c +0 -307
  73. data/ext/nmatrix/depend +0 -18
  74. data/ext/nmatrix/generator/syntax_tree.rb +0 -481
  75. data/ext/nmatrix/generator.rb +0 -594
  76. data/ext/nmatrix/list.c +0 -774
  77. data/ext/nmatrix/nmatrix.c +0 -1977
  78. data/ext/nmatrix/rational.c +0 -98
  79. data/ext/nmatrix/yale/complexmath.template.c +0 -71
  80. data/ext/nmatrix/yale/elementwise.template.c +0 -46
  81. data/ext/nmatrix/yale/elementwise_op.template.c +0 -73
  82. data/ext/nmatrix/yale/numbmm.template.c +0 -94
  83. data/ext/nmatrix/yale/smmp1.template.c +0 -21
  84. data/ext/nmatrix/yale/smmp2.template.c +0 -43
  85. data/ext/nmatrix/yale/smmp2_header.template.c +0 -46
  86. data/ext/nmatrix/yale/sort_columns.template.c +0 -56
  87. data/ext/nmatrix/yale/symbmm.template.c +0 -54
  88. data/ext/nmatrix/yale/transp.template.c +0 -68
  89. data/ext/nmatrix/yale.c +0 -726
  90. data/lib/array.rb +0 -67
  91. data/spec/syntax_tree_spec.rb +0 -46
@@ -0,0 +1,372 @@
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 - 2012, Ruby Science Foundation
13
+ // NMatrix is Copyright (c) 2012, 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
+ // == complex.h
25
+ //
26
+ // Functions and classes for dealing with complex numbers.
27
+
28
+ #ifndef COMPLEX_H
29
+ #define COMPLEX_H
30
+
31
+ /*
32
+ * Standard Includes
33
+ */
34
+
35
+ #include <type_traits>
36
+ #include <iostream>
37
+
38
+ /*
39
+ * Project Includes
40
+ */
41
+
42
+ #include "types.h"
43
+
44
+ /*
45
+ * Macros
46
+ */
47
+
48
+ /*
49
+ * Types
50
+ */
51
+ namespace nm {
52
+
53
+ template <typename IntType> class Rational;
54
+ template <typename Type> class Complex;
55
+
56
+ typedef Complex<float32_t> Complex64;
57
+ typedef Complex<float64_t> Complex128;
58
+
59
+ /*
60
+ * Data
61
+ */
62
+
63
+ /*
64
+ * Classes and Functions
65
+ */
66
+
67
+ template <typename Type>
68
+ class Complex {
69
+ public:
70
+ // The real and immaginary parts of the complex number.
71
+ Type r;
72
+ Type i;
73
+
74
+ /*
75
+ * Default constructor.
76
+ */
77
+ inline Complex(Type real = 0, Type imaginary = 0) : r(real), i(imaginary) {}
78
+
79
+ /*
80
+ * Copy constructors.
81
+ */
82
+ template <typename ComplexType>
83
+ inline Complex(const Complex<ComplexType>& other) : r(other.r), i(other.i) {}
84
+
85
+ template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
86
+ inline Complex(const Rational<IntType>& other) : r(Type(other.n) / Type(other.d)), i(0) {}
87
+
88
+ /*
89
+ * Complex conjugate function -- creates a copy, but inverted.
90
+ */
91
+ inline Complex<Type> conjugate() const {
92
+ return Complex<Type>(this->r, -(this->i));
93
+ }
94
+
95
+ /*
96
+ * Complex inverse function -- creates a copy, but inverted.
97
+ *
98
+ * FIXME: Check that this doesn't duplicate functionality of NativeType / Complex<Type>
99
+ */
100
+ inline Complex<Type> inverse() const {
101
+ Complex<Type> conj = conjugate();
102
+ Type denom = this->r * this->r + this->i * this->i;
103
+ return Complex<Type>(conj.r / denom, conj.i / denom);
104
+ }
105
+
106
+
107
+
108
+ /*
109
+ * Binary operator definitions for various types.
110
+ */
111
+
112
+ ////////////////////////////////
113
+ // Complex-Complex Operations //
114
+ ////////////////////////////////
115
+
116
+ template <typename OtherType>
117
+ inline Complex<Type> operator+(const Complex<OtherType>& other) const {
118
+ return Complex<Type>(this->r + other.r, this->i + other.i);
119
+ }
120
+
121
+ template <typename OtherType>
122
+ inline Complex<Type>& operator+=(const Complex<OtherType>& other) {
123
+ this->r += other.r;
124
+ this->i += other.i;
125
+ return *this;
126
+ }
127
+
128
+ template <typename OtherType>
129
+ inline Complex<Type> operator-(const Complex<OtherType>& other) const {
130
+ return Complex<Type>(this->r - other.r, this->i - other.i);
131
+ }
132
+
133
+ template <typename OtherType>
134
+ inline Complex<Type> operator*(const Complex<OtherType>& other) const {
135
+ return Complex<Type>(this->r * other.r - this->i * other.i, this->r * other.i - this->i * other.r);
136
+ }
137
+
138
+ template <typename OtherType>
139
+ inline Complex<Type>& operator*=(const Complex<OtherType>& other) {
140
+ this->r = this->r * other.r - this->i * other.i;
141
+ this->i = this->r * other.i - this->i * other.r;
142
+ return *this;
143
+ }
144
+
145
+ template <typename OtherType>
146
+ inline Complex<Type> operator/(const Complex<OtherType>& other) const {
147
+ Type new_r, new_i;
148
+ Type denom = this->i * this->i + other.r * other.r;
149
+
150
+ new_r = (this->r * other.r + this->i * other.i) / denom;
151
+ new_i = (this->r * other.i - this->i * other.r) / denom;
152
+
153
+ return Complex<Type>(new_r, new_i);
154
+ }
155
+
156
+ template <typename OtherType>
157
+ inline bool operator<(const Complex<OtherType>& other) const {
158
+ return (this->r < other.r) || ((this->r <= other.r) && (this->i < other.i));
159
+ }
160
+
161
+ template <typename OtherType>
162
+ inline bool operator>(const Complex<OtherType>& other) const {
163
+ return (this->r > other.r) || ((this->r >= other.r) && (this->i > other.i));
164
+ }
165
+
166
+ template <typename OtherType>
167
+ inline bool operator==(const Complex<OtherType>& other) const {
168
+ return FP_EQUAL(this->r, other.r) && FP_EQUAL(this->i, other.i);
169
+ }
170
+
171
+ template <typename OtherType>
172
+ inline bool operator!=(const Complex<OtherType>& other) const {
173
+ return !(*this == other);
174
+ }
175
+
176
+ template <typename OtherType>
177
+ inline bool operator<=(const Complex<OtherType>& other) const {
178
+ return (*this < other) || (*this == other);
179
+ }
180
+
181
+ template <typename OtherType>
182
+ inline bool operator>=(const Complex<OtherType>& other) const {
183
+ return (*this > other) || (*this == other);
184
+ }
185
+
186
+ template <typename OtherType>
187
+ inline operator Complex<OtherType> () const {
188
+ return Complex<OtherType>((OtherType)this->r, (OtherType)this->i);
189
+ }
190
+
191
+ /////////////////////////////////
192
+ // Complex-Rational Operations //
193
+ /////////////////////////////////
194
+
195
+ template <typename RationalType>
196
+ inline Complex<Type> operator+(const Rational<RationalType>& other) const {
197
+ return *this + Complex<Type>(other);
198
+ }
199
+
200
+ template <typename RationalType>
201
+ inline Complex<Type> operator-(const Rational<RationalType>& other) const {
202
+ return *this * Complex<Type>(other);
203
+ }
204
+
205
+ template <typename RationalType>
206
+ inline Complex<Type> operator*(const Rational<RationalType>& other) const {
207
+ return *this * Complex<Type>(other);
208
+ }
209
+
210
+ template <typename RationalType>
211
+ inline Complex<Type> operator/(const Rational<RationalType>& other) const {
212
+ return *this / Complex<Type>(other);
213
+ }
214
+
215
+ template <typename RationalType, typename = typename std::enable_if<std::is_integral<RationalType>::value>::type>
216
+ inline bool operator!=(const Rational<RationalType>& other) const {
217
+ return *this != Complex<Type>(other);
218
+ }
219
+
220
+ template <typename RationalType, typename = typename std::enable_if<std::is_integral<RationalType>::value>::type>
221
+ inline bool operator==(const Rational<RationalType>& other) const {
222
+ return *this == Complex<Type>(other);
223
+ }
224
+
225
+ ///////////////////////////////
226
+ // Complex-Native Operations //
227
+ ///////////////////////////////
228
+
229
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
230
+ inline Complex<Type> operator+(const NativeType& other) const {
231
+ return *this + Complex<Type>(other);
232
+ }
233
+
234
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
235
+ inline Complex<Type> operator-(const NativeType& other) const {
236
+ return *this - Complex<Type>(other);
237
+ }
238
+
239
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
240
+ inline Complex<Type> operator*(const NativeType& other) const {
241
+ return *this * Complex<Type>(other);
242
+ }
243
+
244
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
245
+ inline Complex<Type> operator/(const NativeType& other) const {
246
+ return *this / Complex<Type>(other);
247
+ }
248
+
249
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
250
+ inline bool operator<(const NativeType& other) const {
251
+ return *this < Complex<Type>(other);
252
+ }
253
+
254
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
255
+ inline bool operator>(const NativeType& other) const {
256
+ return *this > Complex<Type>(other);
257
+ }
258
+
259
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
260
+ inline bool operator==(const NativeType& other) const {
261
+ return *this == Complex<Type>(other);
262
+ }
263
+
264
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
265
+ inline bool operator!=(const NativeType& other) const {
266
+ return *this != Complex<Type>(other);
267
+ }
268
+
269
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
270
+ inline bool operator<=(const NativeType& other) const {
271
+ return *this <= Complex<Type>(other);
272
+ }
273
+
274
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
275
+ inline bool operator>=(const NativeType& other) const {
276
+ return *this >= Complex<Type>(other);
277
+ }
278
+
279
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
280
+ inline operator NativeType () const {
281
+ return (NativeType)this->r;
282
+ }
283
+ };
284
+
285
+
286
+ /////////////////////////////////
287
+ // Rational-Complex Operations //
288
+ /////////////////////////////////
289
+
290
+
291
+ template <typename IntType, typename ComplexType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
292
+ inline bool operator==(const Rational<IntType>& left, const Complex<ComplexType>& right) {
293
+ return Complex<ComplexType>(left) == right;
294
+ }
295
+
296
+ template <typename IntType, typename ComplexType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
297
+ inline bool operator!=(const Rational<IntType>& left, const Complex<ComplexType>& right) {
298
+ return Complex<ComplexType>(left) != right;
299
+ }
300
+
301
+
302
+ ///////////////////////////////
303
+ // Native-Complex Operations //
304
+ ///////////////////////////////
305
+
306
+ template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
307
+ inline Complex<ComplexType> operator+(const NativeType& left, const Complex<ComplexType>& right) {
308
+ return Complex<ComplexType>(left) + right;
309
+ }
310
+
311
+ template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
312
+ inline Complex<ComplexType> operator-(const NativeType& left, const Complex<ComplexType>& right) {
313
+ return Complex<ComplexType>(left) - right;
314
+ }
315
+
316
+ template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
317
+ inline Complex<ComplexType> operator*(const NativeType& left, const Complex<ComplexType>& right) {
318
+ return Complex<ComplexType>(left) * right;
319
+ }
320
+
321
+ template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
322
+ inline Complex<ComplexType> operator/(const NativeType& left, const Complex<ComplexType>& right) {
323
+ return Complex<ComplexType>(left) / right;
324
+ }
325
+
326
+ template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
327
+ inline bool operator<(const NativeType left, const Complex<ComplexType>& right) {
328
+ return Complex<ComplexType>(left) < right;
329
+ }
330
+
331
+ template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
332
+ inline bool operator>(const NativeType left, const Complex<ComplexType>& right) {
333
+ return Complex<ComplexType>(left) > right;
334
+ }
335
+
336
+ template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
337
+ inline bool operator==(const NativeType left, const Complex<ComplexType>& right) {
338
+ return Complex<ComplexType>(left) == right;
339
+ }
340
+
341
+ template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
342
+ inline bool operator!=(const NativeType left, const Complex<ComplexType>& right) {
343
+ return Complex<ComplexType>(left) != right;
344
+ }
345
+
346
+ template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
347
+ inline bool operator<=(const NativeType left, const Complex<ComplexType>& right) {
348
+ return Complex<ComplexType>(left) <= right;
349
+ }
350
+
351
+ template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
352
+ inline bool operator>=(const NativeType left, const Complex<ComplexType>& right) {
353
+ return Complex<ComplexType>(left) >= right;
354
+ }
355
+
356
+ template <typename Type>
357
+ inline std::ostream& operator<<(std::ostream& out, const Complex<Type>& rhs) {
358
+ out << "(" << rhs.r << "," << rhs.i << "i)" << std::flush;
359
+ return out;
360
+ }
361
+
362
+ } // end of namespace nm
363
+
364
+ namespace std {
365
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
366
+ nm::Complex<FloatType> abs(const nm::Complex<FloatType>& value) {
367
+ return nm::Complex<FloatType>(value.r < 0 ? -value.r : value.r,
368
+ value.i < 0 ? -value.i : value.i);
369
+ }
370
+ }
371
+
372
+ #endif // COMPLEX_H
@@ -0,0 +1,275 @@
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 - 2012, Ruby Science Foundation
13
+ // NMatrix is Copyright (c) 2012, 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
+ // == data.cpp
25
+ //
26
+ // Functions and data for dealing the data types.
27
+
28
+ /*
29
+ * Standard Includes
30
+ */
31
+
32
+ #include <ruby.h>
33
+
34
+ /*
35
+ * Project Includes
36
+ */
37
+
38
+ #include "types.h"
39
+
40
+ #include "data.h"
41
+
42
+ /*
43
+ * Macros
44
+ */
45
+
46
+ /*
47
+ * Global Variables
48
+ */
49
+
50
+ extern "C" {
51
+
52
+ const char* const DTYPE_NAMES[nm::NUM_DTYPES] = {
53
+ "byte",
54
+ "int8",
55
+ "int16",
56
+ "int32",
57
+ "int64",
58
+ "float32",
59
+ "float64",
60
+ "complex64",
61
+ "complex128",
62
+ "rational32",
63
+ "rational64",
64
+ "rational128",
65
+ "object"
66
+ };
67
+
68
+ const char* const ITYPE_NAMES[nm::NUM_ITYPES] = {
69
+ "uint8",
70
+ "uint16",
71
+ "uint32",
72
+ "uint64"
73
+ };
74
+
75
+ const size_t DTYPE_SIZES[nm::NUM_DTYPES] = {
76
+ sizeof(uint8_t),
77
+ sizeof(int8_t),
78
+ sizeof(int16_t),
79
+ sizeof(int32_t),
80
+ sizeof(int64_t),
81
+ sizeof(float32_t),
82
+ sizeof(float64_t),
83
+ sizeof(nm::Complex64),
84
+ sizeof(nm::Complex128),
85
+ sizeof(nm::Rational32),
86
+ sizeof(nm::Rational64),
87
+ sizeof(nm::Rational128),
88
+ sizeof(nm::RubyObject)
89
+ };
90
+
91
+ const size_t ITYPE_SIZES[nm::NUM_ITYPES] = {
92
+ sizeof(uint8_t),
93
+ sizeof(uint16_t),
94
+ sizeof(uint32_t),
95
+ sizeof(uint64_t),
96
+ };
97
+
98
+ const dtype_t Upcast[nm::NUM_DTYPES][nm::NUM_DTYPES] = {
99
+ { BYTE, INT8, INT16, INT32, INT64, FLOAT32, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL32, RATIONAL64, RATIONAL128, RUBYOBJ},
100
+ { INT8, INT8, INT16, INT32, INT64, FLOAT32, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL32, RATIONAL64, RATIONAL128, RUBYOBJ},
101
+ { INT16, INT16, INT16, INT32, INT64, FLOAT32, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL32, RATIONAL64, RATIONAL128, RUBYOBJ},
102
+ { INT32, INT32, INT32, INT32, INT64, FLOAT32, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL32, RATIONAL64, RATIONAL128, RUBYOBJ},
103
+ { INT64, INT64, INT64, INT64, INT64, FLOAT32, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL32, RATIONAL64, RATIONAL128, RUBYOBJ},
104
+ { FLOAT32, FLOAT32, FLOAT32, FLOAT32, FLOAT32, FLOAT32, FLOAT64, COMPLEX64, COMPLEX128, FLOAT64, FLOAT64, FLOAT64, RUBYOBJ},
105
+ { FLOAT64, FLOAT64, FLOAT64, FLOAT64, FLOAT64, FLOAT64, FLOAT64, COMPLEX128, COMPLEX128, FLOAT64, FLOAT64, FLOAT64, RUBYOBJ},
106
+ { COMPLEX64, COMPLEX64, COMPLEX64, COMPLEX64, COMPLEX64, COMPLEX64, COMPLEX128, COMPLEX64, COMPLEX128, COMPLEX64, COMPLEX64, COMPLEX64, RUBYOBJ},
107
+ { COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, COMPLEX128, RUBYOBJ},
108
+ { RATIONAL32, RATIONAL32, RATIONAL32, RATIONAL32, RATIONAL32, FLOAT64, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL32, RATIONAL64, RATIONAL128, RUBYOBJ},
109
+ { RATIONAL64, RATIONAL64, RATIONAL64, RATIONAL64, RATIONAL64, FLOAT64, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL64, RATIONAL64, RATIONAL128, RUBYOBJ},
110
+ { RATIONAL128, RATIONAL128, RATIONAL128, RATIONAL128, RATIONAL128, FLOAT64, FLOAT64, COMPLEX64, COMPLEX128, RATIONAL128, RATIONAL128, RATIONAL128, RUBYOBJ},
111
+ { RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ, RUBYOBJ}
112
+ };
113
+
114
+
115
+ /*
116
+ * Forward Declarations
117
+ */
118
+
119
+ /*
120
+ * Functions
121
+ */
122
+
123
+ /*
124
+ * Converts a RubyObject
125
+ */
126
+ void rubyval_to_cval(VALUE val, dtype_t dtype, void* loc) {
127
+ using namespace nm;
128
+ switch (dtype) {
129
+ case BYTE:
130
+ *reinterpret_cast<uint8_t*>(loc) = static_cast<uint8_t>(RubyObject(val));
131
+ break;
132
+
133
+ case INT8:
134
+ *reinterpret_cast<int8_t*>(loc) = static_cast<int8_t>(RubyObject(val));
135
+ break;
136
+
137
+ case INT16:
138
+ *reinterpret_cast<int16_t*>(loc) = static_cast<int16_t>(RubyObject(val));
139
+ break;
140
+
141
+ case INT32:
142
+ *reinterpret_cast<int32_t*>(loc) = static_cast<int32_t>(RubyObject(val));
143
+ break;
144
+
145
+ case INT64:
146
+ *reinterpret_cast<int64_t*>(loc) = static_cast<int64_t>(RubyObject(val));
147
+ break;
148
+
149
+ case FLOAT32:
150
+ *reinterpret_cast<float32_t*>(loc) = static_cast<float32_t>(RubyObject(val));
151
+ break;
152
+
153
+ case FLOAT64:
154
+ *reinterpret_cast<float64_t*>(loc) = static_cast<float64_t>(RubyObject(val));
155
+ break;
156
+
157
+ case COMPLEX64:
158
+ *reinterpret_cast<Complex64*>(loc) = RubyObject(val).to<Complex64>();
159
+ break;
160
+
161
+ case COMPLEX128:
162
+ *reinterpret_cast<Complex128*>(loc) = RubyObject(val).to<Complex64>();
163
+ break;
164
+
165
+ case RATIONAL32:
166
+ *reinterpret_cast<Rational32*>(loc) = RubyObject(val).to<Rational32>();
167
+ break;
168
+
169
+ case RATIONAL64:
170
+ *reinterpret_cast<Rational64*>(loc) = RubyObject(val).to<Rational64>();
171
+ break;
172
+
173
+ case RATIONAL128:
174
+ *reinterpret_cast<Rational128*>(loc) = RubyObject(val).to<Rational128>();
175
+ break;
176
+
177
+ case RUBYOBJ:
178
+ *reinterpret_cast<VALUE*>(loc) = RubyObject(val).rval;
179
+ //rb_raise(rb_eTypeError, "Attempting a bad conversion from a Ruby value.");
180
+ break;
181
+
182
+ default:
183
+ rb_raise(rb_eTypeError, "Attempting a bad conversion from a Ruby value.");
184
+ break;
185
+ }
186
+ }
187
+
188
+ /*
189
+ * Create a RubyObject from a regular C value (given a dtype). Does not return a VALUE! To get a VALUE, you need to
190
+ * look at the rval property of what this function returns.
191
+ */
192
+ nm::RubyObject rubyobj_from_cval(void* val, dtype_t dtype) {
193
+ using namespace nm;
194
+ switch (dtype) {
195
+ case BYTE:
196
+ return RubyObject(*reinterpret_cast<uint8_t*>(val));
197
+
198
+ case INT8:
199
+ return RubyObject(*reinterpret_cast<int8_t*>(val));
200
+
201
+ case INT16:
202
+ return RubyObject(*reinterpret_cast<int16_t*>(val));
203
+
204
+ case INT32:
205
+ return RubyObject(*reinterpret_cast<int32_t*>(val));
206
+
207
+ case INT64:
208
+ return RubyObject(*reinterpret_cast<int64_t*>(val));
209
+
210
+ case FLOAT32:
211
+ return RubyObject(*reinterpret_cast<float32_t*>(val));
212
+
213
+ case FLOAT64:
214
+ return RubyObject(*reinterpret_cast<float64_t*>(val));
215
+
216
+ case COMPLEX64:
217
+ return RubyObject(*reinterpret_cast<Complex64*>(val));
218
+
219
+ case COMPLEX128:
220
+ return RubyObject(*reinterpret_cast<Complex128*>(val));
221
+
222
+ case RATIONAL32:
223
+ return RubyObject(*reinterpret_cast<Rational32*>(val));
224
+
225
+ case RATIONAL64:
226
+ return RubyObject(*reinterpret_cast<Rational64*>(val));
227
+
228
+ case RATIONAL128:
229
+ return RubyObject(*reinterpret_cast<Rational128*>(val));
230
+
231
+ default:
232
+ rb_raise(nm_eDataTypeError, "Conversion to RubyObject requested from unknown/invalid data type (did you try to convert from a VALUE?)");
233
+ }
234
+ return Qnil;
235
+ }
236
+
237
+
238
+ /*
239
+ * Convert from itype instead of dtype
240
+ */
241
+ nm::RubyObject rubyobj_from_cval_by_itype(void* val, itype_t itype) {
242
+ using namespace nm;
243
+ switch (itype) {
244
+ case UINT8:
245
+ return RubyObject(*reinterpret_cast<uint8_t*>(val));
246
+
247
+ case UINT16:
248
+ return RubyObject((int16_t)(*reinterpret_cast<uint16_t*>(val)));
249
+
250
+ case UINT32:
251
+ return RubyObject((int32_t)(*reinterpret_cast<uint32_t*>(val)));
252
+
253
+ case UINT64:
254
+ return RubyObject((int64_t)(*reinterpret_cast<uint64_t*>(val)));
255
+
256
+ default:
257
+ rb_raise(nm_eDataTypeError, "Conversion to RubyObject requested from unknown data type");
258
+ }
259
+ return Qnil;
260
+ }
261
+
262
+ /*
263
+ * Allocate and return a piece of data of the correct dtype, converted from a
264
+ * given RubyObject.
265
+ */
266
+ void* rubyobj_to_cval(VALUE val, dtype_t dtype) {
267
+ size_t size = DTYPE_SIZES[dtype];
268
+ void* ret_val = ALLOC_N(char, size);
269
+
270
+ rubyval_to_cval(val, dtype, ret_val);
271
+
272
+ return ret_val;
273
+ }
274
+
275
+ } // end of extern "C" block