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
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
#ifndef REAL_INLINE_H
|
|
2
|
+
#define REAL_INLINE_H
|
|
3
|
+
|
|
4
|
+
#define _QD_SPLITTER 134217729.0 // = 2^27 + 1
|
|
5
|
+
#define _QD_SPLIT_THRESH 6.69692879491417e+299 // = 2^996
|
|
6
|
+
|
|
7
|
+
template <typename T>
|
|
8
|
+
inline T quick_two_sum(T a, T b, T &err)
|
|
9
|
+
{
|
|
10
|
+
T s = a + b;
|
|
11
|
+
err = b - (s - a);
|
|
12
|
+
return s;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
template <typename T>
|
|
16
|
+
inline T quick_two_diff(T a, T b, T &err)
|
|
17
|
+
{
|
|
18
|
+
T s = a - b;
|
|
19
|
+
err = (a - s) - b;
|
|
20
|
+
return s;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
template <typename T>
|
|
24
|
+
inline T two_sum(T a, T b, T &err)
|
|
25
|
+
{
|
|
26
|
+
T s = a + b;
|
|
27
|
+
T c = s - a;
|
|
28
|
+
err = (a - (s - c)) + (b - c);
|
|
29
|
+
return s;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
template <typename T>
|
|
33
|
+
inline T two_diff(T a, T b, T &err)
|
|
34
|
+
{
|
|
35
|
+
T s = a - b;
|
|
36
|
+
T c = s - a;
|
|
37
|
+
err = (a - (s - c)) - (b + c);
|
|
38
|
+
return s;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
template <typename T>
|
|
42
|
+
inline void split(T a, T &hi, T &lo)
|
|
43
|
+
{
|
|
44
|
+
T temp;
|
|
45
|
+
if (a > _QD_SPLIT_THRESH || a < -_QD_SPLIT_THRESH) {
|
|
46
|
+
a *= 3.7252902984619140625e-09; // 2^-28
|
|
47
|
+
temp = _QD_SPLITTER * a;
|
|
48
|
+
hi = temp - (temp - a);
|
|
49
|
+
lo = a - hi;
|
|
50
|
+
hi *= 268435456.0; // 2^28
|
|
51
|
+
lo *= 268435456.0; // 2^28
|
|
52
|
+
} else {
|
|
53
|
+
temp = _QD_SPLITTER * a;
|
|
54
|
+
hi = temp - (temp - a);
|
|
55
|
+
lo = a - hi;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
template <typename T>
|
|
60
|
+
inline T two_prod(T a, T b, T &err)
|
|
61
|
+
{
|
|
62
|
+
T a_hi, a_lo, b_hi, b_lo;
|
|
63
|
+
T p = a * b;
|
|
64
|
+
split(a, a_hi, a_lo);
|
|
65
|
+
split(b, b_hi, b_lo);
|
|
66
|
+
err = ((a_hi * b_hi - p) + a_hi * b_lo + a_lo * b_hi) + a_lo * b_lo;
|
|
67
|
+
return p;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
template <typename T>
|
|
71
|
+
inline T two_sqr(T a, T &err)
|
|
72
|
+
{
|
|
73
|
+
T hi, lo;
|
|
74
|
+
T q = a * a;
|
|
75
|
+
split(a, hi, lo);
|
|
76
|
+
err = ((hi * hi - q) + 2.0 * hi * lo) + lo * lo;
|
|
77
|
+
return q;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
template <typename T>
|
|
81
|
+
inline T two_sqr2(T a0, T a1, T &err)
|
|
82
|
+
{
|
|
83
|
+
T p = two_sqr(a0, err);
|
|
84
|
+
err += 2.0 * a0 * a1;
|
|
85
|
+
err += a1 * a1;
|
|
86
|
+
return quick_two_sum(p, err, err);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
template <typename T>
|
|
90
|
+
inline void three_sum(T &p, T &q, T &r)
|
|
91
|
+
{
|
|
92
|
+
T t1, r1, r2;
|
|
93
|
+
t1 = two_sum( p, q, r1);
|
|
94
|
+
p = two_sum( r, t1, r2);
|
|
95
|
+
q = two_sum(r1, r2, r);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
template <typename T>
|
|
99
|
+
inline void three_sum2(T &p, T &q, T r)
|
|
100
|
+
{
|
|
101
|
+
T t1, r1, r2;
|
|
102
|
+
t1 = two_sum(p, q, r1);
|
|
103
|
+
p = two_sum(r, t1, r2);
|
|
104
|
+
q = r1 + r2;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
template <typename T>
|
|
108
|
+
inline T four_diff1(T a0, T a1, T b, T &e)
|
|
109
|
+
{
|
|
110
|
+
a0 = two_diff(a0, b, b);
|
|
111
|
+
b += a1;
|
|
112
|
+
return quick_two_sum(a0, b, e);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
template <typename T>
|
|
116
|
+
inline T four_diff2(T a0, T a1, T b0, T b1, T &e)
|
|
117
|
+
{
|
|
118
|
+
a0 = two_diff(a0, b0, b0);
|
|
119
|
+
b0 += a1;
|
|
120
|
+
b0 -= b1;
|
|
121
|
+
return quick_two_sum(a0, b0, e);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
template <typename T>
|
|
125
|
+
inline T four_sum1(T a0, T a1, T b, T &e)
|
|
126
|
+
{
|
|
127
|
+
T s = two_sum(a0, b, e);
|
|
128
|
+
e += a1;
|
|
129
|
+
return quick_two_sum(s, e, e);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
template <typename T>
|
|
133
|
+
inline T four_sum2(T a0, T a1, T b0, T b1, T &e)
|
|
134
|
+
{
|
|
135
|
+
T s = two_sum(a0, b0, e);
|
|
136
|
+
e += (a1 + b1);
|
|
137
|
+
return quick_two_sum(s, e, e);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
template <typename T>
|
|
141
|
+
inline void four_sum3(T &s0, T &s1, T &s2, T t)
|
|
142
|
+
{
|
|
143
|
+
s0 = two_sum(t, s0, t);
|
|
144
|
+
s1 = two_sum(t, s1, t);
|
|
145
|
+
s2 += t;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
template <typename T>
|
|
149
|
+
inline T four_prod1(T a0, T a1, T b, T &e)
|
|
150
|
+
{
|
|
151
|
+
T p = two_prod(a0, b, e);
|
|
152
|
+
e += (a1 * b);
|
|
153
|
+
return quick_two_sum(p, e, e);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
template <typename T>
|
|
157
|
+
inline T four_prod2(T a0, T a1, T b0, T b1, T &e)
|
|
158
|
+
{
|
|
159
|
+
T p = two_prod(a0, b0, e);
|
|
160
|
+
e += (a0 * b1 + a1 * b0);
|
|
161
|
+
return quick_two_sum(p, e, e);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
template <typename T>
|
|
165
|
+
inline T quick_three_accum(T &a, T &b, T c)
|
|
166
|
+
{
|
|
167
|
+
T s; bool za, zb;
|
|
168
|
+
|
|
169
|
+
s = two_sum(b, c, b);
|
|
170
|
+
s = two_sum(a, s, a);
|
|
171
|
+
|
|
172
|
+
za = (a != 0.0);
|
|
173
|
+
zb = (b != 0.0);
|
|
174
|
+
|
|
175
|
+
if (za && zb) return s;
|
|
176
|
+
|
|
177
|
+
if (!zb) { b = a; } a = s;
|
|
178
|
+
return 0.0;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
template <typename T>
|
|
182
|
+
inline void quick_renorm(int N, T *w, T c)
|
|
183
|
+
{
|
|
184
|
+
if (N == 0) w[0] = quick_two_sum(w[0], c, c);
|
|
185
|
+
else
|
|
186
|
+
{
|
|
187
|
+
T t[N+1];
|
|
188
|
+
for (int i = 0; i < N; ++i) {
|
|
189
|
+
for (int j = N-i; j >= 0; --j)
|
|
190
|
+
c = quick_two_sum(i == 0 ? w[j] : t[j], c, t[j]);
|
|
191
|
+
w[i] = c; c = t[N-i];
|
|
192
|
+
} w[N] = t[0] + t[1];
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
template <typename T>
|
|
197
|
+
inline void renorm(int N, T *w, T &c)
|
|
198
|
+
{
|
|
199
|
+
if (isinf(w[0])) return;
|
|
200
|
+
|
|
201
|
+
w[N] = quick_two_sum(w[N], c, c);
|
|
202
|
+
if (N > 0)
|
|
203
|
+
for (int i = N; i > 0; --i)
|
|
204
|
+
w[i-1] = quick_two_sum(w[i-1], w[i], w[i]);
|
|
205
|
+
if (N > 1) {
|
|
206
|
+
int k = 0, j = 2;
|
|
207
|
+
while (k < N) {
|
|
208
|
+
if (w[k+1] != 0) k++;
|
|
209
|
+
w[k] = quick_two_sum(w[k], w[j], w[k+1]);
|
|
210
|
+
if (++j > N) break;
|
|
211
|
+
}
|
|
212
|
+
if (w[k+1] != 0) k++;
|
|
213
|
+
w[k] = quick_two_sum(w[k], c, k == N ? c : w[k+1]);
|
|
214
|
+
for (int i = k + 2; i <= N; ++i) w[i] = 0;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
template <typename T>
|
|
219
|
+
inline void renorm(int N, T *w)
|
|
220
|
+
{
|
|
221
|
+
if (isinf(w[0])) return;
|
|
222
|
+
|
|
223
|
+
if (N > 0)
|
|
224
|
+
for (int i = N; i > 0; --i)
|
|
225
|
+
w[i-1] = quick_two_sum(w[i-1], w[i], w[i]);
|
|
226
|
+
if (N > 1) {
|
|
227
|
+
int k = 0, j = 2;
|
|
228
|
+
while (k < N) {
|
|
229
|
+
if (w[k+1] != 0) k++;
|
|
230
|
+
w[k] = quick_two_sum(w[k], w[j], w[k+1]);
|
|
231
|
+
if (++j > N) break;
|
|
232
|
+
}
|
|
233
|
+
for (int i = k + 2; i <= N; ++i) w[i] = 0;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
inline double _ldexp(double a, int b) { return ldexp(a, b); }
|
|
238
|
+
inline double _floor(double a) { return floor(a); }
|
|
239
|
+
inline double _atan2(double a, double b) { return atan2(a, b); }
|
|
240
|
+
inline double _ceil(double a) { return ceil(a); }
|
|
241
|
+
inline double _sqrt(double a) { return sqrt(a); }
|
|
242
|
+
inline double _exp(double a) { return exp(a); }
|
|
243
|
+
inline double _log(double a) { return log(a); }
|
|
244
|
+
|
|
245
|
+
/* Computes the nearest integer to d. */
|
|
246
|
+
template <typename T>
|
|
247
|
+
inline T nint(T d)
|
|
248
|
+
{
|
|
249
|
+
if (d == floor(d)) return d;
|
|
250
|
+
return floor(d + 0.5);
|
|
251
|
+
}
|
|
252
|
+
template <>
|
|
253
|
+
inline double nint(double d)
|
|
254
|
+
{
|
|
255
|
+
if (d == _floor(d)) return d;
|
|
256
|
+
return _floor(d + 0.5);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/* Computes the truncated integer. */
|
|
260
|
+
template <typename T>
|
|
261
|
+
inline T aint(T d)
|
|
262
|
+
{
|
|
263
|
+
return (d >= 0.0) ? floor(d) : ceil(d);
|
|
264
|
+
}
|
|
265
|
+
template <>
|
|
266
|
+
inline double aint(double d)
|
|
267
|
+
{
|
|
268
|
+
return (d >= 0.0) ? _floor(d) : _ceil(d);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
inline double sqr(double t) { return t * t; }
|
|
272
|
+
|
|
273
|
+
inline double _nint(double a) { return nint(a); }
|
|
274
|
+
inline double _aint(double a) { return aint(a); }
|
|
275
|
+
inline double _sqr(double a) { return sqr(a); }
|
|
276
|
+
|
|
277
|
+
void qd_add(size_t, double*, double*, double );
|
|
278
|
+
void qd_add(size_t, double*, double*, double*);
|
|
279
|
+
void qd_sub(size_t, double*, double*, double );
|
|
280
|
+
void qd_sub(size_t, double*, double*, double*);
|
|
281
|
+
void qd_mul(size_t, double*, double*, double );
|
|
282
|
+
void qd_mul(size_t, double*, double*, double*);
|
|
283
|
+
void qd_div(size_t, double*, double*, double );
|
|
284
|
+
void qd_div(size_t, double*, double*, double*);
|
|
285
|
+
void qd_minus(size_t, double*, double*);
|
|
286
|
+
void qd_abs(size_t, double*, double*);
|
|
287
|
+
inline void qd_ass(size_t a, double *b, double *c) { for (size_t i = 0; i <= a; ++i) b[i] = c[i]; }
|
|
288
|
+
bool qd_eq(size_t, double*, double*);
|
|
289
|
+
bool qd_eq(size_t, double*, double );
|
|
290
|
+
bool qd_lt(size_t, double*, double*);
|
|
291
|
+
bool qd_lt(size_t, double*, double );
|
|
292
|
+
bool qd_gt(size_t, double*, double*);
|
|
293
|
+
bool qd_gt(size_t, double*, double );
|
|
294
|
+
bool qd_le(size_t, double*, double*);
|
|
295
|
+
bool qd_le(size_t, double*, double );
|
|
296
|
+
bool qd_ge(size_t, double*, double*);
|
|
297
|
+
bool qd_ge(size_t, double*, double );
|
|
298
|
+
|
|
299
|
+
template <typename T = double> class real;
|
|
300
|
+
|
|
301
|
+
template <typename T> real<T> operator + (const real<T>& a, const real<T>& b)
|
|
302
|
+
{
|
|
303
|
+
const size_t N = a.N, M = b.N;
|
|
304
|
+
const size_t L = (N >= M ? N : M);
|
|
305
|
+
T x[L+1];
|
|
306
|
+
|
|
307
|
+
if (N < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= N) ? a.w[i] : 0.0; qd_add(L, x, c, b.w); } else
|
|
308
|
+
if (M < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= M) ? b.w[i] : 0.0; qd_add(L, x, a.w, c); } else
|
|
309
|
+
{
|
|
310
|
+
qd_add(L, x, a.w, b.w);
|
|
311
|
+
}
|
|
312
|
+
return real<T>(L, x);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
template <typename T> real<T> operator * (const real<T>& a, const real<T>& b)
|
|
316
|
+
{
|
|
317
|
+
const size_t N = a.N, M = b.N;
|
|
318
|
+
const size_t L = (N >= M ? N : M);
|
|
319
|
+
T p[L+1];
|
|
320
|
+
|
|
321
|
+
if (N < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= N) ? a.w[i] : 0.0; qd_mul(L, p, c, b.w); } else
|
|
322
|
+
if (M < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= M) ? b.w[i] : 0.0; qd_mul(L, p, a.w, c); } else
|
|
323
|
+
{
|
|
324
|
+
qd_mul(L, p, a.w, b.w);
|
|
325
|
+
}
|
|
326
|
+
return real<T>(L, p);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
template <typename T> real<T> operator / (const real<T>& a, const real<T>& b)
|
|
330
|
+
{
|
|
331
|
+
const size_t N = a.N, M = b.N;
|
|
332
|
+
const size_t L = (N >= M ? N : M);
|
|
333
|
+
T q[L+1];
|
|
334
|
+
|
|
335
|
+
if (N < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= N) ? a.w[i] : 0.0; qd_div(L, q, c, b.w); } else
|
|
336
|
+
if (M < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= M) ? b.w[i] : 0.0; qd_div(L, q, a.w, c); } else
|
|
337
|
+
{
|
|
338
|
+
qd_div(L, q, a.w, b.w);
|
|
339
|
+
}
|
|
340
|
+
return real<T>(L, q);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
template <typename T> bool operator == (const real<T>& a, const real<T>& b)
|
|
344
|
+
{
|
|
345
|
+
const size_t N = a.N, M = b.N;
|
|
346
|
+
const size_t L = (N >= M ? N : M);
|
|
347
|
+
|
|
348
|
+
if (N < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= N) ? a.w[i] : 0.0; return qd_eq(L, c, b.w); } else
|
|
349
|
+
if (M < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= M) ? b.w[i] : 0.0; return qd_eq(L, a.w, c); } else
|
|
350
|
+
{
|
|
351
|
+
return qd_eq(L, a.w, b.w);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
template <typename T> bool operator < (const real<T>& a, const real<T>& b)
|
|
356
|
+
{
|
|
357
|
+
const size_t N = a.N, M = b.N;
|
|
358
|
+
const size_t L = (N >= M ? N : M);
|
|
359
|
+
|
|
360
|
+
if (N < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= N) ? a.w[i] : 0.0; return qd_lt(L, c, b.w); } else
|
|
361
|
+
if (M < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= M) ? b.w[i] : 0.0; return qd_lt(L, a.w, c); } else
|
|
362
|
+
{
|
|
363
|
+
return qd_lt(L, a.w, b.w);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
template <typename T> bool operator > (const real<T>& a, const real<T>& b)
|
|
368
|
+
{
|
|
369
|
+
const size_t N = a.N, M = b.N;
|
|
370
|
+
const size_t L = (N >= M ? N : M);
|
|
371
|
+
|
|
372
|
+
if (N < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= N) ? a.w[i] : 0.0; return qd_gt(L, c, b.w); } else
|
|
373
|
+
if (M < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= M) ? b.w[i] : 0.0; return qd_gt(L, a.w, c); } else
|
|
374
|
+
{
|
|
375
|
+
return qd_gt(L, a.w, b.w);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
template <typename T> bool operator <= (const real<T>& a, const real<T>& b)
|
|
380
|
+
{
|
|
381
|
+
const size_t N = a.N, M = b.N;
|
|
382
|
+
const size_t L = (N >= M ? N : M);
|
|
383
|
+
|
|
384
|
+
if (N < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= N) ? a.w[i] : 0.0; return qd_le(L, c, b.w); } else
|
|
385
|
+
if (M < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= M) ? b.w[i] : 0.0; return qd_le(L, a.w, c); } else
|
|
386
|
+
{
|
|
387
|
+
return qd_le(L, a.w, b.w);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
template <typename T> bool operator >= (const real<T>& a, const real<T>& b)
|
|
392
|
+
{
|
|
393
|
+
const size_t N = a.N, M = b.N;
|
|
394
|
+
const size_t L = (N >= M ? N : M);
|
|
395
|
+
|
|
396
|
+
if (N < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= N) ? a.w[i] : 0.0; return qd_ge(L, c, b.w); } else
|
|
397
|
+
if (M < L) { T c[L+1]; for (size_t i = 0; i <= L; ++i) c[i] = (i <= M) ? b.w[i] : 0.0; return qd_ge(L, a.w, c); } else
|
|
398
|
+
{
|
|
399
|
+
return qd_ge(L, a.w, b.w);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
template <typename T> real<T> sqr(const real<T>& a)
|
|
404
|
+
{
|
|
405
|
+
const size_t N = a.N;
|
|
406
|
+
|
|
407
|
+
if (N == 0) {
|
|
408
|
+
return real<T>(a.w[0] * a.w[0]);
|
|
409
|
+
} else
|
|
410
|
+
|
|
411
|
+
if (N == 1) {
|
|
412
|
+
double p[2];
|
|
413
|
+
p[0] = two_sqr2(a.w[0], a.w[1], p[1]);
|
|
414
|
+
return real<T>(N, p);
|
|
415
|
+
} else
|
|
416
|
+
|
|
417
|
+
return a * a;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
template <typename T> real<T> npwr(const real<T>& a, int n)
|
|
421
|
+
{
|
|
422
|
+
const size_t N = a.atom();
|
|
423
|
+
real<T> s(1.0, N); /* current answer */
|
|
424
|
+
|
|
425
|
+
if (n != 0) {
|
|
426
|
+
real<T> r = a; /* odd-case multiplier */
|
|
427
|
+
int w = abs(n);
|
|
428
|
+
if (w > 1)
|
|
429
|
+
/* Use binary exponentiation. */
|
|
430
|
+
while (w > 0) {
|
|
431
|
+
/* If odd, multiply by r. Note eventually w = 1, so this eventually executes. */
|
|
432
|
+
if (w % 2 == 1) s *= r;
|
|
433
|
+
w /= 2;
|
|
434
|
+
if (w > 0) r *= r;
|
|
435
|
+
}
|
|
436
|
+
else s = r;
|
|
437
|
+
if (n < 0) s = (1.0 / s);
|
|
438
|
+
}
|
|
439
|
+
return s;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
#endif
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#ifndef _SPLINE_H_INCLUDED_
|
|
2
|
+
#define _SPLINE_H_INCLUDED_
|
|
3
|
+
|
|
4
|
+
//
|
|
5
|
+
// Bスプライン関数
|
|
6
|
+
//
|
|
7
|
+
class spline : public base_spline<>
|
|
8
|
+
{
|
|
9
|
+
Vector *alp;
|
|
10
|
+
|
|
11
|
+
public:
|
|
12
|
+
// constructor
|
|
13
|
+
spline() : alp(NULL) {}
|
|
14
|
+
spline(int n, const Vector& x, const Vector& y, int j, int d = 0, int *dp = NULL);
|
|
15
|
+
spline(const spline& s);
|
|
16
|
+
// destructor
|
|
17
|
+
~spline() { delete alp; }
|
|
18
|
+
// operator
|
|
19
|
+
spline& operator = (const spline& s);
|
|
20
|
+
void ass(Vector& a) { a = *alp; }
|
|
21
|
+
Real operator[](const Real& t) const
|
|
22
|
+
{ assert(t >= x_min() || t <= x_max()); return apply(t, *alp); }
|
|
23
|
+
Real operator[](int i) const
|
|
24
|
+
{ assert(i < 0 || i >= Icox()); return (*alp)[i]; }
|
|
25
|
+
Real operator()(const Real& t, const Vector& a, int b = 0) const
|
|
26
|
+
{ assert(t >= x_min() || t <= x_max() || b <= Jisu()); return apply(t, a, b); }
|
|
27
|
+
// void bibun_keisu(int i, Matrix& m) const { return base_spline::bibun_keisu(i, m); }
|
|
28
|
+
Real bibun(const Real& t, int d = 1) const;
|
|
29
|
+
Real sekibun(const Real& t, int s) const { return base_spline::sekibun<double>(t, *alp, s); }
|
|
30
|
+
Real sekibun(const Real& x) const { return base_spline::sekibun(x, *alp); }
|
|
31
|
+
Real sekibun(const Real& x, const Vector& clp) const { return base_spline::sekibun(x, clp); }
|
|
32
|
+
};
|
|
33
|
+
//
|
|
34
|
+
// Bスプライン補間
|
|
35
|
+
//
|
|
36
|
+
class Bspline
|
|
37
|
+
{
|
|
38
|
+
Matrix *alp; spline *sp;
|
|
39
|
+
|
|
40
|
+
public:
|
|
41
|
+
// constructor
|
|
42
|
+
Bspline() : alp(NULL), sp(NULL) {}
|
|
43
|
+
// bspline : 境界条件のないBスプライン補間
|
|
44
|
+
Bspline(int n, const Vector&, const Vector&, int j);
|
|
45
|
+
// cspline : 関数値境界条件によるBスプライン補間
|
|
46
|
+
Bspline(int n, const Vector&, const Vector&, int j, int d, const Vector&);
|
|
47
|
+
// dspline : 微分境界条件によるBスプライン補間
|
|
48
|
+
Bspline(int n, const Vector&, const Vector&, int j, int d, int *Dp, const Vector&);
|
|
49
|
+
// tspline : 周期境界条件によるスプライン補間
|
|
50
|
+
Bspline(int n, const Vector&, const Vector&, int j, int t);
|
|
51
|
+
// copy constructor
|
|
52
|
+
Bspline(const Bspline& b);
|
|
53
|
+
// destructor
|
|
54
|
+
~Bspline() { delete sp; delete alp; }
|
|
55
|
+
// operator
|
|
56
|
+
Bspline& operator = (const Bspline& b);
|
|
57
|
+
int Imax() const { return sp->Imax(); }
|
|
58
|
+
int Icox() const { return sp->Icox(); }
|
|
59
|
+
int Maxq() const { return sp->Maxq(); }
|
|
60
|
+
int Rank() const { return sp->Rank(); }
|
|
61
|
+
int Jisu() const { return sp->Jisu(); }
|
|
62
|
+
int Shuki()const { return sp->Shuki();}
|
|
63
|
+
Real operator[](const Real& t) const { return (*sp)[t]; }
|
|
64
|
+
Real operator()(const Real& t, int b = 0) const
|
|
65
|
+
{
|
|
66
|
+
if (b > Jisu()) throw "out of range, Bspline()";
|
|
67
|
+
auto v = alp->row((b > 0) ? b : 0);
|
|
68
|
+
return (*sp)(t, v, b);
|
|
69
|
+
}
|
|
70
|
+
Real x_max() const { return sp->x_max(); }
|
|
71
|
+
Real x_min() const { return sp->x_min(); }
|
|
72
|
+
Real bibun(const Real& t, int jbn = 1) const { return sp->bibun(t, jbn); }
|
|
73
|
+
Real sekibun(const Real& t, int jsk) const { return sp->sekibun(t, jsk); }
|
|
74
|
+
Real sekibun(const Real& ta, const Real& tb) const { return sp->sekibun(tb, -1) - sp->sekibun(ta, -1); }
|
|
75
|
+
Real sekibun(const Real& x) const { return sp->Shuki() ? sp->sekibun(x, alp->row(0)) : sp->sekibun(x); }
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
//
|
|
79
|
+
// misc
|
|
80
|
+
//
|
|
81
|
+
int plots(const Bspline&, const Vector&, Vector&, Vector&, int, int = 0);
|
|
82
|
+
|
|
83
|
+
#endif
|