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,1568 +1,1030 @@
1
- #ifndef _POLY_ARRAY_5_H_INCLUDED_
2
- #define _POLY_ARRAY_5_H_INCLUDED_
3
- #include <stdarg.h>
4
-
5
- template<typename T> class poly_array;
6
- template<typename T> class poly_view;
7
- template<typename T> class poly_array_lu;
8
- template<typename T> class comb_array;
9
- template<typename T> class comb_view;
10
- template<typename T> class comp_array;
11
- template<typename T> class comp_view;
12
-
13
- typedef enum {Atom, Colon, Slate, Cube, Tetra, Penta, Hexa} grid_type;
14
-
15
- template <typename T>
16
- void poly_subst(int n, T *w)
17
- {
18
- for (int i = 0; i <= n; ++i) w[i] = 1;
19
- }
20
-
21
- template <typename T, class... Args>
22
- void poly_subst(int n, T *w, T car, Args... cdr)
23
- {
24
- w[0] = car; if (n > 0) poly_subst(n-1, &w[1], cdr...);
25
- }
26
-
27
- /*******************************************************************************
28
- poly<T>(N, T[N]);
29
- [T0,...,TN]
30
- *******************************************************************************/
31
- template<typename T> class poly
32
- {
33
- template<class> friend class poly;
34
- template<class> friend class poly_array;
35
- template<class> friend class poly_view;
36
- template<class> friend class poly_array_lu;
37
- template<class> friend class comb_array;
38
- template<class> friend class comb_view;
39
- template<class> friend class comp_array;
40
- template<class> friend class comp_view;
41
-
42
- int N, *cp; T *w; // data fields
43
-
44
- public:
45
- poly(): cp(NULL), w(NULL) {}
46
- // constructor
47
- // poly<T>(T*, N); alias of T*
48
- poly(T *a, int n = 1) : N(n), cp(NULL), w(a) {} // [T0,...,Tn]
49
- // poly<T>(N, T0, ...);
50
- template <class... Args>
51
- poly(int n, const T car, const Args... cdr) : N(n), cp(new int(1)), w(new T[n+1])
52
- {
53
- w[0] = car; if (n > 0) poly_subst(n-1, &w[1], cdr...);
54
- }
55
- poly(int n, const T *s) : N(n), cp(new int(1)), w(new T[n+1])
56
- {
57
- memcpy(w, s, (N + 1) * sizeof(T));
58
- }
59
- poly(int n, const T *s, T t) : N(n), cp(new int(1)), w(new T[n+1])
60
- {
61
- memcpy(w, s, N * sizeof(T)); w[N] = t;
62
- }
63
- // copy construtor
64
- template <class S>
65
- poly(const poly<S>& p) : N(p.N), cp(new int(1)), w(new T[p.N+1])
66
- {
67
- for (int i = 0; i <= N; ++i) w[i] = p.w[i];
68
- }
69
- poly(const poly& p) : N(p.N), cp(new int(1)), w(new T[p.N+1])
70
- {
71
- for (int i = 0; i <= N; ++i) w[i] = p.w[i];
72
- }
73
- // destructor
74
- ~poly() { if (cp && --*cp == 0) { delete cp; delete[] w; }}
75
- // substituton operator
76
- poly& operator=(const poly& p)
77
- {
78
- if (this != &p)
79
- {
80
- if (cp && --*cp == 0) { delete cp; delete[] w; }
81
- N = p.N; cp = new int(1); w = new T[p.N+1];
82
- for (int i = 0; i <= N; ++i) w[i] = p.w[i];
83
- }
84
- return *this;
85
- }
86
- // substitute grid size
87
- poly& operator=(const T *s)
88
- {
89
- memcpy(w, s, N * sizeof(T));
90
- return *this;
91
- }
92
- // substitute unit size
93
- poly& operator=(T t)
94
- {
95
- w[N] = t;
96
- return *this;
97
- }
98
- poly operator * (const poly& p) const
99
- {
100
- assert(N == p.N);
101
- T result[N];
102
- for (int i=0;i<N;++i) result[i] = w[i] * p.w[i];
103
- return poly(N, result, w[N]);
104
- }
105
- poly operator / (const poly& p) const
106
- {
107
- assert(N == p.N);
108
- T result[N];
109
- for (int i=0;i<N;++i) result[i] = w[i] / p.w[i];
110
- return poly(N, result, w[N]);
111
- }
112
- poly operator + (const poly& p) const
113
- {
114
- assert(N == p.N);
115
- T result[N];
116
- for (int i=0;i<N;++i) result[i] = w[i] + p.w[i];
117
- return poly(N, result, w[N]);
118
- }
119
- poly operator - (const poly& p) const
120
- {
121
- assert(N == p.N);
122
- T result[N];
123
- for (int i=0;i<N;++i) result[i] = w[i] - p.w[i];
124
- return poly(N, result, w[N]);
125
- }
126
- poly& operator *= (const poly& p)
127
- {
128
- assert(N == p.N);
129
- for (int i=0;i<N;++i) w[i] *= p.w[i];
130
- return *this;
131
- }
132
- poly& operator /= (const poly& p)
133
- {
134
- assert(N == p.N);
135
- for (int i=0;i<N;++i) w[i] /= p.w[i];
136
- return *this;
137
- }
138
- poly& operator += (const poly& p)
139
- {
140
- assert(N == p.N);
141
- for (int i=0;i<N;++i) w[i] += p.w[i];
142
- return *this;
143
- }
144
- poly& operator -= (const poly& p)
145
- {
146
- assert(N == p.N);
147
- for (int i=0;i<N;++i) w[i] -= p.w[i];
148
- return *this;
149
- }
150
- poly& operator %= (const poly& p)
151
- {
152
- assert(N == p.N);
153
- for (int i=0;i<N;++i) w[i] %= p.w[i];
154
- return *this;
155
- }
156
- poly operator - () const
157
- {
158
- T s[N];
159
- for (int i=0;i<N;++i) s[i] = - w[i];
160
- return poly(N, s, w[N]);
161
- }
162
- poly operator * (T a) const
163
- {
164
- T s[N];
165
- for (int i=0;i<N;++i) s[i] = w[i] * a;
166
- return poly(N, s, w[N]);
167
- }
168
- poly operator / (T a) const
169
- {
170
- T s[N];
171
- for (int i=0;i<N;++i) s[i] = w[i] / a;
172
- return poly(N, s, w[N]);
173
- }
174
- poly operator + (T a) const
175
- {
176
- T s[N];
177
- for (int i=0;i<N;++i) s[i] = w[i] + a;
178
- return poly(N, s, w[N]);
179
- }
180
- poly operator - (T a) const
181
- {
182
- T s[N];
183
- for (int i=0;i<N;++i) s[i] = w[i] - a;
184
- return poly(N, s, w[N]);
185
- }
186
- poly operator % (int a) const
187
- {
188
- T s[N];
189
- for (int i=0;i<N;++i) s[i] = w[i] % a;
190
- return poly(N, s, w[N]);
191
- }
192
- poly& operator *= (T a)
193
- {
194
- for(int i=0;i<N;i++) w[i] *= a;
195
- return *this;
196
- }
197
- poly& operator /= (T a)
198
- {
199
- for(int i=0;i<N;i++) w[i] /= a;
200
- return *this;
201
- }
202
- poly& operator += (T a)
203
- {
204
- for(int i=0;i<N;i++) w[i] += a;
205
- return *this;
206
- }
207
- poly& operator -= (T a)
208
- {
209
- for(int i=0;i<N;i++) w[i] -= a;
210
- return *this;
211
- }
212
- poly& operator %= (T a)
213
- {
214
- for(int i=0;i<N;i++) w[i] %= a;
215
- return *this;
216
- }
217
- bool operator == (const poly& p) const
218
- {
219
- assert(N == p.N);
220
- int i; for(i=0;i<N;++i) if(w[i] != p.w[i]) break;
221
- return i == N && w[N] == p.w[N];
222
- }
223
- bool operator != (const poly& p) const
224
- {
225
- assert(N == p.N);
226
- int i; for(i=0;i<N;i++) if(w[i] != p.w[i]) break;
227
- return i != N || w[N] != p.w[N];
228
- }
229
- bool operator > (const poly& p) const
230
- {
231
- assert(N == p.N);
232
- int i; for(i=0;i<N;++i) if(w[i] <= p.w[i]) break;
233
- return i == N && w[N] == p.w[N];
234
- }
235
- bool operator >= (const poly& p) const
236
- {
237
- assert(N == p.N);
238
- int i; for(i=0;i<N;++i) if(w[i] < p.w[i]) break;
239
- return i == N && w[N] == p.w[N];
240
- }
241
- bool operator < (const poly& p) const
242
- {
243
- assert(N == p.N);
244
- int i; for(i=0;i<N;i++) if(w[i] >= p.w[i]) break;
245
- return i == N && w[N] == p.w[N];
246
- }
247
- bool operator <= (const poly& p) const
248
- {
249
- assert(N == p.N);
250
- int i; for(i=0;i<N;i++) if(w[i] > p.w[i]) break;
251
- return i == N && w[N] == p.w[N];
252
- }
253
- bool operator == (int a) const
254
- {
255
- int i;
256
- for (i = 0; i < N; ++i) if (w[i] != a) break;
257
- return i == N;
258
- }
259
- bool operator != (int a) const
260
- {
261
- int i;
262
- for (i = 0; i < N; ++i) if (w[i] != a) break;
263
- return i != N;
264
- }
265
- bool operator < (int a) const
266
- {
267
- int i;
268
- for (i = 0; i < N; ++i) if (w[i] >= a) break;
269
- return i == N;
270
- }
271
- bool operator >= (int a) const
272
- {
273
- int i;
274
- for (i = 0; i < N; ++i) if (w[i] < a) break;
275
- return i == N;
276
- }
277
- bool operator > (int a) const
278
- {
279
- int i;
280
- for (i = 0; i < N; ++i) if (w[i] <= a) break;
281
- return i == N;
282
- }
283
- bool operator <= (int a) const
284
- {
285
- int i;
286
- for (i = 0; i < N; ++i) if (w[i] > a) break;
287
- return i == N;
288
- }
289
- // member function
290
- int length() const {return N+1;}
291
- // Π w[i] : i = n,...,N
292
- T data_size(int n = 0) const
293
- {
294
- assert(n <= N);
295
- T z = 1;
296
- for(int i = N; i > n; --i) z *= w[i-1];
297
- return z * w[N];
298
- }
299
- // (Σ com[i] : i = n,...,N-1) * unit_size
300
- T comb_size(int n = 0) const
301
- {
302
- assert(n <= N);
303
- int z = (n == N ? 1 : 0);
304
- for(int i = N; i > n; --i) z += w[i-1];
305
- return z * w[N];
306
- }
307
- T cast_size(int n, int m = 0) const
308
- {
309
- assert(0 < N && n <= N && m <= n);
310
- int z = 0;
311
- for(int i = m; i < n; ++i) z += w[i];
312
- return z * w[N];
313
- }
314
- // Π w[i] : i = 0,...,N-1
315
- T grid_size() const
316
- {
317
- T z = 1;
318
- for (int k = 0; k < N; ++k) z *= w[k];
319
- return z;
320
- }
321
- // Σ w[i] : i = 0,...,N-1
322
- T band_size() const
323
- {
324
- T z = 0;
325
- for (int k = 0; k < N; ++k) z += w[k];
326
- return z;
327
- }
328
- int grid() const {return N;}
329
- // w[N]
330
- T unit_size() const { return w[N]; }
331
- // pointer of w
332
- operator T* () const { return w; }
333
- // calculate Atom Position
334
- T operator && (const poly& p) const
335
- {
336
- int M = p.N;
337
- assert(N >= M);
338
- T sum = p.w[M];
339
- T sek = w[N];
340
- for (int i = N-1; i >= 0; --i) {
341
- if (i < M)
342
- sum += sek * p.w[i];
343
- sek *= w[i];
344
- }
345
- return sum;
346
- }
347
- bool is_variable() const
348
- {
349
- int N = this->grid(); T n = this->data_size();
350
- return N == 0 && n == 1;
351
- }
352
- // dimension of grid
353
- bool is_atom() const { return N == Atom; }
354
- bool is_colon() const { return N == Colon; }
355
- bool is_slate() const { return N == Slate; }
356
- bool is_cube() const { return N == Cube; }
357
- // type conversion operator
358
- // Referrece of element.
359
- T operator[] (int i) const { return w[i]; }
360
- // operators
361
- poly operator<<(int i) const { return poly(N-i, &w[i]); }
362
- poly operator>>(int i) const { return poly(N-i, w, data_size(N-i)); }
363
- poly operator+() { return poly(Colon, grid_size(), unit_size()); }
364
- char *to_s() const
365
- {
366
- char buf[512];
367
- char *c = buf;
368
- sprintf(c++, "<");
369
- if (N > 0) {
370
- sprintf(c++, "{");
371
- for (int i = 0; i < N; ++i) {
372
- sprintg(c, w[i]); while(*c)++c;
373
- if (i == N-1) sprintf(c++, "}");
374
- sprintf(c++, ",");
375
- }
376
- }
377
- sprintg(c, w[N]); while(*c)++c;
378
- sprintf(c++, ">");
379
- int n = c - buf;
380
- char *result = new char[n + 1];
381
- strcpy(result, buf);
382
- return result;
383
- }
384
- void print(const char *end = NULL) const {
385
- char *s = this->to_s();
386
- char f[32] = {"%s"};
387
- char *c = f; while(*c)++c;
388
- if (end) sprintf(c, "%s", end);
389
- fprintf(stdout, f, s);
390
- delete[] s;
391
- }
392
- // end of poly;
393
- };
394
-
395
- // poly type alias
396
- typedef poly<int> Int ;
397
- typedef poly<size_t> Size_t;
398
- typedef poly<double> Double;
399
-
400
- // Modular operation : Unit No. -> Poly Grid.
401
- template<class T>
402
- poly<T> operator % (T a, const poly<T>& q)
403
- {
404
- int N = q.grid();
405
- T p[N];
406
- T sho = a;
407
- for (int i = N-1; i >= 0; --i) {
408
- T qh = q[i];
409
- p[i] = sho % qh;
410
- sho /= qh;
411
- }
412
- return poly<T>(N, p, 0);
413
- }
414
-
415
- /*******************************************************************************
416
- This section define poly_array<T>: [N, size[N], type, data[size]]
417
- *******************************************************************************/
418
- template<typename T = double> class poly_array : public Int
419
- {
420
- template<class> friend class poly_view;
421
- template<class> friend class poly_array_lu;
422
-
423
- const T *data; // data fields
424
-
425
- void init_data(const T *dat)
426
- {
427
- size_t z = this->data_size();
428
- T *dt = new T[z];
429
- memcpy(dt, dat, z * sizeof(T));
430
- data = dt;
431
- }
432
-
433
- public:
434
- // Atom constructor
435
- poly_array(const T *dat) : Int(Atom, 1), data(new T)
436
- {
437
- T *dt = const_cast<T*>(data);
438
- *dt = *dat;
439
- }
440
- poly_array(const T *dat, int s) : Int(Atom, s), data(new T[s])
441
- {
442
- if (s == 0) throw "illegal construct, poly_array(T*,int)";
443
- T *dt = const_cast<T*>(data);
444
- memcpy(dt, dat, s * sizeof(T));
445
- }
446
- // Default constructor
447
- poly_array() : data(NULL) {}
448
- // General constructor
449
- template <class... Args>
450
- poly_array(const T *dat, int n, Args... cdr) : Int(n, cdr...) { init_data(dat); }
451
- poly_array(const T *dat, int n, int *s) : Int(n, s) { init_data(dat); }
452
- poly_array(const T *dat, int n, int *s, int t) : Int(n, s, t) { init_data(dat); }
453
- poly_array(const T *dat, const Int& s) : Int(s) { init_data(dat); }
454
- poly_array(int n, const poly_array& v) : Int(Int(v).N-1, Int(v).w+1)
455
- {
456
- size_t z = this->data_size();
457
- T *dt = new T[z];
458
- memcpy(dt, &v.data[n * z], z * sizeof(T));
459
- data = dt;
460
- }
461
- // copy constructor
462
- poly_array(const poly_array& pa) : Int(pa) { init_data(pa.data); }
463
- // destructor
464
- ~poly_array() { delete data; }
465
- // substitution operator
466
- poly_array& operator=(const poly_array& pa)
467
- {
468
- if (this != &pa) {
469
- delete[] data;
470
- Int::operator=(pa);
471
- init_data(pa.data);
472
- }
473
- return *this;
474
- }
475
- poly_array& operator=(T a)
476
- {
477
- size_t n = this->data_size();
478
- for (size_t i = 0; i < n; ++i)
479
- data[i] = a;
480
- return *this;
481
- }
482
- // type conversion operator
483
- operator T* () const {return const_cast<T*>(data);}
484
- // member function
485
- int rows() { return Int(*this)[0]; }
486
- int cols() { return Int(*this)[1]; }
487
- T operator[](int pos) const
488
- {
489
- return data[pos];
490
- }
491
- int operator()(int i) const
492
- {
493
- return Int::operator[](i);
494
- }
495
- poly_view<T> operator[](const Int& p) const
496
- {
497
- const Int& t = *this;
498
- int pos = t && p, N = t.N, M = p.N;
499
- if (pos >= t.data_size())
500
- throw "out of range, poly_array[Int]";
501
- return poly_view<T>(&data[pos], N-M, t.w + M);
502
- }
503
- T operator * () const { return *data; }
504
-
505
- poly_array operator+(const poly_array& pa) const
506
- {
507
- size_t n = *this; const Int& s = *this;
508
- size_t m = pa;
509
- if (n != m) throw "mismatch argument, poly_array + ";
510
- T result[n];
511
- for (size_t i = 0; i < n; ++i) result[i] = data[i] + pa.data[i];
512
- return poly_array(result, s);
513
- }
514
- poly_array operator-(const poly_array& pa) const
515
- {
516
- size_t n = *this; const Int& s = *this;
517
- size_t m = pa;
518
- if (n != m) throw "mismatch argument, poly_array - ";
519
- T result[n];
520
- for (size_t i = 0; i < n; ++i) result[i] = data[i] - pa.data[i];
521
- return poly_array(result, s);
522
- }
523
- poly_array operator%(T a) const
524
- {
525
- size_t n = *this; const Int& s = *this;
526
- T result[n];
527
- for (size_t i = 0; i < n; ++i) result[i] = data[i] % a;
528
- return poly_array(result, s);
529
- }
530
- char *to_s() const
531
- {
532
- char buf[1024];
533
- char *c = buf;
534
- const Int& p = *this;
535
- char *s = p.to_s();
536
- sprintf(c, "{%s,", s); while(*c)++c;
537
- delete[] s;
538
- poly_to_s<T>(c, p.N, p.w, data);
539
- sprintf(c++, "}");
540
- int n = c - buf;
541
- c = new char[n + 1];
542
- strcpy(c, buf);
543
- return c;
544
- }
545
- void print(const char *end = NULL) const {
546
- char *s = this->to_s();
547
- char f[32] = {"%s"};
548
- char *c = f; while(*c)++c;
549
- if (end) sprintf(c, "%s", end);
550
- fprintf(stdout, f, s);
551
- delete[] s;
552
- }
553
- // end poly_array
554
- };
555
-
556
- template<class L, class Op, class R>
557
- class express
558
- {
559
- const L& l_; const R& r_;
560
- public:
561
- express(const L& l, const R& r) : l_(l), r_(r) {}
562
- double operator[](int s) const { return Op::apply(l_[s], r_[s]); }
563
- };
564
-
565
- template<class L, class Op>
566
- class express<L,Op,double>
567
- {
568
- const L& l_; const double& r_;
569
- public:
570
- express(const L& l, const double& r) : l_(l), r_(r) {}
571
- double operator[](int s) const { return Op::apply(l_[s], r_); }
572
- };
573
-
574
- template<class Op, class R>
575
- class unary
576
- {
577
- const R& r_;
578
- public:
579
- unary(const R& r) : r_(r) {}
580
- double operator[](int s) const { return Op::apply(r_[s]); }
581
- };
582
-
583
- struct add { static double apply(double l, double r) { return l + r; } };
584
- struct sub { static double apply(double l, double r) { return l - r; } };
585
- struct mul { static double apply(double l, double r) { return l * r; } };
586
- struct dvd { static double apply(double l, double r) { return l / r; } };
587
- struct absolute { static double apply(double c) {return c < 0 ? -c : c;}};
588
- struct minus { static double apply(double c) { return -c; } };
589
-
590
- template <class R>
591
- unary<absolute, R> abs(const R& rh)
592
- {
593
- return unary<absolute, R>(rh);
594
- }
595
-
596
- template<typename T> void swap(poly_view<T>&, poly_view<T>&);
597
- /*******************************************************************************
598
- This section define poly_view
599
- *******************************************************************************/
600
- template<typename T = double> class poly_view : public Int
601
- {
602
- template<class> friend class poly_view;
603
- template<class> friend class poly_array_lu;
604
-
605
- const T *data; int *cp;
606
-
607
- public:
608
- poly_view() : data(NULL), cp(NULL) {}
609
- // Atom constructor
610
- poly_view(const T *dat) : Int(Atom, 1), data(dat), cp(NULL) {}
611
- poly_view(const T *dat, int n) : Int(Atom, n), data(dat), cp(NULL) {}
612
- // General constructor
613
- poly_view(const poly_array<T>& pa) : Int(pa), data(pa.data), cp(NULL) {}
614
- template <class... Args>
615
- poly_view(const T *dat, int n, Args... cdr) : Int(n, cdr...), data(dat), cp(NULL) {}
616
- poly_view(const T *dat, int n, int *s) : Int(n, s), data(dat), cp(NULL) {}
617
- poly_view(const T *dat, int n, int *s, int t) : Int(n, s, t), data(dat), cp(NULL) {}
618
- poly_view(const T *dat, const Int& s) : Int(s), data(dat), cp(NULL) {}
619
- poly_view(int n, const poly_view<T>& v) : Int(Int(v).N-1, Int(v).w+1)
620
- {
621
- int s = this->data_size();
622
- data = &v.data[n * s]; cp = NULL;
623
- }
624
- // copy constructor
625
- poly_view(const poly_view& pv) : Int(pv), data(pv.data), cp(pv.cp) { cp && ++*cp; }
626
- // destructor
627
- ~poly_view() { if (cp && --*cp == 0) { delete[] data; delete cp; }}
628
- // substitution operator
629
- poly_view& operator=(const poly_view& pv)
630
- {
631
- if (this != &pv)
632
- {
633
- int s_size = pv.data_size();
634
- if (data == NULL) {
635
- Int::operator=(pv);
636
- data = new T[s_size];
637
- cp = new int(1);
638
- }
639
- int d_size = this->data_size();
640
- if ( Int::N > Atom && d_size > s_size )
641
- {
642
- int w[4] = {0}, &i = w[0], &j = w[2];
643
- int c = (*this)(0), n = pv(0), k(c - n), m((k + 1) / 2), o(k - m);
644
- Int L(&i), J(&j);
645
- for (i=m-1,k=c-m;i>=0;--i) { j=i+k; (*this)[J] = pv[L]; }
646
- for (i=n-1,k=o; i>=0;--i) { j=i+k; (*this)[J] = pv[L]; }
647
- for (i=o-1,k=n; i>=0;--i) { j=i+k; (*this)[L] = (*this)[J]; }
648
- }
649
- else if (d_size == s_size && data != pv.data) {
650
- T *dat = const_cast<T*>(data);
651
- memcpy(dat, pv.data, d_size * sizeof(T));
652
- }
653
- else if (d_size < s_size)
654
- throw "data size is mismatch, poly_view = ";
655
- }
656
- return *this;
657
- }
658
- poly_view& operator=(T a)
659
- {
660
- size_t n = this->data_size();
661
- assert(n > 0);
662
- T *dat = const_cast<T*>(data);
663
- for (size_t i = 0; i < n; ++i) dat[i] = a;
664
- return *this;
665
- }
666
- template<class E>
667
- poly_view& operator=(const E& e)
668
- {
669
- int n = this->data_size();
670
- assert(n > 0);
671
- T *dat = const_cast<T*>(data);
672
- for (int i = 0; i < n; ++i) dat[i] = e[i];
673
- return *this;
674
- }
675
- // type conversion operator
676
- operator T* () {return const_cast<T*>(data);}
677
- // member function
678
- int rows() {const Int& p = *this; return p[0];}
679
- int cols() {const Int& p = *this; return p[1];}
680
- // operators
681
- T operator [] (int pos) const
682
- {
683
- return data[pos];
684
- }
685
- int operator () (int i) const
686
- {
687
- return Int(*this)[i];
688
- }
689
- poly_view operator [] (const Int& p) const
690
- {
691
- const Int& t = *this;
692
- int pos = t && p, N = t.N, M = p.N;
693
- if (pos >= t.data_size())
694
- throw "out of range, poly_array[Int]";
695
- return poly_view(&data[t && p], N-M, t.w + M);
696
- }
697
- T operator * () const { return *data; }
698
- template<class R> express<poly_view, add, R> operator+(const R& pv) const
699
- {
700
- return express<poly_view, add, R>(*this, pv);
701
- }
702
- template<class R> express<poly_view, sub, R> operator-(const R& pv) const
703
- {
704
- return express<poly_view, sub, R>(*this, pv);
705
- }
706
- template<class R> express<poly_view, mul, R> operator*(const R& pv) const
707
- {
708
- return express<poly_view, mul, R>(*this, pv);
709
- }
710
- template<class R> express<poly_view, dvd, R> operator/(const R& pv) const
711
- {
712
- return express<poly_view, dvd, R>(*this, pv);
713
- }
714
- unary<minus, poly_view> operator-() const
715
- {
716
- return unary<minus,poly_view>(*this);
717
- }
718
- poly_view& operator+=(const poly_view& pv)
719
- {
720
- size_t n = *this;
721
- for (size_t i = 0; i < n; ++i) data[i] += pv.data[i];
722
- return *this;
723
- }
724
- template<class E> poly_view& operator+=(const E& e)
725
- {
726
- int n = this->data_size();
727
- T *dat = const_cast<T*>(data);
728
- for (int i = 0; i < n; ++i)
729
- dat[i] += e[i];
730
- return *this;
731
- }
732
- poly_view& operator-=(const poly_view& pv)
733
- {
734
- size_t n = *this;
735
- for (size_t i = 0; i < n; ++i) data[i] -= pv.data[i];
736
- return *this;
737
- }
738
- template<class E> poly_view& operator-=(const E& e)
739
- {
740
- int n = this->data_size();
741
- T *dat = const_cast<T*>(data);
742
- for (int i = 0; i < n; ++i)
743
- dat[i] -= e[i];
744
- return *this;
745
- }
746
- poly_view& operator*=(const poly_view& pv)
747
- {
748
- size_t n = this->data_size();
749
- for (size_t i = 0; i < n; ++i) data[i] *= pv.data[i];
750
- return *this;
751
- }
752
- template<class E> poly_view& operator*=(const E& e)
753
- {
754
- int n = this->data_size();
755
- for (int i = 0; i < n; ++i)
756
- data[i] *= e[i];
757
- return *this;
758
- }
759
- poly_view& operator/=(const poly_view& pv)
760
- {
761
- size_t n = *this;
762
- for (size_t i = 0; i < n; ++i) data[i] /= pv.data[i];
763
- return *this;
764
- }
765
- template<class E> poly_view& operator/=(const E& e)
766
- {
767
- int n = this->data_size();
768
- for (int i = 0; i < n; ++i)
769
- data[i] /= e[i];
770
- return *this;
771
- }
772
- bool operator==(const poly_view& pv)
773
- {
774
- size_t i, n = this->data_size();
775
- for (i = 0; i < n; ++i) { if (data[i] != pv.data[i]) break; }
776
- return i == n;
777
- }
778
- bool operator!=(const poly_view& pv)
779
- {
780
- size_t i, n = this->data_size();
781
- for (i = 0; i < n; ++i) { if (data[i] != pv.data[i]) break; }
782
- return i != n;
783
- }
784
- bool operator==(T a)
785
- {
786
- size_t i, n = this->data_size();
787
- for (i = 0; i < n; ++i) { if (data[i] != a) break; }
788
- return i == n;
789
- }
790
- bool operator!=(T a)
791
- {
792
- size_t i, n = this->data_size();
793
- for (i = 0; i < n; ++i) { if (data[i] != a) break; }
794
- return i != n;
795
- }
796
- bool operator<(const poly_view& pv)
797
- {
798
- size_t i, n = this->data_size();
799
- for (i = 0; i < n; ++i) { if (data[i] >= pv.data[i]) break; }
800
- return i == n;
801
- }
802
- bool operator>(const poly_view& pv)
803
- {
804
- size_t i, n = this->data_size();
805
- for (i = 0; i < n; ++i) { if (data[i] <= pv.data[i]) break; }
806
- return i == n;
807
- }
808
- bool operator<=(const poly_view& pv)
809
- {
810
- size_t i, n = this->data_size();
811
- for (i = 0; i < n; ++i) { if (data[i] > pv.data[i]) break; }
812
- return i == n;
813
- }
814
- bool operator>=(const poly_view& pv)
815
- {
816
- size_t i, n = this->data_size();
817
- for (i = 0; i < n; ++i) { if (data[i] < pv.data[i]) break; }
818
- return i == n;
819
- }
820
- bool operator<(T a)
821
- {
822
- size_t i, n = this->data_size();
823
- for (i = 0; i < n; ++i) { if (data[i] >= a) break; }
824
- return i == n;
825
- }
826
- bool operator>(T a)
827
- {
828
- size_t i, n = this->data_size();
829
- for (i = 0; i < n; ++i) { if (data[i] <= a) break; }
830
- return i == n;
831
- }
832
- bool operator<=(T a)
833
- {
834
- size_t i, n = this->data_size();
835
- for (i = 0; i < n; ++i) { if (data[i] > a) break; }
836
- return i == n;
837
- }
838
- bool operator>=(T a)
839
- {
840
- size_t i, n = this->data_size();
841
- for (i = 0; i < n; ++i) { if (data[i] < a) break; }
842
- return i == n;
843
- }
844
- char *to_s() const
845
- {
846
- char buf[1024];
847
- char *c = buf;
848
- const Int& p = *this;
849
- char *s = p.to_s();
850
- sprintf(c, "{%s,", s); while(*c)++c;
851
- sprintf(c++, "@");
852
- delete[] s;
853
- poly_to_s<T>(c, p.N, p.w, data);
854
- sprintf(c++, "}");
855
- int n = c - buf;
856
- c = new char[n + 1];
857
- strcpy(c, buf);
858
- return c;
859
- }
860
- void print(const char *end = NULL) const {
861
- char *s = this->to_s();
862
- char f[32] = {"%s"};
863
- char *c = f; while(*c)++c;
864
- if (end) sprintf(c, "%s", end);
865
- fprintf(stdout, f, s);
866
- delete[] s;
867
- }
868
- // end of poly_view;
869
- };
870
-
871
- template<typename T> void swap(poly_view<T>& p, poly_view<T>& q)
872
- {
873
- size_t n = p.data_size(); T *pd = p;
874
- size_t m = q.data_size(); T *qd = q;
875
- if (n != m) throw "size mismatch, poly_view.swap";
876
- for (size_t i = 0; i < n; ++i) {
877
- T w = pd[i]; pd[i] = qd[i]; qd[i] = w;
878
- }
879
- }
880
- /*******************************************************************************
881
- Matrix operation
882
- *******************************************************************************/
883
- template <class T>
884
- void plu_decomp(poly_view<T>& A, int *p, int &signum)
885
- {
886
- if (!A.is_slate())
887
- throw "not Slate object in plu_decomp";
888
-
889
- int u[8]; for (int i = 0; i < 8; ++i) u[i] = 0;
890
- int &i = u[0], &j = u[2], &k = u[4], &pivot = u[6];
891
- Int L(&i), J(&j), K(&k), P(&pivot);
892
- int N = A.rows(), n = A.unit_size();
893
- T v[n], w[n];
894
- poly_view<T> ajj(v, n), aij(w, n);
895
-
896
- signum = 1; for (i=0;i<N;++i) p[i] = i;
897
-
898
- for (j=0;j<N-1;++j)
899
- {
900
- ajj = abs(A[J][J]);
901
- pivot = j;
902
- for (i=j+1;i<N;++i)
903
- {
904
- aij = abs(A[L][J]);
905
- if (aij > ajj)
906
- {
907
- ajj = aij;
908
- pivot = i;
909
- }
910
- }
911
- if (pivot != j)
912
- {
913
- auto a = A[J];
914
- auto b = A[P];
915
- swap(a, b);
916
- int q = p[j]; p[j] = p[pivot]; p[pivot] = q;
917
- signum = -signum;
918
- }
919
- if ((ajj = A[J][J]) != 0.0)
920
- for (i=j+1;i<N;++i)
921
- {
922
- auto au = A[L];
923
- auto av = A[J];
924
- aij = au[J] / ajj;
925
- au[J] = aij;
926
- for (k=j+1;k<N;++k) {
927
- au[K] -= aij * av[K];
928
- }
929
- }
930
- else throw "plu_decomp division by zero";
931
- }
932
- }
933
-
934
- template <class T, class S>
935
- void plu_subst(poly_view<T>& LU, int *p, poly_view<S>& b, poly_view<S>& x)
936
- {
937
- int N = LU.rows();
938
- int w[6] = {0}; int &i = w[0], &j = w[2], &k = w[4];
939
- Int L(&i), J(&j), P(&k);
940
-
941
- if (!(b.is_colon() || x.is_colon()))
942
- throw "not Colon object in plu_subst";
943
- for (i=0;i<N;++i)
944
- {
945
- k = p[i]; x[L] = b[P];
946
- }
947
- for (i=1;i<N;++i)
948
- {
949
- auto sum = x[L];
950
- auto lu = LU[L];
951
- for (j=0;j<i;++j) { sum -= x[J] * lu[J]; }
952
- x[L] = sum;
953
- }
954
- for (i=N-1;i>=0;--i)
955
- {
956
- auto sum = x[L];
957
- auto lu = LU[L];
958
- for (j=N-1;j>i;--j) { sum -= x[J] * lu[J]; }
959
- x[L] = sum / lu[L];
960
- }
961
- }
962
- /*******************************************************************************
963
- This section define poly_array_lu
964
- *******************************************************************************/
965
- template <typename T> class poly_array_lu : public poly_view<T>
966
- {
967
-
968
- int s, *sign; // data fields
969
-
970
- public:
971
- // constructor
972
- poly_array_lu(const poly_array<T>& m) : poly_view<T>(m)
973
- {
974
- size_t r = poly_view<T>::rows();
975
- sign = new int[r];
976
- plu_decomp<T>(*this, sign, s);
977
- }
978
- ~poly_array_lu() {delete sign;}
979
- template <typename S> poly_array<S>& solve(poly_array<S>& v)
980
- {
981
- poly_array<S> *result = new poly_array<S>(v.type.N, v.type.size);
982
- plu_subst<T,S>(*this, sign, v, *result);
983
- return *result;
984
- }
985
- poly_array<T> invert()
986
- {
987
- size_t r = poly_view<T>::rows();
988
- size_t c = poly_view<T>::cols();
989
- size_t t = poly_view<T>::unit_size();
990
- size_t s = r * c * t;
991
- T y[s], x[s];
992
- for (size_t i = 0; i < r; ++i)
993
- for (size_t j = 0; j < c; ++j)
994
- for (size_t k = 0; k < t; ++k)
995
- x[(i*c+j)*t+k] = (i == j ? 1 : 0);
996
- Int rct(Slate, r, c, t);
997
- Int ct(Colon, c, t);
998
- for (size_t i = 0; i < r; ++i) {
999
- poly_view<T> v(&y[i*c*t], ct), w(&x[i*c*t], ct);
1000
- plu_subst<T,T>(*this, sign, w, v);
1001
- }
1002
- return poly_array<T>(y, rct);
1003
- }
1004
- poly_array<T> det()
1005
- {
1006
- size_t c = poly_view<T>::cols();
1007
- size_t t = poly_view<T>::unit_size();
1008
- T y[t]; Int s = {0, t};
1009
- poly_view<T> v(y, s);
1010
- for (size_t j = 0; j < c; j++) {
1011
- Int J(1,j,0);
1012
- if (j == 0) v = (*this)[J][J];
1013
- else v *= (*this)[J][J];
1014
- }
1015
- return poly_array<T>(y, s);
1016
- }
1017
- template <typename S> void solve(poly_view<S>& p, poly_view<S>& a)
1018
- {
1019
- plu_subst<T,S>(*this, sign, p, a);
1020
- }
1021
- char *to_s() const
1022
- {
1023
- char buf[1024];
1024
- char *c = buf;
1025
- const poly_view<T>& v = *this;
1026
- char *s = v.to_s();
1027
- sprintf(c, "%s.lu", s); while(*c)++c;
1028
- delete[] s;
1029
- int n = c - buf;
1030
- c = new char[n + 1];
1031
- strcpy(c, buf);
1032
- return c;
1033
- }
1034
- void print(const char *end = NULL) const {
1035
- char *s = this->to_s();
1036
- char f[32] = {"%s"};
1037
- char *c = f; while(*c)++c;
1038
- if (end) sprintf(c, "%s", end);
1039
- fprintf(stdout, f, s);
1040
- delete[] s;
1041
- }
1042
- // end poly_array_lu;
1043
- };
1044
-
1045
- template <typename T>
1046
- void Kronecker(const poly_view<T>& p, const poly_view<T>& q, poly_view<T>& r)
1047
- {
1048
- if (r.is_atom()) r = p * q;
1049
- else
1050
- {
1051
- const Int& u = p;
1052
- const Int& v = q;
1053
- int s = u[0], t = v[0];
1054
- for (int i = 0; i < s; i++) {
1055
- Int L(1, i, 0);
1056
- for (int j = 0; j < t; j++) {
1057
- Int J(1, j, 0), K(1, i*t+j, 0);
1058
- poly_view<T> pdr = p[L], qdr = q[J], rdr = r[K];
1059
- Kronecker(pdr, qdr, rdr);
1060
- }
1061
- }
1062
- }
1063
- }
1064
-
1065
- template <typename T>
1066
- poly_array<T> operator^(const poly_array<T>& p, const poly_array<T>& q)
1067
- {
1068
- const Int& ps = p;
1069
- const Int& qs = q;
1070
- Int rs = ps * qs;
1071
- int len = rs.data_size();
1072
- T result[len];
1073
- poly_view<T> pv(p), qv(q), rv(result, rs);
1074
- Kronecker(pv, qv, rv);
1075
- return poly_array<T>(result, rs);
1076
- }
1077
-
1078
- typedef poly_array<double> Poly_array;
1079
- typedef poly_view<double> Poly_view;
1080
- typedef poly_array_lu<double> Matrix_LU;
1081
-
1082
- /*******************************************************************************
1083
- comb_array<T>(T*,N,S1,...,SN,A);
1084
- {<{S1,...,SN},A>,[(S1,...),...],...,[(SN,...),...]}
1085
- *******************************************************************************/
1086
- template<typename T = double> class comb_array : public Int
1087
- {
1088
- template <class> friend class comb_view;
1089
-
1090
- const T *data;
1091
-
1092
- void init_data(const T *dat)
1093
- {
1094
- if (dat) {
1095
- size_t s = this->comb_size();
1096
- T *dt = new T[s];
1097
- for (size_t i = 0; i < s; ++i) dt[i] = dat[i];
1098
- data = dt;
1099
- } else {
1100
- size_t N = this->grid();
1101
- for (size_t i = 0; i <= N; ++i) Int::w[i] = 0;
1102
- data = NULL;
1103
- }
1104
- }
1105
-
1106
- public:
1107
- // Atom constructor
1108
- comb_array(const T *dat) : Int(Atom, 1) { init_data(dat); }
1109
- // General constructor
1110
- template <class... Args>
1111
- comb_array(const T *dat, int n, Args... cdr) : Int(n, cdr...) { init_data(dat); }
1112
- comb_array(const T *dat, int n, int *c) : Int(n, c) { init_data(dat); }
1113
- comb_array(const T *dat, int n, int *c, int t) : Int(n, c, t) { init_data(dat); }
1114
- comb_array(const T *dat, const Int& b) : Int(b) { init_data(dat); }
1115
- // copy constructor
1116
- comb_array(const comb_array& ba) : Int(ba) { init_data(ba.data); }
1117
- // destructor
1118
- ~comb_array() {delete[] data;}
1119
- // substitution operator
1120
- comb_array& operator=(const comb_array& ba)
1121
- {
1122
- if (this != &ba) {
1123
- delete data;
1124
- Int::operator=(ba);
1125
- init_data(ba.data);
1126
- }
1127
- return *this;
1128
- }
1129
- const T* operator[](int i) const
1130
- {
1131
- int s = this->cast_size(i);
1132
- return &data[s];
1133
- }
1134
- int operator()(int i) const
1135
- {
1136
- return Int::operator[](i);
1137
- }
1138
- char *to_s() const
1139
- {
1140
- char buf[1024];
1141
- char *c = buf;
1142
- const Int& p = *this;
1143
- char *s = p.to_s();
1144
- sprintf(c, "{%s,", s); while(*c)++c;
1145
- delete[] s;
1146
- int N = p.grid(), n = 0, A = p.unit_size();
1147
- if (N > 0) for (int i = 0; i < N; ++i) {
1148
- sprintf(c++, "[");
1149
- int l = p[i];
1150
- for (int j = 0; j < l; ++j) {
1151
- const T *pos = &data[n+j*A];
1152
- if (A > 1) sprintf(c++, "(");
1153
- for (int a = 0; a < A; ++a) {
1154
- sprintg(c, pos[a]); while(*c)++c;
1155
- if (a < A-1) {sprintf(c++, ",");}
1156
- }
1157
- if (A > 1) {sprintf(c++, ")");}
1158
- if (j < l-1) {sprintf(c++, ",");}
1159
- }
1160
- sprintf(c++, "]");
1161
- if (i < N-1) {sprintf(c++, ",");}
1162
- n += l * A;
1163
- } else
1164
- poly_to_s<T>(c, N, p.w, data);
1165
- sprintf(c++, "}");
1166
- n = c - buf;
1167
- c = new char[n + 1];
1168
- strcpy(c, buf);
1169
- return c;
1170
- }
1171
- void print(const char *end = NULL) const {
1172
- char *s = this->to_s();
1173
- char f[32] = {"%s"};
1174
- char *c = f; while(*c)++c;
1175
- if (end) sprintf(c, "%s", end);
1176
- fprintf(stdout, f, s);
1177
- delete[] s;
1178
- }
1179
- // end of comb_array;
1180
- };
1181
-
1182
- template<typename T = double> class comb_view : public Int
1183
- {
1184
-
1185
- const T *data;
1186
-
1187
- public:
1188
- // Atom constructor
1189
- comb_view(const T *dat) : Int(Atom, 1), data(dat) {}
1190
- comb_view(const T *dat, int n) : Int(Atom, n), data(dat) {}
1191
- // General constructor
1192
- template <class... Args>
1193
- comb_view(const T *dat, int n, Args... cdr) : Int(n, cdr...), data(dat) {}
1194
- comb_view(const T *dat, int n, int *c) : Int(n, c), data(dat) {}
1195
- comb_view(const T *dat, int n, int *c, int t) : Int(n, c, t), data(dat) {}
1196
- comb_view(const T *dat, const Int& b) : Int(b), data(dat) {}
1197
- comb_view(const comb_array<T>& ca) : Int(ca), data(ca.data) {}
1198
- // copy constructor
1199
- comb_view(const comb_view& ba) : Int(ba), data(ba.data) {}
1200
- // destructor
1201
- // substitution operator
1202
- comb_view& operator=(const comb_view& ba)
1203
- {
1204
- if (this != &ba) {
1205
- int s = this->comb_size();
1206
- int t = ba.comb_size();
1207
- if (s != t) throw "size mismatch, comb_view = ";
1208
- for (int i = 0; i < s; ++i) data[i] = ba.data[i];
1209
- }
1210
- return *this;
1211
- }
1212
- const T* operator[](int i) const
1213
- {
1214
- int n = this->is_atom() ? *Int::w : Int::N;
1215
- if (i < 0 || i >= n) throw "out of range, comb_view[]";
1216
- int s = this->cast_size(i);
1217
- return &data[s];
1218
- }
1219
- int operator()(int i) const
1220
- {
1221
- if (i < 0 || i > Int::N) throw "out of range, comb_view()";
1222
- return Int::operator[](i);
1223
- }
1224
- char *to_s() const
1225
- {
1226
- char buf[1024];
1227
- char *c = buf;
1228
- const Int& p = *this;
1229
- char *s = p.to_s();
1230
- sprintf(c, "{%s,", s); while(*c)++c;
1231
- delete[] s;
1232
- int N = p.grid(), n = 0, A = p.unit_size();
1233
- if (N > 0) for (int i = 0; i < N; ++i) {
1234
- sprintf(c, "@["); while(*c)++c;
1235
- int l = p[i];
1236
- for (int j = 0; j < l; ++j) {
1237
- const T *pos = &data[n+j*A];
1238
- if (A > 1) {sprintf(c++, "(");}
1239
- for (int a = 0; a < A; ++a) {
1240
- sprintg(c, pos[a]); while(*c)++c;
1241
- if (a < A-1) {sprintf(c++, ",");}
1242
- }
1243
- if (A > 1) {sprintf(c++, ")");}
1244
- if (j < l-1) {sprintf(c++, ",");}
1245
- }
1246
- sprintf(c++, "]");
1247
- if (i < N-1) {sprintf(c++, ",");}
1248
- n += l * A;
1249
- } else {
1250
- sprintf(c++, "@");
1251
- poly_to_s<T>(c, N, p.w, data);
1252
- }
1253
- sprintf(c++, "}");
1254
- n = c - buf;
1255
- c = new char[n + 1];
1256
- strcpy(c, buf);
1257
- return c;
1258
- }
1259
- void print(const char *end = NULL) const {
1260
- char *s = this->to_s();
1261
- char f[32] = {"%s"};
1262
- char *c = f; while(*c)++c;
1263
- if (end) sprintf(c, "%s", end);
1264
- fprintf(stdout, f, s);
1265
- delete[] s;
1266
- }
1267
- // end of comb_view;
1268
- };
1269
-
1270
- template<typename T> class comp_array : public Int
1271
- {
1272
- T *data;
1273
-
1274
- public:
1275
- // mono constructor
1276
- comp_array(T *dat, int o, int s, int k = 1) : Int(2, o, s, k), data(new T[s*k])
1277
- {
1278
- size_t sk = s * k;
1279
- for (size_t i = 0; i < sk; ++i) data[i] = dat[i];
1280
- }
1281
- // General constructor
1282
- comp_array(T *dat, int n, int *s) : Int(n, s)
1283
- {
1284
- int N = this->grid();
1285
- size_t sk = this->cast_size(N, N/2);
1286
- data = new T[sk];
1287
- memcpy(data, dat, sk * sizeof(T));
1288
- }
1289
- comp_array(T *dat, int n, int *s, int k) : Int(n, s, k)
1290
- {
1291
- int N = this->grid();
1292
- size_t sk = this->cast_size(N, N/2);
1293
- data = new T[sk];
1294
- memcpy(data, dat, sk * sizeof(T));
1295
- }
1296
- // copy constructor
1297
- comp_array(const comp_array& pa) : Int(pa)
1298
- {
1299
- int N = this->grid();
1300
- size_t sk = this->cast_size(N, N/2);
1301
- data = new T[sk];
1302
- memcpy(data, pa.data, sk * sizeof(T));
1303
- }
1304
- // destructor
1305
- ~comp_array() {delete data;}
1306
- // substitution operator
1307
- comp_array& operator=(const comp_array& pa)
1308
- {
1309
- if (this != &pa) {
1310
- delete data;
1311
- Int::operator=(pa);
1312
- int N = this->grid();
1313
- size_t sk = this->cast_size(N, N/2);
1314
- data = new T[sk];
1315
- memcpy(data, pa.data, sk * sizeof(T));
1316
- }
1317
- return *this;
1318
- }
1319
- // member function
1320
- Int offset() const
1321
- {
1322
- const Int& b = *this;
1323
- int N = b.grid();
1324
- return Int(N/2, b.w, 0);
1325
- }
1326
- Int size() const
1327
- {
1328
- const Int& b = *this;
1329
- int N = b.grid();
1330
- return Int(N/2, &b.w[N/2], b.unit_size());
1331
- }
1332
- comp_view<T> operator[](const Int& p) const
1333
- {
1334
- const Int& b = *this;
1335
- int N = b.grid(), K = b.unit_size();
1336
- T **nk = new T*[N/2];
1337
- for (int n = 0, i = 0; i < N/2; ++i) {
1338
- int s = b[i+N/2];
1339
- int k = n + p[i];
1340
- nk[i] = &data[k];
1341
- n += s * K;
1342
- }
1343
- return comp_view<T>(nk, N/2, &(b.w[N/2]), p.w[N/2]);
1344
- }
1345
- T* operator[](int i) const
1346
- {
1347
- const Int& b = *this;
1348
- int N = b.grid();
1349
- return &data[b.cast_size(N/2 + i, N/2)];
1350
- }
1351
- int operator() (int i) const
1352
- {
1353
- return Int::w[i];
1354
- }
1355
- operator T* () {return data;}
1356
- comp_array operator & (const comp_array& pa)
1357
- {
1358
- const Int& bt = *this;
1359
- const Int& pt = pa;
1360
- int Nt = bt.grid(), Np = pt.grid();
1361
- int s[Nt + Np + 1], *sp = s;
1362
- for (int i = 0; i < Nt/2; ++i) *sp++ = bt[i];
1363
- for (int i = 0; i < Np/2; ++i) *sp++ = pt[i];
1364
- for (int i =Nt/2; i < Nt; ++i) *sp++ = bt[i];
1365
- for (int i =Np/2; i < Np; ++i) *sp++ = pt[i];
1366
- size_t skt = bt.cast_size(Nt, Nt/2);
1367
- size_t skp = pt.cast_size(Np, Np/2);
1368
- T dt[skt + skp], *dp = dt;
1369
- for (size_t i = 0; i < skt; ++i) *dp++ = data[i];
1370
- for (size_t i = 0; i < skp; ++i) *dp++ = pa.data[i];
1371
- return comp_array(dt, Nt + Np, s, bt.unit_size());
1372
- }
1373
- char *to_s() const
1374
- {
1375
- char buf[1024];
1376
- char *c = buf;
1377
- const Int& p = *this;
1378
- int N = p.grid(), K = p.unit_size();
1379
- sprintf(c, "{<"); while(*c)++c;
1380
- if (N > 0) {
1381
- sprintf(c++, "{");
1382
- for (int i = 0; i < N/2; ++i) {
1383
- sprintf(c, "%d", p[i]); while(*c)++c;
1384
- if (i == N/2-1) sprintf(c++, "}");
1385
- sprintf(c++, ",");
1386
- }
1387
- sprintf(c++, "{");
1388
- for (int i = N/2; i < N; ++i) {
1389
- sprintf(c, "%d", p[i]); while(*c)++c;
1390
- if (i == N-1) sprintf(c++, "}");
1391
- sprintf(c++, ",");
1392
- }
1393
- }
1394
- sprintf(c, "%d>,",p[N]); while(*c)++c;
1395
- int n = 0;
1396
- for (int i = 0; i < N/2; ++i) {
1397
- int z = p[i + N/2];
1398
- sprintf(c++, "[");
1399
- for (int k = 0; k < K; ++k) {
1400
- sprintf(c++, "(");
1401
- for (int j = 0; j < z; ++j) {
1402
- sprintg(c, data[n+z*k+j]); while(*c)++c;
1403
- if (j < z-1) {sprintf(c++, ",");}
1404
- }
1405
- sprintf(c++, ")");
1406
- if (k < K-1) {sprintf(c++, ",");}
1407
- }
1408
- sprintf(c++, "]");
1409
- if (i < N/2-1) {sprintf(c++, ",");}
1410
- n += z * K;
1411
- }
1412
- sprintf(c++, "}");
1413
- n = c - buf;
1414
- c = new char[n + 1];
1415
- strcpy(c, buf);
1416
- return c;
1417
- }
1418
- void print(const char *end = NULL) const {
1419
- char *s = this->to_s();
1420
- char f[32] = {"%s"};
1421
- char *c = f; while(*c)++c;
1422
- if (end) sprintf(c, "%s", end);
1423
- fprintf(stdout, f, s);
1424
- delete[] s;
1425
- }
1426
- // end of comp_array;
1427
- };
1428
-
1429
- template<typename T> class comp_view : public Int
1430
- {
1431
- T **data;
1432
- public:
1433
- template <class... Args>
1434
- comp_view(T **dat, int n, int car, Args... cdr) : Int(n, car, cdr...), data(dat) {}
1435
- comp_view(T **dat, int n, const int *c ) : Int(n, c ), data(dat) {}
1436
- comp_view(T **dat, int n, const int *c, int t ) : Int(n, c, t ), data(dat) {}
1437
- comp_view(T **dat, const Int& b ) : Int(b ), data(dat) {}
1438
- ~comp_view() {delete[] data;}
1439
- T operator * () const
1440
- {
1441
- return coeff(data, Int::w, this->grid());
1442
- }
1443
- T operator[](int j) const
1444
- {
1445
- return coeff(data, Int::w, this->grid(), j);
1446
- }
1447
- T operator[](T *ds) const
1448
- {
1449
- return total_derive(data, Int::w, this->grid(), this->unit_size()-1, ds);
1450
- }
1451
- T operator () (T dh, int j = 0) const
1452
- {
1453
- const Int& p = *this;
1454
- int k = p.unit_size();
1455
- T sum = 0.0;
1456
- T *ds = data[j];
1457
- int c = p[j] * k;
1458
- for (int i = k; i > 0; --i)
1459
- sum = (sum + ds[c -= p[j]]) * dh / (T)i;
1460
- return sum;
1461
- }
1462
-
1463
- T taylor(T dh, int j = 0) const
1464
- {
1465
- const Int& p = *this;
1466
- int k = p.unit_size();
1467
- T sum = 0.0;
1468
- T *ds = data[j];
1469
- int c = p[j] * k;
1470
- for (int i = k; i > 0; --i)
1471
- sum = sum * dh / (T)i + ds[c -= p[j]];
1472
- return sum;
1473
- }
1474
- char *to_s() const
1475
- {
1476
- char buf[1024];
1477
- char *c = buf;
1478
- const Int& p = *this;
1479
- int N = p.grid();
1480
- int K = p.unit_size();
1481
- char *s = p.to_s();
1482
- sprintf(c, "{%s", s); while(*c)++c;
1483
- delete[] s;
1484
- sprintf(c, "@["); while(*c)++c;
1485
- for (int i = 0; i < N; ++i) {
1486
- if (K > 1) sprintf(c++, "[");
1487
- for (int j = 0; j < K; ++j) {
1488
- sprintg(c, data[i][j*p[i]]); while(*c)++c;
1489
- if (j < K-1) sprintf(c++, ",");
1490
- }
1491
- if (K > 1) sprintf(c++, "]");
1492
- if ( i < N-1) sprintf(c++, ",");
1493
- }
1494
- sprintf(c++, "]");
1495
- int n = c - buf;
1496
- c = new char[n + 1];
1497
- strcpy(c, buf);
1498
- return c;
1499
- }
1500
- void print(const char *end = NULL) const {
1501
- char *s = this->to_s();
1502
- char f[32] = {"%s"};
1503
- char *c = f; while(*c)++c;
1504
- if (end) sprintf(c, "%s", end);
1505
- fprintf(stdout, f, s);
1506
- delete[] s;
1507
- }
1508
- // end of comp_view;
1509
- };
1510
-
1511
- template <typename T>
1512
- bool xvalue(int &i, T &x, const T *X, T &t, int &l, int L, int &d, int p, bool F)
1513
- {
1514
- bool f = false;
1515
- if (F) if (d++ == p) {
1516
- if (++l == L) {
1517
- f = true;
1518
- l = 1;
1519
- } t = (X ? (X[l] - X[l-1]) : 1.0)/p;
1520
- d = (l == 1) ? 0 : 1;
1521
- }
1522
- i = d + (l - 1) * p;
1523
- x = (X ? X[l - 1] : l - 1) + d * t;
1524
- return f;
1525
- }
1526
-
1527
- template <typename T> class poly_index
1528
- {
1529
- int N, *index, *Le, *Lc, *Nc, Dx;
1530
- T *value, *Dt; const T **X; Int *e;
1531
- public:
1532
- poly_index(const comb_array<T>& x, int Dp)
1533
- {
1534
- const Int& end = x; N = end.grid(); int Np[N];
1535
- index = new int[N*4]; Le = index + N; Lc = Le + N; Nc = Lc + N;
1536
- value = new T[N*2]; Dt = value + N; X = new const T*[N];
1537
- for (int i = 0; i < N; i++) {
1538
- Np[i] =(end[i] - 1) * Dp + 1;
1539
- Le[i] = end[i]; X[i] = x[i];
1540
- Lc[i] = 1; Nc[i] = 0;
1541
- Dt[i] = (X[i] ? (X[i][1] - X[i][0]) : 1.0) / Dp;
1542
- xvalue(index[i], value[i], X[i], Dt[i], Lc[i], Le[i], Nc[i], Dp, false);
1543
- } Dx = Dp;
1544
- e = new Int(N, Np, 1);
1545
- }
1546
- ~poly_index() {delete e; delete X; delete value; delete index;}
1547
- poly_index& operator++()
1548
- {
1549
- bool f = true;
1550
- for (int i = N-1; i >= 0; --i)
1551
- f = xvalue(index[i], value[i], X[i], Dt[i], Lc[i], Le[i], Nc[i], Dx, f);
1552
- return *this;
1553
- }
1554
- int index_size() // return Npx;
1555
- {
1556
- return e->grid_size();
1557
- }
1558
- int index_value() // convert index to number;
1559
- {
1560
- Int i(N, index, 0);
1561
- return (*e) && i;
1562
- }
1563
- Int get_index() {return Int(N, index, 0);}
1564
- poly<T> get_value() {return poly<T>(N, value, 0);}
1565
- // end of poly_index
1566
- };
1567
-
1568
- #endif
1
+ #ifndef _POLY_ARRAY_5_H_INCLUDED_
2
+ #define _POLY_ARRAY_5_H_INCLUDED_
3
+ /*******************************************************************************
4
+ 微分係数(differential coefficient)
5
+ N個の関数の積のJ階微分係数を求める。
6
+ data : 微分係数の配列 [[f(t),D1f(t),...,DJf(t)],...]
7
+ s : 配列のストライド [st1,...,stN,K] (K = J+1)
8
+ N : 関数の積の項数
9
+ *******************************************************************************/
10
+ template<typename P, typename S, typename T>
11
+ // P = varray<double>, S = poly<double>, T = double;
12
+ static P *diff(T **data, const int *s, int N)
13
+ {
14
+ size_t K = s[N], A = s[N+1];
15
+ P *W = new P(K, A);
16
+ if (N == 1)
17
+ for (size_t i = 0; i < K; ++i) {
18
+ T *w = (*W)(i);
19
+ T *d = &data[0][size_t(*s)*i*(A+1)];
20
+ for (size_t j = 0; j <= A; ++j) w[j] = d[j];
21
+ }
22
+ else {
23
+ T *b = *data;
24
+ P *c = diff<P,S,T>(&data[1], &s[1], N-1);
25
+ int a[K];
26
+ for (size_t j = 0; j < K; ++j) {
27
+ for (size_t p = 1; p < j; p++) {
28
+ a[j] = a[0]; a[0] = a[p]; a[p] = a[0] + a[j];
29
+ } a[j] = a[0] = 1;
30
+ S R = (*W)[j]; R = 0.0;
31
+ for (size_t k = 0; k <= j; ++k) {
32
+ S B(A, &b[size_t(*s)*k*(A+1)], 0);
33
+ S C = (*c)[(j-k)];
34
+ R += a[k] * B * C;
35
+ }
36
+ }
37
+ delete c;
38
+ }
39
+ return W;
40
+ }
41
+ template<typename P, typename S, typename T>
42
+ // P = varray<double>, S = poly<double>, T = double;
43
+ S coefficient(T **data, const int *s, int N, int jbn = 0)
44
+ {
45
+ S result;
46
+ P *W = diff<P,S,T>(data, s, N);
47
+ result = (*W)[jbn];
48
+ delete W;
49
+ return result;
50
+ }
51
+ /*******************************************************************************
52
+ 全微分(Total derivative)
53
+ N個の関数の積のJ階全微分を求める。
54
+ data : 微分係数の配列 [[f(t),D1f(t),...,DJf(t)],...]
55
+ s : 配列のストライド [st1,...,stN,K] (K = J+1)
56
+ N : 関数の積の項数
57
+ ds : 方向ベクトルの成分の配列 [d1,...dN]
58
+ *******************************************************************************/
59
+ template<typename P, typename S, typename T>
60
+ // P = varray<double>, S = poly<double>, T = double;
61
+ static P *sub_derive(T **data, const int *s, int N, const P& ds)
62
+ {
63
+ size_t i, k, K = s[N], A = s[N+1];
64
+ S dt; P *W = new P(K, A);
65
+ if (N == 1)
66
+ for (dt = 1.0, i = 0; i < K; ++i, dt *= (*ds)) {
67
+ S d(A, &data[0][size_t(*s)*i*(A+1)]), e = d * dt;
68
+ T *w = (*W)(i), *u = e;
69
+ for (size_t j = 0; j <= A; ++j) w[j] = u[j];
70
+ }
71
+ else {
72
+ T *b = *data;
73
+ P *c = sub_derive<P,S,T>(&data[1], &s[1], N-1, ds[1]);
74
+ int a[K];
75
+ for (size_t j = 0; j < K; ++j) {
76
+ for (size_t p = 1; p < j; p++) {
77
+ a[j] = a[0]; a[0] = a[p]; a[p] = a[0] + a[j];
78
+ } a[j] = a[0] = 1;
79
+ S R = (*W)[j]; R = 0.0;
80
+ for (dt = 1.0, k = 0; k <= j; ++k, dt *= (*ds)) {
81
+ S B(A, &b[size_t(*s)*k*(A+1)], 0);
82
+ S C = (*c)[(j-k)];
83
+ R += a[k] * B * C * dt;
84
+ }
85
+ }
86
+ delete c;
87
+ }
88
+ return W;
89
+ }
90
+ template<typename P, typename S, typename T>
91
+ // P = varray<double>, S = poly<double>, T = double;
92
+ S total_derive(T **data, const int *s, int N, int jbn, const P& ds)
93
+ {
94
+ S result;
95
+ P *W = sub_derive<P,S,T>(data, s, N, ds);
96
+ result = (*W)[jbn];
97
+ delete W;
98
+ return result;
99
+ }
100
+
101
+ template<typename T> class poly_array;
102
+ template<typename T> class poly_view;
103
+ template<typename T> class comb_array;
104
+ template<typename T> class comb_view;
105
+ template<typename T> class comp_array;
106
+ template<typename T> class comp_view;
107
+
108
+ #include "basis/poly.h"
109
+ #include "basis/real.h"
110
+
111
+ typedef enum {Atom, Unit, Line, Plat, Cube, Tetra, Penta, Hexa} grid_type;
112
+
113
+ /*******************************************************************************
114
+ This section define poly_array<T>: [N, size[N], type, data[size]]
115
+ *******************************************************************************/
116
+ template<typename T = double> class poly_array : Int
117
+ {
118
+ template<class> friend class poly_view;
119
+
120
+ T *data; // data fields
121
+
122
+ void init_data(const T *dat = NULL)
123
+ {
124
+ size_t z = this->data_size();
125
+ data = new T[z];
126
+ if (dat) for (size_t i = 0; i < z; ++i) data[i] = dat[i];
127
+ }
128
+
129
+ public:
130
+ // Default constructor
131
+ poly_array() : Int(), data(NULL) {}
132
+ // Temporary constructor
133
+ template <class... Args>
134
+ poly_array(int car, Args... cdr) : Int(car, cdr...) { init_data(); }
135
+ poly_array(int n, int *s) : Int(n, s ) { init_data(); }
136
+ poly_array(const Int& s) : Int(s ) { init_data(); }
137
+ // General constructor
138
+ template <class... Args>
139
+ poly_array(const T *dat, int car, Args... cdr) : Int(car, cdr...) { init_data(dat); }
140
+ poly_array(const T *dat, int n, int *s) : Int(n, s ) { init_data(dat); }
141
+ poly_array(const T *dat, const Int& s) : Int(s ) { init_data(dat); }
142
+ poly_array(int n, const poly_array& v) : Int( ((Int&)v) << 1 )
143
+ {
144
+ assert(0 <= n && n < ((Int&)v)[0]);
145
+ size_t z = this->data_size();
146
+ data = new T[z];
147
+ for (size_t i = 0; i < z; ++i) data[i] = v.data[n*z+i];
148
+ }
149
+ // copy constructor
150
+ poly_array(const poly_array& pa) : Int(pa) { init_data(pa.data); }
151
+ // destructor
152
+ ~poly_array() { delete[] data; }
153
+ // assignment operator
154
+ poly_array& operator = (const poly_array& pa)
155
+ {
156
+ if (this != &pa) {
157
+ delete[] data;
158
+ Int::operator=(pa);
159
+ init_data(pa.data);
160
+ }
161
+ return *this;
162
+ }
163
+ poly_array& operator = (T a)
164
+ {
165
+ size_t A = Int::atom();
166
+ size_t n = Int::grid_size(Atom);
167
+ for (size_t i = 0; i < n; ++i) {
168
+ T *p = &data[i*(A+1)]; *p = a;
169
+ for (size_t j = 1; j <= A; ++j) p[j] = T();
170
+ }
171
+ return *this;
172
+ }
173
+ // type conversion operator
174
+ operator T* () const {return data;}
175
+ // member function
176
+ size_t grid() const { return Int::grid(); }
177
+ size_t data_size() const { return Int::data_size(); }
178
+ Int tags() const { return Int(*this); }
179
+ int atom() const { return Int::atom(); }
180
+ int atom_size() const { return Int::atom_size(); }
181
+ int unit() const { return Int::unit(); }
182
+ int unit_size() const { return Int::unit_size(); }
183
+ int rows() const
184
+ {
185
+ #ifndef NDEBUG
186
+ size_t N = Int::grid();
187
+ #endif
188
+ assert(N >= 1);
189
+ return Int::grid(0);
190
+ }
191
+ int cols() const
192
+ {
193
+ #ifndef NDEBUG
194
+ size_t N = Int::grid();
195
+ #endif
196
+ assert(N >= 2);
197
+ return Int::grid(1);
198
+ }
199
+ bool is_atom() { return Int::grid() == 0; }
200
+ poly_view<T> operator[](int i) const { return poly_view<T>(i, *this); }
201
+ T *operator()(int i, size_t& a) const { a = Int::atom(); return &data[(a + 1)*i]; }
202
+ varray<T> operator[](const Int& p) const
203
+ {
204
+ const Int& t = *this;
205
+ int pos = t && p, M = p.grid();
206
+ if (pos >= t.data_size())
207
+ throw "out of range, poly_array[Int]";
208
+ int a = t.atom();
209
+ int b = t.data_size(M);
210
+ return varray<T>(size_t(b/(a+1)), size_t(a), &data[pos], 1, 0);
211
+ }
212
+ real<T> operator * () const { return { data, Int::atom_size(), Int::atom(), 1, 0 }; }
213
+
214
+ void swap(size_t i, size_t j)
215
+ {
216
+ Int s = Int(*this) << 1;
217
+ size_t n = s.data_size();
218
+ T *p = &data[i * n], *q = &data[j * n];
219
+ for (size_t k = 0; k < n; ++k) {
220
+ T w = p[k]; p[k] = q[k]; q[k] = w;
221
+ }
222
+ }
223
+
224
+ char *to_s(const char *f = NULL) const
225
+ {
226
+ str_buf c;
227
+ const Int& p = *this;
228
+ char *s = p.to_s();
229
+ c += '{'; c += s;
230
+ delete[] s;
231
+ int N = p.grid(), w[N+1];
232
+ for (int i = 0; i <= N; ++i) w[i] = p[i];
233
+ poly_to_s<T>(c, N, w, data, f);
234
+ c += '}';
235
+ s = new char[c.size() + 1];
236
+ strcpy(s, c.c_str());
237
+ return s;
238
+ }
239
+ void fprint(FILE *f, const char *fmt = "%g\n") const { gprint(*this, f, fmt); }
240
+ void print(const char *fmt = "%g\n") const { this->fprint(stdout, fmt); }
241
+
242
+ }; // end poly_array;
243
+
244
+ /*******************************************************************************
245
+ This section define poly_view
246
+ *******************************************************************************/
247
+ template<typename T = double> class poly_view : Int
248
+ {
249
+ T *data;
250
+
251
+ public:
252
+
253
+ typedef T View;
254
+
255
+ // General constructor
256
+ poly_view(const poly_array<T>& pa) : Int(pa), data(pa.data) {}
257
+ template <class... Args>
258
+ poly_view(T *dat, Args... cdr ) : Int(cdr...), data(dat) {}
259
+ poly_view(T *dat, int n, int *s) : Int(n, s ), data(dat) {}
260
+ poly_view(T *dat, const Int& s) : Int(s ), data(dat) {}
261
+ poly_view(int n, const poly_view<T>& v) : Int( ((Int&)v) << 1 )
262
+ {
263
+ assert(0 <= n && n < ((Int&)v)[0]);
264
+ int s = this->data_size();
265
+ data = &v.data[n * s];
266
+ }
267
+ // copy constructor
268
+ poly_view(const poly_view& pv) = default;
269
+ // destructor
270
+ ~poly_view() = default;
271
+ // assignment operator
272
+ poly_view& operator = (const poly_view& pv)
273
+ {
274
+ if (this != &pv)
275
+ {
276
+ int s_size = pv.data_size();
277
+ if (data == NULL) {
278
+ Int::operator=(pv);
279
+ data = new T[s_size];
280
+ }
281
+ int d_size = this->data_size();
282
+ if ( this->grid() > Atom && d_size > s_size )
283
+ {
284
+ int c = this->rows(), n = pv.rows();
285
+ int i, j, k(c - n), m((k + 1) / 2), o(k - m);
286
+ for (i=m-1,k=c-m;i>=0;--i) { j=i+k; (*this)[j] = pv[i]; }
287
+ for (i=n-1,k=o; i>=0;--i) { j=i+k; (*this)[j] = pv[i]; }
288
+ for (i=o-1,k=n; i>=0;--i) { j=i+k; (*this)[i] = (*this)[j]; }
289
+ }
290
+ else if (d_size == s_size && data != pv.data) {
291
+ for (int i = 0; i < d_size; ++i) data[i] = pv.data[i];
292
+ }
293
+ else if (d_size != s_size)
294
+ throw "data size is mismatch, poly_view = ";
295
+ }
296
+ return *this;
297
+ }
298
+ poly_view& operator = (T a)
299
+ {
300
+ size_t A = Int::atom();
301
+ size_t n = Int::grid_size(Atom);
302
+ for (size_t i = 0; i < n; ++i) {
303
+ T *p = &data[i*(A+1)]; *p = a;
304
+ for (size_t j = 1; j <= A; ++j)
305
+ p[j] = T();
306
+ }
307
+ return *this;
308
+ }
309
+ poly_view& operator = (const poly<T>& a)
310
+ {
311
+ size_t A = Int::atom();
312
+ size_t n = Int::grid_size(Atom);
313
+ T *w = data; size_t s = a.atom();
314
+ for (size_t i = 0; i < n; ++i, w += A + 1)
315
+ for (size_t j = 1; j <= A; ++j) w[j] = (i <= s) ? a[i] : T();
316
+ return *this;
317
+ }
318
+ template<class E>
319
+ poly_view& operator = (const E& e)
320
+ {
321
+ size_t A = Int::atom();
322
+ size_t n = Int::grid_size(Atom);
323
+ T *w = data;
324
+ for (size_t i = 0; i < n; ++i, w += A + 1) e(A, w, (int)i);
325
+ return *this;
326
+ }
327
+ // type conversion operator
328
+ operator T* () const {return data;}
329
+ // member function
330
+ size_t grid() const { return Int::grid(); }
331
+ size_t data_size() const { return Int::data_size(); }
332
+ Int tags() const { return Int(*this); }
333
+ int atom() const { return Int::atom(); }
334
+ int atom_size() const { return Int::atom_size(); }
335
+ int unit() const { return Int::unit(); }
336
+ int unit_size() const { return Int::unit_size(); }
337
+ int rows() const
338
+ {
339
+ #ifndef NDEBUG
340
+ size_t N = Int::grid();
341
+ #endif
342
+ assert(N >= 1);
343
+ return Int::grid(0);
344
+ }
345
+ int cols() const
346
+ {
347
+ #ifndef NDEBUG
348
+ size_t N = Int::grid();
349
+ #endif
350
+ assert(N >= 2);
351
+ return Int::grid(1);
352
+ }
353
+ bool is_atom() { return Int::grid() == 0; }
354
+ // operators
355
+ poly_view operator [] (int i) const { return poly_view(i, *this); }
356
+ int operator()(int i) { return Int::operator[](i); }
357
+ void operator()(size_t& a, T *w, int n) const
358
+ {
359
+ size_t A = Int::atom();
360
+ T *s = &data[(A + 1)*n];
361
+ for (size_t i = 0; i <= a; ++i) w[i] = (i <= A) ? s[i] : 0.0;
362
+ }
363
+ varray<T> operator [] (const Int& p) const
364
+ {
365
+ const Int& t = *this;
366
+ size_t pos = t && p, M = p.grid();
367
+ if (pos >= t.data_size())
368
+ throw "out of range, poly_array[Int]";
369
+ int a = t.atom();
370
+ int b = t.data_size(M);
371
+ return varray<T>(&data[pos], size_t(b/(a+1)), size_t(a), 1, 0);
372
+ }
373
+ real<T> operator * () const { return { data, Int::atom_size(), Int::atom(), 1, 0 }; }
374
+
375
+ private:
376
+
377
+ typedef bool(*Q1)(size_t,double*,double*) ;
378
+ typedef bool(*Q2)(size_t,double*,double) ;
379
+
380
+ bool poly_eq(Q1 qf, const poly_view& pv)
381
+ {
382
+ size_t A = Int::atom();
383
+ size_t i, n = Int::grid_size(Atom);
384
+ T *w = data, u[A + 1];
385
+ for (i = 0; i < n; ++i, w += A + 1) {
386
+ pv(A, u, (int)i);
387
+ if (!qf(A, w, u)) break;
388
+ }
389
+ return i == n;
390
+ }
391
+
392
+ bool poly_eq(Q2 qf, T a)
393
+ {
394
+ size_t A = Int::atom();
395
+ size_t i, n = Int::grid_size(Atom);
396
+ T *w = data;
397
+ for (i = 0; i < n; ++i, w += A + 1)
398
+ if (!qf(A, w, a)) break;
399
+ return i == n;
400
+ }
401
+
402
+ public:
403
+
404
+ bool operator ==(const poly_view& pv) { return poly_eq((bool(*)(size_t,double*,double*))qd_eq, pv); }
405
+ bool operator < (const poly_view& pv) { return poly_eq((bool(*)(size_t,double*,double*))qd_lt, pv); }
406
+ bool operator > (const poly_view& pv) { return poly_eq((bool(*)(size_t,double*,double*))qd_gt, pv); }
407
+ bool operator <=(const poly_view& pv) { return poly_eq((bool(*)(size_t,double*,double*))qd_le, pv); }
408
+ bool operator >=(const poly_view& pv) { return poly_eq((bool(*)(size_t,double*,double*))qd_ge, pv); }
409
+ bool operator !=(const poly_view& pv) { return !((*this) == pv); }
410
+ bool operator ==(T a) { return poly_eq((bool(*)(size_t,double*,double))qd_eq, a); }
411
+ bool operator < (T a) { return poly_eq((bool(*)(size_t,double*,double))qd_lt, a); }
412
+ bool operator > (T a) { return poly_eq((bool(*)(size_t,double*,double))qd_gt, a); }
413
+ bool operator <=(T a) { return poly_eq((bool(*)(size_t,double*,double))qd_le, a); }
414
+ bool operator >=(T a) { return poly_eq((bool(*)(size_t,double*,double))qd_ge, a); }
415
+ bool operator !=(T a) { return !((*this) == a); }
416
+
417
+ void swap(size_t i, size_t j)
418
+ {
419
+ Int s = Int(*this) << 1;
420
+ size_t n = s.data_size();
421
+ T *p = &data[i * n], *q = &data[j * n];
422
+ for (size_t k = 0; k < n; ++k) {
423
+ T w = p[k]; p[k] = q[k]; q[k] = w;
424
+ }
425
+ }
426
+
427
+ char *to_s(const char *f = NULL) const
428
+ {
429
+ char buf[1024];
430
+ char *c = buf;
431
+ const Int& p = *this;
432
+ char *s = p.to_s();
433
+ sprintf(c, "{%s,", s); while(*c)++c;
434
+ sprintf(c++, "@");
435
+ delete[] s;
436
+ int N = p.grid(), w[N+1];
437
+ for (int i = 0; i <= N; ++i) w[i] = p[i];
438
+ poly_to_s<T>(c, N, w, data);
439
+ sprintf(c++, "}");
440
+ int n = c - buf;
441
+ c = new char[n + 1];
442
+ strcpy(c, buf);
443
+ return c;
444
+ }
445
+ void print(const char *fmt = "%g\n") const { poly_print(*this, fmt); }
446
+
447
+ }; // end of poly_view;
448
+
449
+ template<typename T> void swap(const poly_view<T>& p, const poly_view<T>& q)
450
+ {
451
+ size_t n = p.data_size(); T *pd = p;
452
+ size_t m = q.data_size(); T *qd = q;
453
+ if (n != m) throw "size mismatch, poly_view.swap";
454
+ for (size_t i = 0; i < n; ++i) {
455
+ T w = pd[i]; pd[i] = qd[i]; qd[i] = w;
456
+ }
457
+ }
458
+
459
+ template <typename T>
460
+ void Kronecker(const poly_view<T>& p, const poly_view<T>& q, poly_view<T>& r)
461
+ {
462
+ if (r.is_atom()) *r = *p * (*q);
463
+ else
464
+ {
465
+ Int u = p.tags();
466
+ Int v = q.tags();
467
+ int s = u[0], t = v[0];
468
+ for (int i = 0; i < s; i++) {
469
+ for (int j = 0; j < t; j++) {
470
+ poly_view<T> pdr = p[i], qdr = q[j], rdr = r[i*t+j];
471
+ Kronecker(pdr, qdr, rdr);
472
+ }
473
+ }
474
+ }
475
+ }
476
+
477
+ template <typename T>
478
+ poly_array<T> operator^(const poly_array<T>& p, const poly_array<T>& q)
479
+ {
480
+ Int ps = p.tags();
481
+ Int qs = q.tags();
482
+ Int rs = ps * qs;
483
+ poly_array<T> result(rs);
484
+ poly_view<T> pv(p), qv(q), rv(result);
485
+ Kronecker(pv, qv, rv);
486
+ return result;
487
+ }
488
+
489
+ typedef poly_array<double> Real_array;
490
+ typedef poly_view<double> Real_view;
491
+
492
+ /*******************************************************************************
493
+ comb_array<T>(T*,N,S1,...,SN,A);
494
+ {<{S1,...,SN},A>,[(S1,...),...],...,[(SN,...),...]}
495
+ *******************************************************************************/
496
+ template<typename T = double> class comb_array : public Int
497
+ {
498
+ template <class> friend class comb_view;
499
+
500
+ T *data;
501
+
502
+ void init_data(const T *dat)
503
+ {
504
+ if (dat) {
505
+ int N = this->grid();
506
+ size_t s = this->band_size(N);
507
+ T *temp = new T[s];
508
+ for (size_t i = 0; i < s; ++i) temp[i] = dat[i];
509
+ data = temp;
510
+ } else {
511
+ // size_t N = this->grid();
512
+ // for (size_t i = 0; i <= N; ++i) Int::w[i] = 0;
513
+ data = NULL;
514
+ }
515
+ }
516
+
517
+ public:
518
+ // General constructor
519
+ template <class... Args>
520
+ comb_array(T *dat, int car, Args... cdr) : Int(car, cdr...) { init_data(dat); }
521
+ comb_array(T *dat, int n, int *c) : Int(n, c ) { init_data(dat); }
522
+ comb_array(T *dat, const Int& b) : Int(b ) { init_data(dat); }
523
+ // copy constructor
524
+ comb_array(const comb_array& ba) : Int(ba) { init_data(ba.data); }
525
+ // destructor
526
+ ~comb_array() {delete[] data;}
527
+ // assignment operator
528
+ comb_array& operator=(const comb_array& ba)
529
+ {
530
+ if (this != &ba) {
531
+ delete data;
532
+ Int::operator=(ba);
533
+ init_data(ba.data);
534
+ }
535
+ return *this;
536
+ }
537
+ varray<T> operator[](int i) const
538
+ {
539
+ const Int& z = *this;
540
+ int N = z.grid();
541
+ if (!(0 <= i && i <= N)) throw "out of range, comb_view[]";
542
+ varray<T> result;
543
+ if (z[i] != 0) {
544
+ T *r = (i == N) ? data : &data[z.band_size(i)];
545
+ result = varray<T>(r, z[i], z.atom());
546
+ }
547
+ return result;
548
+ }
549
+ int operator()(int i) const
550
+ {
551
+ return Int::operator[](i);
552
+ }
553
+ char *to_s(const char *f = NULL) const
554
+ {
555
+ str_buf c;;
556
+ const Int& p = *this;
557
+ char *s = p.to_s();
558
+ c += '{'; c+= s;
559
+ delete[] s;
560
+ int N = p.grid(), n = 0, A = p.atom();
561
+ if (N > 0) for (int i = 0; i < N; ++i) {
562
+ c += '[';
563
+ int l = p[i];
564
+ for (int j = 0; j < l; ++j) {
565
+ const T *pos = &data[n+j*(A+1)];
566
+ if (A > 0) c += '<';
567
+ for (int a = 0; a <= A; ++a) {
568
+ sprintg(c, pos[a], f);
569
+ if (a < A) c += ',';
570
+ }
571
+ if (A > 0) c += '>';
572
+ if (j < l-1) c += ',';
573
+ }
574
+ c += ']';
575
+ if (i < N-1) c += ',';
576
+ n += l * (A+1);
577
+ } else {
578
+ N = p[0];
579
+ c += '<';
580
+ for (int i = 0; i <= N; ++i) {
581
+ sprintg(c, data[i], f); if (i < N) c += ',';
582
+ }
583
+ c += '>';
584
+ }
585
+ c += '}';
586
+ s = new char[c.size() + 1];
587
+ strcpy(s, c.c_str());
588
+ return s;
589
+ }
590
+ void fprint(FILE *f, const char *fmt = "%g\n") const { gprint(*this, f, fmt); }
591
+ void print(const char *fmt = "%g\n") const { this->fprint(stdout, fmt); }
592
+
593
+ }; // end of comb_array;
594
+
595
+ template<typename T = double> class comb_view : public Int
596
+ {
597
+
598
+ T *data;
599
+
600
+ public:
601
+ // Atom constructor
602
+ comb_view(T *dat) : Int{ 1 }, data(dat) {}
603
+ comb_view(T *dat, int n) : Int{static_cast<UTYPE>(n)}, data(dat) {}
604
+ // General constructor
605
+ template <class... Args>
606
+ comb_view(T *dat, Args... cdr ) : Int(cdr...), data(dat) {}
607
+ comb_view(T *dat, int n, int *c ) : Int(n, c ), data(dat) {}
608
+ comb_view(T *dat, const Int& b ) : Int(b ), data(dat) {}
609
+ comb_view(const comb_array<T>& ca) : Int(ca), data(ca.data) {}
610
+ // copy constructor
611
+ comb_view(const comb_view& ba) : Int(ba), data(ba.data) {}
612
+ // destructor
613
+ // assignment operator
614
+ comb_view& operator=(const comb_view& ba)
615
+ {
616
+ if (this != &ba) {
617
+ int s = this->comb_size();
618
+ int t = ba.comb_size();
619
+ if (s != t) throw "size mismatch, comb_view = ";
620
+ for (int i = 0; i < s; ++i) data[i] = ba.data[i];
621
+ }
622
+ return *this;
623
+ }
624
+ varray<T> operator[](int i) const
625
+ {
626
+ const Int& z = *this;
627
+ int N = z.grid();
628
+ if (!(0 <= i && i <= N)) throw "out of range, comb_view[]";
629
+ varray<T> result;
630
+ if (z[i] != 0) {
631
+ T *r = (i == N) ? data : &data[z.band_size(i)];
632
+ result = varray<T>(r, z[i], z.atom());
633
+ }
634
+ return result;
635
+ }
636
+ int operator()(int i) const
637
+ {
638
+ return Int::operator[](i);
639
+ }
640
+ char *to_s(const char *f = NULL) const
641
+ {
642
+ str_buf c;
643
+ const Int& p = *this;
644
+ char *s = p.to_s();
645
+ c += '{'; c += s;
646
+ delete[] s;
647
+ int N = p.grid(), n = 0, A = p.atom();
648
+ if (N > 0) for (int i = 0; i < N; ++i) {
649
+ c += "@[";
650
+ int l = p[i];
651
+ for (int j = 0; j < l; ++j) {
652
+ const T *pos = &data[n+j*(A+1)];
653
+ if (A > 0) c += '<';
654
+ for (int a = 0; a <= A; ++a) {
655
+ sprintg(c, pos[a], f);
656
+ if (a < A) c += ',';
657
+ }
658
+ if (A > 0) c += '>';
659
+ if (j < l-1) c += ',';
660
+ }
661
+ c += ']';
662
+ if (i < N-1) c += ',';
663
+ n += l * (A+1);
664
+ } else {
665
+ N = p[0];
666
+ c += "@<";
667
+ for (int i = 0; i <= N; ++i) {
668
+ sprintg(c, data[i], f); if (i < N) c += ',';
669
+ }
670
+ c += '>';
671
+ }
672
+ c += '}';
673
+ s = new char[c.size() + 1];
674
+ strcpy(s, c.c_str());
675
+ return s;
676
+ }
677
+ void fprint(FILE *f, const char *fmt = "%g\n") const { gprint(*this, f, fmt); }
678
+ void print(const char *fmt = "%g\n") const { this->fprint(stdout, fmt); }
679
+
680
+ }; // end of comb_view;
681
+
682
+ template<typename T = double> class comp_array : public Int
683
+ {
684
+ T *data;
685
+
686
+ public:
687
+ // mono constructor
688
+ comp_array(T *dat, int o, int s, int k = 1, int a = 0) : Int{
689
+ static_cast<UTYPE>(o),
690
+ static_cast<UTYPE>(s),
691
+ static_cast<UTYPE>(k),
692
+ static_cast<UTYPE>(a) }, data(new T[s*k*(a+1)])
693
+ {
694
+ size_t sk = s * k * (a+1);
695
+ for (size_t i = 0; i < sk; ++i) data[i] = dat[i];
696
+ }
697
+ // General constructor
698
+ template <class... Args>
699
+ comp_array(T *dat, Args... t) : Int(t...)
700
+ {
701
+ int N = this->grid() - 1;
702
+ size_t sk = this->cast_size(N, N/2);
703
+ data = new T[sk];
704
+ for (size_t i = 0; i < sk; ++i) data[i] = dat[i];
705
+ }
706
+ comp_array(T *dat, int n, int *s) : Int(n+1, s)
707
+ {
708
+ int N = this->grid() - 1;
709
+ size_t sk = this->cast_size(N, N/2);
710
+ data = new T[sk];
711
+ for (size_t i = 0; i < sk; ++i) data[i] = dat[i];
712
+ }
713
+ // copy constructor
714
+ comp_array(const comp_array& pa) : Int(pa)
715
+ {
716
+ int N = this->grid() - 1;
717
+ size_t sk = this->cast_size(N, N/2);
718
+ data = new T[sk];
719
+ for (size_t i = 0; i < sk; ++i) data[i] = pa.data[i];
720
+ }
721
+ // destructor
722
+ ~comp_array() {delete[] data;}
723
+ // assignment operator
724
+ comp_array& operator=(const comp_array& pa)
725
+ {
726
+ if (this != &pa) {
727
+ delete data;
728
+ Int::operator=(pa);
729
+ int N = this->grid() - 1;
730
+ size_t sk = this->cast_size(N, N/2);
731
+ data = new T[sk];
732
+ for (size_t i = 0; i < sk; ++i) data[i] = pa.data[i];
733
+ }
734
+ return *this;
735
+ }
736
+ // member function
737
+ Int offset() const
738
+ {
739
+ const Int& b = *this;
740
+ int N = b.grid() - 1;
741
+ Int x(size_t(N/2));
742
+ for (int i = 0; i < N/2; ++i) x[i] = b[i]; x[N/2] = 0;
743
+ return x;
744
+ }
745
+ Int size() const
746
+ {
747
+ const Int& b = *this;
748
+ int N = b.grid() - 1;
749
+ Int x(size_t(N/2));
750
+ for (int i = 0; i < N/2; ++i) x[i] = b[N/2+i]; x[N/2] = b.unit();
751
+ return x;
752
+ }
753
+ comp_view<T> operator[](const Int& p) const
754
+ {
755
+ const Int& b = *this;
756
+ int N = b.grid() - 1, K = b.unit(), A = b.atom();
757
+ T **nk = new T*[N/2];
758
+ for (int n = 0, i = 0; i < N/2; ++i) {
759
+ int s = b[i+N/2];
760
+ int k = n + p[i];
761
+ nk[i] = &data[k*(A+1)];
762
+ n += s * K;
763
+ }
764
+ Int x(size_t(N/2) + 1);
765
+ for (int i = 0; i < N/2; ++i) x[i] = b[N/2+i];
766
+ x[N/2] = p[N/2]; x[N/2 + 1] = A;
767
+ return comp_view<T>(nk, x);
768
+ }
769
+ T* operator[](int i) const
770
+ {
771
+ const Int& b = *this;
772
+ int N = b.grid() - 1;
773
+ return &data[b.cast_size(N/2 + i, N/2)];
774
+ }
775
+ int operator() (int i) const
776
+ {
777
+ return Int(*this)[i];
778
+ }
779
+ operator T* () {return data;}
780
+ comp_array operator & (const comp_array& pa)
781
+ {
782
+ const Int& bt = *this;
783
+ const Int& pt = pa;
784
+ int Nt = bt.grid() - 1, Np = pt.grid() - 1;
785
+ int A = bt.atom(), s[Nt + Np + 2], *sp = s;
786
+ for (int i = 0; i < Nt/2; ++i) *sp++ = bt[i];
787
+ for (int i = 0; i < Np/2; ++i) *sp++ = pt[i];
788
+ for (int i =Nt/2; i < Nt; ++i) *sp++ = bt[i];
789
+ for (int i =Np/2; i < Np; ++i) *sp++ = pt[i];
790
+ size_t skt = bt.cast_size(Nt, Nt/2);
791
+ size_t skp = pt.cast_size(Np, Np/2);
792
+ T dt[(skt + skp)*(A+1)], *dp = dt;
793
+ for (size_t i = 0; i < skt; ++i) *dp++ = data[i];
794
+ for (size_t i = 0; i < skp; ++i) *dp++ = pa.data[i];
795
+ *sp++ = bt.unit(); *sp = A;
796
+ return comp_array(dt, Nt + Np, s);
797
+ }
798
+ char *to_s(const char *f = NULL) const
799
+ {
800
+ str_buf c;
801
+ const Int& p = *this;
802
+ int N = p.grid() - 1, K = p.unit(), A = p.atom();
803
+ c += "{<";
804
+ if (N > 0) {
805
+ c += '{';
806
+ for (int i = 0; i < N/2; ++i) {
807
+ sprintg(c, p[i]);
808
+ if (i == N/2-1) c += '}';
809
+ c += ',';
810
+ }
811
+ c += '{';
812
+ for (int i = N/2; i < N; ++i) {
813
+ sprintg(c, p[i]);
814
+ if (i == N-1) c += '}';
815
+ c += ',';
816
+ }
817
+ }
818
+ sprintg(c, p[N]);
819
+ if (A > 0) sprintg(c, p[N+1]);
820
+ c += ">,";
821
+ int n = 0;
822
+ for (int i = 0; i < N/2; ++i) {
823
+ int z = p[i + N/2];
824
+ c += '[';
825
+ for (int k = 0; k < K; ++k) {
826
+ c += '(';
827
+ for (int j = 0; j < z; ++j) {
828
+ T* w = &data[n+(z*k+j)*(A+1)];
829
+ if (A > 0) c += '<';
830
+ for (int a = 0; a <= A; ++a) {
831
+ sprintg(c, w[a], f);
832
+ if (a < A) c += ',';
833
+ }
834
+ if (A > 0) c += '>';
835
+ if (j < z-1) c += ',';
836
+ }
837
+ c += ')';
838
+ if (k < K-1) c += ',';
839
+ }
840
+ c += ']';
841
+ if (i < N/2-1) c += ',';
842
+ n += z * K * (A+1);
843
+ }
844
+ c += '}';
845
+ char *s = new char[c.size() + 1];
846
+ strcpy(s, c.c_str());
847
+ return s;
848
+ }
849
+ void fprint(FILE *f, const char *fmt = "%g\n") const { gprint(*this, f, fmt); }
850
+ void print(const char *fmt = "%g\n") const { this->fprint(stdout, fmt); }
851
+
852
+ }; // end of comp_array;
853
+
854
+ template<typename T = double> class comp_view : public Int
855
+ {
856
+ T **data;
857
+
858
+ public:
859
+ template <class... Args>
860
+ comp_view(T **dat, Args... cdr ) : Int(cdr...), data(dat) {}
861
+ comp_view(T **dat, int n, int *c) : Int(n, c ), data(dat) {}
862
+ comp_view(T **dat, const Int& b) : Int(b ), data(dat) {}
863
+ //comp_view(const comp_view&) = delete;
864
+ ~comp_view() { delete[] data; }
865
+ // 関数値の計算
866
+ real<T> operator * () const
867
+ {
868
+ const Int& t = *this;
869
+ int N = t.grid(), w[N+1];
870
+ for (int i = 0; i <= N; ++i) w[i] = t[i];
871
+ return coefficient<varray<T>,real<T>,T>(data, w, N-1);
872
+ }
873
+ // 微分値の計算
874
+ real<T> operator[](int j) const
875
+ {
876
+ const Int& t = *this;
877
+ int N = t.grid(), w[N+1];
878
+ for (int i = 0; i <= N; ++i) w[i] = t[i];
879
+ return coefficient<varray<T>,real<T>,T>(data, w, N-1, j);
880
+ }
881
+ // 全微分の計算
882
+ real<T> operator[](const varray<T>& ds) const
883
+ {
884
+ const Int& t = *this;
885
+ int N = t.grid(), w[N+1];
886
+ for (int i = 0; i <= N; ++i) w[i] = t[i];
887
+ return total_derive<varray<T>,real<T>,T>(data, w, N-1, t.unit()-1, ds);
888
+ }
889
+ // 積分値の計算
890
+ real<T> operator () (const real<T>& dh, int j = 0) const
891
+ {
892
+ const Int& p = *this;
893
+ int k = p.unit(); size_t a = p.atom();
894
+ #ifndef NDEBUG
895
+ int N = p.grid();
896
+ #endif
897
+ assert(j < N-1);
898
+ real<T> sum;
899
+ T *ds = data[j];
900
+ int c = p[j] * k;
901
+ for (int i = k; i > 0; --i) {
902
+ real<T> dt(a, &ds[c -= p[j]], 0);
903
+ sum = (sum + dt) * dh / T(i);
904
+ }
905
+ return sum;
906
+ }
907
+ // テイラー展開
908
+ real<T> taylor(const real<T>& dh, int j = 0) const
909
+ {
910
+ const Int& p = *this;
911
+ int k = p.unit_size(); size_t a = p.atom();
912
+ #ifndef NDEBUG
913
+ int N = p.grid()
914
+ #endif
915
+ assert(j < N-1);
916
+ real<T> sum;
917
+ T *ds = data[j];
918
+ int c = p[j] * k;
919
+ for (int i = k; i > 0; --i) {
920
+ real<T> dt(a, &ds[c -= p[j]], 0);
921
+ sum = sum * dh / T(i) + dt;
922
+ }
923
+ return sum;
924
+ }
925
+ char *to_s(const char *f = NULL) const
926
+ {
927
+ str_buf c;
928
+ const Int& p = *this;
929
+ int N = p.grid() - 1;
930
+ int K = p.unit();
931
+ int A = p.atom();
932
+ c += "{<";
933
+ if (N > 0) {
934
+ c += '{';
935
+ for (int i = 0; i < N; ++i) {
936
+ sprintg(c, p[i]);
937
+ if (i == N-1) c += '}';
938
+ c += ',';
939
+ }
940
+ }
941
+ sprintg(c, p[N]);
942
+ if (A > 0) { c += ','; sprintg(c, p[N+1]); }
943
+ c += ">,@[";
944
+ for (int i = 0; i < N; ++i) {
945
+ if (K > 1) c += '[';
946
+ for (int j = 0; j < K; ++j) {
947
+ if (A > 0) c += '<';
948
+ for (int a = 0; a <= A; ++a) {
949
+ sprintg(c, data[i][j*p[i]*(A+1)+a], f);
950
+ if (a < A) c += ',';
951
+ }
952
+ if (A > 0) c += '>';
953
+ if (j < K-1) c += ',';
954
+ }
955
+ if (K > 1) c += ']';
956
+ if (i < N-1) c += ',';
957
+ }
958
+ c += "]}";
959
+ char *s = new char[c.size() + 1];
960
+ strcpy(s, c.c_str());
961
+ return s;
962
+ }
963
+ void fprint(FILE *f, const char *fmt = "%g\n") const { gprint(*this, f, fmt); }
964
+ void print(const char *fmt = "%g\n") const { this->fprint(stdout, fmt); }
965
+
966
+ }; // end of comp_view;
967
+
968
+ template <typename T = double>
969
+ bool xvalue(int &i, real<T>& x, const varray<T>& X, real<T>& t, int &l, int L, int &d, int p, bool F)
970
+ // i:index, l:line counter, L:line limits, d:divide counter, p:divide number
971
+ // x:value, X:variable array, t:divide value
972
+ {
973
+ bool f = false;
974
+ if (F)
975
+ if (d++ == p) {
976
+ if (++l == L) {
977
+ f = true;
978
+ l = 1;
979
+ } t = ((T*)X ? (X[l] - X[l-1]) : 1.0) / p;
980
+ d = (l == 1) ? 0 : 1;
981
+ }
982
+ i = d + (l - 1) * p;
983
+ x = ( (T*)X ? X[l - 1] : real<T>(T(l - 1)) ) + d * t;
984
+ return f;
985
+ }
986
+
987
+ template <typename T = double> class poly_index
988
+ {
989
+ size_t N, A; int *index, *Le, *Lc, *Nc, Dx; varray<T> *value, *Dt, *X; Int *e;
990
+
991
+ public:
992
+ template <class... Args>
993
+ poly_index(const comb_array<T>& x, int Dp, Args... End)
994
+ {
995
+ const Int& end = x; N = end.grid(); A = end.atom();
996
+ int Np[N+1], E[] = { End...}; size_t t = 0;
997
+ Nc = new int[N*4+1]; Lc = Nc + N; Le = Lc + N; index = Le + N;
998
+ value = new varray<T>(N, A); Dt = new varray<T>(N, A); X = new varray<T>[N];
999
+ for (size_t i = 0; i < N; i++) {
1000
+ int size = end[i] ? end[i] : E[t++];
1001
+ Np[i] =(size - 1) * Dp + 1;
1002
+ Le[i] = size; X[i] = x[i];
1003
+ Lc[i] = 1; Nc[i] = 0;
1004
+ (*Dt)[i] = ((T*)X[i] ? (X[i][1] - X[i][0]) : 1.0) / Dp;
1005
+ real<T> u = (*value)[i];
1006
+ real<T> w = (*Dt)[i];
1007
+ xvalue(index[i], u, X[i], w, Lc[i], Le[i], Nc[i], Dp, false);
1008
+ } Dx = Dp; Np[N] = 0; index[N] = 0;
1009
+ e = new Int(int(N), Np);
1010
+ }
1011
+ ~poly_index() { delete e; delete[] X; delete Dt; delete value; delete[] Nc; }
1012
+ poly_index& operator++()
1013
+ {
1014
+ bool f = true;
1015
+ for (size_t j = N; j > 0; --j) {
1016
+ size_t i = j - 1;
1017
+ real<T> u = (*value)[i];
1018
+ real<T> w = (*Dt)[i];
1019
+ f = xvalue<double>(index[i], u, X[i], w, Lc[i], Le[i], Nc[i], Dx, f);
1020
+ }
1021
+ return *this;
1022
+ }
1023
+ int index_size() { return e->grid_size(Atom); } // return Npx;
1024
+ Int get_index() { return Int(int(N), index); }
1025
+ int index_value() { return (*e) && get_index(); } // convert index to number;
1026
+ varray<T>& get_value() { return *value; }
1027
+
1028
+ }; // end of poly_index
1029
+
1030
+ #endif