nmatrix-gemv 0.0.3

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 (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +29 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +14 -0
  5. data/Gemfile +7 -0
  6. data/README.md +29 -0
  7. data/Rakefile +225 -0
  8. data/ext/nmatrix_gemv/binary_format.txt +53 -0
  9. data/ext/nmatrix_gemv/data/complex.h +399 -0
  10. data/ext/nmatrix_gemv/data/data.cpp +298 -0
  11. data/ext/nmatrix_gemv/data/data.h +771 -0
  12. data/ext/nmatrix_gemv/data/meta.h +70 -0
  13. data/ext/nmatrix_gemv/data/rational.h +436 -0
  14. data/ext/nmatrix_gemv/data/ruby_object.h +471 -0
  15. data/ext/nmatrix_gemv/extconf.rb +254 -0
  16. data/ext/nmatrix_gemv/math.cpp +1639 -0
  17. data/ext/nmatrix_gemv/math/asum.h +143 -0
  18. data/ext/nmatrix_gemv/math/geev.h +82 -0
  19. data/ext/nmatrix_gemv/math/gemm.h +271 -0
  20. data/ext/nmatrix_gemv/math/gemv.h +212 -0
  21. data/ext/nmatrix_gemv/math/ger.h +96 -0
  22. data/ext/nmatrix_gemv/math/gesdd.h +80 -0
  23. data/ext/nmatrix_gemv/math/gesvd.h +78 -0
  24. data/ext/nmatrix_gemv/math/getf2.h +86 -0
  25. data/ext/nmatrix_gemv/math/getrf.h +240 -0
  26. data/ext/nmatrix_gemv/math/getri.h +108 -0
  27. data/ext/nmatrix_gemv/math/getrs.h +129 -0
  28. data/ext/nmatrix_gemv/math/idamax.h +86 -0
  29. data/ext/nmatrix_gemv/math/inc.h +47 -0
  30. data/ext/nmatrix_gemv/math/laswp.h +165 -0
  31. data/ext/nmatrix_gemv/math/long_dtype.h +52 -0
  32. data/ext/nmatrix_gemv/math/math.h +1069 -0
  33. data/ext/nmatrix_gemv/math/nrm2.h +181 -0
  34. data/ext/nmatrix_gemv/math/potrs.h +129 -0
  35. data/ext/nmatrix_gemv/math/rot.h +141 -0
  36. data/ext/nmatrix_gemv/math/rotg.h +115 -0
  37. data/ext/nmatrix_gemv/math/scal.h +73 -0
  38. data/ext/nmatrix_gemv/math/swap.h +73 -0
  39. data/ext/nmatrix_gemv/math/trsm.h +387 -0
  40. data/ext/nmatrix_gemv/nm_memory.h +60 -0
  41. data/ext/nmatrix_gemv/nmatrix_gemv.cpp +90 -0
  42. data/ext/nmatrix_gemv/nmatrix_gemv.h +374 -0
  43. data/ext/nmatrix_gemv/ruby_constants.cpp +153 -0
  44. data/ext/nmatrix_gemv/ruby_constants.h +107 -0
  45. data/ext/nmatrix_gemv/ruby_nmatrix.c +84 -0
  46. data/ext/nmatrix_gemv/ttable_helper.rb +122 -0
  47. data/ext/nmatrix_gemv/types.h +54 -0
  48. data/ext/nmatrix_gemv/util/util.h +78 -0
  49. data/lib/nmatrix-gemv.rb +43 -0
  50. data/lib/nmatrix_gemv/blas.rb +85 -0
  51. data/lib/nmatrix_gemv/nmatrix_gemv.rb +35 -0
  52. data/lib/nmatrix_gemv/rspec.rb +75 -0
  53. data/nmatrix-gemv.gemspec +31 -0
  54. data/spec/blas_spec.rb +154 -0
  55. data/spec/spec_helper.rb +128 -0
  56. metadata +186 -0
@@ -0,0 +1,471 @@
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) or (TYPE(val) == T_RATIONAL))
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
+ * Rational number constructor.
81
+ */
82
+ template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
83
+ inline RubyObject(const Rational<IntType>& other) : rval(rb_rational_new(INT2FIX(other.n), INT2FIX(other.d))) {}
84
+
85
+ /*
86
+ * Integer constructor.
87
+ *
88
+ * Does not work as a template.
89
+ */
90
+ inline RubyObject(uint8_t other) : rval(INT2FIX(other)) {}
91
+ inline RubyObject(int8_t other) : rval(INT2FIX(other)) {}
92
+ inline RubyObject(int16_t other) : rval(INT2FIX(other)) {}
93
+ inline RubyObject(uint16_t other) : rval(INT2FIX(other)) {}
94
+ inline RubyObject(int32_t other) : rval(INT2FIX(other)) {}
95
+ // there is no uint32_t here because that's a Ruby VALUE type, and we need the compiler to treat that as a VALUE.
96
+ inline RubyObject(int64_t other) : rval(INT2FIX(other)) {}
97
+ // inline RubyObject(uint64_t other) : rval(INT2FIX(other)) {}
98
+
99
+
100
+ /*
101
+ * Float constructor.
102
+ *
103
+ * Does not work as a template.
104
+ */
105
+ inline RubyObject(float other) : rval(rb_float_new(other)) {}
106
+ inline RubyObject(double other) : rval(rb_float_new(other)) {}
107
+
108
+ /*
109
+ * Operators for converting RubyObjects to other C types.
110
+ */
111
+
112
+ #define RETURN_OBJ2NUM(mac) if (this->rval == Qtrue) return 1; else if (this->rval == Qfalse) return 0; else return mac(this->rval);
113
+
114
+ inline operator int8_t() const { RETURN_OBJ2NUM(NUM2INT) }
115
+ inline operator uint8_t() const { RETURN_OBJ2NUM(NUM2UINT) }
116
+ inline operator int16_t() const { RETURN_OBJ2NUM(NUM2INT) }
117
+ inline operator uint16_t() const { RETURN_OBJ2NUM(NUM2UINT) }
118
+ inline operator int32_t() const { RETURN_OBJ2NUM(NUM2LONG) }
119
+ inline operator VALUE() const { return rval; }
120
+ //inline operator uint32_t() const { return NUM2ULONG(this->rval); }
121
+ inline operator int64_t() const { RETURN_OBJ2NUM(NUM2LONG) }
122
+ inline operator uint64_t() const { RETURN_OBJ2NUM(NUM2ULONG) }
123
+ inline operator double() const { RETURN_OBJ2NUM(NUM2DBL) }
124
+ inline operator float() const { RETURN_OBJ2NUM(NUM2DBL) }
125
+
126
+ inline operator Rational32() const { return this->to<Rational32>(); }
127
+ inline operator Rational64() const { return this->to<Rational64>(); }
128
+ inline operator Rational128() const { return this->to<Rational128>(); }
129
+
130
+ inline operator Complex64() const { return this->to<Complex64>(); }
131
+ inline operator Complex128() const { return this->to<Complex128>(); }
132
+ /*
133
+ * Copy constructors.
134
+ */
135
+ inline RubyObject(const RubyObject& other) : rval(other.rval) {}
136
+
137
+ /*
138
+ * Inverse operator.
139
+ */
140
+ inline RubyObject inverse() const {
141
+ rb_raise(rb_eNotImpError, "RubyObject#inverse needs to be implemented");
142
+ }
143
+
144
+ /*
145
+ * Absolute value.
146
+ */
147
+ inline RubyObject abs() const {
148
+ return RubyObject(rb_funcall(this->rval, rb_intern("abs"), 0));
149
+ }
150
+
151
+ /*
152
+ * Binary operator definitions.
153
+ */
154
+
155
+ inline RubyObject operator+(const RubyObject& other) const {
156
+ return RubyObject(rb_funcall(this->rval, nm_rb_add, 1, other.rval));
157
+ }
158
+
159
+ inline RubyObject& operator+=(const RubyObject& other) {
160
+ this->rval = rb_funcall(this->rval, nm_rb_add, 1, other.rval);
161
+ return *this;
162
+ }
163
+
164
+ inline RubyObject operator-(const RubyObject& other) const {
165
+ return RubyObject(rb_funcall(this->rval, nm_rb_sub, 1, other.rval));
166
+ }
167
+
168
+ inline RubyObject& operator-=(const RubyObject& other) {
169
+ this->rval = rb_funcall(this->rval, nm_rb_sub, 1, other.rval);
170
+ return *this;
171
+ }
172
+
173
+ inline RubyObject operator*(const RubyObject& other) const {
174
+ return RubyObject(rb_funcall(this->rval, nm_rb_mul, 1, other.rval));
175
+ }
176
+
177
+ inline RubyObject& operator*=(const RubyObject& other) {
178
+ this->rval = rb_funcall(this->rval, nm_rb_mul, 1, other.rval);
179
+ return *this;
180
+ }
181
+
182
+ inline RubyObject operator/(const RubyObject& other) const {
183
+ return RubyObject(rb_funcall(this->rval, nm_rb_div, 1, other.rval));
184
+ }
185
+
186
+ inline RubyObject& operator/=(const RubyObject& other) {
187
+ this->rval = rb_funcall(this->rval, nm_rb_div, 1, other.rval);
188
+ return *this;
189
+ }
190
+
191
+ inline RubyObject operator%(const RubyObject& other) const {
192
+ return RubyObject(rb_funcall(this->rval, nm_rb_percent, 1, other.rval));
193
+ }
194
+
195
+ inline bool operator>(const RubyObject& other) const {
196
+ return rb_funcall(this->rval, nm_rb_gt, 1, other.rval) == Qtrue;
197
+ }
198
+
199
+ inline bool operator<(const RubyObject& other) const {
200
+ return rb_funcall(this->rval, nm_rb_lt, 1, other.rval) == Qtrue;
201
+ }
202
+
203
+ template <typename OtherType>
204
+ inline bool operator<(const OtherType& other) const {
205
+ return *this < RubyObject(other);
206
+ }
207
+
208
+ inline bool operator==(const RubyObject& other) const {
209
+ return rb_funcall(this->rval, nm_rb_eql, 1, other.rval) == Qtrue;
210
+ }
211
+
212
+ template <typename OtherType>
213
+ inline bool operator==(const OtherType& other) const {
214
+ return *this == RubyObject(other);
215
+ }
216
+
217
+ inline bool operator!=(const RubyObject& other) const {
218
+ return rb_funcall(this->rval, nm_rb_neql, 1, other.rval) == Qtrue;
219
+ }
220
+
221
+ template <typename OtherType>
222
+ inline bool operator!=(const OtherType& other) const {
223
+ return *this != RubyObject(other);
224
+ }
225
+
226
+ inline bool operator>=(const RubyObject& other) const {
227
+ return rb_funcall(this->rval, nm_rb_gte, 1, other.rval) == Qtrue;
228
+ }
229
+
230
+ template <typename OtherType>
231
+ inline bool operator>=(const OtherType& other) const {
232
+ return *this >= RubyObject(other);
233
+ }
234
+
235
+ inline bool operator<=(const RubyObject& other) const {
236
+ return rb_funcall(this->rval, nm_rb_lte, 1, other.rval) == Qtrue;
237
+ }
238
+
239
+ template <typename OtherType>
240
+ inline bool operator<=(const OtherType& other) const {
241
+ return *this <= RubyObject(other);
242
+ }
243
+
244
+ ////////////////////////////
245
+ // RUBY-NATIVE OPERATIONS //
246
+ ////////////////////////////
247
+ /*
248
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
249
+ inline bool operator==(const NativeType& other) const {
250
+ return *this == RubyObject(other);
251
+ }
252
+
253
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
254
+ inline bool operator!=(const NativeType& other) const {
255
+ return *this != RubyObject(other);
256
+ }
257
+ */
258
+ //////////////////////////////
259
+ // RUBY-RATIONAL OPERATIONS //
260
+ //////////////////////////////
261
+
262
+ template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
263
+ inline bool operator==(const Rational<IntType>& other) const {
264
+ return *this == RubyObject(other);
265
+ }
266
+
267
+ template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
268
+ inline bool operator!=(const Rational<IntType>& other) const {
269
+ return *this != RubyObject(other);
270
+ }
271
+
272
+ //////////////////////////////
273
+ // RUBY-COMPLEX OPERATIONS //
274
+ //////////////////////////////
275
+
276
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
277
+ inline bool operator==(const Complex<FloatType>& other) const {
278
+ return *this == RubyObject(other);
279
+ }
280
+
281
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
282
+ inline bool operator!=(const Complex<FloatType>& other) const {
283
+ return *this != RubyObject(other);
284
+ }
285
+
286
+ /*
287
+ * Convert a Ruby object to an integer.
288
+ */
289
+ template <typename IntType>
290
+ inline typename std::enable_if<std::is_integral<IntType>::value, IntType>::type to(void) {
291
+ return NUM2INT(this->rval);
292
+ }
293
+
294
+ /*
295
+ * Convert a Ruby object to a floating point number.
296
+ */
297
+ template <typename FloatType>
298
+ inline typename std::enable_if<std::is_floating_point<FloatType>::value, FloatType>::type to(void) {
299
+ return NUM2DBL(this->rval);
300
+ }
301
+
302
+ /*
303
+ * Convert a Ruby object to a complex number.
304
+ */
305
+ template <typename ComplexType>
306
+ inline typename std::enable_if<made_from_same_template<ComplexType, Complex64>::value, ComplexType>::type to(void) const {
307
+ if (FIXNUM_P(this->rval) or TYPE(this->rval) == T_FLOAT or TYPE(this->rval) == T_RATIONAL) {
308
+ return ComplexType(NUM2DBL(this->rval));
309
+
310
+ } else if (TYPE(this->rval) == T_COMPLEX) {
311
+ return ComplexType(NUM2DBL(rb_funcall(this->rval, nm_rb_real, 0)), NUM2DBL(rb_funcall(this->rval, nm_rb_imag, 0)));
312
+
313
+ } else {
314
+ rb_raise(rb_eTypeError, "Invalid conversion to Complex type.");
315
+ }
316
+ }
317
+
318
+ /*
319
+ * Convert a Ruby object to a rational number.
320
+ */
321
+ template <typename RationalType>
322
+ inline typename std::enable_if<made_from_same_template<RationalType, Rational32>::value, RationalType>::type to(void) const {
323
+ if (FIXNUM_P(this->rval) or TYPE(this->rval) == T_FLOAT or TYPE(this->rval) == T_COMPLEX) {
324
+ return RationalType(NUM2INT(this->rval));
325
+
326
+ } else if (TYPE(this->rval) == T_RATIONAL) {
327
+ return RationalType(NUM2INT(rb_funcall(this->rval, nm_rb_numer, 0)), NUM2INT(rb_funcall(this->rval, nm_rb_denom, 0)));
328
+
329
+ } else {
330
+ rb_raise(rb_eTypeError, "Invalid conversion to Rational type.");
331
+ }
332
+ }
333
+
334
+ };
335
+
336
+ // Negative operator
337
+ inline RubyObject operator-(const RubyObject& rhs) {
338
+ return RubyObject(rb_funcall(rhs.rval, nm_rb_negate, 0));
339
+ }
340
+
341
+
342
+ ////////////////////////////
343
+ // NATIVE-RUBY OPERATIONS //
344
+ ////////////////////////////
345
+
346
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
347
+ inline RubyObject operator/(const NativeType left, const RubyObject& right) {
348
+ return RubyObject(left) / right;
349
+ }
350
+
351
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
352
+ inline bool operator==(const NativeType left, const RubyObject& right) {
353
+ return RubyObject(left) == right;
354
+ }
355
+
356
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
357
+ inline bool operator!=(const NativeType left, const RubyObject& right) {
358
+ return RubyObject(left) != right;
359
+ }
360
+
361
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
362
+ inline bool operator<=(const NativeType left, const RubyObject& right) {
363
+ return RubyObject(left) <= right;
364
+ }
365
+
366
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
367
+ inline bool operator>=(const NativeType left, const RubyObject& right) {
368
+ return RubyObject(left) >= right;
369
+ }
370
+
371
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
372
+ inline bool operator<(const NativeType left, const RubyObject& right) {
373
+ return RubyObject(left) < right;
374
+ }
375
+
376
+ template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
377
+ inline bool operator>(const NativeType left, const RubyObject& right) {
378
+ return RubyObject(left) > right;
379
+ }
380
+
381
+
382
+ /////////////////////////////
383
+ // COMPLEX-RUBY OPERATIONS //
384
+ /////////////////////////////
385
+
386
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
387
+ inline bool operator==(const Complex<FloatType>& left, const RubyObject& right) {
388
+ return RubyObject(left) == right;
389
+ }
390
+
391
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
392
+ inline bool operator!=(const Complex<FloatType>& left, const RubyObject& right) {
393
+ return RubyObject(left) != right;
394
+ }
395
+
396
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
397
+ inline bool operator<=(const Complex<FloatType>& left, const RubyObject& right) {
398
+ return RubyObject(left) <= right;
399
+ }
400
+
401
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
402
+ inline bool operator>=(const Complex<FloatType>& left, const RubyObject& right) {
403
+ return RubyObject(left) >= right;
404
+ }
405
+
406
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
407
+ inline bool operator<(const Complex<FloatType>& left, const RubyObject& right) {
408
+ return RubyObject(left) < right;
409
+ }
410
+
411
+ template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
412
+ inline bool operator>(const Complex<FloatType>& left, const RubyObject& right) {
413
+ return RubyObject(left) > right;
414
+ }
415
+
416
+
417
+
418
+ //////////////////////////////
419
+ // RATIONAL-RUBY OPERATIONS //
420
+ //////////////////////////////
421
+
422
+ template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
423
+ inline bool operator==(const Rational<IntType>& left, const RubyObject& right) {
424
+ return RubyObject(left) == right;
425
+ }
426
+
427
+ template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
428
+ inline bool operator!=(const Rational<IntType>& left, const RubyObject& right) {
429
+ return RubyObject(left) != right;
430
+ }
431
+
432
+ template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
433
+ inline bool operator>=(const Rational<IntType>& left, const RubyObject& right) {
434
+ return RubyObject(left) >= right;
435
+ }
436
+
437
+ template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
438
+ inline bool operator<=(const Rational<IntType>& left, const RubyObject& right) {
439
+ return RubyObject(left) <= right;
440
+ }
441
+
442
+ template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
443
+ inline bool operator<(const Rational<IntType>& left, const RubyObject& right) {
444
+ return RubyObject(left) < right;
445
+ }
446
+
447
+ template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
448
+ inline bool operator>(const Rational<IntType>& left, const RubyObject& right) {
449
+ return RubyObject(left) > right;
450
+ }
451
+
452
+ inline std::ostream& operator<<(std::ostream& out, const RubyObject& rhs) {
453
+ out << "RUBYOBJECT" << std::flush; // FIXME: Try calling inspect or something on the Ruby object if we really need to debug it.
454
+ return out;
455
+ }
456
+
457
+ } // end of namespace nm
458
+
459
+ namespace std {
460
+ inline nm::RubyObject abs(const nm::RubyObject& obj) {
461
+ return obj.abs();
462
+ }
463
+
464
+
465
+ inline nm::RubyObject sqrt(const nm::RubyObject& obj) {
466
+ VALUE cMath = rb_const_get(rb_cObject, rb_intern("Math"));
467
+ return nm::RubyObject(rb_funcall(cMath, rb_intern("sqrt"), 1, obj.rval));
468
+ }
469
+ }
470
+
471
+ #endif // RUBY_OBJECT_H