pspline 5.0.2

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 (50) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +5 -0
  3. data/README.md +34 -0
  4. data/Rakefile +6 -0
  5. data/bin/console +14 -0
  6. data/bin/setup +8 -0
  7. data/ext/pspline/basis.cpp +351 -0
  8. data/ext/pspline/example/exbspline.ps +2194 -0
  9. data/ext/pspline/example/exbspline.rb +36 -0
  10. data/ext/pspline/example/excspline.ps +2985 -0
  11. data/ext/pspline/example/excspline.rb +36 -0
  12. data/ext/pspline/example/exdspline.ps +2846 -0
  13. data/ext/pspline/example/exdspline.rb +33 -0
  14. data/ext/pspline/example/exfspline.rb +66 -0
  15. data/ext/pspline/example/exfspline1.rb +40 -0
  16. data/ext/pspline/example/expspline.ps +3299 -0
  17. data/ext/pspline/example/expspline.rb +29 -0
  18. data/ext/pspline/example/expspline1.rb +29 -0
  19. data/ext/pspline/example/expspline2.rb +47 -0
  20. data/ext/pspline/example/exqspline.ps +2957 -0
  21. data/ext/pspline/example/exqspline.rb +31 -0
  22. data/ext/pspline/example/exqspline1.rb +31 -0
  23. data/ext/pspline/example/exqspline2.rb +50 -0
  24. data/ext/pspline/example/exqspline3.rb +51 -0
  25. data/ext/pspline/example/exrspline.ps +2812 -0
  26. data/ext/pspline/example/exrspline.rb +34 -0
  27. data/ext/pspline/example/exrspline1.rb +34 -0
  28. data/ext/pspline/example/exrspline2.rb +44 -0
  29. data/ext/pspline/example/exsspline.ps +1965 -0
  30. data/ext/pspline/example/exsspline.rb +35 -0
  31. data/ext/pspline/example/exsspline1.rb +35 -0
  32. data/ext/pspline/example/extspline.ps +2767 -0
  33. data/ext/pspline/example/extspline.rb +32 -0
  34. data/ext/pspline/extconf.rb +7 -0
  35. data/ext/pspline/fft.cpp +552 -0
  36. data/ext/pspline/include/basis/basis.h +137 -0
  37. data/ext/pspline/include/basis/fft.h +152 -0
  38. data/ext/pspline/include/basis/poly_array.h +1568 -0
  39. data/ext/pspline/include/basis/pspline.h +506 -0
  40. data/ext/pspline/include/basis/uspline.h +210 -0
  41. data/ext/pspline/include/basis/util.h +656 -0
  42. data/ext/pspline/include/bspline.h +377 -0
  43. data/ext/pspline/include/bspline_Config.h +2 -0
  44. data/ext/pspline/plotsub.cpp +132 -0
  45. data/ext/pspline/pspline.cpp +897 -0
  46. data/ext/pspline/util.cpp +483 -0
  47. data/lib/pspline.rb +6 -0
  48. data/lib/pspline/version.rb +3 -0
  49. data/pspline.gemspec +25 -0
  50. metadata +122 -0
@@ -0,0 +1,483 @@
1
+ #include <string.h>
2
+ #include <stdlib.h>
3
+ #include <stddef.h>
4
+ #include <stdio.h>
5
+ #include <float.h>
6
+ #include <math.h>
7
+ #include "basis/util.h"
8
+
9
+ class pascal
10
+ {
11
+ int *pas;
12
+ public:
13
+ pascal(int K) : pas(new int[K]) {}
14
+ ~pascal() { delete pas; }
15
+ int* operator[](int j)
16
+ {
17
+ int a, b;
18
+ pas[0] = a = b = 1;
19
+ for (int i = 1; i <= j; ++i) {
20
+ a *= j - i + 1;
21
+ b *= i;
22
+ pas[i] = a / b;
23
+ }
24
+ return pas;
25
+ }
26
+ };
27
+ /*******************************************************************************
28
+ 微分係数(differential coefficient)
29
+ N個の関数の積のJ階微分係数を求める。
30
+ data : 微分係数の配列 [[f(t),D1f(t),...,DJf(t)],...]
31
+ s : 配列のストライド [st1,...,stN,K] (K = J+1)
32
+ N : 関数の積の項数
33
+ *******************************************************************************/
34
+ template<typename T> T *diff(T **data, const int *s, int N)
35
+ {
36
+ int K = s[N];
37
+ T *W = T_ALLOC(T,K);
38
+ if (N == 1)
39
+ for (int i = 0; i < K; ++i) W[i] = (*data)[(*s)*i];
40
+ else {
41
+ const T *b = *data;
42
+ T *c = diff(&data[1], &s[1], N-1);
43
+ pascal pas(K);
44
+ for (int j = 0; j < K; ++j) {
45
+ int *a = pas[j];
46
+ W[j] = 0;
47
+ for (int k = 0; k <= j; ++k)
48
+ W[j] += a[k] * b[(*s)*k] * c[j-k];
49
+ }
50
+ FREE(c);
51
+ }
52
+ return W;
53
+ }
54
+ template<typename T> T coeff(T **data, const int *s, int N, int jbn)
55
+ {
56
+ T *W = diff(data, s, N);
57
+ T result = W[jbn];
58
+ FREE(W);
59
+ return result;
60
+ }
61
+ /*******************************************************************************
62
+ 全微分(Total derivative)
63
+ N個の関数の積のJ階全微分を求める。
64
+ data : 微分係数の配列 [[f(t),D1f(t),...,DJf(t)],...]
65
+ s : 配列のストライド [st1,...,stN,K] (K = J+1)
66
+ N : 関数の積の項数
67
+ ds : 方向ベクトルの成分の配列 [d1,...dN]
68
+ *******************************************************************************/
69
+ template<typename T>
70
+ static T *sub_derive(T **data, const int *s, int N, const T *ds)
71
+ {
72
+ int k, K = s[N];
73
+ T dt, *W = T_ALLOC(T,K);
74
+ if (N == 1)
75
+ for (dt = 1.0, k = 0; k < K; ++k, dt *= (*ds)) W[k] = (*data)[(*s)*k] * dt;
76
+ else {
77
+ const T *b = *data;
78
+ T *c = sub_derive(&data[1], &s[1], N-1, &ds[1]);
79
+ pascal pas(K);
80
+ for (int j = 0; j < K; ++j) {
81
+ int *a = pas[j];
82
+ W[j] = 0;
83
+ for (dt = 1.0, k = 0; k <= j; ++k, dt *= (*ds))
84
+ W[j] += a[k] * b[(*s)*k] * c[j-k] * dt;
85
+ }
86
+ FREE(c);
87
+ }
88
+ return W;
89
+ }
90
+ template<typename T> T total_derive(T **data, const int *s, int N, int jbn, const T *ds)
91
+ {
92
+ T *W = sub_derive(data, s, N, ds);
93
+ T result = W[jbn];
94
+ FREE(W);
95
+ return result;
96
+ }
97
+
98
+ /*******************************************************************************
99
+ Matrix operation
100
+ *******************************************************************************/
101
+ /*
102
+ Doolittle : LU分解 ドゥーリトル法
103
+
104
+ Li0 = ai0; i = 0,...,n-1
105
+ Lij = aij - ΣLik*Ukj; i >= j, k = 0,...,j-1
106
+ Uij =(aij - ΣLik*Ukj)/Lii; i < j, k = 0,...,i-1
107
+ */
108
+ template <class T> void lud_decomp(T * a, size_t n, size_t * p, int & s)
109
+ {
110
+ size_t i, j, k, l, L;
111
+
112
+ s = 1;
113
+ for (i = 0; i < n; i++) {
114
+ T *ai = &a[i*n];
115
+ T aii = ai[i]; L = i;
116
+ for (j = 1; j < n; j++) {
117
+ l = i < j ? i : j;
118
+ T aij = ai[j];
119
+ for (k = 0; k < l; k++) aij -= ai[k] * a[k*n+j];
120
+ ai[j] = aij;
121
+ // ピボット選択
122
+ if ((j == i) || ((j > i) && (gabs(aii) < gabs(aij)))) { L = j; aii = aij; }
123
+ }
124
+ // ピボット列交換
125
+ if (L != i) {
126
+ for (k = 0; k < n; ++k) {
127
+ T *au = &a[k*n];
128
+ T av = au[i]; au[i] = au[L]; au[L] = av; // a[*,i] <=> a[*,L]
129
+ } s *= -1;
130
+ } p[i] = L;
131
+ if (i < n-1) for (j = i+1; j < n; j++) ai[j] /= aii;
132
+ }
133
+ }
134
+
135
+ template <class T, class S> void lud_subst(T * a, size_t n, size_t * p, S * b)
136
+ {
137
+ size_t i, j, k, js = n; S sum;
138
+ // 前進代入
139
+ for (i = 0; i < n; ++i) {
140
+ T *lu = &a[i*n];
141
+ sum = b[i];
142
+ if (js < n)
143
+ for (j = js; j < i; ++j) sum -= lu[j] * b[j];
144
+ else if (sum != 0.0) js = i;
145
+ b[i] = sum / lu[i];
146
+ }
147
+ // 後退代入
148
+ for (k = n-1; k > 0; --k) {
149
+ i = k - 1;
150
+ T *lu = &a[i*n];
151
+ sum = b[i];
152
+ for (j = n-1; j > i; --j) sum -= lu[j] * b[j];
153
+ b[i] = sum;
154
+ }
155
+ // 解の保存
156
+ for (k = n-1; k > 0; --k) {
157
+ i = k - 1; j = p[i];
158
+ if (i != j) { sum = b[j]; b[j] = b[i]; b[i] = sum; }
159
+ }
160
+ }
161
+
162
+ template <class T, class S> void lud_subst(T * a, size_t n, size_t * p, S * b, int K)
163
+ {
164
+ size_t i, j, k, l, js = n; S sum;
165
+ // 前進代入
166
+ for (i = 0; i < n; ++i) {
167
+ T *lu = &a[i*n];
168
+ for (l = 0; l < size_t(K); ++l) {
169
+ sum = b[i*K+l];
170
+ if (js < n)
171
+ for (j = js; j < i; ++j) sum -= lu[j] * b[j*K+l];
172
+ else if (sum != 0.0) js = i;
173
+ b[i*K+l] = sum / lu[i];
174
+ }
175
+ }
176
+ // 後退代入
177
+ for (k = n-1; k > 0; --k) {
178
+ i = k - 1;
179
+ T *lu = &a[i*n];
180
+ for (l = 0; l < size_t(K); ++l) {
181
+ sum = b[i*K+l];
182
+ for (j = n-1; j > i; --j) sum -= lu[j] * b[j*K+l];
183
+ b[i*K+l] = sum;
184
+ }
185
+ }
186
+ // 解の保存
187
+ for (k = n-1; k > 0; --k) {
188
+ i = k - 1; j = p[i];
189
+ if (i != j) for (l = 0; l < size_t(K); ++l) {
190
+ sum = b[j*K+l]; b[j*K+l] = b[i*K+l]; b[i*K+l] = sum;
191
+ }
192
+ }
193
+ }
194
+
195
+ template<class T> void lud_decomp(T ** a, size_t n, size_t * p, int & s)
196
+ {
197
+ size_t i, j, k, L;
198
+ double big, tmp, *v = new double[n];
199
+
200
+ s = 1;
201
+ for (i = 0; i < n; ++i) {
202
+ big = 0.0;
203
+ for (j = 0; j < n; ++j)
204
+ if ((tmp = gabs(a[i][j])) > big) big = tmp;
205
+ if (big == 0.0)
206
+ throw "Singular matrix in routine lud_decomp";
207
+ v[i] = 1.0 / big;
208
+ }
209
+ for (k = 0; k < n-1; ++k) {
210
+ // 陰的ピボット選択
211
+ L = k; big = 0.0;
212
+ for (i = k+1; i < n; ++i)
213
+ if ((tmp = gabs(a[i][k]) * v[i]) > big ) {
214
+ big = tmp; L = i;
215
+ }
216
+ // ピボット行交換
217
+ if (L != k) {
218
+ T *w = a[k]; a[k] = a[L]; a[L] = w; // a[k,*] <=> a[L,*]
219
+ v[L] = v[k];
220
+ s *= -1;
221
+ } p[k] = L;
222
+ // 前進消去
223
+ T akk = a[k][k];
224
+ for (j = k+1; j < n; ++j) {
225
+ T akj = a[k][j] / akk;
226
+ for (i = k+1; i < n; ++i) a[i][j] -= a[i][k] * akj;
227
+ a[k][j] = akj;
228
+ }
229
+ }
230
+ delete[] v;
231
+ }
232
+
233
+ template<class T, class S> void lud_subst(T ** a, size_t n, size_t * p, S * b)
234
+ {
235
+ size_t i, j, k, js = n; S sum;
236
+ // 前進代入
237
+ for (i=0;i<n;++i) {
238
+ T *lu = a[i];
239
+ k = (i < n-1) ? p[i] : i;
240
+ sum = b[k]; if (i != k) b[k] = b[i];
241
+ if (js < n)
242
+ for (j=js;j<i;++j) sum -= lu[j] * b[j];
243
+ else if (sum != 0.0) js = i;
244
+ b[i] = sum / lu[i];
245
+ }
246
+ // 後退代入
247
+ for (k=n-1;k>0;--k) {
248
+ i = k - 1;
249
+ T *lu = a[i];
250
+ sum = b[i];
251
+ for (j=n-1;j>i;--j) sum -= lu[j] * b[j];
252
+ b[i] = sum;
253
+ }
254
+ }
255
+
256
+ template <class T, class S> void lud_subst(T ** a, size_t n, size_t * p, S * x, int K)
257
+ {
258
+ S sum, *su, *sv, **b = create_marray_view(n, K, x);
259
+ size_t i, j, k, l, js = n;
260
+ for (i=0;i<n;++i)
261
+ {
262
+ T *lu = a[i];
263
+ k = (i<n-1) ? p[i] : i;
264
+ su = b[k]; sv = b[i];
265
+ for (l=0;l<size_t(K);++l) {
266
+ sum = su[l]; if (i != k) su[l] = sv[l];
267
+ if (js < n)
268
+ for (j=js;j<i;++j) sum -= lu[j] * b[j][l];
269
+ else if (sum != 0.0) js = i;
270
+ sv[l] = sum / lu[i];
271
+ }
272
+ }
273
+ for (k=n;k>0;--k)
274
+ {
275
+ i = k - 1;
276
+ T *lu = a[i];
277
+ su = b[i];
278
+ for (l=0;l<size_t(K);++l) {
279
+ sum = su[l];
280
+ for (j=n-1;j>i;--j) sum -= lu[j] * b[j][l];
281
+ su[l] = sum;
282
+ }
283
+ }
284
+ FREE(b);
285
+ }
286
+ /*
287
+ Crout : LU分解 クラウト法
288
+
289
+ U0j = a0j; j = 0,...,n-1
290
+ Uij = aij - ΣLik*Ukj; i <= j, k = 0,...,i-1
291
+ Lij =(aij - ΣLik*Ukj)/Ujj; i > j, k = 0,...,j-1
292
+ */
293
+ template<class T> void luc_decomp(T * a, size_t n, size_t * p, int & s)
294
+ {
295
+ size_t i, j, k, L;
296
+
297
+ s = 1;
298
+ for (k = 0; k < n-1; ++k) {
299
+ T *ak = &a[k*n];
300
+ T akk = ak[k]; L = k;
301
+ // ピボット選択
302
+ for (j = k+1; j < n; ++j)
303
+ if (gabs(akk) < gabs(ak[j])) { L = j; akk = ak[j]; }
304
+ // ピボット列交換
305
+ if (L != k) {
306
+ for (i = 0; i < n; ++i) {
307
+ T *au = &a[i*n];
308
+ T av = au[k]; au[k] = au[L]; au[L] = av; // a[*,k] <=> a[*,L]
309
+ } s *= -1;
310
+ } p[k] = L;
311
+ // 前進消去
312
+ for (i = k+1; i < n; ++i) {
313
+ T *ai = &a[i*n];
314
+ T aik = ai[k] / akk;
315
+ for (j = k+1; j < n; ++j) ai[j] -= aik * a[k*n+j];
316
+ ai[k] = aik;
317
+ }
318
+ }
319
+ }
320
+
321
+ template<class T, class S> void luc_subst(T * a, size_t n, size_t * p, S * b)
322
+ {
323
+ size_t i, j, js = n, k; S sum;
324
+ // 前進代入
325
+ for (i=0;i<n;++i) {
326
+ T* lu = &a[i*n];
327
+ sum = b[i];
328
+ if (js < n)
329
+ for (j=js;j<i;++j) sum -= lu[j] * b[j];
330
+ else if (sum != 0.0) js = i;
331
+ b[i] = sum;
332
+ }
333
+ // 後退代入
334
+ for (k=n;k>0;--k) {
335
+ i = k - 1;
336
+ T* lu = &a[i*n];
337
+ sum = b[i];
338
+ for (j=n-1;j>i;--j) sum -= lu[j] * b[j];
339
+ b[i] = sum / lu[i];
340
+ }
341
+ // 解の保存
342
+ for (k=n-1;k>0;--k) {
343
+ i = k - 1; j = p[i];
344
+ if (i != j) { sum = b[j]; b[j] = b[i]; b[i] = sum; }
345
+ }
346
+ }
347
+
348
+ template<class T, class S> void luc_subst(T * a, size_t n, size_t * p, S * b, int K)
349
+ {
350
+ size_t i, j, k, l, js = n; S sum;
351
+ // 前進代入
352
+ for (i=0;i<n;++i) {
353
+ T* lu = &a[i*n];
354
+ for (l=0;l<size_t(K);++l) {
355
+ sum = b[i*K+l];
356
+ if (js < n)
357
+ for (j=js;j<i;++j) sum -= lu[j] * b[j*K+l];
358
+ else if (sum != 0.0) js = i;
359
+ b[i*K+l] = sum;
360
+ }
361
+ }
362
+ // 後退代入
363
+ for (k=n;k>0;--k) {
364
+ i = k - 1;
365
+ T* lu = &a[i*n];
366
+ for (l=0;l<size_t(K);++l) {
367
+ sum = b[i*K+l];
368
+ for (j=n-1;j>i;--j) sum -= lu[j] * b[j*K+l];
369
+ b[i*K+l] = sum / lu[i];
370
+ }
371
+ }
372
+ // 解の保存
373
+ for (k = n-1; k > 0; --k) {
374
+ i = k - 1; j = p[i];
375
+ if (i != j) for (l=0;l<size_t(K);++l) {
376
+ sum = b[j*K+l]; b[j*K+l] = b[i*K+l]; b[i*K+l] = sum;
377
+ }
378
+ }
379
+ }
380
+
381
+ template <class T> void luc_decomp(T ** a, size_t n, size_t * p, int & s)
382
+ {
383
+ size_t i, j, k, l, L;
384
+ double big, tmp, *v = new double[n];
385
+
386
+ s = 1;
387
+ for (i = 0; i < n; ++i) {
388
+ big = 0.0;
389
+ for (j = 0; j < n; ++j)
390
+ if ((tmp = gabs(a[i][j])) > big) big = tmp;
391
+ if (big == 0.0)
392
+ throw "Singular matrix in routine luc_decomp";
393
+ v[i] = 1.0 / big;
394
+ }
395
+ for (j = 0; j < n; j++) {
396
+ L = j; big = 0.0;
397
+ for (i = 1; i < n; i++) {
398
+ l = j < i ? j : i;
399
+ T aij = a[i][j];
400
+ for (k = 0; k < l; k++) aij -= a[i][k] * a[k][j];
401
+ a[i][j] = aij;
402
+ // ピボット選択
403
+ if (i >= j)
404
+ if ((tmp = gabs(aij) * v[i]) > big) { big = tmp; L = i; }
405
+ } p[j] = L;
406
+ // ピボット行交換
407
+ if (L != j) {
408
+ T *w = a[j]; a[j] = a[L]; a[L] = w; // a[j,*] <=> a[L,*]
409
+ v[L] = v[j];
410
+ s *= -1;
411
+ } T ajj = a[j][j];
412
+ if (ajj == 0.0) ajj = DBL_MIN;
413
+ if (j < n-1) for (i = j+1; i < n; i++) a[i][j] /= ajj;
414
+ }
415
+ delete[] v;
416
+ }
417
+
418
+ template <class T, class S> void luc_subst(T ** a, size_t n, size_t * p, S * b)
419
+ {
420
+ size_t i, j, k, js = n; S sum;
421
+ // 前進代入
422
+ for (i=0;i<n;++i) {
423
+ T *lu = a[i]; k = p[i];
424
+ sum = b[k]; if (i != k) b[k] = b[i];
425
+ if (js < n)
426
+ for (j=js;j<i;++j) sum -= lu[j] * b[j];
427
+ else if (sum != 0.0) js = i;
428
+ b[i] = sum;
429
+ }
430
+ // 後退代入
431
+ for (k=n;k>0;--k) {
432
+ i = k - 1;
433
+ T *lu = a[i];
434
+ sum = b[i];
435
+ for (j=n-1;j>i;--j) sum -= lu[j] * b[j];
436
+ b[i] = sum / lu[i];
437
+ }
438
+ }
439
+
440
+ template <class T, class S> void luc_subst(T ** a, size_t n, size_t * p, S * x, int K)
441
+ {
442
+ S sum, *su, *sv, **b = create_marray_view(n, K, x);
443
+ size_t i, j, k, l, js = n;
444
+ // 前進代入
445
+ for (i=0;i<n;++i) {
446
+ T *lu = a[i]; k = p[i];
447
+ su = b[k]; sv = b[i];
448
+ for (l=0;l<size_t(K);++l) {
449
+ sum = su[l]; if (i != k) su[l] = sv[l];
450
+ if (js < n)
451
+ for (j=js;j<i;++j) sum -= lu[j] * b[j][l];
452
+ else if (sum != 0.0) js = i;
453
+ sv[l] = sum;
454
+ }
455
+ }
456
+ // 後退代入
457
+ for (k=n;k>0;--k) {
458
+ i = k - 1;
459
+ T *lu = a[i];
460
+ su = b[i];
461
+ for (l=0;l<size_t(K);++l) {
462
+ sum = su[l];
463
+ for (j=n-1;j>i;--j) sum -= lu[j] * b[j][l];
464
+ su[l] = sum / lu[i];
465
+ }
466
+ }
467
+ free(b);
468
+ }
469
+
470
+ template double coeff(double**, const int*, int, int);
471
+ template double total_derive(double**, const int*, int, int, const double*);
472
+ template void luc_decomp(double *, size_t, size_t*, int&);
473
+ template void luc_decomp(double**, size_t, size_t*, int&);
474
+ template void lud_decomp(double *, size_t, size_t*, int&);
475
+ template void lud_decomp(double**, size_t, size_t*, int&);
476
+ template void luc_subst(double *, size_t, size_t*, double*);
477
+ template void luc_subst(double**, size_t, size_t*, double*);
478
+ template void lud_subst(double *, size_t, size_t*, double*);
479
+ template void lud_subst(double**, size_t, size_t*, double*);
480
+ template void luc_subst(double *, size_t, size_t*, double*, int);
481
+ template void luc_subst(double**, size_t, size_t*, double*, int);
482
+ template void lud_subst(double *, size_t, size_t*, double*, int);
483
+ template void lud_subst(double**, size_t, size_t*, double*, int);