pnmatrix 1.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ext/nmatrix/binary_format.txt +53 -0
- data/ext/nmatrix/data/complex.h +388 -0
- data/ext/nmatrix/data/data.cpp +274 -0
- data/ext/nmatrix/data/data.h +651 -0
- data/ext/nmatrix/data/meta.h +64 -0
- data/ext/nmatrix/data/ruby_object.h +386 -0
- data/ext/nmatrix/extconf.rb +70 -0
- data/ext/nmatrix/math/asum.h +99 -0
- data/ext/nmatrix/math/cblas_enums.h +36 -0
- data/ext/nmatrix/math/cblas_templates_core.h +507 -0
- data/ext/nmatrix/math/gemm.h +241 -0
- data/ext/nmatrix/math/gemv.h +178 -0
- data/ext/nmatrix/math/getrf.h +255 -0
- data/ext/nmatrix/math/getrs.h +121 -0
- data/ext/nmatrix/math/imax.h +82 -0
- data/ext/nmatrix/math/laswp.h +165 -0
- data/ext/nmatrix/math/long_dtype.h +62 -0
- data/ext/nmatrix/math/magnitude.h +54 -0
- data/ext/nmatrix/math/math.h +751 -0
- data/ext/nmatrix/math/nrm2.h +165 -0
- data/ext/nmatrix/math/rot.h +117 -0
- data/ext/nmatrix/math/rotg.h +106 -0
- data/ext/nmatrix/math/scal.h +71 -0
- data/ext/nmatrix/math/trsm.h +336 -0
- data/ext/nmatrix/math/util.h +162 -0
- data/ext/nmatrix/math.cpp +1368 -0
- data/ext/nmatrix/nm_memory.h +60 -0
- data/ext/nmatrix/nmatrix.cpp +285 -0
- data/ext/nmatrix/nmatrix.h +476 -0
- data/ext/nmatrix/ruby_constants.cpp +151 -0
- data/ext/nmatrix/ruby_constants.h +106 -0
- data/ext/nmatrix/ruby_nmatrix.c +3130 -0
- data/ext/nmatrix/storage/common.cpp +77 -0
- data/ext/nmatrix/storage/common.h +183 -0
- data/ext/nmatrix/storage/dense/dense.cpp +1096 -0
- data/ext/nmatrix/storage/dense/dense.h +129 -0
- data/ext/nmatrix/storage/list/list.cpp +1628 -0
- data/ext/nmatrix/storage/list/list.h +138 -0
- data/ext/nmatrix/storage/storage.cpp +730 -0
- data/ext/nmatrix/storage/storage.h +99 -0
- data/ext/nmatrix/storage/yale/class.h +1139 -0
- data/ext/nmatrix/storage/yale/iterators/base.h +143 -0
- data/ext/nmatrix/storage/yale/iterators/iterator.h +131 -0
- data/ext/nmatrix/storage/yale/iterators/row.h +450 -0
- data/ext/nmatrix/storage/yale/iterators/row_stored.h +140 -0
- data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +169 -0
- data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +124 -0
- data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
- data/ext/nmatrix/storage/yale/yale.cpp +2074 -0
- data/ext/nmatrix/storage/yale/yale.h +203 -0
- data/ext/nmatrix/types.h +55 -0
- data/ext/nmatrix/util/io.cpp +279 -0
- data/ext/nmatrix/util/io.h +115 -0
- data/ext/nmatrix/util/sl_list.cpp +627 -0
- data/ext/nmatrix/util/sl_list.h +144 -0
- data/ext/nmatrix/util/util.h +78 -0
- data/lib/nmatrix/blas.rb +378 -0
- data/lib/nmatrix/cruby/math.rb +744 -0
- data/lib/nmatrix/enumerate.rb +253 -0
- data/lib/nmatrix/homogeneous.rb +241 -0
- data/lib/nmatrix/io/fortran_format.rb +138 -0
- data/lib/nmatrix/io/harwell_boeing.rb +221 -0
- data/lib/nmatrix/io/market.rb +263 -0
- data/lib/nmatrix/io/point_cloud.rb +189 -0
- data/lib/nmatrix/jruby/decomposition.rb +24 -0
- data/lib/nmatrix/jruby/enumerable.rb +13 -0
- data/lib/nmatrix/jruby/error.rb +4 -0
- data/lib/nmatrix/jruby/math.rb +501 -0
- data/lib/nmatrix/jruby/nmatrix_java.rb +840 -0
- data/lib/nmatrix/jruby/operators.rb +283 -0
- data/lib/nmatrix/jruby/slice.rb +264 -0
- data/lib/nmatrix/lapack_core.rb +181 -0
- data/lib/nmatrix/lapack_plugin.rb +44 -0
- data/lib/nmatrix/math.rb +953 -0
- data/lib/nmatrix/mkmf.rb +100 -0
- data/lib/nmatrix/monkeys.rb +137 -0
- data/lib/nmatrix/nmatrix.rb +1172 -0
- data/lib/nmatrix/rspec.rb +75 -0
- data/lib/nmatrix/shortcuts.rb +1163 -0
- data/lib/nmatrix/version.rb +39 -0
- data/lib/nmatrix/yale_functions.rb +118 -0
- data/lib/nmatrix.rb +28 -0
- data/spec/00_nmatrix_spec.rb +892 -0
- data/spec/01_enum_spec.rb +196 -0
- data/spec/02_slice_spec.rb +407 -0
- data/spec/03_nmatrix_monkeys_spec.rb +80 -0
- data/spec/2x2_dense_double.mat +0 -0
- data/spec/4x4_sparse.mat +0 -0
- data/spec/4x5_dense.mat +0 -0
- data/spec/blas_spec.rb +215 -0
- data/spec/elementwise_spec.rb +311 -0
- data/spec/homogeneous_spec.rb +100 -0
- data/spec/io/fortran_format_spec.rb +88 -0
- data/spec/io/harwell_boeing_spec.rb +98 -0
- data/spec/io/test.rua +9 -0
- data/spec/io_spec.rb +159 -0
- data/spec/lapack_core_spec.rb +482 -0
- data/spec/leakcheck.rb +16 -0
- data/spec/math_spec.rb +1363 -0
- data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
- data/spec/nmatrix_yale_spec.rb +286 -0
- data/spec/rspec_monkeys.rb +56 -0
- data/spec/rspec_spec.rb +35 -0
- data/spec/shortcuts_spec.rb +474 -0
- data/spec/slice_set_spec.rb +162 -0
- data/spec/spec_helper.rb +172 -0
- data/spec/stat_spec.rb +214 -0
- data/spec/test.pcd +20 -0
- data/spec/utm5940.mtx +83844 -0
- metadata +295 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: be16fe762b002a63a7d2542fb5eb50ed02cf9fd86bc9bb783a480dbeee9aca8a
|
4
|
+
data.tar.gz: c0427a16637c1ed803ce4249d238ef419a903340f81e9705d59f99cd376697ad
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 215cd7e47e75a13afb836e630a61d2f34057452601ca7cd9a70dd9a216258cd0b0763d6c064e36754475833c0ff8cec0144bdedf36f774d65a6498ae705c4954
|
7
|
+
data.tar.gz: b6f3078f05c24952b3dc8bab939a9b5f63cd673bda80450c5e229cc909913382d71adb5e9ff361a293c7e762ea741d0bc78d509567fc52fcdd1b13bb840e5670
|
@@ -0,0 +1,53 @@
|
|
1
|
+
This is the proposed binary format for saving and loading NMatrix objects.
|
2
|
+
|
3
|
+
Order is little-endian.
|
4
|
+
|
5
|
+
List matrices should be converted to dense or yale matrices. There should be no serious need to load or save
|
6
|
+
linked-list matrices, since these exist primarily in order to construct efficient yale matrices.
|
7
|
+
|
8
|
+
|
9
|
+
First 64-bit block:
|
10
|
+
* ui16 major (version)
|
11
|
+
* ui16 minor
|
12
|
+
* ui16 release
|
13
|
+
* i16 NULL
|
14
|
+
|
15
|
+
|
16
|
+
Second 64-bit block:
|
17
|
+
* ui8 dtype
|
18
|
+
* ui8 stype
|
19
|
+
* ui8 itype # ui32 for dense
|
20
|
+
* ui8 symm
|
21
|
+
* i16 NULL
|
22
|
+
* ui16 dim # if 1, NVector; otherwise, NMatrix
|
23
|
+
|
24
|
+
|
25
|
+
3rd - nth 64-bit block: shape
|
26
|
+
|
27
|
+
itype sets the number of bytes allocated for each shape entry. Since only yale uses itype, dense will pretty
|
28
|
+
much always be the UINT32 itype (see nmatrix.h). If the total number of bytes occupied by the shape array is
|
29
|
+
less than 8, the rest of the 64-bit block will be padded with zeros.
|
30
|
+
|
31
|
+
|
32
|
+
(n+1)th 64-bit block: depends on stype, symm
|
33
|
+
|
34
|
+
symm is designed to reduce file size by allowing us to not save certain elements in symmetric, hermitian, skew-
|
35
|
+
symmetric, and triangular matrices. These values will be defined in nmatrix.h; 0 indicates standard (no symmetry).
|
36
|
+
In later versions, additional patterns may be defined which might even have less to do with symmetry than
|
37
|
+
upper/lower do.
|
38
|
+
|
39
|
+
When storing a symmetric matrix, we will only store the upper portion. If the matrix is lower triangular, only the
|
40
|
+
lower portion will be stored.
|
41
|
+
|
42
|
+
For dense, we simply store the contents of the matrix exactly as in memory (or just the upper-triangular part if
|
43
|
+
symm is set).
|
44
|
+
|
45
|
+
For yale, we store:
|
46
|
+
* ui32 ndnz
|
47
|
+
* ui32 length (AKA size, the number of elements in A/IJA that aren't nil/undefined)
|
48
|
+
|
49
|
+
The latter will serve as the capacity when we read a Yale matrix.
|
50
|
+
|
51
|
+
Then we store the a array, again padding with zeros so it's a multiple of 8 bytes.
|
52
|
+
|
53
|
+
Then we store the ija array, padding with zeros so it's a multiple of 8 bytes.
|
@@ -0,0 +1,388 @@
|
|
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
|
+
// == 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 <ruby.h>
|
36
|
+
#include <type_traits>
|
37
|
+
#include <iostream>
|
38
|
+
#include <cmath>
|
39
|
+
|
40
|
+
/*
|
41
|
+
* Project Includes
|
42
|
+
*/
|
43
|
+
|
44
|
+
#include "types.h"
|
45
|
+
|
46
|
+
/*
|
47
|
+
* Macros
|
48
|
+
*/
|
49
|
+
|
50
|
+
/*
|
51
|
+
* Types
|
52
|
+
*/
|
53
|
+
namespace nm {
|
54
|
+
|
55
|
+
class RubyObject;
|
56
|
+
template <typename Type> class Complex;
|
57
|
+
|
58
|
+
typedef Complex<float32_t> Complex64;
|
59
|
+
typedef Complex<float64_t> Complex128;
|
60
|
+
|
61
|
+
/*
|
62
|
+
* Data
|
63
|
+
*/
|
64
|
+
|
65
|
+
/*
|
66
|
+
* Classes and Functions
|
67
|
+
*/
|
68
|
+
|
69
|
+
template <typename Type>
|
70
|
+
class Complex {
|
71
|
+
public:
|
72
|
+
// The real and immaginary parts of the complex number.
|
73
|
+
Type r;
|
74
|
+
Type i;
|
75
|
+
|
76
|
+
/*
|
77
|
+
* Default constructor.
|
78
|
+
*/
|
79
|
+
inline Complex(Type real = 0, Type imaginary = 0) : r(real), i(imaginary) {}
|
80
|
+
|
81
|
+
/*
|
82
|
+
* Copy constructors.
|
83
|
+
*/
|
84
|
+
template <typename ComplexType>
|
85
|
+
explicit inline Complex(const Complex<ComplexType>& other) : r(other.r), i(other.i) {}
|
86
|
+
|
87
|
+
template <typename ComplexType>
|
88
|
+
inline Complex<Type>& operator=(const Complex<ComplexType>& other) {
|
89
|
+
this->r = static_cast<Type>(other.r);
|
90
|
+
this->i = static_cast<Type>(other.i);
|
91
|
+
return *this;
|
92
|
+
}
|
93
|
+
|
94
|
+
explicit Complex(const RubyObject& other);
|
95
|
+
|
96
|
+
Complex<Type>& operator=(const RubyObject& other);
|
97
|
+
|
98
|
+
template<typename OtherType>
|
99
|
+
inline Complex<Type>& operator=(const OtherType& real) {
|
100
|
+
this->r = Type(real);
|
101
|
+
this->i = Type(0);
|
102
|
+
return *this;
|
103
|
+
}
|
104
|
+
|
105
|
+
/*
|
106
|
+
* Complex conjugate function -- creates a copy, but inverted.
|
107
|
+
*/
|
108
|
+
inline Complex<Type> conjugate() const {
|
109
|
+
return Complex<Type>(this->r, -(this->i));
|
110
|
+
}
|
111
|
+
|
112
|
+
/*
|
113
|
+
* Complex inverse function -- creates a copy, but inverted.
|
114
|
+
*
|
115
|
+
* FIXME: Check that this doesn't duplicate functionality of NativeType / Complex<Type>
|
116
|
+
*/
|
117
|
+
inline Complex<Type> inverse() const {
|
118
|
+
Complex<Type> conj = conjugate();
|
119
|
+
Type denom = this->r * this->r + this->i * this->i;
|
120
|
+
return Complex<Type>(conj.r / denom, conj.i / denom);
|
121
|
+
}
|
122
|
+
|
123
|
+
// Negative operator
|
124
|
+
inline Complex<Type> operator-() const {
|
125
|
+
return Complex<Type>(-this->r, -this->i);
|
126
|
+
}
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
/*
|
131
|
+
* Binary operator definitions for various types.
|
132
|
+
*/
|
133
|
+
|
134
|
+
////////////////////////////////
|
135
|
+
// Complex-Complex Operations //
|
136
|
+
////////////////////////////////
|
137
|
+
|
138
|
+
template <typename OtherType>
|
139
|
+
inline Complex<Type> operator+(const Complex<OtherType>& other) const {
|
140
|
+
return Complex<Type>(this->r + other.r, this->i + other.i);
|
141
|
+
}
|
142
|
+
|
143
|
+
template <typename OtherType>
|
144
|
+
inline Complex<Type>& operator+=(const Complex<OtherType>& other) {
|
145
|
+
this->r += other.r;
|
146
|
+
this->i += other.i;
|
147
|
+
return *this;
|
148
|
+
}
|
149
|
+
|
150
|
+
template <typename OtherType>
|
151
|
+
inline Complex<Type>& operator-=(const Complex<OtherType>& other) {
|
152
|
+
this->r -= other.r;
|
153
|
+
this->i -= other.i;
|
154
|
+
return *this;
|
155
|
+
}
|
156
|
+
|
157
|
+
template <typename OtherType>
|
158
|
+
inline Complex<Type> operator-(const Complex<OtherType>& other) const {
|
159
|
+
return Complex<Type>(this->r - other.r, this->i - other.i);
|
160
|
+
}
|
161
|
+
|
162
|
+
template <typename OtherType>
|
163
|
+
inline Complex<Type> operator*(const Complex<OtherType>& other) const {
|
164
|
+
return Complex<Type>(this->r * other.r - this->i * other.i, this->r * other.i + this->i * other.r);
|
165
|
+
}
|
166
|
+
|
167
|
+
template <typename OtherType>
|
168
|
+
inline Complex<Type>& operator*=(const Complex<OtherType>& other) {
|
169
|
+
this->r = this->r * other.r - this->i * other.i;
|
170
|
+
this->i = this->r * other.i + this->i * other.r;
|
171
|
+
return *this;
|
172
|
+
}
|
173
|
+
|
174
|
+
template <typename OtherType>
|
175
|
+
inline Complex<Type> operator/(const Complex<OtherType>& other) const {
|
176
|
+
Type new_r, new_i;
|
177
|
+
Type denom = other.i * other.i + other.r * other.r;
|
178
|
+
|
179
|
+
new_r = (this->r * other.r + this->i * other.i) / denom;
|
180
|
+
new_i = (this->i * other.r - this->r * other.i) / denom;
|
181
|
+
|
182
|
+
return Complex<Type>(new_r, new_i);
|
183
|
+
}
|
184
|
+
|
185
|
+
template <typename OtherType>
|
186
|
+
inline Complex<Type> operator/=(const Complex<OtherType>& other) {
|
187
|
+
Type new_r, new_i;
|
188
|
+
Type denom = other.i * other.i + other.r * other.r;
|
189
|
+
|
190
|
+
new_r = (this->r * other.r + this->i * other.i) / denom;
|
191
|
+
new_i = (this->i * other.r - this->r * other.i) / denom;
|
192
|
+
|
193
|
+
this->r = new_r;
|
194
|
+
this->i = new_i;
|
195
|
+
return *this;
|
196
|
+
}
|
197
|
+
|
198
|
+
template <typename OtherType>
|
199
|
+
inline bool operator<(const Complex<OtherType>& other) const {
|
200
|
+
return (this->r < other.r) || ((this->r <= other.r) && (this->i < other.i));
|
201
|
+
}
|
202
|
+
|
203
|
+
template <typename OtherType>
|
204
|
+
inline bool operator>(const Complex<OtherType>& other) const {
|
205
|
+
return (this->r > other.r) || ((this->r >= other.r) && (this->i > other.i));
|
206
|
+
}
|
207
|
+
|
208
|
+
template <typename OtherType>
|
209
|
+
inline bool operator==(const Complex<OtherType>& other) const {
|
210
|
+
return FP_EQUAL(this->r, other.r) && FP_EQUAL(this->i, other.i);
|
211
|
+
}
|
212
|
+
|
213
|
+
template <typename OtherType>
|
214
|
+
inline bool operator!=(const Complex<OtherType>& other) const {
|
215
|
+
return !(*this == other);
|
216
|
+
}
|
217
|
+
|
218
|
+
template <typename OtherType>
|
219
|
+
inline bool operator<=(const Complex<OtherType>& other) const {
|
220
|
+
return (*this < other) || (*this == other);
|
221
|
+
}
|
222
|
+
|
223
|
+
template <typename OtherType>
|
224
|
+
inline bool operator>=(const Complex<OtherType>& other) const {
|
225
|
+
return (*this > other) || (*this == other);
|
226
|
+
}
|
227
|
+
|
228
|
+
template <typename OtherType>
|
229
|
+
inline operator Complex<OtherType> () const {
|
230
|
+
return Complex<OtherType>((OtherType)this->r, (OtherType)this->i);
|
231
|
+
}
|
232
|
+
|
233
|
+
///////////////////////////////
|
234
|
+
// Complex-Native Operations //
|
235
|
+
///////////////////////////////
|
236
|
+
|
237
|
+
template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
238
|
+
inline Complex<Type> operator+(const NativeType& other) const {
|
239
|
+
return *this + Complex<Type>(other);
|
240
|
+
}
|
241
|
+
|
242
|
+
template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
243
|
+
inline Complex<Type> operator-(const NativeType& other) const {
|
244
|
+
return *this - Complex<Type>(other);
|
245
|
+
}
|
246
|
+
|
247
|
+
template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
248
|
+
inline Complex<Type> operator*(const NativeType& other) const {
|
249
|
+
return *this * Complex<Type>(other);
|
250
|
+
}
|
251
|
+
|
252
|
+
template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
253
|
+
inline Complex<Type> operator/(const NativeType& other) const {
|
254
|
+
return *this / Complex<Type>(other);
|
255
|
+
}
|
256
|
+
|
257
|
+
template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
258
|
+
inline bool operator<(const NativeType& other) const {
|
259
|
+
return *this < Complex<Type>(other);
|
260
|
+
}
|
261
|
+
|
262
|
+
template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
263
|
+
inline bool operator>(const NativeType& other) const {
|
264
|
+
return *this > Complex<Type>(other);
|
265
|
+
}
|
266
|
+
|
267
|
+
template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
268
|
+
inline bool operator==(const NativeType& other) const {
|
269
|
+
return *this == Complex<Type>(other);
|
270
|
+
}
|
271
|
+
|
272
|
+
template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
273
|
+
inline bool operator!=(const NativeType& other) const {
|
274
|
+
return *this != Complex<Type>(other);
|
275
|
+
}
|
276
|
+
|
277
|
+
template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
278
|
+
inline bool operator<=(const NativeType& other) const {
|
279
|
+
return *this <= Complex<Type>(other);
|
280
|
+
}
|
281
|
+
|
282
|
+
template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
283
|
+
inline bool operator>=(const NativeType& other) const {
|
284
|
+
return *this >= Complex<Type>(other);
|
285
|
+
}
|
286
|
+
|
287
|
+
template <typename NativeType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
288
|
+
inline operator NativeType () const {
|
289
|
+
return (NativeType)this->r;
|
290
|
+
}
|
291
|
+
|
292
|
+
operator RubyObject () const;
|
293
|
+
};
|
294
|
+
|
295
|
+
///////////////////////////////
|
296
|
+
// Native-Complex Operations //
|
297
|
+
///////////////////////////////
|
298
|
+
|
299
|
+
template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
300
|
+
inline Complex<ComplexType> operator+(const NativeType& left, const Complex<ComplexType>& right) {
|
301
|
+
return Complex<ComplexType>(left) + right;
|
302
|
+
}
|
303
|
+
|
304
|
+
template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
305
|
+
inline Complex<ComplexType> operator-(const NativeType& left, const Complex<ComplexType>& right) {
|
306
|
+
return Complex<ComplexType>(left) - right;
|
307
|
+
}
|
308
|
+
|
309
|
+
template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
310
|
+
inline Complex<ComplexType> operator*(const NativeType& left, const Complex<ComplexType>& right) {
|
311
|
+
return Complex<ComplexType>(left) * right;
|
312
|
+
}
|
313
|
+
|
314
|
+
template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
315
|
+
inline Complex<ComplexType> operator/(const NativeType& left, const Complex<ComplexType>& right) {
|
316
|
+
return Complex<ComplexType>(left) / right;
|
317
|
+
}
|
318
|
+
|
319
|
+
template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
320
|
+
inline bool operator<(const NativeType left, const Complex<ComplexType>& right) {
|
321
|
+
return Complex<ComplexType>(left) < right;
|
322
|
+
}
|
323
|
+
|
324
|
+
template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
325
|
+
inline bool operator>(const NativeType left, const Complex<ComplexType>& right) {
|
326
|
+
return Complex<ComplexType>(left) > right;
|
327
|
+
}
|
328
|
+
|
329
|
+
template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
330
|
+
inline bool operator==(const NativeType left, const Complex<ComplexType>& right) {
|
331
|
+
return Complex<ComplexType>(left) == right;
|
332
|
+
}
|
333
|
+
|
334
|
+
template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
335
|
+
inline bool operator!=(const NativeType left, const Complex<ComplexType>& right) {
|
336
|
+
return Complex<ComplexType>(left) != right;
|
337
|
+
}
|
338
|
+
|
339
|
+
template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
340
|
+
inline bool operator<=(const NativeType left, const Complex<ComplexType>& right) {
|
341
|
+
return Complex<ComplexType>(left) <= right;
|
342
|
+
}
|
343
|
+
|
344
|
+
template <typename NativeType, typename ComplexType, typename = typename std::enable_if<std::is_arithmetic<NativeType>::value>::type>
|
345
|
+
inline bool operator>=(const NativeType left, const Complex<ComplexType>& right) {
|
346
|
+
return Complex<ComplexType>(left) >= right;
|
347
|
+
}
|
348
|
+
|
349
|
+
template <typename Type>
|
350
|
+
inline std::ostream& operator<<(std::ostream& out, const Complex<Type>& rhs) {
|
351
|
+
out << "(" << rhs.r << "," << rhs.i << "i)" << std::flush;
|
352
|
+
return out;
|
353
|
+
}
|
354
|
+
|
355
|
+
// Negative operator
|
356
|
+
template <typename IntType, typename = typename std::enable_if<std::is_integral<IntType>::value>::type>
|
357
|
+
inline Complex<IntType> operator-(const Complex<IntType>& rhs) {
|
358
|
+
return Complex<IntType>(-rhs.r, -rhs.i);
|
359
|
+
}
|
360
|
+
|
361
|
+
} // end of namespace nm
|
362
|
+
|
363
|
+
namespace std {
|
364
|
+
template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
|
365
|
+
nm::Complex<FloatType> piecewise_abs(const nm::Complex<FloatType>& value) {
|
366
|
+
return nm::Complex<FloatType>(value.r < 0 ? -value.r : value.r,
|
367
|
+
value.i < 0 ? -value.i : value.i);
|
368
|
+
}
|
369
|
+
|
370
|
+
template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
|
371
|
+
nm::Complex<FloatType> real_abs(const nm::Complex<FloatType>& value) {
|
372
|
+
return nm::Complex<FloatType>(value.r < 0 ? -value.r : value.r,
|
373
|
+
value.i);
|
374
|
+
}
|
375
|
+
|
376
|
+
template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
|
377
|
+
nm::Complex<FloatType> imag_abs(const nm::Complex<FloatType>& value) {
|
378
|
+
return nm::Complex<FloatType>(value.r,
|
379
|
+
value.i < 0 ? -value.i : value.i);
|
380
|
+
}
|
381
|
+
|
382
|
+
template <typename FloatType, typename = typename std::enable_if<std::is_floating_point<FloatType>::value>::type>
|
383
|
+
double abs(const nm::Complex<FloatType>& value) {
|
384
|
+
return std::sqrt(double(value.r)*double(value.r) + double(value.i)*double(value.i));
|
385
|
+
}
|
386
|
+
}
|
387
|
+
|
388
|
+
#endif // COMPLEX_H
|