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.
- data/.gitignore +27 -0
- data/.rspec +2 -0
- data/Gemfile +3 -5
- data/Guardfile +6 -0
- data/History.txt +33 -0
- data/Manifest.txt +41 -38
- data/README.rdoc +88 -11
- data/Rakefile +35 -53
- data/ext/nmatrix/data/complex.h +372 -0
- data/ext/nmatrix/data/data.cpp +275 -0
- data/ext/nmatrix/data/data.h +707 -0
- data/ext/nmatrix/data/rational.h +421 -0
- data/ext/nmatrix/data/ruby_object.h +446 -0
- data/ext/nmatrix/extconf.rb +101 -51
- data/ext/nmatrix/new_extconf.rb +56 -0
- data/ext/nmatrix/nmatrix.cpp +1609 -0
- data/ext/nmatrix/nmatrix.h +265 -849
- data/ext/nmatrix/ruby_constants.cpp +134 -0
- data/ext/nmatrix/ruby_constants.h +103 -0
- data/ext/nmatrix/storage/common.cpp +70 -0
- data/ext/nmatrix/storage/common.h +170 -0
- data/ext/nmatrix/storage/dense.cpp +665 -0
- data/ext/nmatrix/storage/dense.h +116 -0
- data/ext/nmatrix/storage/list.cpp +1088 -0
- data/ext/nmatrix/storage/list.h +129 -0
- data/ext/nmatrix/storage/storage.cpp +658 -0
- data/ext/nmatrix/storage/storage.h +99 -0
- data/ext/nmatrix/storage/yale.cpp +1601 -0
- data/ext/nmatrix/storage/yale.h +208 -0
- data/ext/nmatrix/ttable_helper.rb +126 -0
- data/ext/nmatrix/{yale/smmp1_header.template.c → types.h} +36 -9
- data/ext/nmatrix/util/io.cpp +295 -0
- data/ext/nmatrix/util/io.h +117 -0
- data/ext/nmatrix/util/lapack.h +1175 -0
- data/ext/nmatrix/util/math.cpp +557 -0
- data/ext/nmatrix/util/math.h +1363 -0
- data/ext/nmatrix/util/sl_list.cpp +475 -0
- data/ext/nmatrix/util/sl_list.h +255 -0
- data/ext/nmatrix/util/util.h +78 -0
- data/lib/nmatrix/blas.rb +70 -0
- data/lib/nmatrix/io/mat5_reader.rb +567 -0
- data/lib/nmatrix/io/mat_reader.rb +162 -0
- data/lib/{string.rb → nmatrix/monkeys.rb} +49 -2
- data/lib/nmatrix/nmatrix.rb +199 -0
- data/lib/nmatrix/nvector.rb +103 -0
- data/lib/nmatrix/version.rb +27 -0
- data/lib/nmatrix.rb +22 -230
- data/nmatrix.gemspec +59 -0
- data/scripts/mac-brew-gcc.sh +47 -0
- data/spec/4x4_sparse.mat +0 -0
- data/spec/4x5_dense.mat +0 -0
- data/spec/blas_spec.rb +47 -0
- data/spec/elementwise_spec.rb +164 -0
- data/spec/io_spec.rb +60 -0
- data/spec/lapack_spec.rb +52 -0
- data/spec/math_spec.rb +96 -0
- data/spec/nmatrix_spec.rb +93 -89
- data/spec/nmatrix_yale_spec.rb +52 -36
- data/spec/nvector_spec.rb +1 -1
- data/spec/slice_spec.rb +257 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/utm5940.mtx +83844 -0
- metadata +113 -71
- data/.autotest +0 -23
- data/.gemtest +0 -0
- data/ext/nmatrix/cblas.c +0 -150
- data/ext/nmatrix/dense/blas_header.template.c +0 -52
- data/ext/nmatrix/dense/elementwise.template.c +0 -107
- data/ext/nmatrix/dense/gemm.template.c +0 -159
- data/ext/nmatrix/dense/gemv.template.c +0 -130
- data/ext/nmatrix/dense/rationalmath.template.c +0 -68
- data/ext/nmatrix/dense.c +0 -307
- data/ext/nmatrix/depend +0 -18
- data/ext/nmatrix/generator/syntax_tree.rb +0 -481
- data/ext/nmatrix/generator.rb +0 -594
- data/ext/nmatrix/list.c +0 -774
- data/ext/nmatrix/nmatrix.c +0 -1977
- data/ext/nmatrix/rational.c +0 -98
- data/ext/nmatrix/yale/complexmath.template.c +0 -71
- data/ext/nmatrix/yale/elementwise.template.c +0 -46
- data/ext/nmatrix/yale/elementwise_op.template.c +0 -73
- data/ext/nmatrix/yale/numbmm.template.c +0 -94
- data/ext/nmatrix/yale/smmp1.template.c +0 -21
- data/ext/nmatrix/yale/smmp2.template.c +0 -43
- data/ext/nmatrix/yale/smmp2_header.template.c +0 -46
- data/ext/nmatrix/yale/sort_columns.template.c +0 -56
- data/ext/nmatrix/yale/symbmm.template.c +0 -54
- data/ext/nmatrix/yale/transp.template.c +0 -68
- data/ext/nmatrix/yale.c +0 -726
- data/lib/array.rb +0 -67
- data/spec/syntax_tree_spec.rb +0 -46
|
@@ -0,0 +1,421 @@
|
|
|
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
|
+
// == rational.h
|
|
25
|
+
//
|
|
26
|
+
// Functions and classes for dealing with rational numbers.
|
|
27
|
+
|
|
28
|
+
#ifndef RATIONAL_H
|
|
29
|
+
#define RATIONAL_H
|
|
30
|
+
|
|
31
|
+
/*
|
|
32
|
+
* Standard Includes
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
#include <type_traits>
|
|
36
|
+
#include <ruby.h>
|
|
37
|
+
#include <iostream>
|
|
38
|
+
|
|
39
|
+
/*
|
|
40
|
+
* Project Includes
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
#include "types.h"
|
|
44
|
+
|
|
45
|
+
#include "util/util.h"
|
|
46
|
+
|
|
47
|
+
/*
|
|
48
|
+
* Macros
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/*
|
|
52
|
+
* Types
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
namespace nm {
|
|
56
|
+
|
|
57
|
+
template <typename Type> class Rational;
|
|
58
|
+
|
|
59
|
+
typedef Rational<int16_t> Rational32;
|
|
60
|
+
typedef Rational<int32_t> Rational64;
|
|
61
|
+
typedef Rational<int64_t> Rational128;
|
|
62
|
+
|
|
63
|
+
/*
|
|
64
|
+
* Data
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
/*
|
|
68
|
+
* Classes and Functions
|
|
69
|
+
*/
|
|
70
|
+
|
|
71
|
+
template <typename Type>
|
|
72
|
+
class Rational {
|
|
73
|
+
public:
|
|
74
|
+
// The numerator and denominator of the rational number.
|
|
75
|
+
Type n;
|
|
76
|
+
Type d;
|
|
77
|
+
|
|
78
|
+
/*
|
|
79
|
+
* Default constructor.
|
|
80
|
+
*/
|
|
81
|
+
inline Rational(Type num = 0, Type den = 1) : n(num), d(den) {}
|
|
82
|
+
|
|
83
|
+
/*
|
|
84
|
+
* Copy constructors.
|
|
85
|
+
*/
|
|
86
|
+
template <typename OtherType>
|
|
87
|
+
inline Rational(const Rational<OtherType>& other) : n(other.n), d(other.d) {}
|
|
88
|
+
|
|
89
|
+
template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
|
|
90
|
+
inline Rational(const Complex<FloatType>& other) : n(0), d(1) {
|
|
91
|
+
rb_raise(rb_eNotImpError, "cannot convert from complex to rational");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/*
|
|
95
|
+
* Rational inverse function -- creates a copy, but inverted.
|
|
96
|
+
*/
|
|
97
|
+
inline Rational<Type> inverse() const {
|
|
98
|
+
return Rational<Type>(this->d, this->n);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/*
|
|
102
|
+
* Binary operator definitions for varous types.
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
//////////////////////////////////
|
|
106
|
+
// Rational-Rational Operations //
|
|
107
|
+
//////////////////////////////////
|
|
108
|
+
|
|
109
|
+
template <typename OtherType>
|
|
110
|
+
inline Rational<Type> operator+(const Rational<OtherType>& other) const {
|
|
111
|
+
Rational<Type> result((this->n * other.d) + (other.n * this->d), this->d * other.d);
|
|
112
|
+
|
|
113
|
+
long simplify = gcf<Type>(result.n, result.d);
|
|
114
|
+
|
|
115
|
+
result.n /= simplify;
|
|
116
|
+
result.d /= simplify;
|
|
117
|
+
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
template <typename OtherType>
|
|
122
|
+
inline Rational<Type>& operator+=(const Rational<OtherType>& other) {
|
|
123
|
+
this->n = (this->n * other.d) + (other.n * this->d);
|
|
124
|
+
this->d = this->d * other.d;
|
|
125
|
+
|
|
126
|
+
long simplify = gcf<Type>(this->n, this->d);
|
|
127
|
+
|
|
128
|
+
this->n /= simplify;
|
|
129
|
+
this->d /= simplify;
|
|
130
|
+
|
|
131
|
+
return *this;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
template <typename OtherType>
|
|
135
|
+
inline Rational<Type> operator-(const Rational<OtherType>& other) const {
|
|
136
|
+
Rational<Type> result((this->n * other.d) - (other.n * this->d), this->d * other.d);
|
|
137
|
+
|
|
138
|
+
long simplify = gcf<Type>(result.n, result.d);
|
|
139
|
+
|
|
140
|
+
result.n /= simplify;
|
|
141
|
+
result.d /= simplify;
|
|
142
|
+
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
template <typename OtherType>
|
|
147
|
+
inline Rational<Type>& operator-=(const Rational<OtherType>& other) {
|
|
148
|
+
this->n = (this->n * other.d) - (other.n * this->d);
|
|
149
|
+
this->d = this->d * other.d;
|
|
150
|
+
|
|
151
|
+
long simplify = gcf<Type>(this->n, this->d);
|
|
152
|
+
|
|
153
|
+
this->n /= simplify;
|
|
154
|
+
this->d /= simplify;
|
|
155
|
+
|
|
156
|
+
return *this;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
template <typename OtherType>
|
|
160
|
+
inline Rational<Type> operator*(const Rational<OtherType>& other) const {
|
|
161
|
+
int g1 = gcf<Type>(this->n, other.d);
|
|
162
|
+
int g2 = gcf<Type>(this->d, other.n);
|
|
163
|
+
|
|
164
|
+
return Rational<Type>((this->n / g1) * (other.n / g2), (this->d / g2) * (other.d / g1));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
template <typename OtherType>
|
|
169
|
+
inline Rational<Type>& operator*=(const Rational<OtherType>& other) {
|
|
170
|
+
int g1 = gcf<Type>(this->n, other.d);
|
|
171
|
+
int g2 = gcf<Type>(this->d, other.n);
|
|
172
|
+
|
|
173
|
+
this->n = (this->n / g1) * (other.n / g2);
|
|
174
|
+
this->d = (this->d / g2) * (other.d / g1);
|
|
175
|
+
|
|
176
|
+
return *this;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
template <typename OtherType>
|
|
181
|
+
inline Rational<Type> operator/(const Rational<OtherType>& other) const {
|
|
182
|
+
return *this * Rational<OtherType>(other.d, other.n);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
template <typename OtherType>
|
|
186
|
+
inline Rational<Type> operator/=(const Rational<OtherType>& other) {
|
|
187
|
+
*this *= Rational<OtherType>(other.d, other.n);
|
|
188
|
+
return *this;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
template <typename OtherType>
|
|
192
|
+
inline Rational<Type> operator%(const Rational<OtherType>& other) const {
|
|
193
|
+
long floor_div = (this->n * other.n) / (this->d * other.d);
|
|
194
|
+
Rational<Type> prod = other * Rational<long>(floor_div, 1);
|
|
195
|
+
|
|
196
|
+
return Rational<long>(this->n, other.n) - prod;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
template <typename OtherType>
|
|
200
|
+
inline bool operator<(const Rational<OtherType>& other) const {
|
|
201
|
+
return (this->n * other.d) < (other.n * this->d);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
template <typename OtherType>
|
|
205
|
+
inline bool operator>(const Rational<OtherType>& other) const {
|
|
206
|
+
return (this->n * other.d) > (other.n * this->d);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
template <typename OtherType>
|
|
210
|
+
inline bool operator==(const Rational<OtherType>& other) const {
|
|
211
|
+
return (this->n == other.n) && (this->d == other.d);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
template <typename OtherType>
|
|
215
|
+
inline bool operator!=(const Rational<OtherType>& other) const {
|
|
216
|
+
return !(*this == other);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
template <typename OtherType>
|
|
220
|
+
inline bool operator<=(const Rational<OtherType>& other) const {
|
|
221
|
+
return (*this < other) || (*this == other);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
template <typename OtherType>
|
|
225
|
+
inline bool operator>=(const Rational<OtherType>& other) const {
|
|
226
|
+
return (*this > other) || (*this == other);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
template <typename OtherType>
|
|
230
|
+
inline operator Rational<OtherType> () const {
|
|
231
|
+
return Rational<OtherType>((OtherType)this->n, (OtherType)this->d);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
////////////////////////////////
|
|
235
|
+
// Rational-Native Operations //
|
|
236
|
+
////////////////////////////////
|
|
237
|
+
|
|
238
|
+
template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
239
|
+
inline Rational<Type> operator+(const IntType& other) const {
|
|
240
|
+
return *this + Rational<Type>(other);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
244
|
+
inline Rational<Type> operator-(const IntType& other) const {
|
|
245
|
+
return *this - Rational<Type>(other);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
249
|
+
inline Rational<Type> operator*(const IntType& other) const {
|
|
250
|
+
return *this * Rational<Type>(other);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
254
|
+
inline Rational<Type> operator/(const IntType& other) const {
|
|
255
|
+
return *this / Rational<Type>(other);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
259
|
+
inline Rational<Type> operator%(const IntType& other) const {
|
|
260
|
+
return *this % Rational<Type>(other);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
264
|
+
inline bool operator<(const IntType& other) const {
|
|
265
|
+
return *this < Rational<Type>(other);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
269
|
+
inline bool operator>(const IntType& other) const {
|
|
270
|
+
return *this > Rational<Type>(other);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
274
|
+
inline bool operator==(const IntType& other) const {
|
|
275
|
+
return *this == Rational<Type>(other);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
279
|
+
inline bool operator!=(const IntType& other) const {
|
|
280
|
+
return *this != Rational<Type>(other);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
284
|
+
inline bool operator<=(const IntType& other) const {
|
|
285
|
+
return *this <= Rational<Type>(other);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
289
|
+
inline bool operator>=(const IntType& other) const {
|
|
290
|
+
return *this >= Rational<Type>(other);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
template <typename NumType, typename = typename std::enable_if<std::is_arithmetic<NumType>::value>::type>
|
|
294
|
+
inline operator NumType () const {
|
|
295
|
+
return (NumType)this->n / (NumType)this->d;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/*
|
|
299
|
+
* Special casting operator for Complex numbers.
|
|
300
|
+
*/
|
|
301
|
+
template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
|
|
302
|
+
inline operator Rational<FloatType> () const {
|
|
303
|
+
return Rational<FloatType>(((FloatType)this->n) / ((FloatType)this->d));
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
////////////////////////////////
|
|
308
|
+
// Native-Rational Operations //
|
|
309
|
+
////////////////////////////////
|
|
310
|
+
|
|
311
|
+
/*
|
|
312
|
+
* Integer Math
|
|
313
|
+
*/
|
|
314
|
+
|
|
315
|
+
template <typename IntType, typename RationalType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
316
|
+
inline Rational<RationalType> operator+(const IntType& left, const Rational<RationalType>& right) {
|
|
317
|
+
return Rational<RationalType>(left) + right;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
template <typename IntType, typename RationalType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
321
|
+
inline Rational<RationalType> operator-(const IntType& left, const Rational<RationalType>& right) {
|
|
322
|
+
return Rational<RationalType>(left) - right;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
template <typename IntType, typename RationalType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
326
|
+
inline Rational<RationalType> operator*(const IntType& left, const Rational<RationalType>& right) {
|
|
327
|
+
return Rational<RationalType>(left) * right;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
template <typename IntType, typename RationalType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
331
|
+
inline Rational<RationalType> operator/(const IntType& left, const Rational<RationalType>& right) {
|
|
332
|
+
return Rational<RationalType>(left) / right;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/*
|
|
336
|
+
* Floating Point Math
|
|
337
|
+
*/
|
|
338
|
+
|
|
339
|
+
template <typename FloatType, typename RationalType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
|
|
340
|
+
inline FloatType operator+(const FloatType& left, const Rational<RationalType>& right) {
|
|
341
|
+
return left + (FloatType)right;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
template <typename FloatType, typename RationalType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
|
|
345
|
+
inline FloatType operator-(const FloatType& left, const Rational<RationalType>& right) {
|
|
346
|
+
return left - (FloatType)right;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
template <typename FloatType, typename RationalType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
|
|
350
|
+
inline FloatType operator*(const FloatType& left, const Rational<RationalType>& right) {
|
|
351
|
+
return left * (FloatType)right;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
template <typename FloatType, typename RationalType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
|
|
355
|
+
inline FloatType operator/(const FloatType& left, const Rational<RationalType>& right) {
|
|
356
|
+
return left / (FloatType)right;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/*
|
|
360
|
+
* Comparisons
|
|
361
|
+
*/
|
|
362
|
+
|
|
363
|
+
template <typename NativeType, typename RationalType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
|
364
|
+
inline bool operator<(const NativeType left, const Rational<RationalType>& right) {
|
|
365
|
+
//return Rational<RationalType>(left) < right;
|
|
366
|
+
return (left * right.d) < right.n;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
template <typename NativeType, typename RationalType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
|
370
|
+
inline bool operator>(const NativeType left, const Rational<RationalType>& right) {
|
|
371
|
+
//return Rational<RationalType>(left) > right;
|
|
372
|
+
return (left * right.d) > right.n;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
template <typename IntType, typename RationalType>
|
|
376
|
+
inline bool operator==(const typename std::enable_if<std::is_integral<IntType>::value, IntType>::type left, const Rational<RationalType>& right) {
|
|
377
|
+
//return Rational<RationalType>(left) == right;
|
|
378
|
+
return (left * right.d) == right.n;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
template <typename FloatType, typename RationalType>
|
|
382
|
+
inline bool operator==(const typename std::enable_if<std::is_floating_point<FloatType>::value, FloatType>::type left, const Rational<RationalType>& right) {
|
|
383
|
+
//return Rational<RationalType>(left) == right;
|
|
384
|
+
return FP_EQUAL(left, ((FloatType)right));
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
template <typename NativeType, typename RationalType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
|
388
|
+
inline bool operator!=(const NativeType left, const Rational<RationalType>& right) {
|
|
389
|
+
//return Rational<RationalType>(left) != right;
|
|
390
|
+
return !(left == right);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
template <typename NativeType, typename RationalType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
|
394
|
+
inline bool operator<=(const NativeType left, const Rational<RationalType>& right) {
|
|
395
|
+
//return Rational<RationalType>(left) <= right;
|
|
396
|
+
return (left < right) or (left == right);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
template <typename NativeType, typename RationalType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
|
400
|
+
inline bool operator>=(const NativeType left, const Rational<RationalType>& right) {
|
|
401
|
+
//return Rational<RationalType>(left) >= right;
|
|
402
|
+
return (left > right) or (left == right);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
template <typename Type>
|
|
406
|
+
inline std::ostream& operator<<(std::ostream& out, const Rational<Type>& rhs) {
|
|
407
|
+
out << rhs.n << "/" << rhs.d << std::flush;
|
|
408
|
+
return out;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
} // end of namespace nm
|
|
412
|
+
|
|
413
|
+
namespace std {
|
|
414
|
+
template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
|
415
|
+
nm::Rational<IntType> abs(const nm::Rational<IntType>& value) {
|
|
416
|
+
if (value.n >= 0) return value;
|
|
417
|
+
return nm::Rational<IntType>(-value.n, value.d);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
#endif // RATIONAL_H
|