23 #ifndef O2SCL_INTERP_H
24 #define O2SCL_INTERP_H
33 #include <boost/numeric/ublas/vector.hpp>
34 #include <boost/numeric/ublas/vector_proxy.hpp>
36 #include <o2scl/search_vec.h>
37 #include <o2scl/tridiag.h>
38 #include <o2scl/funct.h>
40 #ifndef DOXYGEN_NO_O2NS
83 #ifdef O2SCL_NEVER_DEFINED
87 #ifndef DOXYGEN_INTERNAL
110 double integ_eval(
double ai,
double bi,
double ci,
double di,
double xi,
111 double a,
double b)
const {
116 double bterm=0.5*bi*r12;
117 double cterm=ci*(r1*r1+r2*r2+r1*r2)/3.0;
118 double dterm=0.25*di*r12*(r1*r1+r2*r2);
120 return (b-a)*(ai+bterm+cterm+dterm);
131 virtual ~interp_base() {
142 virtual void set(
size_t size,
const vec_t &x,
const vec2_t &y)=0;
145 virtual double eval(
double x0)
const=0;
153 virtual double deriv(
double x0)
const=0;
158 virtual double deriv2(
double x0)
const=0;
161 virtual double integ(
double a,
double b)
const=0;
164 virtual const char *type()
const=0;
166 #ifndef DOXYGEN_INTERNAL
187 #ifdef O2SCL_NEVER_DEFINED
197 virtual ~interp_linear() {}
200 virtual void set(
size_t size,
const vec_t &x,
const vec2_t &y) {
201 if (size<this->min_size) {
203 " than "+
szttos(this->min_size)+
" in interp_linear::"+
206 this->svx.set_vec(size,x);
214 virtual double eval(
double x0)
const {
216 size_t index=this->svx.find(x0);
218 double x_lo=(*this->px)[index];
219 double x_hi=(*this->px)[index+1];
220 double y_lo=(*this->py)[index];
221 double y_hi=(*this->py)[index+1];
224 return y_lo+(x0-x_lo)/dx*(y_hi-y_lo);
228 virtual double deriv(
double x0)
const {
230 size_t index=this->svx.find(x0);
232 double x_lo=(*this->px)[index];
233 double x_hi=(*this->px)[index+1];
234 double y_lo=(*this->py)[index];
235 double y_hi=(*this->py)[index+1];
250 virtual double integ(
double a,
double b)
const {
252 size_t i, index_a, index_b;
255 if (((*this->px)[0]<(*this->px)[this->sz-1] && a>b) ||
256 ((*this->px)[0]>(*this->px)[this->sz-1] && a<b)) {
263 index_a=this->svx.find(a);
264 index_b=this->svx.find(b);
267 for(i=index_a; i<=index_b; i++) {
269 double x_lo=(*this->px)[i];
270 double x_hi=(*this->px)[i+1];
271 double y_lo=(*this->py)[i];
272 double y_hi=(*this->py)[i+1];
277 if (i == index_a || i == index_b) {
278 double x1=(i == index_a) ? a : x_lo;
279 double x2=(i == index_b) ? b : x_hi;
280 double D=(y_hi-y_lo)/dx;
281 result += (x2-
x1)*(y_lo+0.5*D*((x2-x_lo)+(x1-x_lo)));
283 result += 0.5*dx*(y_lo+y_hi);
287 std::string str=((std::string)
"Interval of length zero ")+
290 " in interp_linear::integ().";
295 if (flip) result=-result;
300 virtual const char *
type()
const {
return "interp_linear"; }
302 #ifndef DOXYGEN_INTERNAL
325 #ifdef O2SCL_NEVER_DEFINED
332 typedef boost::numeric::ublas::vector_slice<ubvector> ubvector_slice;
333 typedef boost::numeric::ublas::vector_range<ubvector> ubvector_range;
334 typedef boost::numeric::ublas::slice slice;
335 typedef boost::numeric::ublas::range range;
337 #ifndef DOXYGEN_INTERNAL
353 void coeff_calc(
const ubvector &c_array,
double dy,
double dx,
354 size_t index,
double &b,
double &c2,
double &d)
const {
356 double c_i=c_array[index];
357 double c_ip1=c_array[index+1];
358 b=(dy/dx)-dx*(c_ip1+2.0*c_i)/3.0;
360 d=(c_ip1-c_i)/(3.0*dx);
381 virtual void set(
size_t size,
const vec_t &xa,
const vec2_t &ya) {
383 if (size<this->min_size) {
385 " than "+
szttos(this->min_size)+
" in interp_cspline::"+
389 if (size!=this->sz) {
393 offdiag.resize(size);
401 this->svx.set_vec(size,xa);
406 size_t num_points=size;
407 size_t max_index=num_points-1;
408 size_t sys_size=max_index-1;
413 for (i=0; i < sys_size; i++) {
414 double h_i=xa[i+1]-xa[i];
415 double h_ip1=xa[i+2]-xa[i+1];
416 double ydiff_i=ya[i+1]-ya[i];
417 double ydiff_ip1=ya[i+2]-ya[i+1];
418 double g_i=(h_i != 0.0) ? 1.0/h_i : 0.0;
419 double g_ip1=(h_ip1 != 0.0) ? 1.0/h_ip1 : 0.0;
421 diag[i]=2.0*(h_ip1+h_i);
422 g[i]=3.0*(ydiff_ip1*g_ip1-ydiff_i*g_i);
432 ubvector_range cp1(c,range(1,c.size()));
435 (diag,offdiag,g,cp1,sys_size,p4m);
441 virtual double eval(
double x0)
const {
443 size_t index=this->svx.find(x0);
445 double x_lo=(*this->px)[index];
446 double x_hi=(*this->px)[index+1];
449 double y_lo=(*this->py)[index];
450 double y_hi=(*this->py)[index+1];
453 double b_i, c_i, d_i;
455 coeff_calc(c,dy,dx,index,b_i,c_i,d_i);
457 return y_lo+delx*(b_i+delx*(c_i+delx*d_i));
461 virtual double deriv(
double x0)
const {
463 size_t index=this->svx.find(x0);
465 double x_lo=(*this->px)[index];
466 double x_hi=(*this->px)[index+1];
469 double y_lo=(*this->py)[index];
470 double y_hi=(*this->py)[index+1];
473 double b_i, c_i, d_i;
475 coeff_calc(c,dy,dx,index,b_i,c_i,d_i);
477 return b_i+delx*(2.0*c_i+3.0*d_i*delx);
485 size_t index=this->svx.find(x0);
487 double x_lo=(*this->px)[index];
488 double x_hi=(*this->px)[index+1];
491 double y_lo=(*this->py)[index];
492 double y_hi=(*this->py)[index+1];
495 double b_i, c_i, d_i;
497 coeff_calc(c,dy,dx,index,b_i,c_i,d_i);
499 return 2.0*c_i+6.0*d_i*delx;
503 virtual double integ(
double a,
double b)
const {
505 size_t i, index_a, index_b;
508 if (((*this->px)[0]<(*this->px)[this->sz-1] && a>b) ||
509 ((*this->px)[0]>(*this->px)[this->sz-1] && a<b)) {
516 index_a=this->svx.find(a);
517 index_b=this->svx.find(b);
521 for(i=index_a; i<=index_b; i++) {
523 double x_lo=(*this->px)[i];
524 double x_hi=(*this->px)[i+1];
525 double y_lo=(*this->py)[i];
526 double y_hi=(*this->py)[i+1];
531 double b_i, c_i, d_i;
532 coeff_calc(c,dy,dx,i,b_i,c_i,d_i);
533 if (i == index_a || i == index_b) {
534 double x1=(i == index_a) ? a : x_lo;
535 double x2=(i == index_b) ? b : x_hi;
536 result += this->integ_eval(y_lo,b_i,c_i,d_i,x_lo,x1,x2);
538 result += dx*(y_lo+dx*(0.5*b_i+
539 dx*(c_i/3.0+0.25*d_i*dx)));
542 std::string str=((std::string)
"Interval of length zero ")+
545 " in interp_cspline::integ().";
551 if (flip) result*=-1.0;
557 virtual const char *
type()
const {
return "interp_cspline"; }
559 #ifndef DOXYGEN_INTERNAL
565 (
const interp_cspline<vec_t,vec2_t>&);
579 #ifdef O2SCL_NEVER_DEFINED
591 typedef boost::numeric::ublas::vector_slice<ubvector> ubvector_slice;
592 typedef boost::numeric::ublas::vector_range<ubvector> ubvector_range;
593 typedef boost::numeric::ublas::slice slice;
594 typedef boost::numeric::ublas::range range;
604 virtual const char *
type()
const {
return "interp_cspline_peri"; }
608 virtual void set(
size_t size,
const vec_t &xa,
const vec2_t &ya) {
610 if (size<this->min_size) {
612 " than "+
szttos(this->min_size)+
" in interp_cspline"+
616 if (size!=this->sz) {
617 this->c.resize(size);
618 this->g.resize(size);
619 this->diag.resize(size);
620 this->offdiag.resize(size);
628 this->svx.set_vec(size,xa);
633 size_t num_points=size;
635 size_t max_index=num_points-1;
637 size_t sys_size=max_index;
643 double h0=xa[1]-xa[0];
644 double h1=xa[2]-xa[1];
645 double h2=xa[3]-xa[2];
646 double A=2.0*(h0+h1);
651 gx[0]=3.0*((ya[2]-ya[1])/h1-(ya[1]-ya[0])/h0);
652 gx[1]=3.0*((ya[1]-ya[2])/h2-(ya[2]-ya[1])/h1);
654 det=3.0*(h0+h1)*(h0+h1);
655 this->c[1]=( A*gx[0]-B*gx[1])/det;
656 this->c[2]=(-B*gx[0]+A*gx[1])/det;
657 this->c[0]=this->c[2];
663 for (i=0; i < sys_size-1; i++) {
664 double h_i=xa[i+1]-xa[i];
665 double h_ip1=xa[i+2]-xa[i+1];
666 double ydiff_i=ya[i+1]-ya[i];
667 double ydiff_ip1=ya[i+2]-ya[i+1];
668 double g_i=(h_i != 0.0) ? 1.0/h_i : 0.0;
669 double g_ip1=(h_ip1 != 0.0) ? 1.0/h_ip1 : 0.0;
670 this->offdiag[i]=h_ip1;
671 this->diag[i]=2.0*(h_ip1+h_i);
672 this->g[i]=3.0*(ydiff_ip1*g_ip1-ydiff_i*g_i);
677 double h_i=xa[i+1]-xa[i];
678 double h_ip1=xa[1]-xa[0];
679 double ydiff_i=ya[i+1]-ya[i];
680 double ydiff_ip1=ya[1]-ya[0];
681 double g_i=(h_i != 0.0) ? 1.0/h_i : 0.0;
682 double g_ip1=(h_ip1 != 0.0) ? 1.0/h_ip1 : 0.0;
683 this->offdiag[i]=h_ip1;
684 this->diag[i]=2.0*(h_ip1+h_i);
685 this->g[i]=3.0*(ydiff_ip1*g_ip1-ydiff_i*g_i);
688 ubvector_range cp1(this->c,range(1,this->c.size()));
691 (this->diag,this->offdiag,this->g,cp1,sys_size,p5m);
692 this->c[0]=this->c[max_index];
699 #ifndef DOXYGEN_INTERNAL
706 (
const interp_cspline_peri<vec_t,vec2_t>&);
728 typedef boost::numeric::ublas::vector_slice<ubvector> ubvector_slice;
729 typedef boost::numeric::ublas::vector_range<ubvector> ubvector_range;
730 typedef boost::numeric::ublas::slice slice;
731 typedef boost::numeric::ublas::range range;
733 #ifndef DOXYGEN_INTERNAL
749 for(
size_t i=0;i<this->
sz-1;i++) {
751 double NE=fabs(umx[3+i]-umx[2+i])+fabs(umx[1+i]-umx[i]);
758 double h_i=(*this->
px)[i+1]-(*this->
px)[i];
759 double NE_next=fabs(umx[4+i]-umx[3+i])+
760 fabs(umx[2+i]-umx[1+i]);
761 double alpha_i=fabs(umx[1+i]-umx[i])/NE;
764 if (NE_next == 0.0) {
767 alpha_ip1=fabs(umx[2+i]-umx[1+i])/NE_next;
768 tL_ip1=(1.0-alpha_ip1)*umx[2+i]+alpha_ip1*umx[3+i];
770 b[i]=(1.0-alpha_i)*umx[1+i]+alpha_i*umx[2+i];
771 c[i]=(3.0*umx[2+i]-2.0*b[i]-tL_ip1)/h_i;
772 d[i]=(b[i]+tL_ip1-2.0*umx[2+i])/(h_i*h_i);
793 virtual void set(
size_t size,
const vec_t &xa,
const vec2_t &ya) {
797 " than "+
szttos(this->min_size)+
" in interp_akima::"+
801 if (size!=this->
sz) {
816 ubvector_range m(um,range(2,um.size()));
818 for (i=0;i<=size-2;i++) {
819 m[i]=(ya[i+1]-ya[i])/(xa[i+1]-xa[i]);
822 um[0]=3.0*m[0]-2.0*m[1];
824 m[this->
sz-1]=2.0*m[size-2]-m[size-3];
825 m[size]=3.0*m[size-2]-2.0*m[size-3];
833 virtual double eval(
double x0)
const {
835 size_t index=this->
svx.
find(x0);
837 double x_lo=(*this->
px)[index];
843 return (*this->
py)[index]+delx*(bb+delx*(cc+dd*delx));
847 virtual double deriv(
double x0)
const {
849 size_t index=this->
svx.
find(x0);
851 double x_lo=(*this->
px)[index];
857 return bb+delx*(2.0*cc+3.0*dd*delx);
865 size_t index=this->
svx.
find(x0);
867 double x_lo=(*this->
px)[index];
872 return 2.0*cc+6.0*dd*delx;
876 virtual double integ(
double aa,
double bb)
const {
878 size_t i, index_a, index_b;
881 if (((*this->
px)[0]<(*this->
px)[this->
sz-1] && aa>bb) ||
882 ((*this->
px)[0]>(*this->
px)[this->
sz-1] && aa<bb)) {
894 for(i=index_a; i<=index_b; i++) {
896 double x_lo=(*this->
px)[i];
897 double x_hi=(*this->
px)[i+1];
898 double y_lo=(*this->
py)[i];
903 if (i==index_a || i==index_b) {
904 double x1=(i==index_a) ? aa : x_lo;
905 double x2=(i==index_b) ? bb : x_hi;
906 result += this->
integ_eval(y_lo,b[i],c[i],d[i],x_lo,x1,x2);
908 result+=dx*(y_lo+dx*(0.5*b[i]+dx*(c[i]/3.0+0.25*d[i]*dx)));
912 double y_hi=(*this->
py)[i+1];
913 std::string str=((std::string)
"Interval of length zero ")+
916 " in interp_akima::integ().";
921 if (flip) result*=-1.0;
927 virtual const char *
type()
const {
return "interp_akima"; }
929 #ifndef DOXYGEN_INTERNAL
951 typedef boost::numeric::ublas::vector_slice<ubvector> ubvector_slice;
952 typedef boost::numeric::ublas::vector_range<ubvector> ubvector_range;
953 typedef boost::numeric::ublas::slice slice;
954 typedef boost::numeric::ublas::range range;
965 virtual const char *
type()
const {
return "interp_akima_peri"; }
968 virtual void set(
size_t size,
const vec_t &xa,
const vec2_t &ya) {
972 " than "+
szttos(this->min_size)+
" in interp_akima"+
976 if (size!=this->
sz) {
977 this->b.resize(size);
978 this->c.resize(size);
979 this->d.resize(size);
980 this->um.resize(size+4);
991 ubvector_range m(this->um,range(2,this->um.size()));
994 for (
size_t i=0;i<=size-2;i++) {
995 m[i]=(ya[i+1]-ya[i])/(xa[i+1]-xa[i]);
998 this->um[0]=m[this->
sz-3];
999 this->um[1]=m[this->
sz-2];
1008 #ifndef DOXYGEN_INTERNAL
1047 #ifdef O2SCL_NEVER_DEFINED
1076 virtual void set(
size_t size,
const vec_t &x,
const vec2_t &y) {
1079 if (size<this->min_size) {
1081 " than "+
szttos(this->min_size)+
" in interp_monotonic::"+
1086 this->svx.set_vec(size,x);
1089 if (this->sz!=size) {
1091 Delta.resize(size-1);
1092 alpha.resize(size-1);
1093 beta.resize(size-1);
1104 for(
size_t i=0;i<size-1;i++) {
1105 Delta[i]=(y[i+1]-y[i])/(x[i+1]-x[i]);
1107 m[i]=(Delta[i]+Delta[i-1])/2.0;
1111 m[size-1]=Delta[size-2];
1114 for(
size_t i=0;i<size-1;i++) {
1122 for(
size_t i=0;i<size-1;i++) {
1123 alpha[i]=m[i]/Delta[i];
1124 beta[i]=m[i+1]/Delta[i];
1128 for(
size_t i=0;i<size-1;i++) {
1129 double norm2=alpha[i]*alpha[i]+beta[i]*beta[i];
1131 double tau=3.0/sqrt(norm2);
1132 m[i]=tau*alpha[i]*Delta[i];
1133 m[i+1]=tau*beta[i]*Delta[i];
1141 virtual double eval(
double x0)
const {
1143 size_t index=this->svx.find(x0);
1145 double x_lo=(*this->px)[index];
1146 double x_hi=(*this->px)[index+1];
1147 double y_lo=(*this->py)[index];
1148 double y_hi=(*this->py)[index+1];
1150 double t=(x0-x_lo)/h;
1151 double t2=t*t, t3=t2*t;
1153 double h00=2.0*t3-3.0*t2+1.0;
1154 double h10=t3-2.0*t2+t;
1155 double h01=-2.0*t3+3.0*t2;
1157 double interp=y_lo*h00+h*m[index]*h10+y_hi*h01+h*m[index+1]*h11;
1165 size_t index=this->svx.find(x0);
1167 double x_lo=(*this->px)[index];
1168 double x_hi=(*this->px)[index+1];
1169 double y_lo=(*this->py)[index];
1170 double y_hi=(*this->py)[index+1];
1172 double t=(x0-x_lo)/h;
1175 double dh00=6.0*t2-6.0*t;
1176 double dh10=3.0*t2-4.0*t+1.0;
1177 double dh01=-6.0*t2+6.0*t;
1178 double dh11=3.0*t2-2.0*t;
1179 double deriv=(y_lo*dh00+h*m[index]*dh10+y_hi*dh01+
1180 h*m[index+1]*dh11)/h;
1190 size_t index=this->svx.find(x0);
1192 double x_lo=(*this->px)[index];
1193 double x_hi=(*this->px)[index+1];
1194 double y_lo=(*this->py)[index];
1195 double y_hi=(*this->py)[index+1];
1197 double t=(x0-x_lo)/h;
1199 double ddh00=12.0*t-6.0;
1200 double ddh10=6.0*t-4.0;
1201 double ddh01=-12.0*t+6.0;
1202 double ddh11=6.0*t-2.0;
1203 double deriv2=(y_lo*ddh00+h*m[index]*ddh10+y_hi*ddh01+
1204 h*m[index+1]*ddh11)/h/h;
1210 virtual double integ(
double a,
double b)
const {
1212 size_t i, index_a, index_b;
1215 if (((*this->px)[0]<(*this->px)[this->sz-1] && a>b) ||
1216 ((*this->px)[0]>(*this->px)[this->sz-1] && a<b)) {
1223 index_a=this->svx.find(a);
1224 index_b=this->svx.find(b);
1228 for(i=index_a; i<=index_b; i++) {
1230 double x_hi=(*this->px)[i+1];
1231 double x_lo=(*this->px)[i];
1232 double y_lo=(*this->py)[i];
1233 double y_hi=(*this->py)[i+1];
1245 double t=(x_hi-x_lo)/h;
1246 double t2=t*t, t3=t2*t, t4=t3*t;
1248 double ih00=t4/2.0-t3+t;
1249 double ih10=t4/4.0-2.0*t3/3.0+t2/2.0;
1250 double ih01=-t4/2.0+t3;
1251 double ih11=t4/4.0-t3/3.0;
1252 double intres=h*(y_lo*ih00+h*m[i]*ih10+y_hi*ih01+
1257 std::string str=((std::string)
"Interval of length zero ")+
1260 " in interp_monotonic::integ().";
1266 if (flip) result*=-1.0;
1272 virtual const char *
type()
const {
return "interp_monotonic"; }
1274 #ifndef DOXYGEN_INTERNAL
1280 (
const interp_monotonic<vec_t,vec2_t>&);
1298 template<
class vec_t=boost::numeric::ublas::vector<
double>,
1301 #ifndef DOXYGEN_INTERNAL
1327 O2SCL_ERR((((std::string)
"Invalid interpolation type, ")+
1338 virtual double eval(
const double x0,
size_t n,
const vec_t &x,
1341 return itp->eval(x0);
1345 virtual double deriv(
const double x0,
size_t n,
const vec_t &x,
1348 return itp->deriv(x0);
1354 virtual double deriv2(
const double x0,
size_t n,
const vec_t &x,
1357 return itp->deriv2(x0);
1361 virtual double integ(
const double x1,
const double x2,
size_t n,
1362 const vec_t &x,
const vec2_t &y) {
1364 return itp->integ(x1,x2);
1381 O2SCL_ERR((((std::string)
"Invalid interpolation type, ")+
1388 #ifndef DOXYGEN_INTERNAL
1419 template<
class vec_t=boost::numeric::ublas::vector<
double>,
1423 #ifndef DOXYGEN_INTERNAL
1445 const vec2_t &y,
size_t interp_type=
itp_cspline) {
1448 O2SCL_ERR((((std::string)
"Vector endpoints equal (value=")+
1466 O2SCL_ERR((((std::string)
"Invalid interpolation type, ")+
1468 "interp_vec::interp_vec().").c_str(),
exc_einval);
1483 void set(
size_t n,
const vec_t &x,
const vec2_t &y) {
1490 void set(
size_t n,
const vec_t &x,
1491 const vec2_t &y,
size_t interp_type) {
1494 O2SCL_ERR((((std::string)
"Vector endpoints equal (value=")+
1513 O2SCL_ERR((((std::string)
"Invalid interpolation type, ")+
1533 virtual double eval(
const double x0)
const {
1535 O2SCL_ERR(
"No vector set in interp_vec::eval().",
1538 return itp->eval(x0);
1544 O2SCL_ERR(
"No vector set in interp_vec::operator().",
1547 return itp->eval(x0);
1551 virtual double deriv(
const double x0)
const {
1553 O2SCL_ERR(
"No vector set in interp_vec::deriv().",
1556 return itp->deriv(x0);
1562 virtual double deriv2(
const double x0)
const {
1564 O2SCL_ERR(
"No vector set in interp_vec::deriv2().",
1567 return itp->deriv2(x0);
1571 virtual double integ(
const double x1,
const double x2)
const {
1573 O2SCL_ERR(
"No vector set in interp_vec::integ().",
1576 return itp->integ(x1,x2);
1581 return "interp_vec";
1584 #ifndef DOXYGEN_INTERNAL
1601 public interp<double[n]> {
1607 :
interp<double[n]>(interp_type) {}
1627 size_t interp_type) :
1651 (
double level,
size_t n, vec_t &x, vec2_t &y) {
1654 O2SCL_ERR2(
"Need at least two data points in ",
1661 if (y[0]==level) count++;
1664 for(
size_t i=0;i<n-1;i++) {
1666 if ((y[i]<level && y[i+1]>=level) ||
1667 (y[i]>level && y[i+1]<=level)) {
1696 (
double level,
size_t n, vec_t &x, vec2_t &y, std::vector<double> &locs) {
1699 O2SCL_ERR2(
"Need at least two data points in ",
1708 locs.push_back(x[0]);
1712 for(
size_t i=0;i<n-1;i++) {
1714 if ((y[i]<level && y[i+1]>level) ||
1715 (y[i]>level && y[i+1]<level)) {
1718 double x0=x[i]+(x[i+1]-x[i])*(level-y[i])/(y[i+1]-y[i]);
1720 }
else if (y[i+1]==level) {
1721 locs.push_back(x[i+1]);
1741 template<
class vec_t,
class vec2_t>
1748 double total=si.
integ(x[0],x[n-1],n,x,y);
1789 (
double sum,
size_t n, vec_t &x, vec2_t &y,
double &lev,
1793 O2SCL_ERR2(
"Need at least two data points in ",
1798 O2SCL_ERR2(
"The first and last y-values must be equal in ",
1806 vector_sort<ubvector,double>(ysort.size(),ysort);
1812 std::vector<double> ylist;
1813 for(
size_t i=0;i<ysort.size()-1;i++) {
1814 if (ysort[i]!=ysort[i+1]) {
1815 ylist.push_back((ysort[i+1]+3.0*ysort[i])/4.0);
1816 ylist.push_back((ysort[i+1]*3.0+ysort[i])/4.0);
1826 std::vector<double> xi, yi;
1830 for(
size_t k=0;k<ylist.size();k++) {
1831 double lev_tmp=ylist[k];
1832 std::vector<double> locs;
1834 if ((locs.size()%2)!=0) {
1837 double sum_temp=0.0;
1838 for(
size_t i=0;i<locs.size()/2;i++) {
1839 double x0=locs[2*i];
1840 double x1=locs[2*i+1];
1841 sum_temp+=itp.
integ(x0,x1,n,x,y);
1843 xi.push_back(sum_temp);
1844 yi.push_back(lev_tmp);
1853 std::cout <<
"i, xi, yi: " << std::endl;
1854 for(
size_t i=0;i<xi.size();i++) {
1855 std::cout << i <<
" " << xi[i] <<
" " << yi[i] << std::endl;
1859 lev=itp2.
eval(sum,xi.size(),xi,yi);
1867 (
size_t n, vec_t &x, vec2_t &y,
double frac, std::vector<double> &locs,
1870 if (frac<0.0 || frac>1.0) {
1871 O2SCL_ERR2(
"Fraction must be between 0 and 1 (exclusive) in ",
1878 std::cout <<
"Total integral: " << total << std::endl;
1881 double partial=frac*total;
1883 std::cout <<
"Partial integral: " << partial << std::endl;
1889 std::cout <<
"Level from vector_invert: " << lev << std::endl;
1894 std::cout <<
"Locations from vector_find_level: ";
1895 for(
size_t i=0;i<locs.size();i++) {
1896 std::cout << locs[i];
1897 if (i!=locs.size()-1) {
1901 std::cout << std::endl;
1909 (
size_t n, vec_t &x, vec2_t &y,
double frac,
double &low,
double &high) {
1911 std::vector<double> locs;
1913 if (locs.size()==0) {
1914 O2SCL_ERR(
"Zero level crossings in vector_bound_sigma().",
1924 #ifndef DOXYGEN_NO_O2NS
void vector_region_parint(size_t n, vec_t &x, vec2_t &y, double frac, std::vector< double > &locs, int verbose=0)
Find the region enclosing a partial integral.
Interpolation class for pre-specified vector.
virtual double operator()(double x0) const
Give the value of the function .
o2scl_linalg::ubvector_5_mem p5m
Memory for the tridiagonalization.
virtual double integ(double a, double b) const
Give the value of the integral .
virtual void set(size_t size, const vec_t &xa, const vec2_t &ya)
Initialize interpolation routine.
virtual double eval(const double x0, size_t n, const vec_t &x, const vec2_t &y)
Give the value of the function .
virtual const char * type() const
Return the type, "interp_akima_peri".
interp_vec(size_t n, const vec_t &x, const vec2_t &y, size_t interp_type=itp_cspline)
Create with base interpolation object it.
virtual double integ(double aa, double bb) const
Give the value of the integral .
double integ_eval(double ai, double bi, double ci, double di, double xi, double a, double b) const
An internal function to assist in computing the integral for both the cspline and Akima types...
interp(size_t interp_type=itp_cspline)
Create with base interpolation object it.
virtual void set(size_t size, const vec_t &xa, const vec2_t &ya)
Initialize interpolation routine.
void solve_tridiag_sym(const vec_t &diag, const vec2_t &offdiag, const vec3_t &b, vec4_t &x, size_t N, mem_t &m)
Solve a symmetric tridiagonal linear system with user-specified memory.
void akima_calc(const vec_t &x_array, size_t size, ubvector &umx)
For initializing the interpolation.
size_t min_size
The minimum size of the vectors to interpolate between.
A specialization of interp for C-style double arrays.
virtual double integ(const double x1, const double x2) const
Give the value of the integral .
interp_base< vec_t, vec2_t > * itp
Pointer to base interpolation object.
Akima spline interpolation with periodic boundary conditions (GSL)
void clear()
Manually clear the pointer to the user-specified vector.
virtual double deriv(double x0) const
Give the value of the derivative .
virtual const char * type() const
Return the type, "interp_cspline".
virtual double deriv2(double x0) const
Give the value of the second derivative (always zero)
virtual double deriv2(const double x0) const
Give the value of the second derivative .
virtual double deriv(double x0) const
Give the value of the derivative .
virtual double eval(double x0) const
Give the value of the function .
invalid argument supplied by user
const vec_t * px
Independent vector.
virtual double deriv2(double x0) const
Give the value of the second derivative .
Monotonicity-preserving interpolation.
Base low-level interpolation class [abstract base].
interp_array_vec(size_t nv, const arr_t &x, const arr_t &y, size_t interp_type)
Create with base interpolation object it.
virtual const char * type() const
Return the type, "interp_cspline_peri".
Akima spline for periodic boundary conditions.
virtual double integ(double a, double b) const
Give the value of the integral .
void vector_min(size_t n, const vec_t &data, size_t &index, data_t &val)
Compute the minimum of the first n elements of a vector.
interp_vec()
Blank interpolator.
virtual double deriv(double x0) const
Give the value of the derivative .
interp_akima()
Create a base interpolation object with or without periodic boundary conditions.
virtual void set(size_t size, const vec_t &xa, const vec2_t &ya)
Initialize interpolation routine.
Cubic spline interpolation with periodic boundary conditions (GSL)
virtual double integ(const double x1, const double x2, size_t n, const vec_t &x, const vec2_t &y)
Give the value of the integral .
virtual double eval(double x0) const
Give the value of the function .
Cubic spline for natural boundary conditions.
virtual double integ(double a, double b) const
Give the value of the integral .
void vector_bound_parint(size_t n, vec_t &x, vec2_t &y, double frac, double &low, double &high)
Find the boundaries of the region enclosing a partial integral.
virtual double deriv2(double x0) const
Give the value of the second derivative .
ubvector beta
Staggered ratio.
Allocation object for 5 arrays of equal size.
virtual double eval(double x0) const
Give the value of the function .
void set(size_t n, const vec_t &x, const vec2_t &y, size_t interp_type)
Set a new vector to interpolate.
interp_array()
Create an interpolator using the default base interpolation objects.
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
size_t itype
Interpolation type.
std::string dtos(double x, int prec=6, bool auto_prec=false)
Convert a double to a string.
virtual const char * type() const
Return the type, "interp_monotonic".
const vec2_t * py
Dependent vector.
o2scl_linalg::ubvector_4_mem p4m
Memory for the tridiagonalization.
virtual double deriv(double x0) const
Give the value of the derivative .
size_t find(const double x0) const
Search an increasing or decreasing vector for the interval containing x0
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
Allocation object for 4 arrays of equal size.
void set_type(size_t interp_type)
Set base interpolation type.
size_t vector_level_count(double level, size_t n, vec_t &x, vec2_t &y)
Count level crossings.
Akima spline for natural boundary conditions.
double vector_integ_linear(size_t n, vec_t &x, vec2_t &y)
Compute the integral over y(x) using linear interpolation.
Akima spline interpolation (GSL)
void coeff_calc(const ubvector &c_array, double dy, double dx, size_t index, double &b, double &c2, double &d) const
Compute coefficients for cubic spline interpolation.
void vector_invert_enclosed_sum(double sum, size_t n, vec_t &x, vec2_t &y, double &lev, int verbose=0)
Compute the endpoints which enclose the regions whose integral is equal to sum.
void vector_max(size_t n, const vec_t &data, size_t &index, data_t &val)
Compute the maximum of the first n elements of a vector.
interp_cspline()
Create a base interpolation object with natural or periodic boundary conditions.
Cubic spline for periodic boundary conditions.
virtual double deriv(const double x0) const
Give the value of the derivative .
Monotonicity-preserving interpolation.
virtual double deriv2(double x0) const
Give the value of the second derivative .
virtual double deriv2(const double x0, size_t n, const vec_t &x, const vec2_t &y)
Give the value of the second derivative .
ubvector Delta
Finite differences.
Cubic spline interpolation (GSL)
virtual double eval(double x0) const
Give the value of the function .
interp_array(size_t interp_type)
Create with base interpolation objects it and rit.
virtual const char * type() const
Return the type, "interp_akima".
void vector_copy(vec_t &src, vec2_t &dest)
Simple generic vector copy.
void solve_cyc_tridiag_sym(const vec_t &diag, const vec2_t &offdiag, const vec3_t &b, vec4_t &x, size_t N, mem_t &m)
Solve a symmetric cyclic tridiagonal linear system with user specified memory.
virtual void set(size_t size, const vec_t &x, const vec2_t &y)
Initialize interpolation routine.
virtual double eval(const double x0) const
Give the value of the function .
virtual const char * type() const
Return the type, "interp_linear".
virtual double operator()(double x0) const
Give the value of the function .
void set_vec(size_t nn, const vec_t &x)
Set the vector to be searched.
search_vec< const vec_t > svx
To perform binary searches.
static const double x2[5]
static const double x1[5]
Linear interpolation (GSL)
std::string szttos(size_t x)
Convert a size_t to a string.
virtual const char * type() const
Return the type, "interp_vec".
void vector_find_level(double level, size_t n, vec_t &x, vec2_t &y, std::vector< double > &locs)
Perform inverse linear interpolation.
A specialization of o2scl::interp_vec for C-style arrays.
interp_base< vec_t, vec2_t > * itp
Base interpolation object.
virtual void set(size_t size, const vec_t &xa, const vec2_t &ya)
Initialize interpolation routine.
Interpolation class for general vectors.
virtual double deriv(const double x0, size_t n, const vec_t &x, const vec2_t &y)
Give the value of the derivative .
void set(size_t n, const vec_t &x, const vec2_t &y)
Set a new vector to interpolate.
virtual void set(size_t size, const vec_t &x, const vec2_t &y)
Initialize interpolation routine.