nmatrix 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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