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.
- checksums.yaml +4 -4
- data/Gemfile +5 -5
- data/README.md +44 -43
- data/Rakefile +6 -6
- data/bin/console +14 -14
- data/bin/setup +8 -8
- data/ext/pspline/basis.cpp +394 -351
- data/ext/pspline/example/exbspline.rb +57 -57
- data/ext/pspline/example/excspline.rb +57 -57
- data/ext/pspline/example/exdspline.rb +55 -55
- data/ext/pspline/example/exfspline.rb +44 -44
- data/ext/pspline/example/exfspline1.rb +40 -40
- data/ext/pspline/example/exfspline2.rb +68 -68
- data/ext/pspline/example/exfspline3.rb +64 -64
- data/ext/pspline/example/exmspline.rb +68 -68
- data/ext/pspline/example/expspline.rb +29 -29
- data/ext/pspline/example/expspline1.rb +29 -29
- data/ext/pspline/example/expspline2.rb +47 -47
- data/ext/pspline/example/exqspline.rb +31 -31
- data/ext/pspline/example/exqspline1.rb +31 -31
- data/ext/pspline/example/exqspline2.rb +50 -50
- data/ext/pspline/example/exqspline3.rb +51 -51
- data/ext/pspline/example/exqspline4.rb +35 -35
- data/ext/pspline/example/exrspline.rb +34 -34
- data/ext/pspline/example/exrspline1.rb +34 -34
- data/ext/pspline/example/exrspline2.rb +44 -44
- data/ext/pspline/example/exsspline.rb +35 -35
- data/ext/pspline/example/exsspline1.rb +35 -35
- data/ext/pspline/example/extspline.rb +54 -54
- data/ext/pspline/extconf.rb +7 -7
- data/ext/pspline/fft.cpp +27 -552
- data/ext/pspline/include/basis/basis.h +145 -137
- data/ext/pspline/include/basis/fft.h +188 -152
- data/ext/pspline/include/basis/fft_complex.h +215 -0
- data/ext/pspline/include/basis/fft_real.h +625 -0
- data/ext/pspline/include/basis/gabs.h +35 -0
- data/ext/pspline/include/basis/marray_class_ext.h +568 -0
- data/ext/pspline/include/basis/marray_ext.h +100 -0
- data/ext/pspline/include/basis/matrix_luc_ext.h +300 -0
- data/ext/pspline/include/basis/matrix_lud_ext.h +298 -0
- data/ext/pspline/include/basis/poly.h +454 -0
- data/ext/pspline/include/basis/poly_array.h +1030 -1568
- data/ext/pspline/include/basis/pspline.h +806 -642
- data/ext/pspline/include/basis/real.h +526 -0
- data/ext/pspline/include/basis/real_inline.h +442 -0
- data/ext/pspline/include/basis/spline.h +83 -0
- data/ext/pspline/include/basis/uspline.h +251 -210
- data/ext/pspline/include/basis/util.h +122 -656
- data/ext/pspline/include/bspline.h +71 -377
- data/ext/pspline/include/bspline_Config.h +8 -2
- data/ext/pspline/include/real_config.h +3 -0
- data/ext/pspline/pspline.cpp +1236 -1038
- data/ext/pspline/real.cpp +1607 -0
- data/ext/pspline/real_const.cpp +585 -0
- data/lib/pspline.rb +71 -71
- data/lib/pspline/version.rb +1 -1
- data/pspline.gemspec +25 -25
- metadata +17 -5
- data/ext/pspline/plotsub.cpp +0 -139
- data/ext/pspline/util.cpp +0 -483
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#ifndef _GABS_H_
|
|
2
|
+
#define _GABS_H_
|
|
3
|
+
|
|
4
|
+
#include <stdlib.h>
|
|
5
|
+
|
|
6
|
+
#ifdef USE_COMPLEX
|
|
7
|
+
#include <complex.h>
|
|
8
|
+
#ifdef I
|
|
9
|
+
#undef I
|
|
10
|
+
#endif
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
#ifdef USE_RATIONAL
|
|
14
|
+
#include <boost/rational.hpp>
|
|
15
|
+
typedef boost::rational<int> Rational;
|
|
16
|
+
#include <iostream>
|
|
17
|
+
#endif
|
|
18
|
+
/*******************************************************************************
|
|
19
|
+
define global absolute.
|
|
20
|
+
*******************************************************************************/
|
|
21
|
+
template <class T> inline T gabs(T);
|
|
22
|
+
|
|
23
|
+
template <> inline int gabs( int a) { return abs(a); }
|
|
24
|
+
template <> inline long int gabs( long int a) { return labs(a); }
|
|
25
|
+
template <> inline double gabs( double a) { return fabs(a); }
|
|
26
|
+
template <> inline float gabs( float a) { return fabsf(a); }
|
|
27
|
+
template <> inline long double gabs(long double a) { return fabsl(a); }
|
|
28
|
+
#ifdef USE_COMPLEX
|
|
29
|
+
template <> inline double gabs(std::complex<double> c) { return abs(c); }
|
|
30
|
+
#endif
|
|
31
|
+
#ifdef USE_RATIONAL
|
|
32
|
+
template <> inline Rational gabs(Rational r) { return abs(r); }
|
|
33
|
+
#endif
|
|
34
|
+
|
|
35
|
+
#endif
|
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
#ifndef _MARRAY_CLASS_H_
|
|
2
|
+
#define _MARRAY_CLASS_H_
|
|
3
|
+
|
|
4
|
+
#include "basis/util.h"
|
|
5
|
+
|
|
6
|
+
template <typename T = double> class varray
|
|
7
|
+
{
|
|
8
|
+
struct add {
|
|
9
|
+
static real<T> apply(const real<T>& l, const real<T>& r) { return l + r; }
|
|
10
|
+
static real<T> apply(T l, const real<T>& r) { return l + r; }
|
|
11
|
+
static real<T> apply(const real<T>& l, T r) { return l + r; }
|
|
12
|
+
};
|
|
13
|
+
struct sub {
|
|
14
|
+
static real<T> apply(const real<T>& l, const real<T>& r) { return l - r; }
|
|
15
|
+
static real<T> apply(T l, const real<T>& r) { return l - r; }
|
|
16
|
+
static real<T> apply(const real<T>& l, T r) { return l - r; }
|
|
17
|
+
};
|
|
18
|
+
struct mul {
|
|
19
|
+
static real<T> apply(const real<T>& l, const real<T>& r) { return l * r; }
|
|
20
|
+
static real<T> apply(T l, const real<T>& r) { return l * r; }
|
|
21
|
+
static real<T> apply(const real<T>& l, T r) { return l * r; }
|
|
22
|
+
};
|
|
23
|
+
struct div {
|
|
24
|
+
static real<T> apply(const real<T>& l, const real<T>& r) { return l / r; }
|
|
25
|
+
static real<T> apply(T l, const real<T>& r) { return l / r; }
|
|
26
|
+
static real<T> apply(const real<T>& l, T r) { return l / r; }
|
|
27
|
+
};
|
|
28
|
+
template <class L, class Op, class R> class expr_
|
|
29
|
+
{
|
|
30
|
+
const L& _l; const R& _r;
|
|
31
|
+
public:
|
|
32
|
+
expr_(const L& l, const R& r) : _l(l), _r(r) {}
|
|
33
|
+
real<T> operator[](size_t i) const { return Op::apply(_l[i], _r); }
|
|
34
|
+
};
|
|
35
|
+
template <class L, class Op, class R> class expr
|
|
36
|
+
{
|
|
37
|
+
const L& _l; const R& _r;
|
|
38
|
+
public:
|
|
39
|
+
expr(const L& l, const R& r) : _l(l), _r(r) {}
|
|
40
|
+
real<T> operator[](size_t i) const { return Op::apply(_l[i], _r[i]); }
|
|
41
|
+
expr<expr,add,varray<T> > operator + (const varray<T> & v) { return expr<expr,add,varray<T> >(*this, v); }
|
|
42
|
+
expr<expr,sub,varray<T> > operator - (const varray<T> & v) { return expr<expr,sub,varray<T> >(*this, v); }
|
|
43
|
+
expr<expr,mul,varray<T> > operator * (const varray<T> & v) { return expr<expr,mul,varray<T> >(*this, v); }
|
|
44
|
+
expr<expr,div,varray<T> > operator / (const varray<T> & v) { return expr<expr,div,varray<T> >(*this, v); }
|
|
45
|
+
expr_<expr,add,T> operator + (const T& d) { return expr_<expr,add,T>(*this, d); }
|
|
46
|
+
expr_<expr,sub,T> operator - (const T& d) { return expr_<expr,sub,T>(*this, d); }
|
|
47
|
+
expr_<expr,mul,T> operator * (const T& d) { return expr_<expr,mul,T>(*this, d); }
|
|
48
|
+
expr_<expr,div,T> operator / (const T& d) { return expr_<expr,div,T>(*this, d); }
|
|
49
|
+
};
|
|
50
|
+
template <class Op> class expr<varray<T>, Op, real<T> >
|
|
51
|
+
{
|
|
52
|
+
const varray<T>& _l; const real<T>& _r;
|
|
53
|
+
public:
|
|
54
|
+
expr(const varray<T>& l, const real<T>& r) : _l(l), _r(r) {}
|
|
55
|
+
real<T> operator[](size_t i) const { return Op::apply(_l[i], _r); }
|
|
56
|
+
};
|
|
57
|
+
template <class Op> class expr<real<T>, Op, varray<T> >
|
|
58
|
+
{
|
|
59
|
+
const real<T>& _l; const varray<T>& _r;
|
|
60
|
+
public:
|
|
61
|
+
expr(const real<T>& l, const varray<T>& r) : _l(l), _r(r) {}
|
|
62
|
+
real<T> operator[](size_t i) const { return Op::apply(_l, _r[i]); }
|
|
63
|
+
};
|
|
64
|
+
template <class Op> class expr<varray<T>, Op, T>
|
|
65
|
+
{
|
|
66
|
+
const varray<T>& _l; T _r;
|
|
67
|
+
public:
|
|
68
|
+
expr(const varray<T>& l, T r) : _l(l), _r(r) {}
|
|
69
|
+
real<T> operator[](size_t i) const { return Op::apply(_l[i], _r); }
|
|
70
|
+
};
|
|
71
|
+
template <class Op> class expr<T, Op, varray<T> >
|
|
72
|
+
{
|
|
73
|
+
T _l; const varray<T>& _r;
|
|
74
|
+
public:
|
|
75
|
+
expr(T l, const varray<T>& r) : _l(l), _r(r) {}
|
|
76
|
+
real<T> operator[](size_t i) const { return Op::apply(_l, _r[i]); }
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
protected:
|
|
80
|
+
|
|
81
|
+
size_t _size, N; T *w; int _st, _f;
|
|
82
|
+
|
|
83
|
+
public:
|
|
84
|
+
varray() : _size(), N(), w(NULL), _st(0), _f(0) {}
|
|
85
|
+
varray(size_t n, size_t m = 0, int st = 1) : _size(n), N(m), w(new T[n*(m+1)]), _st(st), _f(1) {}
|
|
86
|
+
varray(T t, size_t n, size_t m = 0, int st = 1, int f = 1) : _size(n), N(m), w(new T[n*(m+1)*st]), _st(st), _f(f)
|
|
87
|
+
{
|
|
88
|
+
for (size_t i = 0; i < n; ++i) {
|
|
89
|
+
real<T> z(m, &w[i*(m+1)*st], 0); z = t;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
varray(T t, T s, size_t m = 0, int st = 1, int f = 1) : _size(2), N(m), w(new T[2*(m+1)*st]), _st(st), _f(f)
|
|
93
|
+
{
|
|
94
|
+
real<T> z0(m, w, 0); z0 = t;
|
|
95
|
+
real<T> z1(m, &w[(m+1)*st], 0); z1 = s;
|
|
96
|
+
}
|
|
97
|
+
varray(T *dat, size_t n, size_t m = 0, int st = 1, int f = 0) : _size(n), N(m), w(dat), _st(st), _f(f)
|
|
98
|
+
{
|
|
99
|
+
if (_f) {
|
|
100
|
+
size_t s = n*(m+1)*st; w = new T[s];
|
|
101
|
+
for (size_t i = 0; i < s; ++i) w[i] = dat[i];
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
varray(const varray& v) : _size(v._size), N(v.N), w(new T[v._size*(v.N+1)]), _st(1), _f(1)
|
|
105
|
+
{
|
|
106
|
+
for (size_t i = 0; i < _size; ++i)
|
|
107
|
+
for (size_t j = 0; j <= N; ++j)
|
|
108
|
+
w[i*(N+1)+j] = v.w[i*(N+1)*v._st+j];
|
|
109
|
+
}
|
|
110
|
+
~varray() { if (_f) delete[] w; }
|
|
111
|
+
varray& operator = (const varray& v)
|
|
112
|
+
{
|
|
113
|
+
if (this != &v) {
|
|
114
|
+
if (_size < v._size) { delete[] w; w = NULL; }
|
|
115
|
+
if (w == NULL) {
|
|
116
|
+
_size = v._size; N = v.N; size_t size = _size * (N + 1);
|
|
117
|
+
if (size) { w = new T[size]; _st = _f = 1; } else { _st = _f = 0; }
|
|
118
|
+
} assert(_size >= v._size && N == v.N);
|
|
119
|
+
size_t at = (N + 1) * _st, vat = (v.N + 1) * v._st;
|
|
120
|
+
if (_size > v._size)
|
|
121
|
+
{
|
|
122
|
+
int h, i, j, k(_size - v._size), m((k + 1) / 2), o(k - m), s(_size), t(v._size), u(N);
|
|
123
|
+
for(i=m-1,k=s-m;i>=0;--i){ j=i+k; T *p = &w[j*at], *q = &v.w[i*vat]; for(h=0;h<=u;++h)p[h]=q[h];}
|
|
124
|
+
for(i=t-1,k=o; i>=0;--i){ j=i+k; T *p = &w[j*at], *q = &v.w[i*vat]; for(h=0;h<=u;++h)p[h]=q[h];}
|
|
125
|
+
for(i=o-1,k=t; i>=0;--i){ j=i+k; T *p = &w[i*at], *q = &w[j*at]; for(h=0;h<=u;++h)p[h]=q[h];}
|
|
126
|
+
}
|
|
127
|
+
else if (w != v.w)
|
|
128
|
+
for (size_t i = 0; i < _size; ++i)
|
|
129
|
+
for (size_t j = 0; j <= N; ++j)
|
|
130
|
+
w[i*at+j] = v.w[i*vat+j];
|
|
131
|
+
}
|
|
132
|
+
return *this;
|
|
133
|
+
}
|
|
134
|
+
template <class E> varray& operator = (const E& e)
|
|
135
|
+
{
|
|
136
|
+
for (size_t i = 0; i < _size; ++i) (*this)[i] = e[i];
|
|
137
|
+
return *this;
|
|
138
|
+
}
|
|
139
|
+
varray& operator = (T a)
|
|
140
|
+
{
|
|
141
|
+
for (size_t i = 0; i < _size; ++i) {
|
|
142
|
+
T *p = (*this)(i); p[0] = a;
|
|
143
|
+
for (size_t j = 1; j <= N; ++j) p[j] = 0.0;
|
|
144
|
+
}
|
|
145
|
+
return *this;
|
|
146
|
+
}
|
|
147
|
+
operator T* () const { return w; }
|
|
148
|
+
real<T>& operator * () { return *(real<T>*)this; }
|
|
149
|
+
T * operator () (size_t n) const { return &w[n*(N+1)*_st]; }
|
|
150
|
+
real<T> operator [] (size_t n) const { return real<T>(varray(&w[n*(N+1)*_st], _size - n, N, _st)); }
|
|
151
|
+
varray operator -() const { varray r(*this); for (size_t i = 0; i < _size; ++i) r[i] *= -1.0; return r; }
|
|
152
|
+
friend varray abs(const varray& v) { varray r(v._size, v.N); for (size_t i = 0; i < r._size; ++i) r[i] = abs(v[i]); return r; }
|
|
153
|
+
friend real<T> dot(const varray& u, const varray& v)
|
|
154
|
+
{
|
|
155
|
+
assert(u._size == v._size);
|
|
156
|
+
real<T> w(u.N > v.N ? u.N : v.N);
|
|
157
|
+
for (size_t i = 0; i < u._size; ++i) w += u[i] * v[i];
|
|
158
|
+
return sqrt(w);
|
|
159
|
+
}
|
|
160
|
+
size_t size() const { return _size; }
|
|
161
|
+
size_t atom() const { return N; }
|
|
162
|
+
int stride() const { return _st; }
|
|
163
|
+
size_t data_size() const { return _size * (N + 1) * _st; }
|
|
164
|
+
varray& operator += (T t) { for (size_t i = 0; i < _size; ++i) (*this)[i] += t; return *this; }
|
|
165
|
+
varray& operator -= (T t) { for (size_t i = 0; i < _size; ++i) (*this)[i] -= t; return *this; }
|
|
166
|
+
varray& operator *= (T t) { for (size_t i = 0; i < _size; ++i) (*this)[i] *= t; return *this; }
|
|
167
|
+
varray& operator /= (T t) { for (size_t i = 0; i < _size; ++i) (*this)[i] /= t; return *this; }
|
|
168
|
+
varray& operator += (const real<T>& r) { for (size_t i = 0; i < _size; ++i) (*this)[i] += r; return *this; }
|
|
169
|
+
varray& operator -= (const real<T>& r) { for (size_t i = 0; i < _size; ++i) (*this)[i] -= r; return *this; }
|
|
170
|
+
varray& operator *= (const real<T>& r) { for (size_t i = 0; i < _size; ++i) (*this)[i] *= r; return *this; }
|
|
171
|
+
varray& operator /= (const real<T>& r) { for (size_t i = 0; i < _size; ++i) (*this)[i] /= r; return *this; }
|
|
172
|
+
template <class E> varray& operator += (const E& e) { for (size_t i = 0; i < _size; ++i) (*this)[i] += e[i]; return *this; }
|
|
173
|
+
template <class E> varray& operator -= (const E& e) { for (size_t i = 0; i < _size; ++i) (*this)[i] -= e[i]; return *this; }
|
|
174
|
+
template <class E> varray& operator *= (const E& e) { for (size_t i = 0; i < _size; ++i) (*this)[i] *= e[i]; return *this; }
|
|
175
|
+
template <class E> varray& operator /= (const E& e) { for (size_t i = 0; i < _size; ++i) (*this)[i] /= e[i]; return *this; }
|
|
176
|
+
template <class R> friend expr<varray,add,R> operator + (const varray& l, const R& r) { return expr<varray,add,R>(l, r); }
|
|
177
|
+
friend expr<varray,add,varray> operator + (const varray& l, const varray& r) { return expr<varray,add,varray>(l, r); }
|
|
178
|
+
friend expr<varray,sub,varray> operator - (const varray& l, const varray& r) { return expr<varray,sub,varray>(l, r); }
|
|
179
|
+
friend expr<varray,mul,varray> operator * (const varray& l, const varray& r) { return expr<varray,mul,varray>(l, r); }
|
|
180
|
+
friend expr<varray,div,varray> operator / (const varray& l, const varray& r) { return expr<varray,div,varray>(l, r); }
|
|
181
|
+
friend expr<varray,add,real<T> > operator + (const varray& l, const real<T>& r) { return expr<varray,add,real<T> >(l, r); }
|
|
182
|
+
friend expr<varray,sub,real<T> > operator - (const varray& l, const real<T>& r) { return expr<varray,sub,real<T> >(l, r); }
|
|
183
|
+
friend expr<varray,mul,real<T> > operator * (const varray& l, const real<T>& r) { return expr<varray,mul,real<T> >(l, r); }
|
|
184
|
+
friend expr<varray,div,real<T> > operator / (const varray& l, const real<T>& r) { return expr<varray,div,real<T> >(l, r); }
|
|
185
|
+
friend expr<real<T>,add,varray> operator + (const real<T>& l, const varray& r) { return expr<real<T>,add,varray>(l, r); }
|
|
186
|
+
friend expr<real<T>,sub,varray> operator - (const real<T>& l, const varray& r) { return expr<real<T>,sub,varray>(l, r); }
|
|
187
|
+
friend expr<real<T>,mul,varray> operator * (const real<T>& l, const varray& r) { return expr<real<T>,mul,varray>(l, r); }
|
|
188
|
+
friend expr<real<T>,div,varray> operator / (const real<T>& l, const varray& r) { return expr<real<T>,div,varray>(l, r); }
|
|
189
|
+
friend expr<varray,add,T> operator + (const varray& l, T r) { return expr<varray,add,T>(l, r); }
|
|
190
|
+
friend expr<varray,sub,T> operator - (const varray& l, T r) { return expr<varray,sub,T>(l, r); }
|
|
191
|
+
friend expr<varray,mul,T> operator * (const varray& l, T r) { return expr<varray,mul,T>(l, r); }
|
|
192
|
+
friend expr<varray,div,T> operator / (const varray& l, T r) { return expr<varray,div,T>(l, r); }
|
|
193
|
+
friend expr<T,add,varray> operator + (const T l, const varray& r) { return expr<T,add,varray>(l, r); }
|
|
194
|
+
friend expr<T,sub,varray> operator - (const T l, const varray& r) { return expr<T,sub,varray>(l, r); }
|
|
195
|
+
friend expr<T,mul,varray> operator * (const T l, const varray& r) { return expr<T,mul,varray>(l, r); }
|
|
196
|
+
friend expr<T,div,varray> operator / (const T l, const varray& r) { return expr<T,div,varray>(l, r); }
|
|
197
|
+
char *to_s(const char *f = "%g") const;
|
|
198
|
+
void fprint(FILE *f, const char *fmt = "%g\n") const { gprint(*this, f, fmt); }
|
|
199
|
+
void print(const char *fmt = "%g\n") const { this->fprint(stdout, fmt); }
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
#include "basis/real_inline.h"
|
|
203
|
+
|
|
204
|
+
template <typename T = double> class marray_view;
|
|
205
|
+
|
|
206
|
+
template <typename T = double> class marray
|
|
207
|
+
{
|
|
208
|
+
size_t r, c, a; T **index, *data;
|
|
209
|
+
public:
|
|
210
|
+
marray() : r(), c(), a(), index(nullptr), data(nullptr) {}
|
|
211
|
+
marray(size_t nr, size_t nc, size_t na = 0, const T *dat = NULL) : r(nr), c(nc), a(na)
|
|
212
|
+
{
|
|
213
|
+
index = create_marray<T>(r, c, a); data = *index;
|
|
214
|
+
if (dat) for (size_t i = 0; i < r * c * (a + 1); ++i) data[i] = dat[i];
|
|
215
|
+
}
|
|
216
|
+
marray(const marray& m) : r(m.r), c(m.c), a(m.a)
|
|
217
|
+
{
|
|
218
|
+
index = create_marray<T>(r, c, a); data = *index;
|
|
219
|
+
for (size_t i = 0; i < r; ++i)
|
|
220
|
+
for (size_t j = 0; j < c; ++j)
|
|
221
|
+
for (size_t k = 0; k <= a; ++k)
|
|
222
|
+
index[i][j*(a+1)+k] = m.index[i][j*(a+1)+k];
|
|
223
|
+
}
|
|
224
|
+
marray(const marray_view<T>& m) : r(m.rows()), c(m.cols()), a(m.atom())
|
|
225
|
+
{
|
|
226
|
+
index = create_marray<T>(r, c, a); data = *index;
|
|
227
|
+
T **m_index = m;
|
|
228
|
+
for (size_t i = 0; i < r; ++i)
|
|
229
|
+
for (size_t j = 0; j < c; ++j)
|
|
230
|
+
for (size_t k = 0; k <= a; ++k)
|
|
231
|
+
index[i][j*(a+1)+k] = m_index[i][j*(a+1)+k];
|
|
232
|
+
}
|
|
233
|
+
~marray() { free((void*)index); }
|
|
234
|
+
marray& operator = (const marray& m)
|
|
235
|
+
{
|
|
236
|
+
if (this != &m) {
|
|
237
|
+
free((void*)index);
|
|
238
|
+
r = m.r; c = m.c; a = m.a;
|
|
239
|
+
index = create_marray<T>(r, c, a); data = *index;
|
|
240
|
+
for (size_t i = 0; i < r; ++i)
|
|
241
|
+
for (size_t j = 0; j < c; ++j)
|
|
242
|
+
for (size_t k = 0; k <= a; ++k)
|
|
243
|
+
index[i][j*(a+1)+k] = m.index[i][j*(a+1)+k];
|
|
244
|
+
}
|
|
245
|
+
return *this;
|
|
246
|
+
}
|
|
247
|
+
operator T** () const { return index; }
|
|
248
|
+
T * operator * () const { return data; }
|
|
249
|
+
varray<T> operator [] (size_t i) const { return varray<T>(index[i], c, a); }
|
|
250
|
+
T * operator () (size_t i, size_t j) const { return &index[i][j*(a+1)]; }
|
|
251
|
+
void row_swap(size_t i, size_t j) { T *w = index[i]; index[i] = index[j]; index[j] = w; }
|
|
252
|
+
void col_swap(size_t i, size_t j);
|
|
253
|
+
size_t rows() const { return r; }
|
|
254
|
+
size_t cols() const { return c; }
|
|
255
|
+
size_t atom() const { return a; }
|
|
256
|
+
size_t data_size() const { return r * c * (a + 1); }
|
|
257
|
+
varray<T> row(size_t i) const { return varray<T>(index[i], c, a); }
|
|
258
|
+
varray<T> col(size_t i) const { return varray<T>(data + i*(a+1), r, a, c); }
|
|
259
|
+
char *to_s(const char *f = "%g") const;
|
|
260
|
+
void fprint(FILE *f, const char *fmt = "%g\n") const { gprint(*this, f, fmt); }
|
|
261
|
+
void print(const char *fmt = "%g\n") const { this->fprint(stdout, fmt); }
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
template <typename T> void marray<T>::col_swap(size_t i, size_t j)
|
|
265
|
+
{
|
|
266
|
+
if (i == j) return;
|
|
267
|
+
T *u = &data[i * (a + 1)], v = &data[j * (a + 1)], w[a + 1];
|
|
268
|
+
for (size_t k = 0; k < r; ++k, u += c * (a + 1), v += c * (a + 1)) {
|
|
269
|
+
qd_ass(a, w, u); qd_ass(a, u, v); qd_ass(a, v, w);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
template <typename T> class marray_view
|
|
274
|
+
{
|
|
275
|
+
size_t r, c, a; T **index, *data;
|
|
276
|
+
public:
|
|
277
|
+
marray_view(T *dat, size_t nr, size_t nc, size_t na = 0) : r(nr), c(nc), a(na)
|
|
278
|
+
{
|
|
279
|
+
index = (T**)malloc(r * sizeof(T*)); data = dat;
|
|
280
|
+
index[0] = data;
|
|
281
|
+
for (size_t i = 1; i < r; ++i) index[i] = index[i-1] + c * (a + 1);
|
|
282
|
+
}
|
|
283
|
+
marray_view(const marray<T>& m) : r(m.rows()), c(m.cols()), a(m.atom())
|
|
284
|
+
{
|
|
285
|
+
index = (T**)malloc(r * sizeof(T*)); data = *m;
|
|
286
|
+
T **m_index = m;
|
|
287
|
+
for (size_t i = 0; i < r; ++i) index[i] = m_index[i];
|
|
288
|
+
}
|
|
289
|
+
marray_view(const marray_view& m) : r(m.r), c(m.c), a(m.a)
|
|
290
|
+
{
|
|
291
|
+
index = (T**)malloc(r * sizeof(T*)); data = m.data;
|
|
292
|
+
T **m_index = m;
|
|
293
|
+
for (size_t i = 0; i < r; ++i) index[i] = m_index[i];
|
|
294
|
+
}
|
|
295
|
+
~marray_view() { free((void*)index); }
|
|
296
|
+
marray_view& operator = (const marray_view&) = delete;
|
|
297
|
+
operator T** () const { return index; }
|
|
298
|
+
T * operator * () const { return data; }
|
|
299
|
+
varray<T> operator [] (size_t i) const { return varray<T>(index[i], c, a); }
|
|
300
|
+
T * operator () (size_t i, size_t j) const { return &index[i][j*(a+1)]; }
|
|
301
|
+
void row_swap(size_t i, size_t j) { T *w = index[i]; index[i] = index[j]; index[j] = w; }
|
|
302
|
+
void col_swap(size_t i, size_t j);
|
|
303
|
+
size_t rows() const { return r; }
|
|
304
|
+
size_t cols() const { return c; }
|
|
305
|
+
size_t atom() const { return a; }
|
|
306
|
+
size_t data_size() const { return r * c * (a + 1); }
|
|
307
|
+
varray<T> row(size_t i) const { return varray<T>(index[i], c, a); }
|
|
308
|
+
varray<T> col(size_t i) const { return varray<T>(data + i*(a+1), r, a, c); }
|
|
309
|
+
char *to_s(const char *f = "%g") const;
|
|
310
|
+
void fprint(FILE *f, const char *fmt = "%g\n") const { gprint(*this, f, fmt); }
|
|
311
|
+
void print(const char *fmt = "%g\n") const { this->fprint(stdout, fmt); }
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
template <typename T> void marray_view<T>::col_swap(size_t i, size_t j)
|
|
315
|
+
{
|
|
316
|
+
if (i == j) return;
|
|
317
|
+
T *u = &data[i * (a + 1)], v = &data[j * (a + 1)], w[a + 1];
|
|
318
|
+
for (size_t k = 0; k < r; ++k, u += c * (a + 1), v += c * (a + 1)) {
|
|
319
|
+
qd_ass(a, w, u); qd_ass(a, u, v); qd_ass(a, v, w);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
template <typename T = double>
|
|
324
|
+
void kronecker(const varray<T>& p, const varray<T>& q, const varray<T>& r)
|
|
325
|
+
{
|
|
326
|
+
size_t s = p.size(), t = q.size(), a = r.atom();
|
|
327
|
+
for (size_t i = 0; i < s; i++)
|
|
328
|
+
for (size_t j = 0; j < t; j++)
|
|
329
|
+
qd_mul(a, r(i*t+j), p(i), q(j));
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
template <typename T = double>
|
|
333
|
+
void kronecker(const marray<T>& p, const marray<T>& q, const marray<T>& r)
|
|
334
|
+
{
|
|
335
|
+
size_t s = p.rows(), t = q.rows();
|
|
336
|
+
for (size_t i = 0; i < s; i++)
|
|
337
|
+
for (size_t j = 0; j < t; j++)
|
|
338
|
+
kronecker(p.row(i), q.row(j), r.row(i*t+j));
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
template <typename T = double>
|
|
342
|
+
marray<T> operator^(const marray<T>& p, const marray<T>& q)
|
|
343
|
+
{
|
|
344
|
+
size_t r = p.rows() * q.rows(), c = p.cols() * q.cols(), a = p.atom();
|
|
345
|
+
assert(a == q.atom());
|
|
346
|
+
marray<T> result(r, c, a);
|
|
347
|
+
kronecker(p, q, result);
|
|
348
|
+
return result;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
#ifdef CROUT
|
|
352
|
+
#include "basis/matrix_luc_ext.h"
|
|
353
|
+
#else
|
|
354
|
+
#include "basis/matrix_lud_ext.h"
|
|
355
|
+
#endif
|
|
356
|
+
|
|
357
|
+
template <typename T= double> class marray_lu : public marray<T>
|
|
358
|
+
{
|
|
359
|
+
size_t *p; int s;
|
|
360
|
+
|
|
361
|
+
public:
|
|
362
|
+
marray_lu(const marray<T>& ma) : marray<T>(ma), p(new size_t[ma.rows()])
|
|
363
|
+
{
|
|
364
|
+
lu_decomp<T,marray<T> >(*this, p, s);
|
|
365
|
+
}
|
|
366
|
+
marray_lu(const marray_view<T>& ma) : marray<T>(ma), p(new size_t[ma.rows()])
|
|
367
|
+
{
|
|
368
|
+
lu_decomp<T,marray<T> >(*this, p, s);
|
|
369
|
+
}
|
|
370
|
+
marray_lu(const marray_lu&) = delete;
|
|
371
|
+
~marray_lu() { delete[] p; }
|
|
372
|
+
marray_lu& operator = (const marray_lu&) = delete;
|
|
373
|
+
template <class S> void solve(const varray<S>& b, varray<S>& x)
|
|
374
|
+
{
|
|
375
|
+
if (&x != &b) for (size_t i = 0; i < x.size(); ++i) x[i] = b[i];
|
|
376
|
+
lu_subst<T,marray<T> >(*this, p, x);
|
|
377
|
+
}
|
|
378
|
+
template <class S> void solve(const marray<S>& b, marray<S>& x)
|
|
379
|
+
{
|
|
380
|
+
if (&x != &b) memcpy(*x, *b, x.data_size() * sizeof(T));
|
|
381
|
+
size_t K = x.cols();
|
|
382
|
+
for (size_t i = 0; i < K; ++i) {
|
|
383
|
+
varray<T> v = x.col(i);
|
|
384
|
+
lu_subst<T,marray<T> >(*this, p, v);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
template <class S> S solve(const S& b)
|
|
388
|
+
{
|
|
389
|
+
S result(b);
|
|
390
|
+
lu_subst<T,marray<T> >(*this, p, result);
|
|
391
|
+
return result;
|
|
392
|
+
}
|
|
393
|
+
real<T> det()
|
|
394
|
+
{
|
|
395
|
+
size_t N = this->rows(), a = this->atom();
|
|
396
|
+
real<T> result(a); result = s; T *u = result;
|
|
397
|
+
for (size_t k = 0; k < N; ++k) qd_mul(a, u, u, (*this)(k,k)); // det *= A[k][k];
|
|
398
|
+
return result;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
}; // end of marray_lu;
|
|
402
|
+
|
|
403
|
+
template <typename T = double> class marray_lu_view : public marray_view<T>
|
|
404
|
+
{
|
|
405
|
+
size_t *p; int s;
|
|
406
|
+
|
|
407
|
+
public:
|
|
408
|
+
marray_lu_view(const marray<T>& ma) : marray_view<T>(ma), p(new size_t[ma.rows()])
|
|
409
|
+
{
|
|
410
|
+
lu_decomp<T,marray_view<T>>(*this, p, s);
|
|
411
|
+
}
|
|
412
|
+
marray_lu_view(const marray_view<T>& ma) : marray_view<T>(ma), p(new size_t[ma.rows()])
|
|
413
|
+
{
|
|
414
|
+
lu_decomp<T,marray_view<T>>(*this, p, s);
|
|
415
|
+
}
|
|
416
|
+
marray_lu_view(const marray_lu_view&) = delete;
|
|
417
|
+
~marray_lu_view() { delete[] p; }
|
|
418
|
+
marray_lu_view& operator = (const marray_lu_view&) = delete;
|
|
419
|
+
template <class S> void solve(const varray<S>& b, varray<S>& x)
|
|
420
|
+
{
|
|
421
|
+
if (&x != &b) for (size_t i = 0; i < x.size(); ++i) x[i] = b[i];
|
|
422
|
+
lu_subst<T,marray_view<T> >(*this, p, x);
|
|
423
|
+
}
|
|
424
|
+
template <class S> void solve(const marray_view<S>& b, marray_view<S>& x)
|
|
425
|
+
{
|
|
426
|
+
if (&x != &b) memcpy(*x, *b, x.data_size() * sizeof(T));
|
|
427
|
+
lu_subst<T,marray_view<T> >(*this, p, x);
|
|
428
|
+
}
|
|
429
|
+
template <class S> S solve(const S& b)
|
|
430
|
+
{
|
|
431
|
+
S result(b);
|
|
432
|
+
lu_subst<T,marray_view<T> >(*this, p, result);
|
|
433
|
+
return result;
|
|
434
|
+
}
|
|
435
|
+
real<T> det()
|
|
436
|
+
{
|
|
437
|
+
size_t N = this->rows(), a = this->atom();
|
|
438
|
+
real<T> result(a); result = s; T *u = result;
|
|
439
|
+
for (size_t k = 0; k < N; ++k) qd_mul(a, u, u, (*this)(k,k)); // det *= A[k][k];
|
|
440
|
+
return result;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
}; // end of marray_lu_view;
|
|
444
|
+
|
|
445
|
+
template <typename T = double> class carray
|
|
446
|
+
{
|
|
447
|
+
size_t n, *s, a; T **index, *data;
|
|
448
|
+
public:
|
|
449
|
+
carray(size_t ns, size_t *sp, size_t na): n(ns), s(new size_t[ns]), a(na)
|
|
450
|
+
{
|
|
451
|
+
for (size_t i = 0; i < n; i++) s[i] = sp[i];
|
|
452
|
+
index = create_carray<T>(n, s, a); data = index[0];
|
|
453
|
+
}
|
|
454
|
+
carray(const carray& ca) : n(ca.n), s(new size_t[ca.n]), a(ca.a)
|
|
455
|
+
{
|
|
456
|
+
size_t size = 0;
|
|
457
|
+
for (size_t i = 0; i < n; i++) { s[i] = ca.s[i]; size += s[i]*(a+1); }
|
|
458
|
+
index = create_carray<T>(n, s, a); data = index[0];
|
|
459
|
+
for (size_t i = 0; i < size; ++i) data[i] = ca.data[i];
|
|
460
|
+
}
|
|
461
|
+
~carray() { free((void*)index); delete[] s; }
|
|
462
|
+
carray& operator = (const carray&) = delete;
|
|
463
|
+
operator T** () const { return index; }
|
|
464
|
+
T * operator * () const { return data; }
|
|
465
|
+
varray<T> operator [] (size_t i) const { return varray<T>(index[i], s[i], a); }
|
|
466
|
+
T * operator () (size_t i, size_t j) const { return &index[i][j*(a+1)]; }
|
|
467
|
+
size_t size(size_t i) const { return s[i]; }
|
|
468
|
+
size_t rows() const { return n; }
|
|
469
|
+
size_t atom() const { return a; }
|
|
470
|
+
varray<T> row(size_t i) const { return varray<T>(index[i], s[i], a); }
|
|
471
|
+
}; // end of carray;
|
|
472
|
+
|
|
473
|
+
template <typename T = double> class carray_view
|
|
474
|
+
{
|
|
475
|
+
size_t n, *s, a; T **index, *data;
|
|
476
|
+
public:
|
|
477
|
+
carray_view(const carray<T>& ca) : n(ca.rows()), s(new size_t[n]), a(ca.atom())
|
|
478
|
+
{
|
|
479
|
+
index = (T**)malloc(n * sizeof(T*)); data = *ca;
|
|
480
|
+
for (size_t i = 0; i < n; ++i) {
|
|
481
|
+
s[i] = ca.size(i);
|
|
482
|
+
if (i == 0) index[0] = data;
|
|
483
|
+
else index[i] = index[i-1] + s[i-1]*(a+1);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
carray_view(size_t ns, size_t *sp, size_t na, T *dat) : n(ns), s(new size_t[n]), a(na)
|
|
487
|
+
{
|
|
488
|
+
index = (T**)malloc(n * sizeof(T*)); data = dat;
|
|
489
|
+
for (size_t i = 0; i < n; ++i) {
|
|
490
|
+
s[i] = sp[i];
|
|
491
|
+
if (i == 0) index[0] = data;
|
|
492
|
+
else index[i] = index[i-1] + s[i-1]*(a+1);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
carray_view(const carray_view& cv) : n(cv.n), s(new size_t[n]), a(cv.a)
|
|
496
|
+
{
|
|
497
|
+
index = (T**)malloc(n * sizeof(T*)); data = cv.data;
|
|
498
|
+
for (size_t i = 0; i < n; ++i) {
|
|
499
|
+
s[i] = cv.s[i];
|
|
500
|
+
if (i == 0) index[0] = data;
|
|
501
|
+
else index[i] = index[i-1] + s[i-1]*(a+1);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
~carray_view() { free((void*)index); delete[] s; }
|
|
505
|
+
carray_view& operator = (const carray_view&) = delete;
|
|
506
|
+
operator T** () const { return index; }
|
|
507
|
+
T * operator * () const { return data; }
|
|
508
|
+
varray<T> operator [] (size_t i) const { return varray<T>(index[i], s[i], a); }
|
|
509
|
+
T * operator () (size_t i, size_t j) const { return &index[i][j*(a+1)]; }
|
|
510
|
+
size_t size(size_t i) const { return s[i]; }
|
|
511
|
+
size_t rows() const { return n; }
|
|
512
|
+
size_t atom() const { return a; }
|
|
513
|
+
varray<T> row(size_t i) const { return varray<T>(index[i], s[i], a); }
|
|
514
|
+
// end of carray_view;
|
|
515
|
+
};
|
|
516
|
+
|
|
517
|
+
template <typename T = double> class parray
|
|
518
|
+
{
|
|
519
|
+
T **index, *data; int o, s, k, a;
|
|
520
|
+
public:
|
|
521
|
+
parray(int no, int ns, int nk, int na) : o(no), s(ns), k(nk), a(na)
|
|
522
|
+
{
|
|
523
|
+
index = create_marray<T>(k, s, a); data = index[0];
|
|
524
|
+
}
|
|
525
|
+
parray(const parray& p) : o(p.o), s(p.s), k(p.k), a(p.a)
|
|
526
|
+
{
|
|
527
|
+
index = create_marray<T>(k, s, a); data = index[0];
|
|
528
|
+
for (int i = 0; i < s * k * (a + 1); ++i) data[i] = p.data[i];
|
|
529
|
+
}
|
|
530
|
+
~parray() { free((void*)index); }
|
|
531
|
+
parray& operator=(const parray&) = delete;
|
|
532
|
+
operator T** () const { return index; }
|
|
533
|
+
T * operator * () const { return data; } // return index block;
|
|
534
|
+
varray<T> operator [] (int i) const { assert(i < k); return varray<T>(index[i], s, a); }
|
|
535
|
+
T * operator () (int i, int j) const { return &index[j][i*(a+1)]; }
|
|
536
|
+
int operator () (int i) { return i == 0 ? o : i == 1 ? s : i == 2 ? k : a; }
|
|
537
|
+
int offset() const { return o; }
|
|
538
|
+
int size() const { return s; }
|
|
539
|
+
int rows() const { return k; }
|
|
540
|
+
int atom() const { return a; }
|
|
541
|
+
varray<T> row(int i) const { assert(i < k); return varray<T>(index[i], s, a); }
|
|
542
|
+
varray<T> col(int i) const { assert(i < s); return varray<T>(data + i * (a + 1), k, a, s); }
|
|
543
|
+
real<T> saylor(int i, const real<T>& h)
|
|
544
|
+
{
|
|
545
|
+
real<T> q((size_t)a);
|
|
546
|
+
for (int j = k; j > 0; --j) {
|
|
547
|
+
real<T> r(size_t(a), (*this)(i, j-1), 0);
|
|
548
|
+
q = (q + r) * h / T(j);
|
|
549
|
+
}
|
|
550
|
+
return q;
|
|
551
|
+
}
|
|
552
|
+
real<T> taylor(int i, const real<T>& h)
|
|
553
|
+
{
|
|
554
|
+
real<T> q((size_t)a);
|
|
555
|
+
for (int j = k; j > 0; --j) {
|
|
556
|
+
real<T> r(size_t(a), (*this)(i, j-1), 0);
|
|
557
|
+
q = q * h / T(j) + r;
|
|
558
|
+
}
|
|
559
|
+
return q;
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
typedef int * narray;
|
|
564
|
+
typedef varray<double> Vector;
|
|
565
|
+
typedef marray<double> Matrix;
|
|
566
|
+
typedef marray_view<double> Matrix_view;
|
|
567
|
+
|
|
568
|
+
#endif
|