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.
- checksums.yaml +7 -0
- data/Gemfile +5 -0
- data/README.md +34 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/pspline/basis.cpp +351 -0
- data/ext/pspline/example/exbspline.ps +2194 -0
- data/ext/pspline/example/exbspline.rb +36 -0
- data/ext/pspline/example/excspline.ps +2985 -0
- data/ext/pspline/example/excspline.rb +36 -0
- data/ext/pspline/example/exdspline.ps +2846 -0
- data/ext/pspline/example/exdspline.rb +33 -0
- data/ext/pspline/example/exfspline.rb +66 -0
- data/ext/pspline/example/exfspline1.rb +40 -0
- data/ext/pspline/example/expspline.ps +3299 -0
- data/ext/pspline/example/expspline.rb +29 -0
- data/ext/pspline/example/expspline1.rb +29 -0
- data/ext/pspline/example/expspline2.rb +47 -0
- data/ext/pspline/example/exqspline.ps +2957 -0
- data/ext/pspline/example/exqspline.rb +31 -0
- data/ext/pspline/example/exqspline1.rb +31 -0
- data/ext/pspline/example/exqspline2.rb +50 -0
- data/ext/pspline/example/exqspline3.rb +51 -0
- data/ext/pspline/example/exrspline.ps +2812 -0
- data/ext/pspline/example/exrspline.rb +34 -0
- data/ext/pspline/example/exrspline1.rb +34 -0
- data/ext/pspline/example/exrspline2.rb +44 -0
- data/ext/pspline/example/exsspline.ps +1965 -0
- data/ext/pspline/example/exsspline.rb +35 -0
- data/ext/pspline/example/exsspline1.rb +35 -0
- data/ext/pspline/example/extspline.ps +2767 -0
- data/ext/pspline/example/extspline.rb +32 -0
- data/ext/pspline/extconf.rb +7 -0
- data/ext/pspline/fft.cpp +552 -0
- data/ext/pspline/include/basis/basis.h +137 -0
- data/ext/pspline/include/basis/fft.h +152 -0
- data/ext/pspline/include/basis/poly_array.h +1568 -0
- data/ext/pspline/include/basis/pspline.h +506 -0
- data/ext/pspline/include/basis/uspline.h +210 -0
- data/ext/pspline/include/basis/util.h +656 -0
- data/ext/pspline/include/bspline.h +377 -0
- data/ext/pspline/include/bspline_Config.h +2 -0
- data/ext/pspline/plotsub.cpp +132 -0
- data/ext/pspline/pspline.cpp +897 -0
- data/ext/pspline/util.cpp +483 -0
- data/lib/pspline.rb +6 -0
- data/lib/pspline/version.rb +3 -0
- data/pspline.gemspec +25 -0
- metadata +122 -0
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
#ifndef _PSPLINE_5_H_INCLUDED_
|
|
2
|
+
#define _PSPLINE_5_H_INCLUDED_
|
|
3
|
+
|
|
4
|
+
/*******************************************************************************
|
|
5
|
+
define poly_spline[base_spline1*,...base_splineN*]
|
|
6
|
+
*******************************************************************************/
|
|
7
|
+
template <typename S = double> class poly_spline
|
|
8
|
+
{
|
|
9
|
+
|
|
10
|
+
int N; base_spline<S> **base;
|
|
11
|
+
|
|
12
|
+
public:
|
|
13
|
+
struct values_ {
|
|
14
|
+
Int imax, icox, rank, jisu, shuki;
|
|
15
|
+
carray_view<S> *knots;
|
|
16
|
+
values_(poly_spline<S>& own, int as) :
|
|
17
|
+
imax(own.Imax(as)), icox(own.Icox(as)),
|
|
18
|
+
rank(own.Rank() ), jisu(own.Jisu() ), shuki(own.Shuki())
|
|
19
|
+
{
|
|
20
|
+
size_t n = own.Grid();
|
|
21
|
+
knots = new carray_view<S>(n, own.Maxq(), NULL);
|
|
22
|
+
for (size_t i = 0; i < n; i++)
|
|
23
|
+
(*knots)[i] = own[i].Knots();
|
|
24
|
+
}
|
|
25
|
+
~values_() { delete knots; }
|
|
26
|
+
} *values;
|
|
27
|
+
|
|
28
|
+
// constructor
|
|
29
|
+
poly_spline(const comb_array<S>& x, const Int& n, const Int& j, const Int& s) : N(x.grid())
|
|
30
|
+
{
|
|
31
|
+
base = new base_spline<S>*[N];
|
|
32
|
+
for (int i = 0; i < N; i++)
|
|
33
|
+
base[i] = new base_spline<S>(n[i], x[i], j[i], -s[i]%2);
|
|
34
|
+
values = new values_(*this, n.unit_size());
|
|
35
|
+
}
|
|
36
|
+
// copy constructor
|
|
37
|
+
poly_spline(const poly_spline& p) : N(p.N)
|
|
38
|
+
{
|
|
39
|
+
for (int i = 0; i < N; i++)
|
|
40
|
+
base[i] = new base_spline<S>(*p.base[i]);
|
|
41
|
+
values = new values_(*this, p.values->imax.unit_size());
|
|
42
|
+
}
|
|
43
|
+
// destructor
|
|
44
|
+
~poly_spline() {delete[] base; delete values;}
|
|
45
|
+
// substitution operator
|
|
46
|
+
poly_spline& operator=(const poly_spline& p)
|
|
47
|
+
{
|
|
48
|
+
if (this != &p) {
|
|
49
|
+
delete[] base;
|
|
50
|
+
int N = p.N;
|
|
51
|
+
for (int i = 0; i < N; i++) {
|
|
52
|
+
base[i] = base_spline<S>(*p.base[i]);
|
|
53
|
+
} delete values;
|
|
54
|
+
values = new values_(*this, p.values->imax.unit_size());
|
|
55
|
+
}
|
|
56
|
+
return *this;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
marray<S> gyoretsu(base_spline<S> *base, int a, const S *x)
|
|
60
|
+
{
|
|
61
|
+
int imax = base->Imax();
|
|
62
|
+
marray<S> bd(imax, imax);
|
|
63
|
+
base->gyoretu(bd, a, x);
|
|
64
|
+
return bd;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
marray<S> gyoretu(const Int& a, const comb_array<S>& x)
|
|
68
|
+
{
|
|
69
|
+
marray<S> res = gyoretsu(base[0], a[0], x[0]);
|
|
70
|
+
for (int i = 1; i < N; ++i) {
|
|
71
|
+
res = res ^ gyoretsu(base[i], a[i], x[i]);
|
|
72
|
+
}
|
|
73
|
+
return res;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
comp_array<S> basis(const poly<S>& t, const int *jb = NULL) const
|
|
77
|
+
{
|
|
78
|
+
int s[N*2];
|
|
79
|
+
int size = this->values->rank.comb_size();
|
|
80
|
+
S data[size], *p = data;
|
|
81
|
+
for (int i = 0; i < N; i++) {
|
|
82
|
+
parray<S> bc = base[i]->basis(t[i], jb ? jb[i] : 0);
|
|
83
|
+
s[i] = bc(0); s[i+N] = bc(1);
|
|
84
|
+
S *dat = *bc;
|
|
85
|
+
for (int j = 0; j < bc(1); ++j) *p++ = dat[j];
|
|
86
|
+
}
|
|
87
|
+
return comp_array<S>(data, N*2, s, 1);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
comp_array<S> bases(const poly<S>& t, int jbn = 0) const
|
|
91
|
+
{
|
|
92
|
+
int s[N*2], K = jbn + 1;
|
|
93
|
+
int size = this->values->rank.comb_size();
|
|
94
|
+
S data[size * K], *p = data;
|
|
95
|
+
for (int i = 0; i < N; i++) {
|
|
96
|
+
parray<S> bc = base[i]->bases(t[i], jbn);
|
|
97
|
+
s[i] = bc(0); s[i+N] = bc(1);
|
|
98
|
+
int sz = bc(1) * K;
|
|
99
|
+
S *dat = *bc;
|
|
100
|
+
for (int j = 0; j < sz; ++j) *p++ = dat[j];
|
|
101
|
+
}
|
|
102
|
+
return comp_array<S>(data, N*2, s, K);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
template <typename T>
|
|
106
|
+
void sekibun(poly_view<T>& r, const poly_view<T>& clp, const poly<int>& h, const poly<S>& x) const
|
|
107
|
+
{
|
|
108
|
+
int offset[N+1], size[N+1];
|
|
109
|
+
Size_t z = this->values->rank;
|
|
110
|
+
S **sp = create_carray<S>(N, z);
|
|
111
|
+
for (int i = 0; i < N; ++i) {
|
|
112
|
+
S ql = (*base[i])[h[i]];
|
|
113
|
+
S qm = (*base[i])[h[i] + 1];
|
|
114
|
+
S qh = (x[i] < qm ? x[i] : qm) - ql;
|
|
115
|
+
parray<S> pc = base[i]->bases(ql, base[i]->Jisu());
|
|
116
|
+
offset[i] = pc(0); size[i] = pc(1);
|
|
117
|
+
for (int j = 0; j < size[i]; j++) sp[i][j] = pc.saylor(j, qh);
|
|
118
|
+
} offset[N] = 0; size[N] = 0;
|
|
119
|
+
Int o = Int(offset,N);
|
|
120
|
+
Int s = Int(size, N);
|
|
121
|
+
int end = s.grid_size();
|
|
122
|
+
for (int i = 0; i < end; ++i) {
|
|
123
|
+
Int k = i % s, j = k + o;
|
|
124
|
+
r += clp[j] * [](int N, T **p, Int& k) -> T {
|
|
125
|
+
T u = 1.0;
|
|
126
|
+
for (int i = 0; i < N; ++i) u *= p[i][k[i]];
|
|
127
|
+
return u;
|
|
128
|
+
} (N, sp, k);
|
|
129
|
+
}
|
|
130
|
+
FREE(sp);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
base_spline<S>& operator[](int i) {return *base[i];}
|
|
134
|
+
|
|
135
|
+
int Grid() {return N;}
|
|
136
|
+
|
|
137
|
+
Int Kset(const poly<S>& x) const
|
|
138
|
+
{
|
|
139
|
+
int v[N];
|
|
140
|
+
for (int i = 0; i < N; i++) v[i] = base[i]->Kset(x[i]);
|
|
141
|
+
return Int(N, v, 0);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private:
|
|
145
|
+
|
|
146
|
+
Int Imax(int as = 1) const
|
|
147
|
+
{
|
|
148
|
+
int v[N];
|
|
149
|
+
for (int i = 0; i < N; i++) v[i] = base[i]->Imax();
|
|
150
|
+
return Int(N, v, as);
|
|
151
|
+
}
|
|
152
|
+
Int Icox(int as = 1) const
|
|
153
|
+
{
|
|
154
|
+
int v[N];
|
|
155
|
+
for (int i = 0; i < N; i++) v[i] = base[i]->Icox();
|
|
156
|
+
return Int(N, v, as);
|
|
157
|
+
}
|
|
158
|
+
Int Rank() const
|
|
159
|
+
{
|
|
160
|
+
int v[N];
|
|
161
|
+
for (int i = 0; i < N; i++) v[i] = base[i]->Rank();
|
|
162
|
+
return Int(N, v, 1);
|
|
163
|
+
}
|
|
164
|
+
Int Jisu() const
|
|
165
|
+
{
|
|
166
|
+
int v[N];
|
|
167
|
+
for (int i = 0; i < N; i++) v[i] = base[i]->Jisu();
|
|
168
|
+
return Int(N, v, 0);
|
|
169
|
+
}
|
|
170
|
+
Int Shuki() const
|
|
171
|
+
{
|
|
172
|
+
int v[N];
|
|
173
|
+
for (int i = 0; i < N; i++) v[i] = base[i]->Shuki();
|
|
174
|
+
return Int(N, v, 0);
|
|
175
|
+
}
|
|
176
|
+
size_t *Maxq() const
|
|
177
|
+
{
|
|
178
|
+
size_t *vp = new size_t[N];
|
|
179
|
+
for (int i = 0; i < N; i++) vp[i] = base[i]->Maxq();
|
|
180
|
+
return vp;
|
|
181
|
+
}
|
|
182
|
+
// end poly_spline
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
/*******************************************************************************
|
|
186
|
+
N変数K次元パラメトリック & リーゼンフェルト スプライン補間
|
|
187
|
+
int N : number of parameters (Grid)
|
|
188
|
+
typename S : poly<S,N> = (s, t, u, ...)
|
|
189
|
+
int K : number of axis (Atom)
|
|
190
|
+
typename T : poly<T,K> = (x, y, z, ...)
|
|
191
|
+
--------------------------------------------------------------------------------
|
|
192
|
+
パラメトリックスプライン (曲面補間) s = {0,...}
|
|
193
|
+
パラメトリック周期スプライン (閉曲面補間)s = {1,...}
|
|
194
|
+
リーゼンフェルトスプライン (曲面補間) s = {2,...}
|
|
195
|
+
リーゼンフェルト周期スプライン(閉曲面補間)s = {3,...}
|
|
196
|
+
*******************************************************************************/
|
|
197
|
+
template <typename T, typename S = double>
|
|
198
|
+
class pspline : public poly_spline<S>
|
|
199
|
+
{
|
|
200
|
+
|
|
201
|
+
int K; T *clp;
|
|
202
|
+
|
|
203
|
+
public:
|
|
204
|
+
// constructor
|
|
205
|
+
pspline():clp(NULL){}
|
|
206
|
+
pspline(const poly_array<T>&, const comb_array<S>&, const Int&, const Int&);
|
|
207
|
+
pspline(const pspline&);
|
|
208
|
+
// destructor
|
|
209
|
+
~pspline() { delete[] clp; }
|
|
210
|
+
// operator
|
|
211
|
+
pspline& operator=(const pspline&);
|
|
212
|
+
poly_array<T> operator[](const poly<S>& p) const {return (*this)(p);}
|
|
213
|
+
poly_array<T> operator()(const poly<S>&, const int* = NULL) const;
|
|
214
|
+
poly_array<T> operator()(const poly<S>&, int, T*) const;
|
|
215
|
+
poly_array<T> sekibun(const poly<S>&) const;
|
|
216
|
+
int Unit_size() const {return K;}
|
|
217
|
+
operator T* () const {return clp;}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
template <typename T, typename S>
|
|
221
|
+
pspline<T,S>::pspline(const poly_array<T>& p, const comb_array<S>& x, const Int& j, const Int& s)
|
|
222
|
+
: poly_spline<S>(x, Int(p), j, s), K(p.unit_size())
|
|
223
|
+
{
|
|
224
|
+
Int a = poly_spline<S>::values->imax;
|
|
225
|
+
Int c = poly_spline<S>::values->icox;
|
|
226
|
+
T *alp = clp = new T[c.data_size()];
|
|
227
|
+
poly_view<T> alv(alp, a), clv(clp, c);
|
|
228
|
+
if (s < 2) {
|
|
229
|
+
marray<S> bd = poly_spline<S>::gyoretu(a, x);
|
|
230
|
+
marray_lu_view<S> lu(bd);
|
|
231
|
+
lu.solve((T*)p, alp, K);
|
|
232
|
+
} else
|
|
233
|
+
memcpy(alp, (T*)p, p.data_size() * sizeof(T));
|
|
234
|
+
clv = alv;
|
|
235
|
+
}
|
|
236
|
+
// copy constructor
|
|
237
|
+
template <typename T, typename S>
|
|
238
|
+
pspline<T,S>::pspline(const pspline& ps) : poly_spline<S>(ps), K(ps.K)
|
|
239
|
+
{
|
|
240
|
+
Int c = poly_spline<S>::icox;
|
|
241
|
+
int len = c.data_size();
|
|
242
|
+
clp = new T[len];
|
|
243
|
+
memcpy(clp, (T*)ps, len * sizeof(T));
|
|
244
|
+
}
|
|
245
|
+
// substitution operator
|
|
246
|
+
template <typename T, typename S>
|
|
247
|
+
pspline<T,S>& pspline<T,S>::operator=(const pspline& ps)
|
|
248
|
+
{
|
|
249
|
+
if (this != &ps) {
|
|
250
|
+
delete clp;
|
|
251
|
+
poly_spline<S>::operator=(ps); K = ps.K;
|
|
252
|
+
Int c = poly_spline<S>::icox;
|
|
253
|
+
int len = c.data_size();
|
|
254
|
+
clp = new T[len];
|
|
255
|
+
memcpy(clp, (T*)ps, len * sizeof(T));
|
|
256
|
+
}
|
|
257
|
+
return *this;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
template <typename T, typename S>
|
|
261
|
+
poly_array<T> pspline<T,S>::operator()(const poly<S>& t, const int *jb) const
|
|
262
|
+
{
|
|
263
|
+
if (jb) {
|
|
264
|
+
Int jbn(t.grid(), jb, 0);
|
|
265
|
+
if (!(poly_spline<S>::values->jisu >= jbn))
|
|
266
|
+
throw "out of range, pspline()";
|
|
267
|
+
}
|
|
268
|
+
T result[K]; for (int i = 0; i < K; ++i) result[i] = 0;
|
|
269
|
+
poly_view<T> res(result, K);
|
|
270
|
+
comp_array<S> pc = poly_spline<S>::basis(t, jb);
|
|
271
|
+
Int& c = poly_spline<S>::values->icox;
|
|
272
|
+
poly_view<T> clv(clp, c);
|
|
273
|
+
Int offset = pc.offset(), size = pc.size();
|
|
274
|
+
int s = size.grid_size();
|
|
275
|
+
for (int i = 0; i < s; ++i)
|
|
276
|
+
{
|
|
277
|
+
Int k = i % size, l = k + offset;
|
|
278
|
+
res += clv[l] * pc[k = 1][0];
|
|
279
|
+
}
|
|
280
|
+
return poly_array<T>(result, K);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
template <typename T, typename S>
|
|
284
|
+
poly_array<T> pspline<T,S>::operator()(const poly<S>& t, int jbn, T *ds) const
|
|
285
|
+
{
|
|
286
|
+
if (!(poly_spline<S>::values->jisu >= jbn))
|
|
287
|
+
throw "out of range, pspline()";
|
|
288
|
+
T result[K]; for (int i = 0; i < K; ++i) result[i] = 0;
|
|
289
|
+
poly_view<T> res(result, K);
|
|
290
|
+
comp_array<S> pc = poly_spline<S>::bases(t, jbn);
|
|
291
|
+
Int& c = poly_spline<S>::values->icox;
|
|
292
|
+
poly_view<T> clv(clp, c);
|
|
293
|
+
Int offset = pc.offset(), size = pc.size();
|
|
294
|
+
int s = size.grid_size();
|
|
295
|
+
for (int i = 0; i < s; ++i)
|
|
296
|
+
{
|
|
297
|
+
Int k = i % size, l = k + offset;
|
|
298
|
+
res += clv[l] * pc[k = jbn + 1][ds];
|
|
299
|
+
}
|
|
300
|
+
return poly_array<T>(result, K);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
template <typename T, typename S>
|
|
304
|
+
poly_array<T> pspline<T,S>::sekibun(const poly<S>& t) const
|
|
305
|
+
{
|
|
306
|
+
const Int& c = poly_spline<S>::values->icox;
|
|
307
|
+
const Int& j = poly_spline<S>::values->jisu;
|
|
308
|
+
Int n = poly_spline<S>::Kset(t) - j + 1;
|
|
309
|
+
int Imax = n.grid_size();
|
|
310
|
+
poly_view<T> clw(clp, c);
|
|
311
|
+
int a = c.unit_size();
|
|
312
|
+
T result[a]; for (int i = 0; i < a; i++) result[i] = 0;
|
|
313
|
+
poly_view<T> R(result, a);
|
|
314
|
+
for (int i = 0; i < Imax; ++i) {
|
|
315
|
+
Int h = i % n + j;
|
|
316
|
+
poly_spline<S>::sekibun(R, clw, h, t);
|
|
317
|
+
}
|
|
318
|
+
return poly_array<T>(result, a);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// 1変数N次元パラメトリックスプライン
|
|
322
|
+
typedef pspline<double,double> Pspline;
|
|
323
|
+
// 1変数N次元パラメトリックスプライン
|
|
324
|
+
typedef pspline<double,double> Pspline2;
|
|
325
|
+
|
|
326
|
+
/*******************************************************************************
|
|
327
|
+
1変数多次元パラメトリックスプライン
|
|
328
|
+
*******************************************************************************/
|
|
329
|
+
template <class T = double, class S = T> class bspline : public base_spline<S>
|
|
330
|
+
{
|
|
331
|
+
int K; T *clp;
|
|
332
|
+
|
|
333
|
+
public:
|
|
334
|
+
// constructor
|
|
335
|
+
bspline(const poly_array<T>&, int, S*, int, int = 0, int* = NULL);
|
|
336
|
+
bspline(const bspline&);
|
|
337
|
+
// destructor
|
|
338
|
+
~bspline() { delete clp; }
|
|
339
|
+
// operator
|
|
340
|
+
bspline& operator=(const bspline&);
|
|
341
|
+
poly_array<T> operator[](S t) const {return (*this)(t);}
|
|
342
|
+
poly_array<T> operator()(S, int = 0) const;
|
|
343
|
+
poly_array<T> sekibun(S) const;
|
|
344
|
+
T line_element(S) const;
|
|
345
|
+
bspline *line_integral(T(*)(poly_array<S>&), int, S*, S = 0, T = 0) const;
|
|
346
|
+
int Unit_size() const {return K;}
|
|
347
|
+
operator T* () const {return clp;}
|
|
348
|
+
};
|
|
349
|
+
/*******************************************************************************
|
|
350
|
+
1変数パラメトリックスプライン コンストラクタ
|
|
351
|
+
--------------------------------------------------------------------------------
|
|
352
|
+
パラメトリックスプライン (曲線補間) s = 0
|
|
353
|
+
パラメトリック周期スプライン (閉曲線補間)s = 1
|
|
354
|
+
リーゼンフェルトスプライン (曲線補間) s = 2
|
|
355
|
+
リーゼンフェルト周期スプライン(閉曲線補間)s = 3
|
|
356
|
+
*******************************************************************************/
|
|
357
|
+
template <class T, class S>
|
|
358
|
+
bspline<T,S>::bspline(
|
|
359
|
+
const poly_array<T>& p, // Vector Array<1>, [P0,...,Pn-1];
|
|
360
|
+
int n, S* x, // Variables, [X0,...,Xn-1];
|
|
361
|
+
int j, // Dimension
|
|
362
|
+
int s, // Type parameter
|
|
363
|
+
int *d // Differential rank, [D0,...,Dn-1];
|
|
364
|
+
)
|
|
365
|
+
: base_spline<S>(n, x, j, p(0) - n - (s%2)), K(p.unit_size())
|
|
366
|
+
{
|
|
367
|
+
int a = base_spline<S>::imax;
|
|
368
|
+
int c = base_spline<S>::icox;
|
|
369
|
+
T *alp = clp = new T[c * K];
|
|
370
|
+
if (s < 2) {
|
|
371
|
+
marray<S> bd(a, a);
|
|
372
|
+
base_spline<S>::gyoretu((S**)bd, a, x, d); //係数行列を作成
|
|
373
|
+
marray_lu_view<S> lu(bd);
|
|
374
|
+
lu.solve((T*)p, alp, K);
|
|
375
|
+
} else
|
|
376
|
+
memcpy(alp, (T*)p, a * K * sizeof(T));
|
|
377
|
+
poly_view<T> alv(alp, Colon, a, K);
|
|
378
|
+
poly_view<T> clv(clp, Colon, c, K);
|
|
379
|
+
clv = alv;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
template <class T, class S>
|
|
383
|
+
bspline<T,S>::bspline(const bspline& s) : base_spline<S>(s)
|
|
384
|
+
{
|
|
385
|
+
int c = base_spline<S>::icox;
|
|
386
|
+
clp = new T[c];
|
|
387
|
+
memcpy(clp, s, c * sizeof(T));
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
template <class T, class S>
|
|
391
|
+
bspline<T,S>& bspline<T,S>::operator=(const bspline& s)
|
|
392
|
+
{
|
|
393
|
+
if (this != &s) {
|
|
394
|
+
base_spline<S>::operator=(s);
|
|
395
|
+
delete clp;
|
|
396
|
+
int c = base_spline<S>::icox;
|
|
397
|
+
clp = new T[c];
|
|
398
|
+
memcpy(clp, s, c * sizeof(T));
|
|
399
|
+
}
|
|
400
|
+
return *this;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
template <typename T, typename S>
|
|
404
|
+
void sekibun(const bspline<T,S>& p, S t, const poly_view<T>& alp, int Jsk, poly_view<T>& sek)
|
|
405
|
+
{
|
|
406
|
+
const base_spline<S>& base = p;
|
|
407
|
+
const Int& size = alp;
|
|
408
|
+
int ks, kset, k = base.Rank() + Jsk;
|
|
409
|
+
S b[k], *q = base.Knots();
|
|
410
|
+
ks = deboor<S>(base.Rank(), q, base.Icox(), t, b, kset, k);
|
|
411
|
+
poly_view<T> *a[2], *w = new poly_view<T>[2*(kset+1)];
|
|
412
|
+
a[0] = w; a[1] = &w[kset+1];
|
|
413
|
+
for (int i = 0; i <= kset; ++i) {
|
|
414
|
+
Int k = i % size;
|
|
415
|
+
a[Jsk%2][i] = alp[k]; a[(Jsk+1)%2][i] = sek;
|
|
416
|
+
}
|
|
417
|
+
while (Jsk) {
|
|
418
|
+
poly_view<T> *a0 = a[Jsk%2], *a1 = a[(Jsk+1)%2];
|
|
419
|
+
for (int i = 0; i <= kset; ++i) {
|
|
420
|
+
if (i == 0) a1[i] = 0.0;
|
|
421
|
+
else a1[i] = a1[i-1];
|
|
422
|
+
a1[i] += a0[i] * ((q[i+(k-Jsk)] - q[i]) / S(k-Jsk));
|
|
423
|
+
}
|
|
424
|
+
Jsk--;
|
|
425
|
+
}
|
|
426
|
+
for (int i = ks > 0 ? ks : 0; i <= kset; ++i)
|
|
427
|
+
sek += a[0][i] * b[i-ks];
|
|
428
|
+
delete[] w;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
//
|
|
432
|
+
// 1変数パラメトリックスプライン関数値の計算(曲線補間)
|
|
433
|
+
//
|
|
434
|
+
|
|
435
|
+
template <class T, class S>
|
|
436
|
+
poly_array<T> bspline<T,S>::operator()(S t, int b) const
|
|
437
|
+
{
|
|
438
|
+
if (b > base_spline<S>::jisu)
|
|
439
|
+
throw "out of range, bspline value";
|
|
440
|
+
T result[K]; for (int i = 0; i < K; ++i) result[i] = 0;
|
|
441
|
+
poly_view<T> res(result, size_t(K));
|
|
442
|
+
Int c(Colon, base_spline<S>::icox, K);
|
|
443
|
+
poly_view<T> clv(clp, c);
|
|
444
|
+
if (b >= 0) {
|
|
445
|
+
parray<S> bc = base_spline<S>::basis(t, b);
|
|
446
|
+
Int offset(1, bc(0), 0), size(1, bc(1), 0);
|
|
447
|
+
int s = size.grid_size();
|
|
448
|
+
for (int i = 0; i < s; ++i)
|
|
449
|
+
{
|
|
450
|
+
Int k = i % size, l = k + offset;
|
|
451
|
+
res += clv[l] * bc[0][i];
|
|
452
|
+
}
|
|
453
|
+
} else ::sekibun<T,S>(*this, t, clv, -b, res);
|
|
454
|
+
return poly_array<T>(result, K);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
template <class T, class S>
|
|
458
|
+
poly_array<T> bspline<T,S>::sekibun(S t) const
|
|
459
|
+
{
|
|
460
|
+
T result[K]; for (int i = 0; i < K; ++i) result[i] = 0.0;
|
|
461
|
+
base_spline<S>::sekibun(t, clp, K, result);
|
|
462
|
+
return poly_array<T>(result, K);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
template <class T, class S>
|
|
466
|
+
T bspline<T,S>::line_element(S t) const
|
|
467
|
+
{
|
|
468
|
+
poly_array<T> r = (*this)(t, 1);
|
|
469
|
+
T s = 0;
|
|
470
|
+
for (int i = 0; i < K; ++i) s += r[i] * r[i];
|
|
471
|
+
return sqrt(s);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
template <class T, class S>
|
|
475
|
+
bspline<T,S> *bspline<T,S>::line_integral(T(*F)(poly_array<S>&), int n, S *u, S x, T y) const
|
|
476
|
+
{
|
|
477
|
+
int N = n+1, D[N]; S X[N]; T Y[N];
|
|
478
|
+
for (int i = 0; i < n; i++) D[i] = 1; D[n] = 0;
|
|
479
|
+
for (int i = 0; i < n; i++) {
|
|
480
|
+
poly_array<S> U = (*this)[u[i]];
|
|
481
|
+
X[i] = u[i];
|
|
482
|
+
Y[i] = F(U) * this->line_element(u[i]);
|
|
483
|
+
} X[n] = x;
|
|
484
|
+
Y[n] = y;
|
|
485
|
+
poly_array<T> Ya(Y, 1, N, 1);
|
|
486
|
+
return new bspline<T,S>(Ya, n, X, base_spline<S>::jisu, 0, D);
|
|
487
|
+
}
|
|
488
|
+
//
|
|
489
|
+
// misc
|
|
490
|
+
//
|
|
491
|
+
template <class T, class S = double>
|
|
492
|
+
int plot(const pspline<T,S>&, const comb_array<S>&, S**, T**, int, const int* = NULL);
|
|
493
|
+
|
|
494
|
+
template <class T, class S = double>
|
|
495
|
+
int plot(const pspline<T,S>&, const comb_array<S>&, S**, T**, int, int, S*);
|
|
496
|
+
|
|
497
|
+
template <class T, class S = double>
|
|
498
|
+
int plot(const pspline<T,S>&, int, S*, S**, T**, int, int = 0);
|
|
499
|
+
|
|
500
|
+
template <class T, class S = double>
|
|
501
|
+
int plot(const bspline<T,S>&, const comb_array<S>&, S**, T**, int, int = 0);
|
|
502
|
+
|
|
503
|
+
template <class T, class S = double>
|
|
504
|
+
int plot(const bspline<T,S>&, int, S*, S**, T**, int, int = 0);
|
|
505
|
+
|
|
506
|
+
#endif
|