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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -5
  3. data/README.md +44 -43
  4. data/Rakefile +6 -6
  5. data/bin/console +14 -14
  6. data/bin/setup +8 -8
  7. data/ext/pspline/basis.cpp +394 -351
  8. data/ext/pspline/example/exbspline.rb +57 -57
  9. data/ext/pspline/example/excspline.rb +57 -57
  10. data/ext/pspline/example/exdspline.rb +55 -55
  11. data/ext/pspline/example/exfspline.rb +44 -44
  12. data/ext/pspline/example/exfspline1.rb +40 -40
  13. data/ext/pspline/example/exfspline2.rb +68 -68
  14. data/ext/pspline/example/exfspline3.rb +64 -64
  15. data/ext/pspline/example/exmspline.rb +68 -68
  16. data/ext/pspline/example/expspline.rb +29 -29
  17. data/ext/pspline/example/expspline1.rb +29 -29
  18. data/ext/pspline/example/expspline2.rb +47 -47
  19. data/ext/pspline/example/exqspline.rb +31 -31
  20. data/ext/pspline/example/exqspline1.rb +31 -31
  21. data/ext/pspline/example/exqspline2.rb +50 -50
  22. data/ext/pspline/example/exqspline3.rb +51 -51
  23. data/ext/pspline/example/exqspline4.rb +35 -35
  24. data/ext/pspline/example/exrspline.rb +34 -34
  25. data/ext/pspline/example/exrspline1.rb +34 -34
  26. data/ext/pspline/example/exrspline2.rb +44 -44
  27. data/ext/pspline/example/exsspline.rb +35 -35
  28. data/ext/pspline/example/exsspline1.rb +35 -35
  29. data/ext/pspline/example/extspline.rb +54 -54
  30. data/ext/pspline/extconf.rb +7 -7
  31. data/ext/pspline/fft.cpp +27 -552
  32. data/ext/pspline/include/basis/basis.h +145 -137
  33. data/ext/pspline/include/basis/fft.h +188 -152
  34. data/ext/pspline/include/basis/fft_complex.h +215 -0
  35. data/ext/pspline/include/basis/fft_real.h +625 -0
  36. data/ext/pspline/include/basis/gabs.h +35 -0
  37. data/ext/pspline/include/basis/marray_class_ext.h +568 -0
  38. data/ext/pspline/include/basis/marray_ext.h +100 -0
  39. data/ext/pspline/include/basis/matrix_luc_ext.h +300 -0
  40. data/ext/pspline/include/basis/matrix_lud_ext.h +298 -0
  41. data/ext/pspline/include/basis/poly.h +454 -0
  42. data/ext/pspline/include/basis/poly_array.h +1030 -1568
  43. data/ext/pspline/include/basis/pspline.h +806 -642
  44. data/ext/pspline/include/basis/real.h +526 -0
  45. data/ext/pspline/include/basis/real_inline.h +442 -0
  46. data/ext/pspline/include/basis/spline.h +83 -0
  47. data/ext/pspline/include/basis/uspline.h +251 -210
  48. data/ext/pspline/include/basis/util.h +122 -656
  49. data/ext/pspline/include/bspline.h +71 -377
  50. data/ext/pspline/include/bspline_Config.h +8 -2
  51. data/ext/pspline/include/real_config.h +3 -0
  52. data/ext/pspline/pspline.cpp +1236 -1038
  53. data/ext/pspline/real.cpp +1607 -0
  54. data/ext/pspline/real_const.cpp +585 -0
  55. data/lib/pspline.rb +71 -71
  56. data/lib/pspline/version.rb +1 -1
  57. data/pspline.gemspec +25 -25
  58. metadata +17 -5
  59. data/ext/pspline/plotsub.cpp +0 -139
  60. data/ext/pspline/util.cpp +0 -483
@@ -1,7 +1,7 @@
1
- require 'mkmf'
2
-
3
- dir_config('PSPLINE','.')
4
- $CPPFLAGS += " -std=c++11"
5
- if have_header('bspline.h')
6
- create_makefile('pspline')
7
- end
1
+ require 'mkmf'
2
+
3
+ dir_config('PSPLINE','.')
4
+ $CPPFLAGS += " -std=c++11"
5
+ if have_header('bspline.h')
6
+ create_makefile('pspline')
7
+ end
@@ -1,552 +1,27 @@
1
- #include <stddef.h>
2
- #include <stdlib.h>
3
- #include <stdio.h>
4
- #include <string.h>
5
- #include <math.h>
6
- #include <assert.h>
7
- #include "bspline.h"
8
-
9
- #ifndef M_PI
10
- #define M_PI 3.14159265358979323846
11
- #endif
12
-
13
-
14
- #define SDIM 10
15
-
16
- template <typename T>
17
- inline void relat(T & xr, T & xi, T wqr, T wqi)
18
- {
19
- T wtemp = xr;
20
- xr = wtemp * wqr - xi * wqi;
21
- xi = wtemp * wqi + xi * wqr;
22
- }
23
- template <typename T>
24
- inline void relat(T & yr, T & yi, T xr, T xi, T gr, T gi)
25
- {
26
- T wtemp = yr;
27
- yr = wtemp * xr - yi * xi + gr;
28
- yi = wtemp * xi + yi * xr + gi;
29
- }
30
- template <typename T>
31
- inline void relat(T *xr, T *xi, T *yr, T *yi, T wr, T wi)
32
- {
33
- T tr = wr * (*yr) - wi * (*yi);
34
- T ti = wr * (*yi) + wi * (*yr);
35
- *yr = *xr - tr; *xr += tr;
36
- *yi = *xi - ti; *xi += ti;
37
- }
38
- /*******************************************************************************
39
- 複素高速フーリエ変換(実数配列の引数)
40
- Fast Fourier Transformation / Cooley-Tukey Method
41
- *******************************************************************************/
42
- template <typename T>
43
- void cft2(T *data, size_t n, int f)
44
- {
45
- size_t mmax, m, j, istep, i, N = n >> 1;
46
- T wr, wi, wpr, wpi, theta;
47
-
48
- // ビット反転アルゴリズム
49
- for (j = 1, i = 1; i < n; i += 2) {
50
- if (j > i) { // 複素数を交換
51
- wr = data[j-1]; data[j-1] = data[i-1]; data[i-1] = wr;
52
- wi = data[ j ]; data[ j ] = data[ i ]; data[ i ] = wi;
53
- }
54
- m = N;
55
- while(m >= 2 && j > m) { j -= m; m >>= 1; }
56
- j += m;
57
- }
58
- T F = -f;
59
- mmax = 2; theta = M_PI * F;
60
- while (n > mmax) {
61
- istep = mmax << 1;
62
- wpr = cos(theta); wpi = sin(theta); // 三角関数の漸化式の初期値
63
- wr = 1.0; wi = 0.0;
64
- for (m = 1; m < mmax; m += 2) { // 2重の内側ループ
65
- for (i = m; i <= n; i += istep) {
66
- j = i + mmax;
67
- relat<T>(&data[i-1], &data[i], &data[j-1], &data[j], wr, wi);
68
- }
69
- relat<T>(wr, wi, wpr, wpi); // 三角関数の漸化式
70
- }
71
- mmax = istep;
72
- theta /= 2.0;
73
- }
74
- }
75
- /*
76
- 任意基数のFFT
77
- */
78
- template <typename T, size_t R>
79
- void cft(T *data, size_t n, int f)
80
- {
81
- size_t h, i, j, k, L, m, mmax, istep;
82
- size_t N = n >> 1, Nr = N / R;
83
- T wr, wi, wpr, wpi, wqr, wqi, Xr, Xi, Yr, Yi, *gw;
84
- gw = new T[R*2];
85
- // R進数の桁反転
86
- for (j = 1, i = 1; i < n; i += 2) {
87
- if (i < j) {
88
- wr = data[i-1]; data[i-1] = data[j-1]; data[j-1] = wr;
89
- wi = data[ i ]; data[ i ] = data[ j ]; data[ j ] = wi;
90
- }
91
- m = (R-1) * (Nr << 1);
92
- while (m >= 2 && j > m) {j -= m; m /= R;}
93
- j += m / (R-1);
94
- }
95
- T F = -f;
96
- T theta = 2 * M_PI * F / (T)R;
97
- wqr = cos(theta); wqi = sin(theta);
98
- mmax = 2;
99
- while (n > mmax) {
100
- istep = mmax * R;
101
- wpr = cos(theta); wpi = sin(theta);
102
- wr = 1.0; wi = 0.0;
103
- for (m = 1; m < mmax; m += 2) {
104
- for (i = m; i <= n; i += istep) {
105
- for (j = i, L = 0; L < R; L++, j += mmax) {
106
- h = (L << 1) + 1;
107
- gw[h-1] = data[j-1]; gw[h] = data[j];
108
- }
109
- // バタフライ演算
110
- Xr = wr; Xi = wi;
111
- for (j = i, L = 0; L < R; L++, j += mmax) {
112
- Yr = Yi = 0;
113
- for (k = R; k > 0; --k) {
114
- h = (k << 1) - 1;
115
- relat<T>(Yr, Yi, Xr, Xi, gw[h-1], gw[h]);
116
- } data[j-1] = Yr; data[j] = Yi;
117
- relat<T>(Xr, Xi, wqr, wqi);
118
- }
119
- }
120
- relat<T>(wr, wi, wpr, wpi);
121
- }
122
- mmax = istep;
123
- theta /= R;
124
- }
125
- delete[] gw;
126
- }
127
- /*
128
- 複数基数のFFT subroutine
129
- */
130
- template <typename T>
131
- void cft(size_t r, T *data, size_t n, int f, size_t stride = 1)
132
- {
133
- size_t h, i, j, k, L, Li, Lj;
134
- T xr, xi, yr, yi, *gw;
135
- size_t N = n >> 1, Nr = N / r; // N = r**M;
136
- gw = new T[r*2];
137
- // r進数の桁反転
138
- for (j = Nr, i = 1; i < N - 1; ++i) {
139
- if (i < j) {
140
- size_t ki = (i * stride) << 1;
141
- size_t kj = (j * stride) << 1;
142
- xr = data[ ki ]; data[ ki ] = data[ kj ]; data[ kj ] = xr;
143
- xi = data[ki+1]; data[ki+1] = data[kj+1]; data[kj+1] = xi;
144
- }
145
- size_t m = (r-1) * Nr;
146
- while (m > 0 && j >= m) {j -= m; m /= r;}
147
- j += m / (r-1);
148
- }
149
- T F = -f;
150
- T theta = 2 * M_PI * F / r;
151
- T wqr = cos(theta), wqi = sin(theta);
152
- size_t Nj = 1;
153
- while (Nj < N) {
154
- size_t step = Nj * r;
155
- T wpr = cos(theta), wpi = sin(theta);
156
- T wr = 1.0, wi = 0.0;
157
- for (L = 0; L < Nj; ++L) {
158
- for (h = L; h < N; h += step) {
159
- size_t m = h * stride;
160
- for (Li = m, Lj = 0; Lj < r; ++Lj, Li += Nj * stride) {
161
- i = Li << 1; j = Lj << 1;
162
- gw[j] = data[i]; gw[j+1] = data[i+1];
163
- }
164
- // バタフライ演算
165
- xr = wr; xi = wi;
166
- for (Li = m, Lj = 0; Lj < r; Lj++, Li += Nj * stride) {
167
- yr = yi = 0;
168
- for (k = r; k > 0; --k) {
169
- j = (k << 1) - 1;
170
- relat<T>(yr, yi, xr, xi, gw[j-1], gw[j]);
171
- } i = Li << 1;
172
- data[i] = yr; data[i+1] = yi;
173
- relat<T>(xr, xi, wqr, wqi);
174
- }
175
- }
176
- relat<T>(wr, wi, wpr, wpi);
177
- }
178
- theta /= r;
179
- Nj = step;
180
- }
181
- delete[] gw;
182
- }
183
- /*
184
- 複数基数のFFT main routine
185
- g : データ配列
186
- N : データ個数
187
- f : 1 forward, 0 backword, -1 invert
188
- */
189
- template <typename T>
190
- bool cft(T *data, size_t n, int f)
191
- {
192
- size_t N = n >> 1, Nres = N, s = 0, k;
193
- size_t Ni[SDIM], ni[SDIM], M[SDIM], r[SDIM] = {2};
194
- // Chinese Remainder Theorem
195
- do {
196
- M[s] = 0; ni[s] = 1; Ni[s] = N;
197
- while (Ni[s] % r[s] == 0) {
198
- M[s]++;
199
- ni[s] *= r[s]; // ni = r**M;
200
- Ni[s] /= r[s];
201
- } Nres /= ni[s];
202
- int rnew;
203
- if (Nres != 1) {
204
- rnew = r[s] + (r[s] == 2 ? 1 : 2);
205
- if (M[s] > 0) s++;
206
- if (s < SDIM) {
207
- // 素因数分解
208
- while (Nres % rnew != 0) rnew += 2;
209
- r[s] = rnew;
210
- }
211
- }
212
- } while (Nres > 1 && s < SDIM);
213
- int F = (f > 0) ? 1 : -1;
214
- if (s >= SDIM) return false; else
215
- if (s == 0) {
216
- switch (r[s]) {
217
- case 2: cft2<T>(data, n, F); break;
218
- case 3: cft<T,3>(data, n, F); break;
219
- case 5: cft<T,5>(data, n, F); break;
220
- case 7: cft<T,7>(data, n, F); break;
221
- default: cft<T>(r[s], data, n, F);
222
- }
223
- } else {
224
- size_t smax = s + 1;
225
- T gw[n];
226
- // 最初の並び替え
227
- for (k = 0; k < N; ++k) {
228
- size_t ks, kk = 0;
229
- for (s = 0; s < smax; ++s)
230
- kk = kk * ni[s] + k % ni[s];
231
- kk <<= 1; ks = k << 1;
232
- gw[kk] = data[ks]; gw[kk+1] = data[ks+1];
233
- }
234
- size_t step, stride = 1;
235
- // フーリエ変換
236
- for (k = smax; k > 0; --k) {
237
- s = k - 1;
238
- step = stride * ni[s];
239
- for (size_t k1 = 0; k1 < stride; ++k1)
240
- for (size_t k0 = k1; k0 < N; k0 += step)
241
- cft(r[s], &gw[k0<<1], ni[s] << 1, F, stride);
242
- stride = step;
243
- }
244
- // 最終の並び替え
245
- for (k = 0; k < N; ++k) {
246
- size_t Ls, Lu, L = 0, LL = 0;
247
- for (s = 0; s < smax; ++s) {
248
- Ls = k % ni[s];
249
- LL = LL * ni[s] + Ls;
250
- L += Ni[s] * Ls;
251
- } Ls = (L % N) << 1;
252
- Lu = LL << 1;
253
- data[Ls] = gw[Lu]; data[Ls+1] = gw[Lu+1];
254
- }
255
- }
256
- if (f < 0) for (k = 0; k < n; ++k) data[k] /= N;
257
- return true;
258
- }
259
- /*******************************************************************************
260
- 実数値高速フーリエ変換
261
- Fast Fourier Transformation / Cooley-Tukey Method
262
- *******************************************************************************/
263
- /*
264
- 基数2のFFT
265
- */
266
- template <typename T>
267
- void rft2(T *data, size_t N, int f)
268
- {
269
- size_t i, j, NH = N >> 1;
270
- T c, g1r, g1i, g2r, g2i, temp;
271
- T wr, wi, wpr, wpi, wtemp;
272
- T F = -f, theta = M_PI * F / (T)NH;
273
-
274
- wpr = cos(theta); wpi = sin(theta);
275
- if (f < 0) {
276
- wr = data[0]; wi = data[N-1];
277
- data[0] = wr + wi; wtemp = wr - wi;
278
- wr = 0.0; wi = 1.0;
279
- for (i = 2; i <= NH; i += 2) {
280
- relat<T>(wr, wi, wpr, wpi);
281
- j = N - i; temp = data[i-1]; data[i-1] = wtemp;
282
- g1r = (temp + data[j-1]); g1i = (data[i] - data[j]);
283
- g2r = (temp - data[j-1]); g2i = (data[i] + data[j]);
284
- relat<T>(g2r, g2i, wr, wi);
285
- if (i < j) {
286
- data[i] = g1r + g2r; wtemp = g1i + g2i;
287
- }
288
- data[j] = g1r - g2r; data[j+1] = g2i - g1i;
289
- }
290
- }
291
- cft2(data, N, f);
292
- if (f > 0) {
293
- c = 0.5;
294
- wr = data[0]; wi = data[1];
295
- data[0] = wr + wi; wtemp = wr - wi;
296
- wr = 0.0; wi = -1.0;
297
- for (i = 2; i <= NH; i += 2) {
298
- relat<T>(wr, wi, wpr, wpi);
299
- j = N - i; temp = data[j+1]; data[j+1] = wtemp;
300
- g1r = c*(data[i] + data[j]); g1i = c*(data[i+1] - temp);
301
- g2r = c*(data[i] - data[j]); g2i = c*(data[i+1] + temp);
302
- relat<T>(g2r, g2i, wr, wi);
303
- data[i-1] = g1r + g2r; data[i] = g1i + g2i;
304
- if (i < j) {
305
- wtemp = g1r - g2r; data[j] = g2i - g1i;
306
- }
307
- }
308
- }
309
- }
310
- /*
311
- 任意基数のFFT
312
- */
313
- template <typename T, size_t R>
314
- void rft(T *data, size_t N, int f)
315
- {
316
- size_t h, i, j, k, L, m, mmax, istep;
317
- size_t n = N << 1, Nr = N / R;
318
- T wr, wi, wpr, wpi, wqr, wqi, *temp;
319
- T xr, xi, yr, yi, *gw;
320
- temp = new T[n]; gw = new T[R*2];
321
- // R進数の桁反転
322
- for (j = 1, i = 0; i < n; i += 2) {
323
- if (f > 0) {
324
- xr = data[i>>1];
325
- xi = 0;
326
- } else if (i == 0) {
327
- xr = data[0];
328
- xi = 0;
329
- } else if (i < n/2) {
330
- xr = data[i-1];
331
- xi = data[ i ];
332
- } else if (i == n/2) {
333
- xr = data[i-1];
334
- xi = 0;
335
- } else {
336
- xr = data[n-i-1];
337
- xi =-data[ n-i ];
338
- }
339
- temp[j-1] = xr; temp[j] = xi;
340
- m = (R-1) * (Nr << 1);
341
- while (m >= 2 && j > m) {j -= m; m /= R;}
342
- j += m / (R-1);
343
- }
344
- T F = -f;
345
- T theta = 2.0 * M_PI * F / (T)R;
346
- wqr = cos(theta); wqi = sin(theta);
347
- mmax = 2;
348
- while (n > mmax) {
349
- istep = mmax * R;
350
- wpr = cos(theta); wpi = sin(theta);
351
- wr = 1.0; wi = 0.0;
352
- for (m = 1; m < mmax; m += 2) {
353
- for (i = m; i <= n; i += istep) {
354
- for (j = i, L = 0; L < R; L++, j += mmax) {
355
- h = (L << 1) + 1;
356
- gw[h-1] = temp[j-1]; gw[h] = temp[j];
357
- }
358
- // バタフライ演算
359
- xr = wr; xi = wi;
360
- for (j = i, L = 0; L < R; L++, j += mmax) {
361
- yr = yi = 0;
362
- for (k = R; k > 0; --k) {
363
- h = (k << 1) - 1;
364
- relat<T>(yr, yi, xr, xi, gw[h-1], gw[h]);
365
- } temp[j-1] = yr; temp[j] = yi;
366
- relat<T>(xr, xi, wqr, wqi);
367
- }
368
- }
369
- relat<T>(wr, wi, wpr, wpi);
370
- }
371
- mmax = istep;
372
- theta /= R;
373
- }
374
- data[0] = temp[0];
375
- for (i = 1; i < N; ++i) data[i] = temp[f > 0 ? i + 1 : i << 1];
376
- delete[] gw; delete[] temp;
377
- }
378
- /*
379
- 複数基数のFFT subroutine
380
- */
381
- template <typename T>
382
- void rft(size_t r, T *data, size_t N, int f)
383
- {
384
- size_t h, i, j, k, L, m, mmax, istep;
385
- size_t n = N << 1, Nr = N / r;
386
- T wr, wi, wpr, wpi, wqr, wqi, *temp;
387
- T xr, xi, yr, yi, *gw;
388
- temp = new T[n]; gw = new T[r*2];
389
- // r進数の桁反転
390
- for (j = 1, i = 0; i < n; i += 2) {
391
- if (f > 0) {
392
- xr = data[i>>1];
393
- xi = 0;
394
- } else if (i == 0) {
395
- xr = data[0];
396
- xi = 0;
397
- } else if (i < N) {
398
- xr = data[i-1];
399
- xi = data[ i ];
400
- } else if (i == N) {
401
- xr = data[i-1];
402
- xi = 0;
403
- } else {
404
- xr = data[n-i-1];
405
- xi =-data[ n-i ];
406
- }
407
- temp[j-1] = xr; temp[j] = xi;
408
- m = (r-1) * (Nr << 1);
409
- while (m >= 2 && j > m) {j -= m; m /= r;}
410
- j += m / (r-1);
411
- }
412
- T F = -f;
413
- T theta = 2.0 * M_PI * F / (T)r;
414
- wqr = cos(theta); wqi = sin(theta);
415
- mmax = 2;
416
- while (n > mmax) {
417
- istep = mmax * r;
418
- wpr = cos(theta); wpi = sin(theta);
419
- wr = 1.0; wi = 0.0;
420
- for (m = 1; m < mmax; m += 2) {
421
- for (i = m; i <= n; i += istep) {
422
- for (j = i, L = 0; L < r; L++, j += mmax) {
423
- h = (L << 1) + 1;
424
- gw[h-1] = temp[j-1]; gw[h] = temp[j];
425
- }
426
- // バタフライ演算
427
- xr = wr; xi = wi;
428
- for (j = i, L = 0; L < r; L++, j += mmax) {
429
- yr = yi = 0;
430
- for (k = r; k > 0; --k) {
431
- h = (k << 1) - 1;
432
- relat<T>(yr, yi, xr, xi, gw[h-1], gw[h]);
433
- } temp[j-1] = yr; temp[j] = yi;
434
- relat<T>(xr, xi, wqr, wqi);
435
- }
436
- }
437
- relat<T>(wr, wi, wpr, wpi);
438
- }
439
- mmax = istep;
440
- theta /= r;
441
- }
442
- data[0] = temp[0];
443
- for (i = 1; i < N; ++i) data[i] = temp[f > 0 ? i + 1 : i << 1];
444
- delete[] gw; delete[] temp;
445
- }
446
- /*
447
- 複数基数のFFT main routine
448
- g : データ配列
449
- N : データ個数
450
- f : 1 forward, 0 backword, -1 invert
451
- */
452
- template <typename T>
453
- bool rft(T *data, size_t N, int f)
454
- {
455
- size_t Nres = N, s = 0, k, n = N << 1;
456
- size_t Ni[SDIM], ni[SDIM], M[SDIM], r[SDIM]; r[0] = 2;
457
- // Chinese Remainder Theorem
458
- do {
459
- M[s] = 0; ni[s] = 1; Ni[s] = N;
460
- while (Ni[s] % r[s] == 0) {
461
- M[s]++;
462
- ni[s] *= r[s]; // ni = r**M;
463
- Ni[s] /= r[s];
464
- } Nres /= ni[s];
465
- int rnew;
466
- if (Nres != 1) {
467
- rnew = r[s] + (r[s] == 2 ? 1 : 2);
468
- if (M[s] > 0) s++;
469
- if (s < SDIM) {
470
- // 素因数分解
471
- while (Nres % rnew != 0) rnew += 2;
472
- r[s] = rnew;
473
- }
474
- }
475
- } while (Nres > 1 && s < SDIM);
476
- int F = (f > 0) ? 1 : -1;
477
- if (s >= SDIM) return false; else
478
- if (s == 0) {
479
- switch (r[s]) {
480
- case 2: rft2<T>(data, N, F); break;
481
- case 3: rft<T,3>(data, N, F); break;
482
- case 5: rft<T,5>(data, N, F); break;
483
- case 7: rft<T,7>(data, N, F); break;
484
- default: rft<T>(r[s], data, N, F);
485
- }
486
- } else {
487
- size_t smax = s + 1;
488
- T gw[n];
489
- // 最初の並び替え
490
- for (k = 0; k < N; ++k) {
491
- size_t ks, kk = 0;
492
- T wr, wi;
493
- for (s = 0; s < smax; ++s)
494
- kk = kk * ni[s] + k % ni[s];
495
- kk <<= 1; ks = k << 1;
496
- if (F > 0) {
497
- wr = data[k];
498
- wi = 0;
499
- } else if (ks == 0) {
500
- wr = data[0];
501
- wi = 0;
502
- } else if (ks == N) {
503
- wr = data[N-1];
504
- wi = 0;
505
- } else if (ks < N) {
506
- wr = data[ks-1];
507
- wi = data[ ks ];
508
- } else {
509
- ks = (N-k) << 1;
510
- wr = data[ks-1];
511
- wi =-data[ ks ];
512
- }
513
- gw[kk] = wr; gw[kk+1] = wi;
514
- }
515
- size_t step, stride = 1;
516
- // フーリエ変換
517
- for (k = smax; k > 0; --k) {
518
- s = k - 1;
519
- step = stride * ni[s];
520
- for (size_t k1 = 0; k1 < stride; ++k1)
521
- for (size_t k0 = k1; k0 < N; k0 += step)
522
- cft(r[s], &gw[k0<<1], ni[s] << 1, F, stride);
523
- stride = step;
524
- }
525
- // 最終の並び替え
526
- for (k = 0; k < N; ++k) {
527
- size_t Ls, Lu, L = 0, LL = 0;
528
- for (s = 0; s < smax; ++s) {
529
- Ls = k % ni[s];
530
- LL = LL * ni[s] + Ls;
531
- L += Ni[s] * Ls;
532
- } Ls = (L % N);
533
- Lu = LL << 1;
534
- if (F > 0) {
535
- Ls <<= 1;
536
- if (Ls == 0) data[Ls] = gw[Lu];
537
- else
538
- if (Ls == N) data[Ls-1] = gw[Lu];
539
- else
540
- if (Ls < N) {
541
- data[Ls-1] = gw[ Lu ];
542
- data[ Ls ] = gw[Lu+1];
543
- }
544
- } else data[ Ls ] = gw[ Lu ];
545
- }
546
- }
547
- if (f < 0) for (k = 0; k < N; ++k) data[k] /= N;
548
- return true;
549
- }
550
-
551
- template bool cft<double>(double *, size_t, int);
552
- template bool rft<double>(double *, size_t, int);
1
+ #define SLOPPY
2
+ #define IEEE
3
+
4
+ #include <cstdlib>
5
+ #include <cmath>
6
+ #include <cstring>
7
+ #include <cassert>
8
+ #include <functional>
9
+ #include "basis/fft.h"
10
+
11
+ template <typename T>
12
+ inline void relat(real<T>& xr, real<T>& xi, const real<T>& wqr, const real<T>& wqi)
13
+ {
14
+ real<T> wtemp = xr;
15
+ xr = wtemp * wqr - xi * wqi;
16
+ xi = wtemp * wqi + xi * wqr;
17
+ }
18
+
19
+ #include "basis/fft_complex.h"
20
+
21
+ #define FFTPACK
22
+
23
+ #include "basis/fft_real.h"
24
+
25
+ template bool cfft<double>(varray<double>&, size_t, int);
26
+ template bool rfft<double>(varray<double>&, size_t, int);
27
+