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,210 @@
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
@@ -0,0 +1,656 @@
1
+ #ifndef _UTIL_H_INCLUDED_
2
+ #define _UTIL_H_INCLUDED_
3
+
4
+ #include <complex.h>
5
+
6
+ // T配列 [T0,...,Ti-1] : T*
7
+ #define T_ALLOC(T,i) (T*)malloc((i)*sizeof(T))
8
+ // T行列 [[T00,...],...] : T**
9
+ #define T_MALLOC(T,i,j) create_marray<T>((i),(j))
10
+ // destructor
11
+ #define FREE(m) free((char*)(m))
12
+
13
+ template <typename T> inline
14
+ T pow(T a, int n)
15
+ {
16
+ return n == 0 ? 1 : a * pow(a, n-1);
17
+ }
18
+
19
+ template <typename T> T coeff(T**, const int*, int, int = 0);
20
+ template <typename T> T total_derive(T**, const int*, int, int, const T*);
21
+
22
+ /*******************************************************************************
23
+ define print utility.
24
+ *******************************************************************************/
25
+ template <class T> inline int sprintg(char* &c, T o);
26
+
27
+ template <> inline int sprintg(char* &c, int a) {return sprintf(c, "%d", a);}
28
+ template <> inline int sprintg(char* &c, size_t a) {return sprintf(c, "%ld",a);}
29
+ template <> inline int sprintg(char* &c, double a) {return sprintf(c, "%g", a);}
30
+
31
+ template <class T> inline double gabs(T o);
32
+
33
+ template <> inline double gabs(double a) {return fabs(a);}
34
+ template <> inline double gabs(std::complex<double> c) {return abs(c);}
35
+
36
+ template <typename T> void poly_to_s(char* &c, int N, const int *size, const T *data)
37
+ {
38
+ int n = *size;
39
+ if (N == 0) {
40
+ if (n > 1) sprintf(c, "("); while(*c)++c;
41
+ for (int i = 0; i < n; ++i) {
42
+ sprintg<T>(c, data[i]); while(*c)++c;
43
+ if (i < n-1) sprintf(c, ","); while(*c)++c;
44
+ }
45
+ if (n > 1) sprintf(c, ")"); while(*c)++c;
46
+ }
47
+ else {
48
+ sprintf(c, "["); while(*c)++c;
49
+ int m = 1; for (int i = 1; i <= N; ++i) m *= size[i];
50
+ for (int i = 0; i < n; ++i) {
51
+ poly_to_s(c, N-1, size+1, &data[i*m]);
52
+ if (i < n-1) sprintf(c, ","); while(*c)++c;
53
+ }
54
+ sprintf(c, "]"); while(*c)++c;
55
+ }
56
+ }
57
+
58
+ /*******************************************************************************
59
+ Matrix operation
60
+ *******************************************************************************/
61
+ template <class T>
62
+ void luc_decomp(T *, size_t, size_t*, int&);
63
+
64
+ template <class T>
65
+ void lud_decomp(T *, size_t, size_t*, int&);
66
+
67
+ template <class T>
68
+ void luc_decomp(T**, size_t, size_t*, int&);
69
+
70
+ template <class T>
71
+ void lud_decomp(T**, size_t, size_t*, int&);
72
+
73
+ template <class T, class S = T>
74
+ void luc_subst(T *, size_t, size_t*, S*);
75
+
76
+ template <class T, class S = T>
77
+ void lud_subst(T *, size_t, size_t*, S*);
78
+
79
+ template <class T, class S = T>
80
+ void luc_subst(T**, size_t, size_t*, S*);
81
+
82
+ template <class T, class S = T>
83
+ void lud_subst(T**, size_t, size_t*, S*);
84
+
85
+ template <class T, class S = T>
86
+ void luc_subst(T *, size_t, size_t*, S*, int);
87
+
88
+ template <class T, class S = T>
89
+ void lud_subst(T *, size_t, size_t*, S*, int);
90
+
91
+ template <class T, class S = T>
92
+ void luc_subst(T**, size_t, size_t*, S*, int);
93
+
94
+ template <class T, class S = T>
95
+ void lud_subst(T**, size_t, size_t*, S*, int);
96
+
97
+ template <class T> T luc_solve(T * a, size_t n, T * b, int K = 1)
98
+ {
99
+ size_t *p = new size_t[n];
100
+ int s; luc_decomp(a, n, p, s);
101
+ if (K>1) luc_subst(a, n, p, b, K); else luc_subst(a, n, p, b);
102
+ T det = s;
103
+ for (size_t k = 0; k < n; ++k) det *= a[k*n+k];
104
+ delete[] p;
105
+ return det;
106
+ }
107
+
108
+ template <class T> T luc_solve(T ** a, size_t n, T * b, int K = 1)
109
+ {
110
+ size_t *p = new size_t[n];
111
+ int s; luc_decomp(a, n, p, s);
112
+ if (K>1) luc_subst(a, n, p, b, K); else luc_subst(a, n, p, b);
113
+ T det = s;
114
+ for (size_t k=0;k<n;++k) det *= a[k][k];
115
+ delete[] p;
116
+ return det;
117
+ }
118
+
119
+ template <class T> T lud_solve(T * a, size_t n, T * b, int K = 1)
120
+ {
121
+ size_t *p = new size_t[n];
122
+ int s; lud_decomp(a, n, p, s);
123
+ if (K>1) lud_subst(a, n, p, b, K); else lud_subst(a, n, p, b);
124
+ T det = s;
125
+ for (size_t k = 0; k < n; ++k) det *= a[k*n+k];
126
+ delete[] p;
127
+ return det;
128
+ }
129
+
130
+ template <class T> T lud_solve(T ** a, size_t n, T * b, int K = 1)
131
+ {
132
+ size_t *p = new size_t[n];
133
+ int s; lud_decomp(a, n, p, s);
134
+ if (K>1) lud_subst(a, n, p, b, K); else lud_subst(a, n, p, b);
135
+ T det = s;
136
+ for (size_t k = 0; k < n; ++k) det *= a[k][k];
137
+ delete[] p;
138
+ return det;
139
+ }
140
+
141
+ #define lu_decomp lud_decomp
142
+ #define lu_subst lud_subst
143
+ #define lu_solve lud_solve
144
+
145
+ template <class T>
146
+ T ** marray_alloc(char *mm, int nr, size_t sr, size_t sc)
147
+ {
148
+ T **m = (T **)mm;
149
+ m[0] = (T *)(mm = mm + sr);
150
+ for (int i = 1; i < nr; ++i) m[i] = (T *)(mm = mm + sc);
151
+ return m;
152
+ }
153
+
154
+ template <typename T>
155
+ T ** create_marray(int nr, int nc)
156
+ {
157
+ size_t sr = nr * sizeof(T *);
158
+ size_t sc = nc * sizeof(T);
159
+ char * mm = (char *)malloc(sr + nr * sc);
160
+ if (mm == NULL) throw "allocate error, create_marray";
161
+ return marray_alloc<T>(mm, nr, sr, sc);
162
+ }
163
+
164
+ template <typename T>
165
+ T ** marray_view_alloc(T **m, int nr, int nc, T *v)
166
+ {
167
+ m[0] = v;
168
+ for (int i = 1; i < nr; i++) m[i] = m[i-1] + nc;
169
+ m[nr] = v;
170
+ return m;
171
+ }
172
+
173
+ template <typename T>
174
+ T ** create_marray_view(int nr, int nc, T *v)
175
+ {
176
+ T **m = (T**)malloc((nr+1) * sizeof(T*));
177
+ return marray_view_alloc(m, nr, nc, v);
178
+ }
179
+
180
+ template <typename T>
181
+ T ** carray_alloc(char *mm, size_t sr, size_t n, size_t *s)
182
+ {
183
+ T **m = (T**)mm;
184
+ m[0] = (T*)(mm = mm + sr);
185
+ for (size_t i = 1; i < n; ++i) m[i] = (T*)(mm = mm + s[i-1] * sizeof(T));
186
+ return m;
187
+ }
188
+
189
+ template <typename T>
190
+ T ** create_carray(size_t n, size_t *s)
191
+ {
192
+ size_t c = 0;
193
+ for (size_t i = 0; i < n; ++i) c += s[i];
194
+ size_t sr = n * sizeof(T *);
195
+ size_t sc = c * sizeof(T);
196
+ char * mm = (char *)malloc(sr + sc);
197
+ if (mm == NULL) throw "allocate error, create_carray";
198
+ return carray_alloc<T>(mm, sr, n, s);
199
+ }
200
+
201
+ template <typename T>
202
+ T ** carray_view_alloc(T **m, size_t n, size_t *s, T *a)
203
+ {
204
+ m[0] = a;
205
+ for (size_t i = 1; i < n; ++i) m[i] = m[i-1] + s[i-1];
206
+ m[n] = a;
207
+ return m;
208
+ }
209
+
210
+ template <typename T>
211
+ T ** create_carray_view(size_t n, size_t *s, T *a)
212
+ {
213
+ T **m = (T**)malloc((n+1) * sizeof(T*));
214
+ return a == NULL ? m : carray_view_alloc<T>(m, n, s, a);
215
+ }
216
+
217
+ template <typename T> class varray
218
+ {
219
+ T *data; int s;
220
+ public:
221
+ varray(int n) : s(n)
222
+ {
223
+ data = (T*)malloc(s * sizeof(T));
224
+ }
225
+ varray(const varray& v) : s(v.s)
226
+ {
227
+ data = (T*)malloc(s * sizeof(T));
228
+ memcpy(data, v.data, s * sizeof(T));
229
+ }
230
+ ~varray() { free((void*)data); }
231
+ varray& operator = (const varray& v)
232
+ {
233
+ if (this != &v) {
234
+ free((void*)data);
235
+ s = v.s;
236
+ data = (T*)malloc(s * sizeof(T));
237
+ memcpy(data, v.data, s * sizeof(T));
238
+ }
239
+ return *this;
240
+ }
241
+ operator T* () { return data; }
242
+ T operator * () { return *data; }
243
+ T & operator [] (int i) { return data[i]; }
244
+ int size() const { return s; }
245
+ };
246
+
247
+ template <typename T> class varray_view
248
+ {
249
+ T *data; int s, t;
250
+ public:
251
+ varray_view(T *v, int n, int st = 1) : data(v), s(n), t(st) {}
252
+ ~varray_view() {}
253
+ varray_view& operator = (const varray_view& v)
254
+ {
255
+ if (this != &v) {
256
+ assert(s >= v.s);
257
+ if (s > v.s)
258
+ {
259
+ int i, j, k(s - v.s), m((k + 1) / 2), o(k - m);
260
+ for (i=m-1, k=s-m;i>=0;--i) { j=i+k; data[j*t] = v.data[i*v.t]; }
261
+ for (i=v.s-1,k=o; i>=0;--i) { j=i+k; data[j*t] = v.data[i*v.t]; }
262
+ for (i=o-1, k=v.s;i>=0;--i) { j=i+k; data[i*t] = data[j*t]; }
263
+ }
264
+ else if (data != v.data)
265
+ for (int i = 0; i < s; ++i) data[i*t] = v.data[i*v.t];
266
+ }
267
+ return *this;
268
+ }
269
+ operator T* () { return data; }
270
+ T operator * () { return *data; }
271
+ T & operator [] (int i) const { return data[i*t]; }
272
+ int size() const { return s; }
273
+ };
274
+
275
+ template <typename T> class marray
276
+ {
277
+ T **index; int r, c;
278
+ public:
279
+ marray(int nr, int nc) : r(nr), c(nc)
280
+ {
281
+ index = create_marray<T>(nr, nc);
282
+ }
283
+ marray(const marray& m) : r(m.r), c(m.c)
284
+ {
285
+ index = create_marray<T>(r, c);
286
+ memcpy(*index, *m, r * c * sizeof(T));
287
+ }
288
+ ~marray() { free((void*)index); }
289
+ marray& operator = (const marray& m)
290
+ {
291
+ if (this != &m) {
292
+ free((void*)index);
293
+ r = m.r; c = m.c;
294
+ index = create_marray<T>(r, c);
295
+ memcpy(*index, *m, r * c * sizeof(T));
296
+ }
297
+ return *this;
298
+ }
299
+ operator T** () const { return index; }
300
+ T * operator * () const { return (T*)(index + r); }
301
+ T * operator [] (int i) { return index[i]; }
302
+ void swap(int i, int j) { T *w = index[i]; index[i] = index[j]; index[j] = w; }
303
+ int rows() const { return r; }
304
+ int cols() const { return c; }
305
+ varray_view<T> row(int i) const { return varray_view<T>(index[i], c); }
306
+ varray_view<T> col(int i) const { return varray_view<T>((T*)(index + r) + i, r, c); }
307
+ };
308
+
309
+ template <typename T> class marray_view
310
+ {
311
+ T **index; int r, c;
312
+ public:
313
+ marray_view(T *m, int nr, int nc) : r(nr), c(nc)
314
+ {
315
+ index = create_marray_view<T>(r, c, m);
316
+ }
317
+ marray_view(const marray<T>& m) : r(m.rows()), c(m.cols())
318
+ {
319
+ index = create_marray_view<T>(r, c, *m);
320
+ }
321
+ marray_view(const marray_view& m) : r(m.r), c(m.c)
322
+ {
323
+ index = create_marray_view<T>(r, c, *m);
324
+ }
325
+ ~marray_view() { free((void*)index); }
326
+ marray_view& operator = (const marray_view& m)
327
+ {
328
+ if (this != &m) {
329
+ free((void*)index);
330
+ r = m.r; c = m.c;
331
+ index = create_marray_view<T>(r, c, *m);
332
+ }
333
+ return *this;
334
+ }
335
+ operator T** () { return index; }
336
+ T * operator * () { return index[r]; }
337
+ T * operator [] (int i) const { return index[i]; }
338
+ void swap(int i, int j) { T *w = index[i]; index[i] = index[j]; index[j] = w; }
339
+ int rows() const { return r; }
340
+ int cols() const { return c; }
341
+ varray_view<T> row(int i) const { return varray_view<T>(index[i], c); }
342
+ varray_view<T> col(int i) const { return varray_view<T>(index[r] + i, r, c); }
343
+ };
344
+
345
+ template <typename T> class marray_lu
346
+ {
347
+ int n;
348
+ T ** m;
349
+ size_t *p;
350
+ int s;
351
+ public:
352
+ marray_lu(int N, const T *dat) : n(N) {
353
+ m = create_marray<T>(N, N);
354
+ p = (size_t*)malloc(N * sizeof(size_t));
355
+ memcpy((T*)(m+n), dat, n * n * sizeof(T));
356
+ lu_decomp<T>(m, size_t(N), p, s);
357
+ }
358
+ marray_lu(const marray_lu& lu) : n(lu.n) {
359
+ m = create_marray<T>(n, n);
360
+ p = (size_t*)malloc(n * sizeof(size_t));
361
+ memcpy((T*)(m+n), *lu, n * n * sizeof(T));
362
+ memcpy(p, lu.p, n * sizeof(size_t));
363
+ s = lu.s;
364
+ }
365
+ ~marray_lu() { FREE(p); FREE(m); }
366
+ marray_lu& operator= (const marray_lu& lu) {
367
+ if (this != &lu) {
368
+ FREE(p); FREE(m);
369
+ n = lu.n;
370
+ m = create_marray<T>(n, n);
371
+ p = (size_t*)malloc(n * sizeof(size_t));
372
+ memcpy((T*)(m+n), *lu, n * n * sizeof(T));
373
+ memcpy(p, lu.p, n * sizeof(size_t));
374
+ s = lu.s;
375
+ }
376
+ return *this;
377
+ }
378
+ T * operator[](int i) { return m[i]; }
379
+ T * operator * () { return (T*)(m + n); }
380
+ template <class S>
381
+ void solve(S * b, S * x, int K = 1) {
382
+ for (int i = 0; i < n*K; ++i) x[i] = b[i];
383
+ if (K > 1)
384
+ lu_subst<T,S>(m, size_t(n), p, x, K);
385
+ else
386
+ lu_subst<T,S>(m, size_t(n), p, x);
387
+ }
388
+ template <class S>
389
+ S *solve(S *b, int K = 1) {
390
+ S *result = new S[n*K];
391
+ for (int i = 0; i < n*K; ++i) result[i] = b[i];
392
+ if (K > 1)
393
+ lu_subst<T,S>(m, size_t(n), p, result, K);
394
+ else
395
+ lu_subst<T,S>(m, size_t(n), p, result);
396
+ return result;
397
+ }
398
+ // end of marray_lu;
399
+ };
400
+
401
+ template <typename T>
402
+ class marray_lu_view
403
+ {
404
+ int n;
405
+ T ** m;
406
+ int s;
407
+ size_t *p;
408
+ public:
409
+ marray_lu_view(int N, T *dat) : n(N) {
410
+ m = create_marray_view<T>(n, n, dat);
411
+ p = (size_t*)malloc(n * sizeof(size_t));
412
+ lu_decomp<T>(m, size_t(n), p, s);
413
+ }
414
+ marray_lu_view(const marray<T>& mm) : n(mm.rows()) {
415
+ m = create_marray_view<T>(n, n, *mm);
416
+ p = (size_t*)malloc(n * sizeof(size_t));
417
+ lu_decomp<T>(m, size_t(n), p, s);
418
+ }
419
+ marray_lu_view(const marray_lu<T>& lu) : n(lu.n) {
420
+ m = create_marray_view<T>(n, n, *lu);
421
+ p = (size_t*)malloc(n * sizeof(size_t));
422
+ memcpy(p, lu.p, n * sizeof(size_t));
423
+ s = lu.s;
424
+ }
425
+ marray_lu_view(const marray_lu_view& lu) : n(lu.n) {
426
+ m = create_marray_view<T>(n, n, *lu);
427
+ p = (size_t*)malloc(n * sizeof(size_t));
428
+ memcpy(p, lu.p, n * sizeof(size_t));
429
+ s = lu.s;
430
+ }
431
+ ~marray_lu_view() { FREE(p); FREE(m); }
432
+ marray_lu_view& operator= (const marray_lu_view& lu) {
433
+ if (this != &lu) {
434
+ FREE(p); FREE(m);
435
+ n = lu.n;
436
+ m = create_marray_view(n, n, *lu);
437
+ p = (size_t*)malloc(n * sizeof(size_t));
438
+ memcpy(p, lu.p, n * sizeof(size_t));
439
+ s = lu.s;
440
+ }
441
+ return *this;
442
+ }
443
+ T * operator[](int i) { return m[i]; }
444
+ T * operator * () { return m[n]; }
445
+ template <class S>
446
+ void solve(S * b, S * x, int K = 1) {
447
+ for (int i = 0; i < n*K; ++i)
448
+ x[i] = b[i];
449
+ if (K > 1)
450
+ lu_subst<T,S>(m, n, p, x, K);
451
+ else
452
+ lu_subst<T,S>(m, n, p, x);
453
+ }
454
+ template <class S>
455
+ S *solve(S *b, int K = 1) {
456
+ S *result = new S[n*K];
457
+ for (int i = 0; i < n*K; ++i)
458
+ result[i] = b[i];
459
+ if (K > 1)
460
+ lu_subst<T,S>(m, n, p, result, K);
461
+ else
462
+ lu_subst<T,S>(m, n, p, result);
463
+ return result;
464
+ }
465
+ // end of marray_lu_view;
466
+ };
467
+
468
+ template <typename T>
469
+ void kronecker(const varray_view<T>& p, const varray_view<T>& q, const varray_view<T>& r)
470
+ {
471
+ int s = p.size(), t = q.size();
472
+ for (int i = 0; i < s; i++)
473
+ for (int j = 0; j < t; j++)
474
+ r[i*t+j] = p[i] * q[j];
475
+ }
476
+
477
+ template <typename T>
478
+ void kronecker(const marray<T>& p, const marray<T>& q, const marray<T>& r)
479
+ {
480
+ int s = p.rows(), t = q.rows();
481
+ for (int i = 0; i < s; i++)
482
+ for (int j = 0; j < t; j++)
483
+ kronecker(p.row(i), q.row(j), r.row(i*t+j));
484
+ }
485
+
486
+ template <typename T>
487
+ marray<T> operator^(const marray<T>& p, const marray<T>& q)
488
+ {
489
+ int r = p.rows() * q.rows(), c = p.cols() * q.cols();
490
+ marray<T> result(r, c);
491
+ kronecker(p, q, result);
492
+ return result;
493
+ }
494
+
495
+ template <typename T> class carray
496
+ {
497
+ size_t n, *s; T **data;
498
+ public:
499
+ carray(size_t ns, size_t *sp): n(ns), s(new size_t[ns])
500
+ {
501
+ for (size_t i = 0; i < n; i++) s[i] = sp[i];
502
+ data = create_carray<T>(n, s);
503
+ }
504
+ carray(const carray& ca) : n(ca.n), s(new size_t[ca.n])
505
+ {
506
+ size_t m = 0;
507
+ for (size_t i = 0; i < n; i++) {
508
+ s[i] = ca.s[i];
509
+ m += s[i];
510
+ }
511
+ data = create_carray<T>(n, s);
512
+ memcpy(data + n, ca.data + ca.n, m * sizeof(T));
513
+ }
514
+ ~carray() { delete[] s; free((void*)data); }
515
+ carray& operator = (const carray& ca)
516
+ {
517
+ if (this != &ca) {
518
+ delete[] s; free((void*)data);
519
+ n = ca.n; s = new size_t[ca.n];
520
+ size_t m = 0;
521
+ for (size_t i = 0; i < n; i++) {
522
+ s[i] = ca.s[i];
523
+ m += s[i];
524
+ }
525
+ data = create_carray<T>(n, s);
526
+ memcpy(data + n, ca.data + ca.n, m * sizeof(T));
527
+ }
528
+ return *this;
529
+ }
530
+ operator T** () const { return data; }
531
+ T * operator * () const { return (T*)(data + n); }
532
+ T * operator [] (size_t i) const { return data[i]; }
533
+ size_t size(size_t i) const { return s[i]; }
534
+ varray_view<T> row(size_t i) const { return varray_view<T>(data[i], s[i]); }
535
+ // end of carray;
536
+ };
537
+
538
+ template <typename T> class carray_view
539
+ {
540
+ size_t n, *s; T **data;
541
+ public:
542
+ carray_view(size_t ns, size_t *sp) : n(ns), s(new size_t[ns])
543
+ {
544
+ data = (T**)malloc(n * sizeof(T*));
545
+ for (size_t i = 0; i < n; i++) s[i] = sp[i];
546
+ }
547
+ carray_view(size_t ns, size_t *sp, T *dat) : n(ns), s(sp)
548
+ {
549
+ data = create_carray_view<T>(n, s, dat);
550
+ }
551
+ carray_view(const carray_view& ca) : n(ca.n), s(new size_t[ca.n])
552
+ {
553
+ data = (T**)malloc(n * sizeof(T*));
554
+ memcpy(s, ca.s, n * sizeof(size_t));
555
+ memcpy(data, ca.data, n * sizeof(T*));
556
+ }
557
+ ~carray_view() { delete[] s; free((void*)data); }
558
+ carray_view& operator = (const carray_view& ca)
559
+ {
560
+ if (this != &ca) {
561
+ delete[] s; free((void*)data);
562
+ n = ca.n; s = new size_t[ca.n];
563
+ data = (T**)malloc(n * sizeof(T*));
564
+ memcpy(s, ca.s, n * sizeof(size_t));
565
+ memcpy(data, ca.data, n * sizeof(T*));
566
+ }
567
+ return *this;
568
+ }
569
+ operator T** () const { return data; }
570
+ T*& operator [] (size_t i) const { return data[i]; }
571
+ size_t size(size_t i) const { return s[i]; }
572
+ varray_view<T> row(size_t i) const { return varray_view<T>(data[i], s[i]); }
573
+ // end of carray_view;
574
+ };
575
+
576
+ template <typename T> class parray
577
+ {
578
+ T **data; int o, s, k;
579
+ public:
580
+ parray(int no, int ns, int nk) : o(no), s(ns), k(nk)
581
+ {
582
+ data = create_marray<T>(k, s);
583
+ }
584
+ ~parray() { free((void*)data); }
585
+ operator T** () const { return data; }
586
+ T * operator * () const { return (T*)(data + k); }
587
+ T * operator [] (int i) { return data[i]; }
588
+ int operator () (int i) { return i == 0 ? o : i == 1 ? s : k; }
589
+ int offset() const { return o; }
590
+ int size() const { return s; }
591
+ int rows() const { return k; }
592
+ varray_view<T> row(int i) const { return varray_view<T>(data[i], s); }
593
+ varray_view<T> col(int i) const { return varray_view<T>((T*)(data + k) + i, k, s); }
594
+ T saylor(int i, T h)
595
+ {
596
+ T q = 0.0;
597
+ for (int j=k;j>0;--j) q = (q + data[j-1][i]) * h / (T)j;
598
+ return q;
599
+ }
600
+ T taylor(int i, T h)
601
+ {
602
+ T q = 0.0;
603
+ for (int j=k;j>0;--j) q = q * h / (T)j + data[j-1][i];
604
+ return q;
605
+ }
606
+ };
607
+
608
+ typedef int * narray;
609
+ typedef varray<double> vector;
610
+ typedef marray<double> matrix;
611
+
612
+ // 整数配列 [I0,...,Ii-1] : narray
613
+ #define NALLOC(i) (int*)malloc((i)*sizeof(int))
614
+ // 実数配列 [X0,...,Xi-1] : varray
615
+ #define VALLOC(i) (double*)malloc((i)*sizeof(double))
616
+ // dis配列 [D0,...,Di-1] : di_array
617
+ #define DI_ALLOC(i) (dis*)malloc((i)*sizeof(dis))
618
+ // bis配列 [B0,...,Bi-1] : bi_array
619
+ #define BI_ALLOC(i) (bis*)malloc((i)*sizeof(bis))
620
+ // tris配列 [R0,...,Ri-1] : tri_array
621
+ #define TRI_ALLOC(i) (tris*)malloc((i)*sizeof(tris))
622
+ //tetra配列 [E0,...,Ei-1] : tetra_array
623
+ #define TETRA_ALLOC(i) (tetris*)malloc((i)*sizeof(tetris))
624
+ // 実数行列 [[X00,...,X0(c-1)],...,[X(r-1)0,...,X(r-1)(c-1)]] : marray
625
+ #define MALLOC(r,c) create_marray<double>(r,c)
626
+ // dis行列 [[D00,...,D0(c-1)],...,[D(r-1)0,...,D(r-1)(c-1)]] : di_marray
627
+ #define DI_MALLOC(r,c) create_marray<dis>(r,c)
628
+ // bis行列 [[B00,...,B0(c-1)],...,[B(r-1)0,...,B(r-1)(c-1)]] : bi_marray
629
+ #define BI_MALLOC(r,c) create_marray<bis>(r,c)
630
+ // tris行列 [[R00,...,R0(c-1)],...,[R(r-1)0,...,R(r-1)(c-1)]] : tri_marray
631
+ #define TRI_MALLOC(r,c) create_marray<tris>(r,c)
632
+ //tetra行列 [[E00,...,E0(c-1)],...,[E(r-1)0,...,E(r-1)(c-1)]] : tetra_marray
633
+ #define TETRA_MALLOC(r,c) create_marray<tetris>(r,c)
634
+ // 実数行列 [[X00,...],...] : double**
635
+ #define S_MALLOC(d) create_marray<double>(d[0],d[1])
636
+ // dis行列 [[D00,...],...] : dis**
637
+ #define DIS_MALLOC(d) create_marray<dis>(d[0],d[1])
638
+ // bis行列 [[B00,...],...] : bis**
639
+ #define BIS_MALLOC(d) create_marray<bis>(d[0],d[1])
640
+ // tris行列 [[R00,...],...] : tris**
641
+ #define TRIS_MALLOC(d) create_marray<tris>(d[0],d[1])
642
+ //tetra行列 [[E00,...],...] : tetris**
643
+ #define TETRIS_MALLOC(d) create_marray<tetris>(d[0],d[1])
644
+ // ポインター演算
645
+ #define CDR(T,N,p) (poly<T,N>*)(&(p)+1)
646
+ #define CAR(T,N,p) *(poly<T,N>*)&(p)
647
+
648
+ template<class T, class Object, T (Object::*getter) () const> class Rproperty
649
+ {
650
+ Object *orner;
651
+ public:
652
+ void operator()(Object* obj) { orner = obj; }
653
+ operator T () { return (orner->*getter)(); }
654
+ };
655
+
656
+ #endif