nmatrix-fftw 0.2.1 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/nmatrix/data/data.h +7 -8
- data/ext/nmatrix/data/ruby_object.h +1 -4
- data/ext/nmatrix/math/asum.h +10 -31
- data/ext/nmatrix/math/cblas_templates_core.h +10 -10
- data/ext/nmatrix/math/getrf.h +2 -2
- data/ext/nmatrix/math/imax.h +12 -9
- data/ext/nmatrix/math/laswp.h +3 -3
- data/ext/nmatrix/math/long_dtype.h +16 -3
- data/ext/nmatrix/math/magnitude.h +54 -0
- data/ext/nmatrix/math/nrm2.h +19 -14
- data/ext/nmatrix/math/trsm.h +40 -36
- data/ext/nmatrix/math/util.h +14 -0
- data/ext/nmatrix/nmatrix.h +39 -1
- data/ext/nmatrix/storage/common.h +9 -3
- data/ext/nmatrix/storage/yale/class.h +1 -1
- data/ext/nmatrix_fftw/extconf.rb +1 -71
- data/spec/00_nmatrix_spec.rb +50 -1
- data/spec/02_slice_spec.rb +21 -21
- data/spec/blas_spec.rb +25 -3
- data/spec/math_spec.rb +233 -5
- data/spec/shortcuts_spec.rb +145 -5
- data/spec/spec_helper.rb +24 -1
- metadata +18 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7378e6fd7c9670258c30a213fb0a637c5fd85b66
|
4
|
+
data.tar.gz: dd928a35d61614dd587cfbc0d4033407017475dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3285bb810027fa4447a902b5565a791ea38099fade45a0be0a60bf4c163ac317f2d31aeb0ba45cb08803ee8b3fa7cb3230e08af9811290ed8ef4cf73cfc0f8e5
|
7
|
+
data.tar.gz: 0d73fd3af914084bb2ac9913899718e47e9563a0629fb3ac187fc0f40b11e65d35da43aeda8ca63ccd4e49d731434f3a41ba0ac471d31c3b5d7fa9bd1938b5fb
|
data/ext/nmatrix/data/data.h
CHANGED
@@ -121,18 +121,17 @@ namespace nm {
|
|
121
121
|
|
122
122
|
template <typename Type>
|
123
123
|
Complex<Type>& Complex<Type>::operator=(const RubyObject& other) {
|
124
|
-
|
125
|
-
case T_COMPLEX:
|
124
|
+
if (RB_TYPE_P(other.rval, T_COMPLEX)) {
|
126
125
|
this->r = NUM2DBL(rb_funcall(other.rval, rb_intern("real"), 0));
|
127
126
|
this->i = NUM2DBL(rb_funcall(other.rval, rb_intern("imag"), 0));
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
127
|
+
}
|
128
|
+
else if (RB_TYPE_P(other.rval, T_FLOAT) ||
|
129
|
+
RB_TYPE_P(other.rval, T_FIXNUM) ||
|
130
|
+
RB_TYPE_P(other.rval, T_BIGNUM)) {
|
132
131
|
this->r = NUM2DBL(other.rval);
|
133
132
|
this->i = 0.0;
|
134
|
-
|
135
|
-
|
133
|
+
}
|
134
|
+
else {
|
136
135
|
rb_raise(rb_eTypeError, "not sure how to convert this type of VALUE to a complex");
|
137
136
|
}
|
138
137
|
return *this;
|
@@ -45,10 +45,7 @@
|
|
45
45
|
/*
|
46
46
|
* Macros
|
47
47
|
*/
|
48
|
-
#define NM_RUBYVAL_IS_NUMERIC(val) (FIXNUM_P(val) or (
|
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.");
|
48
|
+
#define NM_RUBYVAL_IS_NUMERIC(val) (FIXNUM_P(val) or RB_FLOAT_TYPE_P(val) or RB_TYPE_P(val, T_COMPLEX))
|
52
49
|
|
53
50
|
/*
|
54
51
|
* Classes and Functions
|
data/ext/nmatrix/math/asum.h
CHANGED
@@ -9,8 +9,8 @@
|
|
9
9
|
//
|
10
10
|
// == Copyright Information
|
11
11
|
//
|
12
|
-
// SciRuby is Copyright (c) 2010 -
|
13
|
-
// NMatrix is Copyright (c) 2012 -
|
12
|
+
// SciRuby is Copyright (c) 2010 - present, Ruby Science Foundation
|
13
|
+
// NMatrix is Copyright (c) 2012 - present, John Woods and the Ruby Science Foundation
|
14
14
|
//
|
15
15
|
// Please see LICENSE.txt for additional copyright notices.
|
16
16
|
//
|
@@ -60,6 +60,8 @@
|
|
60
60
|
#define ASUM_H
|
61
61
|
|
62
62
|
|
63
|
+
#include "math/magnitude.h"
|
64
|
+
|
63
65
|
namespace nm { namespace math {
|
64
66
|
|
65
67
|
/*
|
@@ -73,44 +75,21 @@ namespace nm { namespace math {
|
|
73
75
|
* complex64 -> float or double
|
74
76
|
* complex128 -> double
|
75
77
|
*/
|
76
|
-
template <typename
|
77
|
-
inline
|
78
|
-
|
79
|
-
if ((N > 0) && (incX > 0)) {
|
80
|
-
for (int i = 0; i < N; ++i) {
|
81
|
-
sum += std::abs(X[i*incX]);
|
82
|
-
}
|
83
|
-
}
|
84
|
-
return sum;
|
85
|
-
}
|
86
|
-
|
87
|
-
|
88
|
-
template <>
|
89
|
-
inline float asum(const int N, const Complex64* X, const int incX) {
|
90
|
-
float sum = 0;
|
91
|
-
if ((N > 0) && (incX > 0)) {
|
92
|
-
for (int i = 0; i < N; ++i) {
|
93
|
-
sum += std::abs(X[i*incX].r) + std::abs(X[i*incX].i);
|
94
|
-
}
|
95
|
-
}
|
96
|
-
return sum;
|
97
|
-
}
|
98
|
-
|
99
|
-
template <>
|
100
|
-
inline double asum(const int N, const Complex128* X, const int incX) {
|
101
|
-
double sum = 0;
|
78
|
+
template <typename DType, typename MDType = typename MagnitudeDType<DType>::type>
|
79
|
+
inline MDType asum(const int N, const DType* X, const int incX) {
|
80
|
+
MDType sum = 0;
|
102
81
|
if ((N > 0) && (incX > 0)) {
|
103
82
|
for (int i = 0; i < N; ++i) {
|
104
|
-
sum +=
|
83
|
+
sum += magnitude(X[i*incX]);
|
105
84
|
}
|
106
85
|
}
|
107
86
|
return sum;
|
108
87
|
}
|
109
88
|
|
110
89
|
|
111
|
-
template <typename
|
90
|
+
template <typename DType, typename MDType = typename MagnitudeDType<DType>::type>
|
112
91
|
inline void cblas_asum(const int N, const void* X, const int incX, void* sum) {
|
113
|
-
*reinterpret_cast<
|
92
|
+
*reinterpret_cast<MDType*>( sum ) = asum<DType,MDType>( N, reinterpret_cast<const DType*>(X), incX );
|
114
93
|
}
|
115
94
|
|
116
95
|
|
@@ -107,9 +107,9 @@ inline void cblas_rot(const int N, void* X, const int incX, void* Y, const int i
|
|
107
107
|
* complex64 -> float or double
|
108
108
|
* complex128 -> double
|
109
109
|
*/
|
110
|
-
template <typename
|
111
|
-
inline
|
112
|
-
return nm::math::asum<
|
110
|
+
template <typename DType, typename MDType = typename MagnitudeDType<DType>::type>
|
111
|
+
inline MDType asum(const int N, const DType* X, const int incX) {
|
112
|
+
return nm::math::asum<DType,MDType>(N,X,incX);
|
113
113
|
}
|
114
114
|
|
115
115
|
|
@@ -134,9 +134,9 @@ inline double asum(const int N, const Complex128* X, const int incX) {
|
|
134
134
|
}
|
135
135
|
|
136
136
|
|
137
|
-
template <typename
|
137
|
+
template <typename DType, typename MDType = typename MagnitudeDType<DType>::type>
|
138
138
|
inline void cblas_asum(const int N, const void* X, const int incX, void* sum) {
|
139
|
-
*static_cast<
|
139
|
+
*static_cast<MDType*>( sum ) = asum<DType, MDType>( N, static_cast<const DType*>(X), incX );
|
140
140
|
}
|
141
141
|
|
142
142
|
/*
|
@@ -149,9 +149,9 @@ inline void cblas_asum(const int N, const void* X, const int incX, void* sum) {
|
|
149
149
|
* complex64 -> float or double
|
150
150
|
* complex128 -> double
|
151
151
|
*/
|
152
|
-
template <typename
|
153
|
-
inline
|
154
|
-
return nm::math::nrm2<
|
152
|
+
template <typename DType, typename MDType = typename MagnitudeDType<DType>::type>
|
153
|
+
inline MDType nrm2(const int N, const DType* X, const int incX) {
|
154
|
+
return nm::math::nrm2<DType,MDType>(N, X, incX);
|
155
155
|
}
|
156
156
|
|
157
157
|
|
@@ -175,9 +175,9 @@ inline double nrm2(const int N, const Complex128* X, const int incX) {
|
|
175
175
|
return cblas_dznrm2(N, X, incX);
|
176
176
|
}
|
177
177
|
|
178
|
-
template <typename
|
178
|
+
template <typename DType, typename MDType = typename MagnitudeDType<DType>::type>
|
179
179
|
inline void cblas_nrm2(const int N, const void* X, const int incX, void* result) {
|
180
|
-
*static_cast<
|
180
|
+
*static_cast<MDType*>( result ) = nrm2<DType, MDType>( N, static_cast<const DType*>(X), incX );
|
181
181
|
}
|
182
182
|
|
183
183
|
//imax
|
data/ext/nmatrix/math/getrf.h
CHANGED
@@ -9,8 +9,8 @@
|
|
9
9
|
//
|
10
10
|
// == Copyright Information
|
11
11
|
//
|
12
|
-
// SciRuby is Copyright (c) 2010 -
|
13
|
-
// NMatrix is Copyright (c) 2012 -
|
12
|
+
// SciRuby is Copyright (c) 2010 - present, Ruby Science Foundation
|
13
|
+
// NMatrix is Copyright (c) 2012 - present, John Woods and the Ruby Science Foundation
|
14
14
|
//
|
15
15
|
// Please see LICENSE.txt for additional copyright notices.
|
16
16
|
//
|
data/ext/nmatrix/math/imax.h
CHANGED
@@ -9,8 +9,8 @@
|
|
9
9
|
//
|
10
10
|
// == Copyright Information
|
11
11
|
//
|
12
|
-
// SciRuby is Copyright (c) 2010 -
|
13
|
-
// NMatrix is Copyright (c) 2012 -
|
12
|
+
// SciRuby is Copyright (c) 2010 - present, Ruby Science Foundation
|
13
|
+
// NMatrix is Copyright (c) 2012 - present, John Woods and the Ruby Science Foundation
|
14
14
|
//
|
15
15
|
// Please see LICENSE.txt for additional copyright notices.
|
16
16
|
//
|
@@ -29,8 +29,11 @@
|
|
29
29
|
#ifndef IMAX_H
|
30
30
|
#define IMAX_H
|
31
31
|
|
32
|
+
#include "math/magnitude.h"
|
33
|
+
|
32
34
|
namespace nm { namespace math {
|
33
35
|
|
36
|
+
|
34
37
|
template<typename DType>
|
35
38
|
inline int imax(const int n, const DType *x, const int incx) {
|
36
39
|
|
@@ -41,28 +44,28 @@ inline int imax(const int n, const DType *x, const int incx) {
|
|
41
44
|
return 0;
|
42
45
|
}
|
43
46
|
|
44
|
-
DType dmax;
|
47
|
+
typename MagnitudeDType<DType>::type dmax;
|
45
48
|
int imax = 0;
|
46
49
|
|
47
50
|
if (incx == 1) { // if incrementing by 1
|
48
51
|
|
49
|
-
dmax =
|
52
|
+
dmax = magnitude(x[0]);
|
50
53
|
|
51
54
|
for (int i = 1; i < n; ++i) {
|
52
|
-
if (
|
55
|
+
if (magnitude(x[i]) > dmax) {
|
53
56
|
imax = i;
|
54
|
-
dmax =
|
57
|
+
dmax = magnitude(x[i]);
|
55
58
|
}
|
56
59
|
}
|
57
60
|
|
58
61
|
} else { // if incrementing by more than 1
|
59
62
|
|
60
|
-
dmax =
|
63
|
+
dmax = magnitude(x[0]);
|
61
64
|
|
62
65
|
for (int i = 1, ix = incx; i < n; ++i, ix += incx) {
|
63
|
-
if (
|
66
|
+
if (magnitude(x[ix]) > dmax) {
|
64
67
|
imax = i;
|
65
|
-
dmax =
|
68
|
+
dmax = magnitude(x[ix]);
|
66
69
|
}
|
67
70
|
}
|
68
71
|
}
|
data/ext/nmatrix/math/laswp.h
CHANGED
@@ -102,7 +102,7 @@ inline void laswp(const int N, DType* A, const int lda, const int K1, const int
|
|
102
102
|
DType *a0 = &(A[i]),
|
103
103
|
*a1 = &(A[ip]);
|
104
104
|
|
105
|
-
for (
|
105
|
+
for (int h = 32; h; h--) {
|
106
106
|
DType r = *a0;
|
107
107
|
*a0 = *a1;
|
108
108
|
*a1 = r;
|
@@ -131,7 +131,7 @@ inline void laswp(const int N, DType* A, const int lda, const int K1, const int
|
|
131
131
|
DType *a0 = &(A[i]),
|
132
132
|
*a1 = &(A[ip]);
|
133
133
|
|
134
|
-
for (
|
134
|
+
for (int h = mr; h; h--) {
|
135
135
|
DType r = *a0;
|
136
136
|
*a0 = *a1;
|
137
137
|
*a1 = r;
|
@@ -162,4 +162,4 @@ inline void clapack_laswp(const int n, void* a, const int lda, const int k1, con
|
|
162
162
|
}
|
163
163
|
|
164
164
|
} } // namespace nm::math
|
165
|
-
#endif // LASWP_H
|
165
|
+
#endif // LASWP_H
|
@@ -9,8 +9,8 @@
|
|
9
9
|
//
|
10
10
|
// == Copyright Information
|
11
11
|
//
|
12
|
-
// SciRuby is Copyright (c) 2010 -
|
13
|
-
// NMatrix is Copyright (c) 2012 -
|
12
|
+
// SciRuby is Copyright (c) 2010 - present, Ruby Science Foundation
|
13
|
+
// NMatrix is Copyright (c) 2012 - present, John Woods and the Ruby Science Foundation
|
14
14
|
//
|
15
15
|
// Please see LICENSE.txt for additional copyright notices.
|
16
16
|
//
|
@@ -23,7 +23,8 @@
|
|
23
23
|
//
|
24
24
|
// == long_dtype.h
|
25
25
|
//
|
26
|
-
// Declarations necessary for the native versions of GEMM and GEMV
|
26
|
+
// Declarations necessary for the native versions of GEMM and GEMV,
|
27
|
+
// as well as for IMAX.
|
27
28
|
//
|
28
29
|
|
29
30
|
#ifndef LONG_DTYPE_H
|
@@ -44,6 +45,18 @@ namespace nm { namespace math {
|
|
44
45
|
template <> struct LongDType<Complex128> { typedef Complex128 type; };
|
45
46
|
template <> struct LongDType<RubyObject> { typedef RubyObject type; };
|
46
47
|
|
48
|
+
template <typename DType> struct MagnitudeDType;
|
49
|
+
template <> struct MagnitudeDType<uint8_t> { typedef uint8_t type; };
|
50
|
+
template <> struct MagnitudeDType<int8_t> { typedef int8_t type; };
|
51
|
+
template <> struct MagnitudeDType<int16_t> { typedef int16_t type; };
|
52
|
+
template <> struct MagnitudeDType<int32_t> { typedef int32_t type; };
|
53
|
+
template <> struct MagnitudeDType<int64_t> { typedef int64_t type; };
|
54
|
+
template <> struct MagnitudeDType<float> { typedef float type; };
|
55
|
+
template <> struct MagnitudeDType<double> { typedef double type; };
|
56
|
+
template <> struct MagnitudeDType<Complex64> { typedef float type; };
|
57
|
+
template <> struct MagnitudeDType<Complex128> { typedef double type; };
|
58
|
+
template <> struct MagnitudeDType<RubyObject> { typedef RubyObject type; };
|
59
|
+
|
47
60
|
}} // end of namespace nm::math
|
48
61
|
|
49
62
|
#endif
|
@@ -0,0 +1,54 @@
|
|
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 - present, Ruby Science Foundation
|
13
|
+
// NMatrix is Copyright (c) 2012 - present, 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
|
+
// == math/magnitude.h
|
25
|
+
//
|
26
|
+
// Takes the absolute value (meaning magnitude) of each DType.
|
27
|
+
// Needed for a variety of BLAS/LAPACK functions.
|
28
|
+
//
|
29
|
+
|
30
|
+
#ifndef MAGNITUDE_H
|
31
|
+
#define MAGNITUDE_H
|
32
|
+
|
33
|
+
#include "math/long_dtype.h"
|
34
|
+
|
35
|
+
namespace nm { namespace math {
|
36
|
+
|
37
|
+
/* Magnitude -- may be complicated for unsigned types, and need to call the correct STL abs for floats/doubles */
|
38
|
+
template <typename DType, typename MDType = typename MagnitudeDType<DType>::type>
|
39
|
+
inline MDType magnitude(const DType& v) {
|
40
|
+
return v.abs();
|
41
|
+
}
|
42
|
+
template <> inline float magnitude(const float& v) { return std::abs(v); }
|
43
|
+
template <> inline double magnitude(const double& v) { return std::abs(v); }
|
44
|
+
template <> inline uint8_t magnitude(const uint8_t& v) { return v; }
|
45
|
+
template <> inline int8_t magnitude(const int8_t& v) { return std::abs(v); }
|
46
|
+
template <> inline int16_t magnitude(const int16_t& v) { return std::abs(v); }
|
47
|
+
template <> inline int32_t magnitude(const int32_t& v) { return std::abs(v); }
|
48
|
+
template <> inline int64_t magnitude(const int64_t& v) { return std::abs(v); }
|
49
|
+
template <> inline float magnitude(const nm::Complex64& v) { return std::sqrt(v.r * v.r + v.i * v.i); }
|
50
|
+
template <> inline double magnitude(const nm::Complex128& v) { return std::sqrt(v.r * v.r + v.i * v.i); }
|
51
|
+
|
52
|
+
}}
|
53
|
+
|
54
|
+
#endif // MAGNITUDE_H
|
data/ext/nmatrix/math/nrm2.h
CHANGED
@@ -9,8 +9,8 @@
|
|
9
9
|
//
|
10
10
|
// == Copyright Information
|
11
11
|
//
|
12
|
-
// SciRuby is Copyright (c) 2010 -
|
13
|
-
// NMatrix is Copyright (c) 2012 -
|
12
|
+
// SciRuby is Copyright (c) 2010 - present, Ruby Science Foundation
|
13
|
+
// NMatrix is Copyright (c) 2012 - present, John Woods and the Ruby Science Foundation
|
14
14
|
//
|
15
15
|
// Please see LICENSE.txt for additional copyright notices.
|
16
16
|
//
|
@@ -74,8 +74,8 @@ namespace nm { namespace math {
|
|
74
74
|
* complex64 -> float or double
|
75
75
|
* complex128 -> double
|
76
76
|
*/
|
77
|
-
template <typename
|
78
|
-
|
77
|
+
template <typename DType, typename MDType = typename MagnitudeDType<DType>::type>
|
78
|
+
MDType nrm2(const int N, const DType* X, const int incX) {
|
79
79
|
const DType ONE = 1, ZERO = 0;
|
80
80
|
typename LongDType<DType>::type scale = 0, ssq = 1, absxi, temp;
|
81
81
|
|
@@ -89,13 +89,14 @@ ReturnDType nrm2(const int N, const DType* X, const int incX) {
|
|
89
89
|
temp = scale / absxi;
|
90
90
|
scale = absxi;
|
91
91
|
ssq = ONE + ssq * (temp * temp);
|
92
|
-
}
|
92
|
+
}
|
93
|
+
else if(scale != 0) {
|
93
94
|
temp = absxi / scale;
|
94
95
|
ssq += temp * temp;
|
95
96
|
}
|
96
97
|
}
|
97
98
|
|
98
|
-
return scale * std::sqrt( ssq );
|
99
|
+
return (MDType)(scale * std::sqrt( ssq ));
|
99
100
|
}
|
100
101
|
|
101
102
|
|
@@ -106,7 +107,8 @@ static inline void nrm2_complex_helper(const FloatDType& xr, const FloatDType& x
|
|
106
107
|
double temp = scale / absx;
|
107
108
|
scale = absx;
|
108
109
|
ssq = 1.0 + ssq * (temp * temp);
|
109
|
-
}
|
110
|
+
}
|
111
|
+
else if(scale != 0) {
|
110
112
|
double temp = absx / scale;
|
111
113
|
ssq += temp * temp;
|
112
114
|
}
|
@@ -116,7 +118,8 @@ static inline void nrm2_complex_helper(const FloatDType& xr, const FloatDType& x
|
|
116
118
|
double temp = scale / absx;
|
117
119
|
scale = absx;
|
118
120
|
ssq = 1.0 + ssq * (temp * temp);
|
119
|
-
}
|
121
|
+
}
|
122
|
+
else if(scale != 0) {
|
120
123
|
double temp = absx / scale;
|
121
124
|
ssq += temp * temp;
|
122
125
|
}
|
@@ -124,33 +127,35 @@ static inline void nrm2_complex_helper(const FloatDType& xr, const FloatDType& x
|
|
124
127
|
|
125
128
|
template <>
|
126
129
|
float nrm2(const int N, const Complex64* X, const int incX) {
|
127
|
-
double scale = 0, ssq = 1
|
130
|
+
double scale = 0, ssq = 1;
|
128
131
|
|
129
132
|
if ((N < 1) || (incX < 1)) return 0.0;
|
130
133
|
|
131
134
|
for (int i = 0; i < N; ++i) {
|
132
|
-
nrm2_complex_helper<float>(X[i*incX].r, X[i*incX].i, scale,
|
135
|
+
nrm2_complex_helper<float>(X[i*incX].r, X[i*incX].i, scale, ssq);
|
133
136
|
}
|
134
137
|
|
135
138
|
return scale * std::sqrt( ssq );
|
136
139
|
}
|
137
140
|
|
141
|
+
// FIXME: Function above is duplicated here, should be writeable as a template using
|
142
|
+
// FIXME: xMagnitudeDType.
|
138
143
|
template <>
|
139
144
|
double nrm2(const int N, const Complex128* X, const int incX) {
|
140
|
-
double scale = 0, ssq = 1
|
145
|
+
double scale = 0, ssq = 1;
|
141
146
|
|
142
147
|
if ((N < 1) || (incX < 1)) return 0.0;
|
143
148
|
|
144
149
|
for (int i = 0; i < N; ++i) {
|
145
|
-
nrm2_complex_helper<double>(X[i*incX].r, X[i*incX].i, scale,
|
150
|
+
nrm2_complex_helper<double>(X[i*incX].r, X[i*incX].i, scale, ssq);
|
146
151
|
}
|
147
152
|
|
148
153
|
return scale * std::sqrt( ssq );
|
149
154
|
}
|
150
155
|
|
151
|
-
template <typename
|
156
|
+
template <typename DType, typename MDType = typename MagnitudeDType<DType>::type>
|
152
157
|
inline void cblas_nrm2(const int N, const void* X, const int incX, void* result) {
|
153
|
-
*reinterpret_cast<
|
158
|
+
*reinterpret_cast<MDType*>( result ) = nrm2<DType, MDType>( N, reinterpret_cast<const DType*>(X), incX );
|
154
159
|
}
|
155
160
|
|
156
161
|
|