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,210 +1,251 @@
1
- #ifndef _USPLINE_5_H_INCLUDED_
2
- #define _USPLINE_5_H_INCLUDED_
3
-
4
- template <typename T = double> struct Func { int jbn, jis; T val; };
5
- template <typename T = double> struct Bound { int pos, jbn; T val; };
6
- template <typename T = double> using Factor = T(*)(T);
7
-
8
- /*******************************************************************************
9
- uspline<T>{base_spline*[N]}
10
- *******************************************************************************/
11
- template <typename T = double> class uspline : public base_spline<T>
12
- {
13
-
14
- T *data;
15
-
16
- // 汎関数線型項
17
- void hankansu1(const Func<T>& F, T *hr)
18
- {
19
- T *q = base_spline<T>::knots;
20
- int K = base_spline<T>::rank, J = K - 1;
21
- int Imax = base_spline<T>::imax;
22
- T t = q[Imax];
23
- T B[K];
24
- int kset = base_spline<T>::basic(t, K, B);
25
- int ks = kset - J;
26
- for (int l = 0; l < Imax; ++l) {
27
- T aj[Imax], ac[Imax];
28
- for (int i = 0; i < Imax; ++i) ac[i] = 0;
29
- ac[l] = 1;
30
- aj[0] = ac[0] * (q[K] - q[0]) / K;
31
- for (int j = 1; j < Imax; ++j)
32
- aj[j] = aj[j-1] + ac[j] * (q[j+K] - q[j]) / K;
33
- T rn = 0;
34
- for (int i = ks; i <= kset; ++i)
35
- rn += aj[i] * B[i - ks];
36
- hr[l] += F.val * rn;
37
- }
38
- }
39
-
40
- // 汎関数2乗項
41
- void hankansu2(const Func<T>& F, T *hl)
42
- {
43
- T *q = base_spline<T>::knots;
44
- int K = base_spline<T>::rank, J = K - 1;
45
- int Imax = base_spline<T>::imax;
46
- T ld[K*2];
47
- for (int l = 0; l < K*2; ++l) {
48
- if (l == 0)
49
- ld[l] = 1.0;
50
- else
51
- ld[l] = ld[l-1] * l;
52
- }
53
- int jb = F.jbn;
54
- for (int l = 0; l < Imax; ++l) {
55
- int ql = l + J;
56
- T t = q[ql];
57
- parray<T> fl = base_spline<T>::bases(t, J);
58
- int ks = fl(0), kt = fl(1), kset = ks + J;
59
- T *ft = *fl;
60
- for (int i = ks; i <= kset; ++i) {
61
- for (int j = ks; j <= kset; ++j) {
62
- for (int r = jb; r < K; ++r) {
63
- int rb = r - jb;
64
- T Bik = ft[i - ks + r*kt];
65
- for (int s = jb; s < K; ++s) {
66
- int sb = s - jb;
67
- T Bjk = ft[j - ks + s*kt];
68
- int lm = rb + sb + 1;
69
- T Ql = pow(q[ql+1] - q[ql], lm);
70
- T p = Bik * Bjk * Ql / (ld[rb] * ld[sb] * lm);
71
- hl[i*Imax + j] += F.val * p;
72
- }
73
- }
74
- }
75
- }
76
- }
77
- }
78
-
79
- void gyoretu_ritz(double *hl, double *hr, double *Bd, double *Dy)
80
- {
81
- int Imax = base_spline<T>::imax;
82
- for (int l = 0; l < Imax; ++l) {
83
- for (int i = 0; i < Imax; ++i)
84
- Bd[l*Imax + i] = 2 * hl[l*Imax + i];
85
- Dy[l] = -hr[l];
86
- }
87
- }
88
-
89
- void zyoken(int lcc, int *ibd, const Bound<T> *Bs, T *Bd, T *Dx, T *Dy)
90
- {
91
- int K = base_spline<T>::rank, J = K - 1;
92
- int Imax = base_spline<T>::imax;
93
- T B[K];
94
- for (int l = 0; l < lcc; l++) {
95
- T t = Dx[Bs[l].pos];
96
- int jb = Bs[l].jbn;
97
- int kset = base_spline<T>::basic(t, K, B, -jb);
98
- int ks = kset - J;
99
- for (int i = 0; i < Imax; i++)
100
- Bd[ibd[l]*Imax + i] = (i < ks || kset < i) ? 0 : B[i - ks];
101
- Dy[ibd[l]] = Bs[l].val;
102
- }
103
- }
104
-
105
- public:
106
- uspline() : data(NULL) {}
107
- ~uspline() {delete[] data;}
108
- uspline(int R, Func<T> *df, int n, T *x, int j, int d, int lcc, Bound<T> *bf, int *lbd)
109
- : base_spline<T>(n, x, j, d)
110
- {
111
- int Imax = base_spline<T>::imax;
112
- T hl[Imax * Imax], hr[Imax];
113
- T Bd[Imax][Imax], Dy[Imax];
114
- for (int i = 0; i < Imax; ++i) {
115
- for (int j = 0; j < Imax; ++j)
116
- hl[i*Imax+j] = 0;
117
- hr[i] = 0;
118
- }
119
- for (int term = 0; term < R; ++term)
120
- if (df[term].jis == 2)
121
- hankansu2(df[term], hl);
122
- else
123
- hankansu1(df[term], hr);
124
- gyoretu_ritz(hl, hr, (T*)Bd, Dy);
125
- zyoken(lcc, lbd, bf, (T*)Bd, x, Dy);
126
- data = new T[Imax];
127
- for (int i = 0; i < Imax; ++i) data[i] = Dy[i];
128
- lu_solve((T*)Bd, Imax, data);
129
- }
130
-
131
- T operator [] (T t) const { return base_spline<T>::apply(t, data); }
132
-
133
- }; // end of uspline;
134
-
135
- /*******************************************************************************
136
- nspline<T>{base_spline*[N]}
137
- *******************************************************************************/
138
- template <typename T> class nspline : public base_spline<T>
139
- {
140
- T *data;
141
-
142
- // 微分方程式左辺
143
- void sa_hen(T *Dx, int term, Func<T> *F, Factor<T> *C, T *Bd)
144
- {
145
- int K = base_spline<T>::rank, J = K - 1;
146
- int Imax = base_spline<T>::imax;
147
- T B[K*(K+1)];
148
- for (int l = 0; l < Imax; ++l) {
149
- T t = Dx[l];
150
- for (int k = 0; k < term; ++k) {
151
- F[k].val = C[k](t);
152
- int jb = F[k].jbn;
153
- int kset = base_spline<T>::basic(t, K, B, -jb);
154
- int ks = kset - J;
155
- for (int i = 0; i < Imax; ++i)
156
- Bd[l*Imax + i] += F[k].val * ((ks <= i && i <= kset) ? B[i - ks] : 0.0);
157
- }
158
- }
159
- }
160
-
161
- // 微分方程式右辺
162
- void u_hen(Factor<T>& f, int Imax, T *Dx, T *Dy)
163
- {
164
- for (int i = 0; i < Imax; ++i) Dy[i] = f(Dx[i]);
165
- }
166
-
167
- void zyoken(int lcc, int *ibd, const Bound<T> *Bs, T *Bd, T *Dx, T *Dy)
168
- {
169
- int K = base_spline<T>::rank, J = K - 1;
170
- int Imax = base_spline<T>::imax;
171
- T B[K];
172
- for (int l = 0; l < lcc; l++) {
173
- T t = Dx[Bs[l].pos];
174
- int jb = Bs[l].jbn;
175
- int kset = base_spline<T>::basic(t, K, B, -jb);
176
- int ks = kset - J;
177
- for (int i = 0; i < Imax; i++)
178
- Bd[ibd[l]*Imax + i] = (i < ks || kset < i) ? 0 : B[i - ks];
179
- Dy[ibd[l]] = Bs[l].val;
180
- }
181
- }
182
-
183
- public:
184
- nspline() : data(NULL) {}
185
- ~nspline(){delete[] data;}
186
- nspline(int R, Func<T> *df, Factor<T> *uf, int n, T *x, int j, int d, int lcc, Bound<T> *bf, int *lbd)
187
- : base_spline<T>(n, x, j, d)
188
- {
189
- int Imax = base_spline<T>::imax;
190
- double Bd[Imax * Imax], Dy[Imax];
191
- for (int i = 0; i < Imax; ++i) {
192
- for (int j = 0; j < Imax; ++j)
193
- Bd[i*Imax+j] = 0;
194
- Dy[i] = 0;
195
- }
196
- sa_hen(x, R, df, uf, Bd);
197
- u_hen(uf[R], Imax, x, Dy);
198
- zyoken(lcc, lbd, bf, Bd, x, Dy);
199
- data = new T[Imax];
200
- for (int i = 0; i < Imax; ++i) data[i] = Dy[i];
201
- lu_solve(Bd, Imax, data);
202
- }
203
-
204
- T operator [] (T t) const { return base_spline<T>::apply(t, data); }
205
-
206
- T operator () (T t, int Jbn = 0) const { return base_spline<T>::apply(t, data, Jbn); }
207
-
208
- }; // end of nspline
209
-
210
- #endif
1
+ #ifndef _USPLINE_4_H_INCLUDED_
2
+ #define _USPLINE_4_H_INCLUDED_
3
+
4
+ template <typename T = double> struct Func { int jbn, jis; real<T> val; };
5
+ template <typename T = double> struct Bound { int jbn, pos; real<T> val; };
6
+ template <typename T = double> using Factor = real<T>(*)(const real<T>&);
7
+ template <typename T = double> class FTerm
8
+ {
9
+ int R, N;
10
+ int *pos; T *val;
11
+ public:
12
+ FTerm(int r, int n) : R(r), N(n), pos(new int[r*2]), val(new T[r*(n+1)]) {}
13
+ FTerm(const FTerm&) = delete;
14
+ ~FTerm() { delete[] pos; delete[] val; }
15
+ FTerm& operator = (const FTerm&) = delete;
16
+ real<T> operator [] (int i) const { return real<T>((size_t)N, &val[i*(N+1)], 0); }
17
+ int order(int i) const { return pos[i]; }
18
+ int& order(int i) { return pos[i]; }
19
+ int point(int i) const { return pos[i+R]; }
20
+ int& point(int i) { return pos[i+R]; }
21
+ int degree(int i) const { return pos[i+R]; }
22
+ int& degree(int i) { return pos[i+R]; }
23
+ Func<T> operator () (int i) const
24
+ {
25
+ Func<T> result;
26
+ result.jbn = pos[i];
27
+ result.jis = pos[i+R];
28
+ result.val = (*this)[i];
29
+ return result;
30
+ }
31
+ int Atom() const { return N; }
32
+ int Size() const { return R; }
33
+ };
34
+ template <typename T> using FBcon = FTerm<T>;
35
+
36
+ /*******************************************************************************
37
+ uspline<T>{base_spline*[N]}
38
+ *******************************************************************************/
39
+ template <typename T = double> class uspline : base_spline<T>
40
+ {
41
+
42
+ varray<T> *data;
43
+
44
+ // 汎関数線型項
45
+ void hankansu1(const Func<T>& F, varray<T>& hr)
46
+ {
47
+ const varray<T>& q = *this->knots;
48
+ size_t A = q.atom();
49
+ int K = this->rank, J = K - 1;
50
+ int Imax = this->imax;
51
+ varray<T> B((size_t)K, A);
52
+ int ks = this->basic(q[Imax], K, B);
53
+ int kset = ks + J;
54
+ varray<T> ac((size_t)Imax, A); real<T> sum(A);
55
+ for (int i = 0; i < Imax; ++i) {
56
+ for (int j = 0; j < Imax; ++j) ac[j] = T(0.0);
57
+ ac[i] = T(1.0);
58
+ for (int j = 0; j < Imax; ++j)
59
+ ac[j] = (j > 0 ? ac[j-1] : T(0.0)) + ac[j] * (q[j+K] - q[j]) / T(K);
60
+ sum = T(0.0);
61
+ for (int j = ks; j <= kset; ++j)
62
+ sum += ac[j] * B[j - ks];
63
+ hr[i] += F.val * sum;
64
+ }
65
+ }
66
+
67
+ // 汎関数2乗項
68
+ void hankansu2(const Func<T>& F, marray<T>& hl)
69
+ {
70
+ const varray<T>& q = *this->knots;
71
+ int K = this->rank, J = K - 1;
72
+ int Imax = this->imax;
73
+ T ld[K*2];
74
+ for (int l = 0; l < K*2; ++l) {
75
+ if (l == 0)
76
+ ld[l] = 1.0;
77
+ else
78
+ ld[l] = ld[l-1] * l;
79
+ }
80
+ int jb = F.jbn;
81
+ for (int l = 0; l < Imax; ++l) {
82
+ int ql = l + J;
83
+ real<T> t = q[ql];
84
+ parray<T> fl = this->bases(t, J);
85
+ int ks = fl(0), kset = ks + J;
86
+ for (int i = ks; i <= kset; ++i) {
87
+ for (int j = ks; j <= kset; ++j) {
88
+ for (int r = jb; r < K; ++r) {
89
+ int rb = r - jb;
90
+ real<T> Bik = fl[r][i - ks];
91
+ for (int s = jb; s < K; ++s) {
92
+ int sb = s - jb;
93
+ real<T> Bjk = fl[s][j - ks];
94
+ int lm = rb + sb + 1;
95
+ real<T> Ql = pow(q[ql+1] - q[ql], lm);
96
+ real<T> p = Bik * Bjk * Ql / (ld[rb] * ld[sb] * lm);
97
+ hl[i][j] += F.val * p;
98
+ }
99
+ }
100
+ }
101
+ }
102
+ }
103
+ }
104
+
105
+ void gyoretu_ritz(const marray<T>& hl, marray<T>& Bd)
106
+ {
107
+ int Imax = this->imax;
108
+ for (int l = 0; l < Imax; ++l) {
109
+ for (int i = 0; i < Imax; ++i)
110
+ Bd[l][i] = 2.0 * hl[l][i];
111
+ Bd[Imax][l] = -hl[Imax][l];
112
+ }
113
+ }
114
+
115
+ void zyoken(int lcc, int *ibd, const FBcon<T>& Bs, marray<T>& Bd, const varray<T>& Dx, varray<T>& Dy)
116
+ {
117
+ int K = this->rank, J = K - 1;
118
+ int Imax = this->imax;
119
+ size_t A = Dx.atom();
120
+ varray<T> B((size_t)K, A);
121
+ for (int l = 0; l < lcc; l++) {
122
+ real<T> t = Dx[Bs.point(l)];
123
+ int jb = Bs.order(l);
124
+ int ks = this->basic(t, K, B, -jb);
125
+ int kset = ks + J;
126
+ for (int i = 0; i < Imax; i++)
127
+ Bd[ibd[l]][i] = (i < ks || kset < i) ? 0.0 : B[i - ks];
128
+ Dy[ibd[l]] = Bs[l];
129
+ }
130
+ }
131
+
132
+ public:
133
+
134
+ uspline() : data(NULL) {}
135
+
136
+ ~uspline() {delete data;}
137
+
138
+ uspline(const FTerm<T>& df, const FBcon<T>& bf, int *lbd, int n, const varray<T>& x, int j, int d = 0)
139
+ : base_spline<T>(n, x, j, d)
140
+ {
141
+ int R = df.Size(), L = bf.Size();
142
+ size_t A = df.Atom();
143
+ int Imax = this->imax;
144
+ auto hl = marray<T>(Imax+1, Imax, A); auto hr = hl[Imax];
145
+ auto Bd = marray<T>(Imax+1, Imax, A); auto Dy = Bd[Imax];
146
+ for (int i = 0; i <= Imax; ++i)
147
+ for (int j = 0; j < Imax; ++j)
148
+ hl[i][j] = T();
149
+ for (int term = 0; term < R; ++term) {
150
+ Func<T> def = df(term);
151
+ if (def.jis == 2)
152
+ hankansu2(def, hl);
153
+ else
154
+ hankansu1(def, hr);
155
+ }
156
+ gyoretu_ritz(hl, Bd);
157
+ zyoken(L, lbd, bf, Bd, x, Dy);
158
+ data = new varray<T>((size_t)Imax, A);
159
+ marray_view<T> B(*Bd, Imax, Imax, A);
160
+ marray_lu_view<T> lu(B);
161
+ lu.solve(Dy, *data);
162
+ }
163
+
164
+ real<T> operator [] (const real<T>& t) const { return this->apply(t, *data); }
165
+
166
+ }; // end of uspline;
167
+
168
+ /*******************************************************************************
169
+ nspline<T>{base_spline*[N]}
170
+ *******************************************************************************/
171
+ template <typename T> class nspline : base_spline<T>
172
+ {
173
+ varray<T> *data;
174
+
175
+ // 微分方程式左辺
176
+ void sa_hen(const varray<T>& Dx, const FTerm<T>& F, const Factor<T> *C, marray<T>& Bd)
177
+ {
178
+ int R = F.Size();
179
+ int K = this->rank, J = K - 1;
180
+ size_t A = F.Atom();
181
+ int Imax = this->imax;
182
+ varray<T> B((size_t)K, A);
183
+ for (int l = 0; l < Imax; ++l) {
184
+ real<T> t = Dx[l];
185
+ for (int k = 0; k < R; ++k) {
186
+ real<T> c = C[k](t);
187
+ int jb = F.order(k);
188
+ int ks = this->basic(t, K, B, -jb);
189
+ int kset = ks + J;
190
+ for (int i = 0; i < Imax; ++i)
191
+ Bd[l][i] += c * ((ks <= i && i <= kset) ? B[i - ks] : 0.0);
192
+ }
193
+ }
194
+ }
195
+
196
+ // 微分方程式右辺
197
+ void u_hen(Factor<T> f, int Imax, const varray<T>& Dx, varray<T>& Dy)
198
+ {
199
+ for (int i = 0; i < Imax; ++i) Dy[i] = f(Dx[i]);
200
+ }
201
+
202
+ void zyoken(const FBcon<T>& Bs, int *ibd, marray<T>& Bd, const varray<T>& Dx, varray<T>& Dy)
203
+ {
204
+ int L = Bs.Size();
205
+ int K = this->rank, J = K - 1;
206
+ size_t A = Bs.Atom();
207
+ int Imax = this->imax;
208
+ varray<T> B((size_t)K, A);
209
+ for (int l = 0; l < L; l++) {
210
+ real<T> t = Dx[Bs.point(l)];
211
+ int jb = Bs.order(l);
212
+ int ks = this->basic(t, K, B, -jb);
213
+ int kset = ks + J;
214
+ for (int i = 0; i < Imax; i++)
215
+ Bd[ibd[l]][i] = (i < ks || kset < i) ? 0.0 : B[i - ks];
216
+ Dy[ibd[l]] = Bs[l];
217
+ }
218
+ }
219
+
220
+ public:
221
+
222
+ nspline() : data(NULL) {}
223
+
224
+ ~nspline(){ delete data; }
225
+
226
+ nspline(const FTerm<T>& df, const Factor<T> *uf, const FBcon<T>& bf, int *lbd, int n, const varray<T>& x, int j, int d = 0)
227
+ : base_spline<T>(n, x, j, d)
228
+ {
229
+ int R = df.Size();
230
+ size_t A = df.Atom();
231
+ int Imax = this->imax;
232
+ auto Bd = marray<T>(Imax+1, Imax, A); auto Dy = Bd[Imax];
233
+ for (int i = 0; i <= Imax; ++i)
234
+ for (int j = 0; j < Imax; ++j)
235
+ Bd[i][j] = T(0.0);
236
+ sa_hen(x, df, uf, Bd);
237
+ u_hen(uf[R], Imax, x, Dy);
238
+ zyoken(bf, lbd, Bd, x, Dy);
239
+ data = new varray<T>((size_t)Imax, A);
240
+ marray_view<T> B(*Bd, Imax, Imax, A);
241
+ marray_lu_view<T> lu(B);
242
+ lu.solve(Dy, *data);
243
+ }
244
+
245
+ real<T> operator [] (const real<T>& t) const { return this->apply(t, *data); }
246
+
247
+ real<T> operator () (const real<T>& t, int Jbn = 0) const { return this->apply(t, *data, Jbn); }
248
+
249
+ }; // end of nspline
250
+
251
+ #endif