48 std::vector< std::vector<double> > m_upper;
49 std::vector< std::vector<double> > m_lower;
52 band_matrix(
int dim,
int n_u,
int n_l);
54 void resize(
int dim,
int n_u,
int n_l);
58 return m_upper.size()-1;
62 return m_lower.size()-1;
65 double & operator () (
int i,
int j);
66 double operator () (
int i,
int j)
const;
68 double& saved_diag(
int i);
69 double saved_diag(
int i)
const;
71 std::vector<double> r_solve(
const std::vector<double>&
b)
const;
72 std::vector<double> l_solve(
const std::vector<double>&
b)
const;
73 std::vector<double> lu_solve(
const std::vector<double>&
b,
74 bool is_lu_decomposed=
false);
89 std::vector<double> m_x,m_y;
92 std::vector<double> m_a,m_b,m_c;
94 bd_type m_left, m_right;
95 double m_left_value, m_right_value;
96 bool m_force_linear_extrapolation;
100 spline(): m_left(second_deriv), m_right(second_deriv),
101 m_left_value(0.0), m_right_value(0.0),
102 m_force_linear_extrapolation(
false)
108 void set_boundary(bd_type
left,
double left_value,
109 bd_type
right,
double right_value,
110 bool force_linear_extrapolation=
false);
111 void set_points(
const std::vector<double>&
x,
112 const std::vector<double>&
y,
bool cubic_spline=
true);
113 double operator() (
double x)
const;
126 band_matrix::band_matrix(
int dim,
int n_u,
int n_l)
128 resize(dim, n_u, n_l);
130 void band_matrix::resize(
int dim,
int n_u,
int n_l)
135 m_upper.resize(n_u+1);
136 m_lower.resize(n_l+1);
137 for(
size_t i=0;
i<m_upper.size();
i++) {
138 m_upper[
i].resize(dim);
140 for(
size_t i=0;
i<m_lower.size();
i++) {
141 m_lower[
i].resize(dim);
144 int band_matrix::dim()
const
146 if(m_upper.size()>0) {
147 return m_upper[0].size();
156 double & band_matrix::operator () (
int i,
int j)
159 assert( (
i>=0) && (
i<dim()) && (
j>=0) && (
j<dim()) );
160 assert( (-num_lower()<=
k) && (
k<=num_upper()) );
162 if(
k>=0)
return m_upper[
k][
i];
163 else return m_lower[-
k][
i];
165 double band_matrix::operator () (
int i,
int j)
const
168 assert( (
i>=0) && (
i<dim()) && (
j>=0) && (
j<dim()) );
169 assert( (-num_lower()<=
k) && (
k<=num_upper()) );
171 if(
k>=0)
return m_upper[
k][
i];
172 else return m_lower[-
k][
i];
175 double band_matrix::saved_diag(
int i)
const
177 assert( (
i>=0) && (
i<dim()) );
178 return m_lower[0][
i];
180 double & band_matrix::saved_diag(
int i)
182 assert( (
i>=0) && (
i<dim()) );
183 return m_lower[0][
i];
187 void band_matrix::lu_decompose()
195 for(
int i=0;
i<this->dim();
i++) {
196 assert(this->
operator()(i,
i)!=0.0);
197 this->saved_diag(
i)=1.0/this->operator()(
i,
i);
199 j_max=
std::min(this->dim()-1,
i+this->num_upper());
200 for(
int j=j_min;
j<=j_max;
j++) {
201 this->operator()(
i,
j) *= this->saved_diag(
i);
203 this->operator()(
i,
i)=1.0;
207 for(
int k=0;
k<this->dim();
k++) {
208 i_max=
std::min(this->dim()-1,
k+this->num_lower());
209 for(
int i=
k+1;
i<=i_max;
i++) {
210 assert(this->
operator()(
k,
k)!=0.0);
211 x=-this->operator()(
i,
k)/this->operator()(
k,
k);
212 this->operator()(
i,
k)=-
x;
213 j_max=
std::min(this->dim()-1,
k+this->num_upper());
214 for(
int j=
k+1;
j<=j_max;
j++) {
216 this->operator()(
i,
j)=this->operator()(
i,
j)+
x*this->operator()(
k,
j);
222 std::vector<double> band_matrix::l_solve(
const std::vector<double>&
b)
const
224 assert( this->dim()==(
int)
b.size() );
225 std::vector<double>
x(this->dim());
228 for(
int i=0;
i<this->dim();
i++) {
231 for(
int j=j_start;
j<
i;
j++) sum += this->
operator()(
i,
j)*x[
j];
232 x[
i]=(
b[
i]*this->saved_diag(
i)) - sum;
237 std::vector<double> band_matrix::r_solve(
const std::vector<double>&
b)
const
239 assert( this->dim()==(
int)
b.size() );
240 std::vector<double>
x(this->dim());
243 for(
int i=this->dim()-1;
i>=0;
i--) {
245 j_stop=
std::min(this->dim()-1,
i+this->num_upper());
246 for(
int j=
i+1;
j<=j_stop;
j++) sum += this->
operator()(
i,
j)*x[
j];
247 x[
i]=(
b[
i] - sum ) / this->
operator()(
i,
i);
252 std::vector<double> band_matrix::lu_solve(
const std::vector<double>&
b,
253 bool is_lu_decomposed)
255 assert( this->dim()==(
int)
b.size() );
256 std::vector<double>
x,
y;
257 if(is_lu_decomposed==
false) {
258 this->lu_decompose();
271 void spline::set_boundary(spline::bd_type
left,
double left_value,
272 spline::bd_type
right,
double right_value,
273 bool force_linear_extrapolation)
275 assert(m_x.size()==0);
278 m_left_value=left_value;
279 m_right_value=right_value;
280 m_force_linear_extrapolation=force_linear_extrapolation;
284 void spline::set_points(
const std::vector<double>&
x,
285 const std::vector<double>&
y,
bool cubic_spline)
287 assert(
x.size()==
y.size());
293 for(
int i=0;
i<n-1;
i++) {
294 assert(m_x[
i]<m_x[
i+1]);
297 if(cubic_spline==
true) {
300 band_matrix A(n,1,1);
301 std::vector<double> rhs(n);
302 for(
int i=1;
i<n-1;
i++) {
303 A(
i,
i-1)=1.0/3.0*(
x[
i]-
x[
i-1]);
304 A(
i,
i)=2.0/3.0*(
x[
i+1]-
x[
i-1]);
305 A(
i,
i+1)=1.0/3.0*(
x[
i+1]-
x[
i]);
309 if(m_left == spline::second_deriv) {
317 A(0,0)=2.0*(
x[1]-
x[0]);
318 A(0,1)=1.0*(
x[1]-
x[0]);
319 rhs[0]=3.0*((
y[1]-
y[0])/(
x[1]-
x[0])-m_left_value);
323 if(m_right == spline::second_deriv) {
327 rhs[n-1]=m_right_value;
332 A(n-1,n-1)=2.0*(
x[n-1]-
x[n-2]);
333 A(n-1,n-2)=1.0*(
x[n-1]-
x[n-2]);
334 rhs[n-1]=3.0*(m_right_value-(
y[n-1]-
y[n-2])/(
x[n-1]-
x[n-2]));
345 for(
int i=0;
i<n-1;
i++) {
346 m_a[
i]=1.0/3.0*(m_b[
i+1]-m_b[
i])/(
x[
i+1]-
x[
i]);
348 - 1.0/3.0*(2.0*m_b[
i]+m_b[
i+1])*(
x[
i+1]-
x[
i]);
354 for(
int i=0;
i<n-1;
i++) {
357 m_c[
i]=(m_y[
i+1]-m_y[
i])/(m_x[
i+1]-m_x[
i]);
362 m_b0 = (m_force_linear_extrapolation==
false) ? m_b[0] : 0.0;
367 double h=
x[n-1]-
x[n-2];
370 m_c[n-1]=3.0*m_a[n-2]*
h*
h+2.0*m_b[n-2]*
h+m_c[n-2];
371 if(m_force_linear_extrapolation==
true)
375 double spline::operator() (
double x)
const
379 std::vector<double>::const_iterator it;
380 it=std::lower_bound(m_x.begin(),m_x.end(),
x);
381 int idx=
std::max(
int(it-m_x.begin())-1, 0);
387 interpol=(m_b0*
h + m_c0)*
h + m_y[0];
388 }
else if(
x>m_x[n-1]) {
390 interpol=(m_b[n-1]*
h + m_c[n-1])*
h + m_y[n-1];
393 interpol=((m_a[idx]*
h + m_b[idx])*
h + m_c[idx])*
h + m_y[idx];