pspline 5.0.5 → 5.1.0
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.
- checksums.yaml +4 -4
- data/Gemfile +5 -5
- data/README.md +44 -43
- data/Rakefile +6 -6
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/ext/pspline/basis.cpp +394 -351
- data/ext/pspline/example/exbspline.rb +57 -57
- data/ext/pspline/example/excspline.rb +57 -57
- data/ext/pspline/example/exdspline.rb +55 -55
- data/ext/pspline/example/exfspline.rb +44 -44
- data/ext/pspline/example/exfspline1.rb +40 -40
- data/ext/pspline/example/exfspline2.rb +68 -68
- data/ext/pspline/example/exfspline3.rb +64 -64
- data/ext/pspline/example/exmspline.rb +68 -68
- data/ext/pspline/example/expspline.rb +29 -29
- data/ext/pspline/example/expspline1.rb +29 -29
- data/ext/pspline/example/expspline2.rb +47 -47
- data/ext/pspline/example/exqspline.rb +31 -31
- data/ext/pspline/example/exqspline1.rb +31 -31
- data/ext/pspline/example/exqspline2.rb +50 -50
- data/ext/pspline/example/exqspline3.rb +51 -51
- data/ext/pspline/example/exqspline4.rb +35 -35
- data/ext/pspline/example/exrspline.rb +34 -34
- data/ext/pspline/example/exrspline1.rb +34 -34
- data/ext/pspline/example/exrspline2.rb +44 -44
- data/ext/pspline/example/exsspline.rb +35 -35
- data/ext/pspline/example/exsspline1.rb +35 -35
- data/ext/pspline/example/extspline.rb +54 -54
- data/ext/pspline/extconf.rb +7 -7
- data/ext/pspline/fft.cpp +27 -552
- data/ext/pspline/include/basis/basis.h +145 -137
- data/ext/pspline/include/basis/fft.h +188 -152
- data/ext/pspline/include/basis/fft_complex.h +215 -0
- data/ext/pspline/include/basis/fft_real.h +625 -0
- data/ext/pspline/include/basis/gabs.h +35 -0
- data/ext/pspline/include/basis/marray_class_ext.h +568 -0
- data/ext/pspline/include/basis/marray_ext.h +100 -0
- data/ext/pspline/include/basis/matrix_luc_ext.h +300 -0
- data/ext/pspline/include/basis/matrix_lud_ext.h +298 -0
- data/ext/pspline/include/basis/poly.h +454 -0
- data/ext/pspline/include/basis/poly_array.h +1030 -1568
- data/ext/pspline/include/basis/pspline.h +806 -642
- data/ext/pspline/include/basis/real.h +526 -0
- data/ext/pspline/include/basis/real_inline.h +442 -0
- data/ext/pspline/include/basis/spline.h +83 -0
- data/ext/pspline/include/basis/uspline.h +251 -210
- data/ext/pspline/include/basis/util.h +122 -656
- data/ext/pspline/include/bspline.h +71 -377
- data/ext/pspline/include/bspline_Config.h +8 -2
- data/ext/pspline/include/real_config.h +3 -0
- data/ext/pspline/pspline.cpp +1236 -1038
- data/ext/pspline/real.cpp +1607 -0
- data/ext/pspline/real_const.cpp +585 -0
- data/lib/pspline.rb +71 -71
- data/lib/pspline/version.rb +1 -1
- data/pspline.gemspec +25 -25
- metadata +17 -5
- data/ext/pspline/plotsub.cpp +0 -139
- data/ext/pspline/util.cpp +0 -483
|
@@ -1,137 +1,145 @@
|
|
|
1
|
-
#ifndef _BASIS_H_INCLUDED_
|
|
2
|
-
#define _BASIS_H_INCLUDED_
|
|
3
|
-
#include <
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
public:
|
|
20
|
-
// constructor
|
|
21
|
-
base_spline() : knots(NULL) {}
|
|
22
|
-
|
|
23
|
-
base_spline(const S
|
|
24
|
-
base_spline(const
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
//
|
|
28
|
-
base_spline
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
int
|
|
33
|
-
int
|
|
34
|
-
int
|
|
35
|
-
int
|
|
36
|
-
|
|
37
|
-
int
|
|
38
|
-
S
|
|
39
|
-
S
|
|
40
|
-
S
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
void
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
for (int i =
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
int
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
1
|
+
#ifndef _BASIS_H_INCLUDED_
|
|
2
|
+
#define _BASIS_H_INCLUDED_
|
|
3
|
+
#include <assert.h>
|
|
4
|
+
|
|
5
|
+
template <typename P, typename T>
|
|
6
|
+
int deboor(int, const P&, int, const T&, P&, int&, int = 0);
|
|
7
|
+
template <typename P, typename T>
|
|
8
|
+
void deboor_cox(int, const P&, int, const T&, P&, int&, int, int = 0);
|
|
9
|
+
|
|
10
|
+
/*******************************************************************************
|
|
11
|
+
Bスプライン基底(節点列によるBスプライン関数計算)
|
|
12
|
+
*******************************************************************************/
|
|
13
|
+
template <typename S = double> class base_spline
|
|
14
|
+
{
|
|
15
|
+
protected:
|
|
16
|
+
int imax, icox, rank, jisu, shuki, maxq;
|
|
17
|
+
varray<S> *knots;
|
|
18
|
+
base_spline *Base() { return this; }
|
|
19
|
+
public:
|
|
20
|
+
// default constructor
|
|
21
|
+
base_spline() : knots(NULL) {}
|
|
22
|
+
// constructor
|
|
23
|
+
base_spline(int, const varray<S>&, int, int = 0, int* = NULL);
|
|
24
|
+
base_spline(const varray<S>&, int, int, int);
|
|
25
|
+
// copy constructor
|
|
26
|
+
base_spline(const base_spline&);
|
|
27
|
+
// destructor
|
|
28
|
+
~base_spline() { delete knots; }
|
|
29
|
+
// assignment operator
|
|
30
|
+
base_spline& operator=(const base_spline&);
|
|
31
|
+
// properties
|
|
32
|
+
int Imax() const { return imax; }
|
|
33
|
+
int Icox() const { return icox; }
|
|
34
|
+
int Rank() const { return rank; }
|
|
35
|
+
int Jisu() const { return jisu; }
|
|
36
|
+
int Shuki()const { return shuki;}
|
|
37
|
+
int Maxq() const { return maxq; }
|
|
38
|
+
varray<S>& Knots() const { return *knots; }
|
|
39
|
+
int Kset(const real<S>& x) const;
|
|
40
|
+
real<S> x_max() const {return (*knots)[icox];}
|
|
41
|
+
real<S> x_min() const {return (*knots)[jisu];}
|
|
42
|
+
real<S> operator[] (int i) const {return (*knots)[i];}
|
|
43
|
+
int basic(const real<S>&, int, varray<S>&, int = 0) const;
|
|
44
|
+
void bibun_keisu(int, marray<S>&) const;
|
|
45
|
+
void sekibun_keisu(int, marray<S>&) const;
|
|
46
|
+
void gyoretu(marray<S>&, int, const varray<S>&, const int* = NULL) const;
|
|
47
|
+
marray<S> gyoretu(const Int&, const varray<S>&, const int* = NULL) const;
|
|
48
|
+
parray<S> basis(const real<S>&, int = 0) const;
|
|
49
|
+
parray<S> bases(const real<S>&, int = 0) const;
|
|
50
|
+
parray<S> sekibun(const real<S>&, int) const;
|
|
51
|
+
void print() const;
|
|
52
|
+
/*******************************************************************************
|
|
53
|
+
線形結合係数の適用 Σa[i]*b[i]; i = kset-Kai+1,...,kset;
|
|
54
|
+
d: d > 0 ? 微分階数 : d == 0 ? 補間値 : 高階積分
|
|
55
|
+
t: データ点の座標値
|
|
56
|
+
alp: (微分)線形結合係数の配列
|
|
57
|
+
*******************************************************************************/
|
|
58
|
+
template <typename T> real<T> apply(const real<S>& t, const varray<T>& alp, int d = 0) const
|
|
59
|
+
{
|
|
60
|
+
if (d >= 0) {
|
|
61
|
+
assert(rank > d);
|
|
62
|
+
int k = rank - d;
|
|
63
|
+
varray<S> b(size_t(icox), t.atom());
|
|
64
|
+
int ks = basic(t, icox, b, k);
|
|
65
|
+
int kset = ks + k - 1;
|
|
66
|
+
if (ks < 0) ks = 0;
|
|
67
|
+
real<T> sum(T(), t.atom());
|
|
68
|
+
for (int i = ks; i <= kset; i++) sum += alp[i] * b[i];
|
|
69
|
+
return sum;
|
|
70
|
+
} else
|
|
71
|
+
return sekibun<T,real<T>,varray<T> >(t, alp, d);
|
|
72
|
+
}
|
|
73
|
+
/*******************************************************************************
|
|
74
|
+
不定積分の計算
|
|
75
|
+
*******************************************************************************/
|
|
76
|
+
template <typename T> real<T> sekibun(const real<S>& x, const varray<T>& alp) const
|
|
77
|
+
{
|
|
78
|
+
const varray<S>& q = *knots;
|
|
79
|
+
int K = rank, J = K - 1;
|
|
80
|
+
int Imax = Kset(x);
|
|
81
|
+
real<T> sum(alp.atom());
|
|
82
|
+
for (int ql = J; ql <= Imax; ++ql) {
|
|
83
|
+
real<S> t = q[ql];
|
|
84
|
+
parray<S> fl = bases(t, J);
|
|
85
|
+
int ks = fl.offset(), kset = ks + J;
|
|
86
|
+
real<S> Qh = (ql < Imax ? q[ql+1] : x) - t;
|
|
87
|
+
for (int i = ks; i <= kset; ++i) {
|
|
88
|
+
real<S> Qs = fl.saylor(i - ks, Qh);
|
|
89
|
+
sum += alp[i] * Qs;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return sum;
|
|
93
|
+
}
|
|
94
|
+
/*******************************************************************************
|
|
95
|
+
高階積分の計算
|
|
96
|
+
*******************************************************************************/
|
|
97
|
+
template <typename T, typename P = real<T>, typename Q = varray<T> >
|
|
98
|
+
P sekibun(const real<S>& t, const Q& alp, int Jsk) const
|
|
99
|
+
{
|
|
100
|
+
assert(Jsk < 0);
|
|
101
|
+
size_t A = alp.atom();
|
|
102
|
+
int k = rank - Jsk;
|
|
103
|
+
varray<S> b(size_t(k), t.atom());
|
|
104
|
+
const varray<S>& q = *knots;
|
|
105
|
+
int kset, ks = deboor(rank, q, icox, t, b, kset, k);
|
|
106
|
+
Q a(size_t(kset+1), A);
|
|
107
|
+
for (int i = 0; i <= kset; ++i) a[i] = alp[i];
|
|
108
|
+
while (Jsk < 0) {
|
|
109
|
+
P ab(T(), A);
|
|
110
|
+
for (int i = 0; i <= kset; ++i) {
|
|
111
|
+
real<S> w = (q[i+(k+Jsk)] - q[i]) / S(k+Jsk);
|
|
112
|
+
a[i] = ab + a[i] * w; ab = a[i];
|
|
113
|
+
}
|
|
114
|
+
Jsk++;
|
|
115
|
+
}
|
|
116
|
+
P sek(T(), A);
|
|
117
|
+
for (int i = ks > 0 ? ks : 0; i <= kset; ++i) sek += a[i] * b[i-ks];
|
|
118
|
+
return sek;
|
|
119
|
+
}
|
|
120
|
+
/*******************************************************************************
|
|
121
|
+
多次元積分の計算
|
|
122
|
+
*******************************************************************************/
|
|
123
|
+
template <typename T> varray<T> sekibun(const real<S>& x, const marray<T>& clp) const
|
|
124
|
+
{
|
|
125
|
+
const varray<S>& q = *knots;
|
|
126
|
+
int K = rank, J = K - 1;
|
|
127
|
+
int Imax = Kset(x);
|
|
128
|
+
varray<T> p(T(), clp.cols(), clp.atom());
|
|
129
|
+
for (int ql = J; ql <= Imax; ++ql) {
|
|
130
|
+
real<S> t = q[ql];
|
|
131
|
+
parray<S> fl = bases(t, J);
|
|
132
|
+
int ks = fl.offset(), kset = ks + J;
|
|
133
|
+
real<S> Qh = (ql < Imax ? q[ql+1] : x) - t;
|
|
134
|
+
for (int i = ks; i <= kset; ++i) {
|
|
135
|
+
real<S> Qs = fl.saylor(i - ks, Qh);
|
|
136
|
+
size_t n = p.size();
|
|
137
|
+
for (size_t k = 0; k < n; ++k) p[k] += clp[i][k] * Qs;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return p;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
}; // end of base_spline;
|
|
144
|
+
|
|
145
|
+
#endif
|
|
@@ -1,152 +1,188 @@
|
|
|
1
|
-
#ifndef _FFT_H_INCLUDED_
|
|
2
|
-
#define _FFT_H_INCLUDED_
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
i
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
{
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
if (i
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
i
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
val[
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
1
|
+
#ifndef _FFT_H_INCLUDED_
|
|
2
|
+
#define _FFT_H_INCLUDED_
|
|
3
|
+
#include "basis/marray_ext.h"
|
|
4
|
+
#include "basis/real_inline.h"
|
|
5
|
+
#include "basis/marray_class_ext.h"
|
|
6
|
+
#include "basis/util.h"
|
|
7
|
+
#include "basis/poly_array.h"
|
|
8
|
+
#include "basis/basis.h"
|
|
9
|
+
#include "basis/pspline.h"
|
|
10
|
+
|
|
11
|
+
template <typename T> bool rfft(varray<T>&, size_t, int); // 実数値高速フーリエ変換
|
|
12
|
+
template <typename T> bool cfft(varray<T>&, size_t, int); // 複素高速フーリエ変換(実数値配列引数)
|
|
13
|
+
|
|
14
|
+
template <typename T = double, typename S = T> struct fft
|
|
15
|
+
{
|
|
16
|
+
|
|
17
|
+
static bool complex_forward(varray<T>& dat) { return cfft(dat, dat.size(), 1); }
|
|
18
|
+
|
|
19
|
+
static bool complex_backward(varray<T>& dat) { return cfft(dat, dat.size(), 0); }
|
|
20
|
+
|
|
21
|
+
static bool complex_inverse(varray<T>& dat) { return cfft(dat, dat.size(), -1); }
|
|
22
|
+
|
|
23
|
+
static bool complex_transform(varray<T>& dat, int f) { return cfft(dat, dat.size(), f); }
|
|
24
|
+
|
|
25
|
+
static varray<T> half_en_pack(const varray<T>& dfft)
|
|
26
|
+
{
|
|
27
|
+
size_t nn = dfft.size(), n = nn >> 1, i, j;
|
|
28
|
+
varray<T> data(nn, dfft.atom());
|
|
29
|
+
const varray<T>& data1 = data[0], &data2 = data[n];
|
|
30
|
+
|
|
31
|
+
data1[0] = dfft[0]; data2[0] = dfft[1];
|
|
32
|
+
for (i = 2; i < n; i += 2) {
|
|
33
|
+
j = nn - i;
|
|
34
|
+
data1[i-1] = 0.5*(dfft[ j ] + dfft[ i ]);
|
|
35
|
+
data1[ i ] = 0.5*(dfft[i+1] - dfft[j+1]);
|
|
36
|
+
data2[i-1] = 0.5*(dfft[i+1] + dfft[j+1]);
|
|
37
|
+
data2[ i ] = 0.5*(dfft[ j ] - dfft[ i ]);
|
|
38
|
+
}
|
|
39
|
+
if (i == n) {
|
|
40
|
+
data1[i-1] = dfft[i]; data2[i-1] = dfft[i+1];
|
|
41
|
+
}
|
|
42
|
+
return data;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static void complex_get(const varray<T>& data, int i, varray<T>& val)
|
|
46
|
+
{
|
|
47
|
+
int nn = data.size(), N = nn >> 1;
|
|
48
|
+
i %= N;
|
|
49
|
+
if (N/2 < i ) i -= N;
|
|
50
|
+
if (i < -N/2) i += N;
|
|
51
|
+
const varray<T>& var = data[(i < 0 ? i + N : i) << 1];
|
|
52
|
+
val[0] = var[0];
|
|
53
|
+
val[1] = var[1];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static bspline<T,S> *cfft_spline(const varray<T>& dfft, int j)
|
|
57
|
+
{
|
|
58
|
+
int nn = dfft.size(), N = nn >> 1;
|
|
59
|
+
size_t A = dfft.atom();
|
|
60
|
+
poly_array<T> Y(Int{N, 2, int(A)});
|
|
61
|
+
varray<S> X(size_t(N+1), A);
|
|
62
|
+
const varray<T>& data = *Y;
|
|
63
|
+
for (int i = 0; i < N; ++i) {
|
|
64
|
+
X[i] = T(i - N/2);
|
|
65
|
+
int r = i < N/2 ? i + N/2 + N%2 : i - N/2;
|
|
66
|
+
data[2*i] = dfft[r*2];
|
|
67
|
+
data[2*i+1] = dfft[r*2+1];
|
|
68
|
+
} X[N] = T(N - N/2);
|
|
69
|
+
return new bspline<T,S>(Y, X, N+1, j, 1);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
static bool real_forward(varray<T>& dat) { return rfft(dat, dat.size(), 1); }
|
|
73
|
+
|
|
74
|
+
static bool real_backward(varray<T>& dat) { return rfft(dat, dat.size(), 0); }
|
|
75
|
+
|
|
76
|
+
static bool real_inverse(varray<T>& dat) { return rfft(dat, dat.size(), -1); }
|
|
77
|
+
|
|
78
|
+
static bool real_transform(varray<T>& dat, int f) { return rfft(dat, dat.size(), f); }
|
|
79
|
+
|
|
80
|
+
static varray<T> half_de_pack(const varray<T>& data)
|
|
81
|
+
{
|
|
82
|
+
size_t nn = data.size(), n = nn >> 1, i, j;
|
|
83
|
+
varray<T> dfft(nn, data.atom());
|
|
84
|
+
const varray<T>& data1 = data[0], &data2 = data[n];
|
|
85
|
+
|
|
86
|
+
dfft[0] = data1[0]; dfft[1] = data2[0];
|
|
87
|
+
for (i = 2; i < n; i += 2) {
|
|
88
|
+
j = nn - i;
|
|
89
|
+
dfft[ i ] = data1[i-1] - data2[ i ];
|
|
90
|
+
dfft[i+1] = data2[i-1] + data1[ i ];
|
|
91
|
+
dfft[ j ] = data1[i-1] + data2[ i ];
|
|
92
|
+
dfft[j+1] = data2[i-1] - data1[ i ];
|
|
93
|
+
}
|
|
94
|
+
if (i == n) {
|
|
95
|
+
dfft[n] = data1[n-1]; dfft[n+1] = data2[n-1];
|
|
96
|
+
}
|
|
97
|
+
return dfft;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static void real_get(varray<T>& data, int i, varray<T>& val)
|
|
101
|
+
{
|
|
102
|
+
int N = data.size();
|
|
103
|
+
i %= N;
|
|
104
|
+
if (N/2 < i ) i -= N;
|
|
105
|
+
if (i < -N/2) i += N;
|
|
106
|
+
int j = (i < 0 ? -i : i) << 1;
|
|
107
|
+
const varray<T>& var = data[i == 0 ? 0 : j - 1];
|
|
108
|
+
val[0] = var[0];
|
|
109
|
+
if (i == 0 || j == N)
|
|
110
|
+
val[1] = T();
|
|
111
|
+
else
|
|
112
|
+
val[1] = var[1] * (i < 0 ? -1 : 1);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
static void half_get(varray<T>& data1, int i, varray<T>& val)
|
|
116
|
+
{
|
|
117
|
+
int nn = data1.size(), N = nn >> 1;
|
|
118
|
+
i %= N;
|
|
119
|
+
if (N/2 < i ) i -= N;
|
|
120
|
+
if (i < -N/2) i += N;
|
|
121
|
+
int j = (i < 0 ? -i : i) << 1;
|
|
122
|
+
const varray<T>& data2 = data1[N];
|
|
123
|
+
if (i == 0) {
|
|
124
|
+
val[0] = data1[0];
|
|
125
|
+
val[1] = data2[0];
|
|
126
|
+
} else if (j == N) {
|
|
127
|
+
val[0] = data1[N-1];
|
|
128
|
+
val[1] = data2[N-1];
|
|
129
|
+
} else if (i < 0) {
|
|
130
|
+
val[0] = data1[j-1] + data2[j];
|
|
131
|
+
val[1] = data2[j-1] - data1[j];
|
|
132
|
+
} else {
|
|
133
|
+
val[0] = data1[j-1] - data2[j];
|
|
134
|
+
val[1] = data2[j-1] + data1[j];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
static bspline<T,S> *rfft_spline(varray<T>& dat, int j)
|
|
139
|
+
{
|
|
140
|
+
int N = dat.size();
|
|
141
|
+
size_t A = dat.atom();
|
|
142
|
+
poly_array<T> Y(Int{N, 2, int(A)});
|
|
143
|
+
varray<S> X(size_t(N+1), A);
|
|
144
|
+
const varray<T>& data = *Y;
|
|
145
|
+
for (int i = 0; i < N; ++i) {
|
|
146
|
+
X[i] = T(i - N/2);
|
|
147
|
+
int r = i < N/2 ? N/2 - i : i - N/2;
|
|
148
|
+
if (i == 0 && N%2 == 0) {
|
|
149
|
+
data[0] = dat[2*r-1];
|
|
150
|
+
data[1] = T();
|
|
151
|
+
} else if (i == N/2) {
|
|
152
|
+
data[2*i] = dat[0];
|
|
153
|
+
data[2*i+1] = T();
|
|
154
|
+
} else {
|
|
155
|
+
data[2*i] = dat[2*r-1];
|
|
156
|
+
data[2*i+1] = dat[2*r] * T(i < N/2 ? -1 : 1);
|
|
157
|
+
}
|
|
158
|
+
} X[N] = T(N - N/2);
|
|
159
|
+
return new bspline<T,S>(Y, X, N+1, j, 1);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
static varray<T> real_mul(const varray<T>& data1, const varray<T>& data2)
|
|
163
|
+
{
|
|
164
|
+
size_t N = data1.size();
|
|
165
|
+
size_t A = data1.atom();
|
|
166
|
+
varray<T> result(N, A);
|
|
167
|
+
for (size_t i = 0; i <= N; i += 2) {
|
|
168
|
+
if (i == 0) result[ i ] = data1[ i ] * data2[ i ]; else
|
|
169
|
+
if (i == N) result[N-1] = data1[N-1] * data2[N-1]; else
|
|
170
|
+
{
|
|
171
|
+
result[i-1] = data1[i-1]*data2[i-1] - data1[i]*data2[ i ];
|
|
172
|
+
result[ i ] = data1[i-1]*data2[ i ] + data1[i]*data2[i-1];
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
static varray<T> half_mul(const varray<T>& data)
|
|
179
|
+
{
|
|
180
|
+
size_t n = data.size(), N = n >> 1;
|
|
181
|
+
size_t A = data.atom();
|
|
182
|
+
varray<T> vect((T*)data, N, A);
|
|
183
|
+
return real_mul(vect, data[N]);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
}; // end of fft;
|
|
187
|
+
|
|
188
|
+
#endif
|