nmatrix-atlas 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/ext/nmatrix/data/complex.h +364 -0
  3. data/ext/nmatrix/data/data.h +638 -0
  4. data/ext/nmatrix/data/meta.h +64 -0
  5. data/ext/nmatrix/data/ruby_object.h +389 -0
  6. data/ext/nmatrix/math/asum.h +120 -0
  7. data/ext/nmatrix/math/cblas_enums.h +36 -0
  8. data/ext/nmatrix/math/cblas_templates_core.h +507 -0
  9. data/ext/nmatrix/math/gemm.h +241 -0
  10. data/ext/nmatrix/math/gemv.h +178 -0
  11. data/ext/nmatrix/math/getrf.h +255 -0
  12. data/ext/nmatrix/math/getrs.h +121 -0
  13. data/ext/nmatrix/math/imax.h +79 -0
  14. data/ext/nmatrix/math/laswp.h +165 -0
  15. data/ext/nmatrix/math/long_dtype.h +49 -0
  16. data/ext/nmatrix/math/math.h +744 -0
  17. data/ext/nmatrix/math/nrm2.h +160 -0
  18. data/ext/nmatrix/math/rot.h +117 -0
  19. data/ext/nmatrix/math/rotg.h +106 -0
  20. data/ext/nmatrix/math/scal.h +71 -0
  21. data/ext/nmatrix/math/trsm.h +332 -0
  22. data/ext/nmatrix/math/util.h +148 -0
  23. data/ext/nmatrix/nm_memory.h +60 -0
  24. data/ext/nmatrix/nmatrix.h +408 -0
  25. data/ext/nmatrix/ruby_constants.h +106 -0
  26. data/ext/nmatrix/storage/common.h +176 -0
  27. data/ext/nmatrix/storage/dense/dense.h +128 -0
  28. data/ext/nmatrix/storage/list/list.h +137 -0
  29. data/ext/nmatrix/storage/storage.h +98 -0
  30. data/ext/nmatrix/storage/yale/class.h +1139 -0
  31. data/ext/nmatrix/storage/yale/iterators/base.h +142 -0
  32. data/ext/nmatrix/storage/yale/iterators/iterator.h +130 -0
  33. data/ext/nmatrix/storage/yale/iterators/row.h +449 -0
  34. data/ext/nmatrix/storage/yale/iterators/row_stored.h +139 -0
  35. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +168 -0
  36. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +123 -0
  37. data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
  38. data/ext/nmatrix/storage/yale/yale.h +202 -0
  39. data/ext/nmatrix/types.h +54 -0
  40. data/ext/nmatrix/util/io.h +115 -0
  41. data/ext/nmatrix/util/sl_list.h +143 -0
  42. data/ext/nmatrix/util/util.h +78 -0
  43. data/ext/nmatrix_atlas/extconf.rb +250 -0
  44. data/ext/nmatrix_atlas/math_atlas.cpp +1206 -0
  45. data/ext/nmatrix_atlas/math_atlas/cblas_templates_atlas.h +72 -0
  46. data/ext/nmatrix_atlas/math_atlas/clapack_templates.h +332 -0
  47. data/ext/nmatrix_atlas/math_atlas/geev.h +82 -0
  48. data/ext/nmatrix_atlas/math_atlas/gesdd.h +83 -0
  49. data/ext/nmatrix_atlas/math_atlas/gesvd.h +81 -0
  50. data/ext/nmatrix_atlas/math_atlas/inc.h +47 -0
  51. data/ext/nmatrix_atlas/nmatrix_atlas.cpp +44 -0
  52. data/lib/nmatrix/atlas.rb +213 -0
  53. data/lib/nmatrix/lapack_ext_common.rb +69 -0
  54. data/spec/00_nmatrix_spec.rb +730 -0
  55. data/spec/01_enum_spec.rb +190 -0
  56. data/spec/02_slice_spec.rb +389 -0
  57. data/spec/03_nmatrix_monkeys_spec.rb +78 -0
  58. data/spec/2x2_dense_double.mat +0 -0
  59. data/spec/4x4_sparse.mat +0 -0
  60. data/spec/4x5_dense.mat +0 -0
  61. data/spec/blas_spec.rb +193 -0
  62. data/spec/elementwise_spec.rb +303 -0
  63. data/spec/homogeneous_spec.rb +99 -0
  64. data/spec/io/fortran_format_spec.rb +88 -0
  65. data/spec/io/harwell_boeing_spec.rb +98 -0
  66. data/spec/io/test.rua +9 -0
  67. data/spec/io_spec.rb +149 -0
  68. data/spec/lapack_core_spec.rb +482 -0
  69. data/spec/leakcheck.rb +16 -0
  70. data/spec/math_spec.rb +730 -0
  71. data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
  72. data/spec/nmatrix_yale_spec.rb +286 -0
  73. data/spec/plugins/atlas/atlas_spec.rb +242 -0
  74. data/spec/rspec_monkeys.rb +56 -0
  75. data/spec/rspec_spec.rb +34 -0
  76. data/spec/shortcuts_spec.rb +310 -0
  77. data/spec/slice_set_spec.rb +157 -0
  78. data/spec/spec_helper.rb +140 -0
  79. data/spec/stat_spec.rb +203 -0
  80. data/spec/test.pcd +20 -0
  81. data/spec/utm5940.mtx +83844 -0
  82. metadata +159 -0
@@ -0,0 +1,64 @@
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
+ // == meta.h
25
+ //
26
+ // Header file for dealing with template metaprogramming.
27
+
28
+ #ifndef META_H
29
+ # define META_H
30
+
31
+ namespace nm {
32
+ /*
33
+ * Template Metaprogramming
34
+ */
35
+ template <typename T> struct ctype_to_dtype_enum {
36
+ static const nm::dtype_t value_type = nm::BYTE;
37
+ };
38
+ template <> struct ctype_to_dtype_enum<uint8_t> { static const nm::dtype_t value_type = nm::BYTE; };
39
+ template <> struct ctype_to_dtype_enum<int8_t> { static const nm::dtype_t value_type = nm::INT8; };
40
+ template <> struct ctype_to_dtype_enum<int16_t> { static const nm::dtype_t value_type = nm::INT16; };
41
+ template <> struct ctype_to_dtype_enum<int32_t> { static const nm::dtype_t value_type = nm::INT32; };
42
+ template <> struct ctype_to_dtype_enum<int64_t> { static const nm::dtype_t value_type = nm::INT64; };
43
+ template <> struct ctype_to_dtype_enum<float> { static const nm::dtype_t value_type = nm::FLOAT32; };
44
+ template <> struct ctype_to_dtype_enum<double> { static const nm::dtype_t value_type = nm::FLOAT64; };
45
+ template <> struct ctype_to_dtype_enum<Complex64> { static const nm::dtype_t value_type = nm::COMPLEX64; };
46
+ template <> struct ctype_to_dtype_enum<Complex128> { static const nm::dtype_t value_type = nm::COMPLEX128; };
47
+ template <> struct ctype_to_dtype_enum<RubyObject> { static const nm::dtype_t value_type = nm::RUBYOBJ; };
48
+
49
+
50
+ template <nm::dtype_t Enum> struct dtype_enum_T;
51
+ template <> struct dtype_enum_T<nm::BYTE> { typedef uint8_t type; };
52
+ template <> struct dtype_enum_T<nm::INT8> { typedef int8_t type; };
53
+ template <> struct dtype_enum_T<nm::INT16> { typedef int16_t type; };
54
+ template <> struct dtype_enum_T<nm::INT32> { typedef int32_t type; };
55
+ template <> struct dtype_enum_T<nm::INT64> { typedef int64_t type; };
56
+ template <> struct dtype_enum_T<nm::FLOAT32> { typedef float type; };
57
+ template <> struct dtype_enum_T<nm::FLOAT64> { typedef double type; };
58
+ template <> struct dtype_enum_T<nm::COMPLEX64> { typedef nm::Complex64 type; };
59
+ template <> struct dtype_enum_T<nm::COMPLEX128> { typedef nm::Complex128 type; };
60
+ template <> struct dtype_enum_T<nm::RUBYOBJ> { typedef nm::RubyObject type; };
61
+
62
+ } // end namespace nm
63
+
64
+ #endif
@@ -0,0 +1,389 @@
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
+ // == ruby_object.h
25
+ //
26
+ // Functions and classes for dealing with Ruby objects.
27
+
28
+ #ifndef RUBY_OBJECT_H
29
+ #define RUBY_OBJECT_H
30
+
31
+ /*
32
+ * Standard Includes
33
+ */
34
+
35
+ #include <ruby.h>
36
+ #include <iostream>
37
+ #include <type_traits>
38
+
39
+ /*
40
+ * Project Includes
41
+ */
42
+
43
+ #include "ruby_constants.h"
44
+
45
+ /*
46
+ * Macros
47
+ */
48
+ #define NM_RUBYVAL_IS_NUMERIC(val) (FIXNUM_P(val) or (TYPE(val) == T_FLOAT) or (TYPE(val) == T_COMPLEX))
49
+ #define NMATRIX_CHECK_TYPE(val) \
50
+ if (TYPE(val) != T_DATA || (RDATA(val)->dfree != (RUBY_DATA_FUNC)nm_delete && RDATA(val)->dfree != (RUBY_DATA_FUNC)nm_delete_ref)) \
51
+ rb_raise(rb_eTypeError, "Expected NMatrix on left-hand side of operation.");
52
+
53
+ /*
54
+ * Classes and Functions
55
+ */
56
+
57
+ namespace nm {
58
+ template<typename T, typename U>
59
+ struct made_from_same_template : std::false_type {};
60
+
61
+ template<template<typename> class Templ, typename Arg1, typename Arg2>
62
+ struct made_from_same_template<Templ<Arg1>, Templ<Arg2>> : std::true_type {};
63
+
64
+ class RubyObject {
65
+ public:
66
+ VALUE rval;
67
+
68
+ /*
69
+ * Value constructor.
70
+ */
71
+ inline RubyObject(VALUE ref = Qnil) : rval(ref) {}
72
+
73
+ /*
74
+ * Complex number constructor.
75
+ */
76
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
77
+ inline RubyObject(const Complex<FloatType>& other) : rval(rb_complex_new(rb_float_new(other.r), rb_float_new(other.i))) {}
78
+
79
+ /*
80
+ * Integer constructor.
81
+ *
82
+ * Does not work as a template.
83
+ */
84
+ inline RubyObject(uint8_t other) : rval(INT2FIX(other)) {}
85
+ inline RubyObject(int8_t other) : rval(INT2FIX(other)) {}
86
+ inline RubyObject(int16_t other) : rval(INT2FIX(other)) {}
87
+ inline RubyObject(uint16_t other) : rval(INT2FIX(other)) {}
88
+ inline RubyObject(int32_t other) : rval(INT2FIX(other)) {}
89
+ // there is no uint32_t here because that's a Ruby VALUE type, and we need the compiler to treat that as a VALUE.
90
+ inline RubyObject(int64_t other) : rval(INT2FIX(other)) {}
91
+ // inline RubyObject(uint64_t other) : rval(INT2FIX(other)) {}
92
+
93
+
94
+ /*
95
+ * Float constructor.
96
+ *
97
+ * Does not work as a template.
98
+ */
99
+ inline RubyObject(float other) : rval(rb_float_new(other)) {}
100
+ inline RubyObject(double other) : rval(rb_float_new(other)) {}
101
+
102
+ /*
103
+ * Operators for converting RubyObjects to other C types.
104
+ */
105
+
106
+ #define RETURN_OBJ2NUM(mac) if (this->rval == Qtrue) return 1; else if (this->rval == Qfalse) return 0; else return mac(this->rval);
107
+
108
+ inline operator int8_t() const { RETURN_OBJ2NUM(NUM2INT) }
109
+ inline operator uint8_t() const { RETURN_OBJ2NUM(NUM2UINT) }
110
+ inline operator int16_t() const { RETURN_OBJ2NUM(NUM2INT) }
111
+ inline operator uint16_t() const { RETURN_OBJ2NUM(NUM2UINT) }
112
+ inline operator int32_t() const { RETURN_OBJ2NUM(NUM2LONG) }
113
+ inline operator VALUE() const { return rval; }
114
+ //inline operator uint32_t() const { return NUM2ULONG(this->rval); }
115
+ inline operator int64_t() const { RETURN_OBJ2NUM(NUM2LONG) }
116
+ inline operator uint64_t() const { RETURN_OBJ2NUM(NUM2ULONG) }
117
+ inline operator double() const { RETURN_OBJ2NUM(NUM2DBL) }
118
+ inline operator float() const { RETURN_OBJ2NUM(NUM2DBL) }
119
+
120
+ inline operator Complex64() const { return this->to<Complex64>(); }
121
+ inline operator Complex128() const { return this->to<Complex128>(); }
122
+ /*
123
+ * Copy constructors.
124
+ */
125
+ inline RubyObject(const RubyObject& other) : rval(other.rval) {}
126
+
127
+ /*
128
+ * Inverse operator.
129
+ */
130
+ inline RubyObject inverse() const {
131
+ rb_raise(rb_eNotImpError, "RubyObject#inverse needs to be implemented");
132
+ }
133
+
134
+ /*
135
+ * Absolute value.
136
+ */
137
+ inline RubyObject abs() const {
138
+ return RubyObject(rb_funcall(this->rval, rb_intern("abs"), 0));
139
+ }
140
+
141
+ /*
142
+ * Binary operator definitions.
143
+ */
144
+
145
+ inline RubyObject operator+(const RubyObject& other) const {
146
+ return RubyObject(rb_funcall(this->rval, nm_rb_add, 1, other.rval));
147
+ }
148
+
149
+ inline RubyObject& operator+=(const RubyObject& other) {
150
+ this->rval = rb_funcall(this->rval, nm_rb_add, 1, other.rval);
151
+ return *this;
152
+ }
153
+
154
+ inline RubyObject operator-(const RubyObject& other) const {
155
+ return RubyObject(rb_funcall(this->rval, nm_rb_sub, 1, other.rval));
156
+ }
157
+
158
+ inline RubyObject& operator-=(const RubyObject& other) {
159
+ this->rval = rb_funcall(this->rval, nm_rb_sub, 1, other.rval);
160
+ return *this;
161
+ }
162
+
163
+ inline RubyObject operator*(const RubyObject& other) const {
164
+ return RubyObject(rb_funcall(this->rval, nm_rb_mul, 1, other.rval));
165
+ }
166
+
167
+ inline RubyObject& operator*=(const RubyObject& other) {
168
+ this->rval = rb_funcall(this->rval, nm_rb_mul, 1, other.rval);
169
+ return *this;
170
+ }
171
+
172
+ inline RubyObject operator/(const RubyObject& other) const {
173
+ return RubyObject(rb_funcall(this->rval, nm_rb_div, 1, other.rval));
174
+ }
175
+
176
+ inline RubyObject& operator/=(const RubyObject& other) {
177
+ this->rval = rb_funcall(this->rval, nm_rb_div, 1, other.rval);
178
+ return *this;
179
+ }
180
+
181
+ inline RubyObject operator%(const RubyObject& other) const {
182
+ return RubyObject(rb_funcall(this->rval, nm_rb_percent, 1, other.rval));
183
+ }
184
+
185
+ inline bool operator>(const RubyObject& other) const {
186
+ return rb_funcall(this->rval, nm_rb_gt, 1, other.rval) == Qtrue;
187
+ }
188
+
189
+ inline bool operator<(const RubyObject& other) const {
190
+ return rb_funcall(this->rval, nm_rb_lt, 1, other.rval) == Qtrue;
191
+ }
192
+
193
+ template <typename OtherType>
194
+ inline bool operator<(const OtherType& other) const {
195
+ return *this < RubyObject(other);
196
+ }
197
+
198
+ inline bool operator==(const RubyObject& other) const {
199
+ return rb_funcall(this->rval, nm_rb_eql, 1, other.rval) == Qtrue;
200
+ }
201
+
202
+ template <typename OtherType>
203
+ inline bool operator==(const OtherType& other) const {
204
+ return *this == RubyObject(other);
205
+ }
206
+
207
+ inline bool operator!=(const RubyObject& other) const {
208
+ return rb_funcall(this->rval, nm_rb_neql, 1, other.rval) == Qtrue;
209
+ }
210
+
211
+ template <typename OtherType>
212
+ inline bool operator!=(const OtherType& other) const {
213
+ return *this != RubyObject(other);
214
+ }
215
+
216
+ inline bool operator>=(const RubyObject& other) const {
217
+ return rb_funcall(this->rval, nm_rb_gte, 1, other.rval) == Qtrue;
218
+ }
219
+
220
+ template <typename OtherType>
221
+ inline bool operator>=(const OtherType& other) const {
222
+ return *this >= RubyObject(other);
223
+ }
224
+
225
+ inline bool operator<=(const RubyObject& other) const {
226
+ return rb_funcall(this->rval, nm_rb_lte, 1, other.rval) == Qtrue;
227
+ }
228
+
229
+ template <typename OtherType>
230
+ inline bool operator<=(const OtherType& other) const {
231
+ return *this <= RubyObject(other);
232
+ }
233
+
234
+ ////////////////////////////
235
+ // RUBY-NATIVE OPERATIONS //
236
+ ////////////////////////////
237
+ /*
238
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
239
+ inline bool operator==(const NativeType& other) const {
240
+ return *this == RubyObject(other);
241
+ }
242
+
243
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
244
+ inline bool operator!=(const NativeType& other) const {
245
+ return *this != RubyObject(other);
246
+ }
247
+ */
248
+ //////////////////////////////
249
+ // RUBY-COMPLEX OPERATIONS //
250
+ //////////////////////////////
251
+
252
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
253
+ inline bool operator==(const Complex<FloatType>& other) const {
254
+ return *this == RubyObject(other);
255
+ }
256
+
257
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
258
+ inline bool operator!=(const Complex<FloatType>& other) const {
259
+ return *this != RubyObject(other);
260
+ }
261
+
262
+ /*
263
+ * Convert a Ruby object to an integer.
264
+ */
265
+ template <typename IntType>
266
+ inline typename std::enable_if<std::is_integral<IntType>::value, IntType>::type to(void) {
267
+ return NUM2INT(this->rval);
268
+ }
269
+
270
+ /*
271
+ * Convert a Ruby object to a floating point number.
272
+ */
273
+ template <typename FloatType>
274
+ inline typename std::enable_if<std::is_floating_point<FloatType>::value, FloatType>::type to(void) {
275
+ return NUM2DBL(this->rval);
276
+ }
277
+
278
+ /*
279
+ * Convert a Ruby object to a complex number.
280
+ */
281
+ template <typename ComplexType>
282
+ inline typename std::enable_if<made_from_same_template<ComplexType, Complex64>::value, ComplexType>::type to(void) const {
283
+ if (FIXNUM_P(this->rval) or TYPE(this->rval) == T_FLOAT) {
284
+ return ComplexType(NUM2DBL(this->rval));
285
+
286
+ } else if (TYPE(this->rval) == T_COMPLEX) {
287
+ return ComplexType(NUM2DBL(rb_funcall(this->rval, nm_rb_real, 0)), NUM2DBL(rb_funcall(this->rval, nm_rb_imag, 0)));
288
+
289
+ } else {
290
+ rb_raise(rb_eTypeError, "Invalid conversion to Complex type.");
291
+ }
292
+ }
293
+ };
294
+
295
+ // Negative operator
296
+ inline RubyObject operator-(const RubyObject& rhs) {
297
+ return RubyObject(rb_funcall(rhs.rval, nm_rb_negate, 0));
298
+ }
299
+
300
+
301
+ ////////////////////////////
302
+ // NATIVE-RUBY OPERATIONS //
303
+ ////////////////////////////
304
+
305
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
306
+ inline RubyObject operator/(const NativeType left, const RubyObject& right) {
307
+ return RubyObject(left) / right;
308
+ }
309
+
310
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
311
+ inline bool operator==(const NativeType left, const RubyObject& right) {
312
+ return RubyObject(left) == right;
313
+ }
314
+
315
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
316
+ inline bool operator!=(const NativeType left, const RubyObject& right) {
317
+ return RubyObject(left) != right;
318
+ }
319
+
320
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
321
+ inline bool operator<=(const NativeType left, const RubyObject& right) {
322
+ return RubyObject(left) <= right;
323
+ }
324
+
325
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
326
+ inline bool operator>=(const NativeType left, const RubyObject& right) {
327
+ return RubyObject(left) >= right;
328
+ }
329
+
330
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
331
+ inline bool operator<(const NativeType left, const RubyObject& right) {
332
+ return RubyObject(left) < right;
333
+ }
334
+
335
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
336
+ inline bool operator>(const NativeType left, const RubyObject& right) {
337
+ return RubyObject(left) > right;
338
+ }
339
+
340
+
341
+ /////////////////////////////
342
+ // COMPLEX-RUBY OPERATIONS //
343
+ /////////////////////////////
344
+
345
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
346
+ inline bool operator==(const Complex<FloatType>& left, const RubyObject& right) {
347
+ return RubyObject(left) == right;
348
+ }
349
+
350
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
351
+ inline bool operator!=(const Complex<FloatType>& left, const RubyObject& right) {
352
+ return RubyObject(left) != right;
353
+ }
354
+
355
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
356
+ inline bool operator<=(const Complex<FloatType>& left, const RubyObject& right) {
357
+ return RubyObject(left) <= right;
358
+ }
359
+
360
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
361
+ inline bool operator>=(const Complex<FloatType>& left, const RubyObject& right) {
362
+ return RubyObject(left) >= right;
363
+ }
364
+
365
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
366
+ inline bool operator<(const Complex<FloatType>& left, const RubyObject& right) {
367
+ return RubyObject(left) < right;
368
+ }
369
+
370
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
371
+ inline bool operator>(const Complex<FloatType>& left, const RubyObject& right) {
372
+ return RubyObject(left) > right;
373
+ }
374
+
375
+ } // end of namespace nm
376
+
377
+ namespace std {
378
+ inline nm::RubyObject abs(const nm::RubyObject& obj) {
379
+ return obj.abs();
380
+ }
381
+
382
+
383
+ inline nm::RubyObject sqrt(const nm::RubyObject& obj) {
384
+ VALUE cMath = rb_const_get(rb_cObject, rb_intern("Math"));
385
+ return nm::RubyObject(rb_funcall(cMath, rb_intern("sqrt"), 1, obj.rval));
386
+ }
387
+ }
388
+
389
+ #endif // RUBY_OBJECT_H