46 #ifndef O2SCL_INTERP_H 47 #define O2SCL_INTERP_H 56 #include <boost/numeric/ublas/vector.hpp> 57 #include <boost/numeric/ublas/vector_proxy.hpp> 59 #include <o2scl/search_vec.h> 60 #include <o2scl/tridiag.h> 62 #ifndef DOXYGEN_NO_O2NS 106 #ifdef O2SCL_NEVER_DEFINED 110 #ifndef DOXYGEN_INTERNAL 133 double integ_eval(
double ai,
double bi,
double ci,
double di,
double xi,
134 double a,
double b)
const {
139 double bterm=0.5*bi*r12;
140 double cterm=ci*(r1*r1+r2*r2+r1*r2)/3.0;
141 double dterm=0.25*di*r12*(r1*r1+r2*r2);
143 return (b-a)*(ai+bterm+cterm+dterm);
165 virtual void set(
size_t size,
const vec_t &x,
const vec2_t &y)=0;
168 virtual double eval(
double x0)
const=0;
176 virtual double deriv(
double x0)
const=0;
181 virtual double deriv2(
double x0)
const=0;
184 virtual double integ(
double a,
double b)
const=0;
187 virtual const char *
type()
const=0;
189 #ifndef DOXYGEN_INTERNAL 210 #ifdef O2SCL_NEVER_DEFINED 223 virtual void set(
size_t size,
const vec_t &x,
const vec2_t &y) {
226 " than "+
szttos(this->min_size)+
" in interp_linear::"+
237 virtual double eval(
double x0)
const {
239 size_t index=this->
svx.
find(x0);
241 double x_lo=(*this->
px)[index];
242 double x_hi=(*this->
px)[index+1];
243 double y_lo=(*this->
py)[index];
244 double y_hi=(*this->
py)[index+1];
247 return y_lo+(x0-x_lo)/dx*(y_hi-y_lo);
251 virtual double deriv(
double x0)
const {
253 size_t index=this->
svx.
find(x0);
255 double x_lo=(*this->
px)[index];
256 double x_hi=(*this->
px)[index+1];
257 double y_lo=(*this->
py)[index];
258 double y_hi=(*this->
py)[index+1];
273 virtual double integ(
double a,
double b)
const {
275 size_t i, index_a, index_b;
278 if (((*this->
px)[0]<(*this->
px)[this->
sz-1] && a>b) ||
279 ((*this->
px)[0]>(*this->
px)[this->
sz-1] && a<b)) {
290 for(i=index_a; i<=index_b; i++) {
292 double x_lo=(*this->
px)[i];
293 double x_hi=(*this->
px)[i+1];
294 double y_lo=(*this->
py)[i];
295 double y_hi=(*this->
py)[i+1];
300 if (i == index_a || i == index_b) {
301 double x1=(i == index_a) ? a : x_lo;
302 double x2=(i == index_b) ? b : x_hi;
303 double D=(y_hi-y_lo)/dx;
304 result += (x2-
x1)*(y_lo+0.5*D*((x2-x_lo)+(x1-x_lo)));
306 result += 0.5*dx*(y_lo+y_hi);
310 std::string str=((std::string)
"Interval of length zero ")+
313 " in interp_linear::integ().";
318 if (flip) result=-result;
323 virtual const char *
type()
const {
return "interp_linear"; }
325 #ifndef DOXYGEN_INTERNAL 348 #ifdef O2SCL_NEVER_DEFINED 355 typedef boost::numeric::ublas::vector_slice<ubvector> ubvector_slice;
356 typedef boost::numeric::ublas::vector_range<ubvector> ubvector_range;
357 typedef boost::numeric::ublas::slice slice;
358 typedef boost::numeric::ublas::range range;
360 #ifndef DOXYGEN_INTERNAL 376 void coeff_calc(
const ubvector &c_array,
double dy,
double dx,
377 size_t index,
double &b,
double &c2,
double &d)
const {
379 double c_i=c_array[index];
380 double c_ip1=c_array[index+1];
381 b=(dy/dx)-dx*(c_ip1+2.0*c_i)/3.0;
383 d=(c_ip1-c_i)/(3.0*dx);
404 virtual void set(
size_t size,
const vec_t &xa,
const vec2_t &ya) {
408 " than "+
szttos(this->min_size)+
" in interp_cspline::"+
412 if (size!=this->
sz) {
416 offdiag.resize(size);
429 size_t num_points=size;
430 size_t max_index=num_points-1;
431 size_t sys_size=max_index-1;
436 for (i=0; i < sys_size; i++) {
437 double h_i=xa[i+1]-xa[i];
438 double h_ip1=xa[i+2]-xa[i+1];
439 double ydiff_i=ya[i+1]-ya[i];
440 double ydiff_ip1=ya[i+2]-ya[i+1];
441 double g_i=(h_i != 0.0) ? 1.0/h_i : 0.0;
442 double g_ip1=(h_ip1 != 0.0) ? 1.0/h_ip1 : 0.0;
444 diag[i]=2.0*(h_ip1+h_i);
445 g[i]=3.0*(ydiff_ip1*g_ip1-ydiff_i*g_i);
455 ubvector_range cp1(c,range(1,c.size()));
458 (diag,offdiag,g,cp1,sys_size,p4m);
464 virtual double eval(
double x0)
const {
466 size_t index=this->
svx.
find(x0);
468 double x_lo=(*this->
px)[index];
469 double x_hi=(*this->
px)[index+1];
472 double y_lo=(*this->
py)[index];
473 double y_hi=(*this->
py)[index+1];
476 double b_i, c_i, d_i;
478 coeff_calc(c,dy,dx,index,b_i,c_i,d_i);
480 return y_lo+delx*(b_i+delx*(c_i+delx*d_i));
484 virtual double deriv(
double x0)
const {
486 size_t index=this->
svx.
find(x0);
488 double x_lo=(*this->
px)[index];
489 double x_hi=(*this->
px)[index+1];
492 double y_lo=(*this->
py)[index];
493 double y_hi=(*this->
py)[index+1];
496 double b_i, c_i, d_i;
498 coeff_calc(c,dy,dx,index,b_i,c_i,d_i);
500 return b_i+delx*(2.0*c_i+3.0*d_i*delx);
508 size_t index=this->
svx.
find(x0);
510 double x_lo=(*this->
px)[index];
511 double x_hi=(*this->
px)[index+1];
514 double y_lo=(*this->
py)[index];
515 double y_hi=(*this->
py)[index+1];
518 double b_i, c_i, d_i;
520 coeff_calc(c,dy,dx,index,b_i,c_i,d_i);
522 return 2.0*c_i+6.0*d_i*delx;
526 virtual double integ(
double a,
double b)
const {
528 size_t i, index_a, index_b;
531 if (((*this->
px)[0]<(*this->
px)[this->
sz-1] && a>b) ||
532 ((*this->
px)[0]>(*this->
px)[this->
sz-1] && a<b)) {
544 for(i=index_a; i<=index_b; i++) {
546 double x_lo=(*this->
px)[i];
547 double x_hi=(*this->
px)[i+1];
548 double y_lo=(*this->
py)[i];
549 double y_hi=(*this->
py)[i+1];
554 double b_i, c_i, d_i;
555 coeff_calc(c,dy,dx,i,b_i,c_i,d_i);
556 if (i == index_a || i == index_b) {
557 double x1=(i == index_a) ? a : x_lo;
558 double x2=(i == index_b) ? b : x_hi;
559 result += this->
integ_eval(y_lo,b_i,c_i,d_i,x_lo,x1,x2);
561 result += dx*(y_lo+dx*(0.5*b_i+
562 dx*(c_i/3.0+0.25*d_i*dx)));
565 std::string str=((std::string)
"Interval of length zero ")+
568 " in interp_cspline::integ().";
574 if (flip) result*=-1.0;
580 virtual const char *
type()
const {
return "interp_cspline"; }
582 #ifndef DOXYGEN_INTERNAL 588 (
const interp_cspline<vec_t,vec2_t>&);
602 #ifdef O2SCL_NEVER_DEFINED 614 typedef boost::numeric::ublas::vector_slice<ubvector> ubvector_slice;
615 typedef boost::numeric::ublas::vector_range<ubvector> ubvector_range;
616 typedef boost::numeric::ublas::slice slice;
617 typedef boost::numeric::ublas::range range;
627 virtual const char *
type()
const {
return "interp_cspline_peri"; }
631 virtual void set(
size_t size,
const vec_t &xa,
const vec2_t &ya) {
635 " than "+
szttos(this->min_size)+
" in interp_cspline"+
639 if (size!=this->
sz) {
640 this->c.resize(size);
641 this->g.resize(size);
642 this->diag.resize(size);
643 this->offdiag.resize(size);
656 size_t num_points=size;
658 size_t max_index=num_points-1;
660 size_t sys_size=max_index;
666 double h0=xa[1]-xa[0];
667 double h1=xa[2]-xa[1];
668 double h2=xa[3]-xa[2];
669 double A=2.0*(h0+h1);
674 gx[0]=3.0*((ya[2]-ya[1])/h1-(ya[1]-ya[0])/h0);
675 gx[1]=3.0*((ya[1]-ya[2])/h2-(ya[2]-ya[1])/h1);
677 det=3.0*(h0+h1)*(h0+h1);
678 this->c[1]=( A*gx[0]-B*gx[1])/det;
679 this->c[2]=(-B*gx[0]+A*gx[1])/det;
680 this->c[0]=this->c[2];
686 for (i=0; i < sys_size-1; i++) {
687 double h_i=xa[i+1]-xa[i];
688 double h_ip1=xa[i+2]-xa[i+1];
689 double ydiff_i=ya[i+1]-ya[i];
690 double ydiff_ip1=ya[i+2]-ya[i+1];
691 double g_i=(h_i != 0.0) ? 1.0/h_i : 0.0;
692 double g_ip1=(h_ip1 != 0.0) ? 1.0/h_ip1 : 0.0;
693 this->offdiag[i]=h_ip1;
694 this->diag[i]=2.0*(h_ip1+h_i);
695 this->g[i]=3.0*(ydiff_ip1*g_ip1-ydiff_i*g_i);
700 double h_i=xa[i+1]-xa[i];
701 double h_ip1=xa[1]-xa[0];
702 double ydiff_i=ya[i+1]-ya[i];
703 double ydiff_ip1=ya[1]-ya[0];
704 double g_i=(h_i != 0.0) ? 1.0/h_i : 0.0;
705 double g_ip1=(h_ip1 != 0.0) ? 1.0/h_ip1 : 0.0;
706 this->offdiag[i]=h_ip1;
707 this->diag[i]=2.0*(h_ip1+h_i);
708 this->g[i]=3.0*(ydiff_ip1*g_ip1-ydiff_i*g_i);
711 ubvector_range cp1(this->c,range(1,this->c.size()));
714 (this->diag,this->offdiag,this->g,cp1,sys_size,p5m);
715 this->c[0]=this->c[max_index];
722 #ifndef DOXYGEN_INTERNAL 729 (
const interp_cspline_peri<vec_t,vec2_t>&);
751 typedef boost::numeric::ublas::vector_slice<ubvector> ubvector_slice;
752 typedef boost::numeric::ublas::vector_range<ubvector> ubvector_range;
753 typedef boost::numeric::ublas::slice slice;
754 typedef boost::numeric::ublas::range range;
756 #ifndef DOXYGEN_INTERNAL 772 for(
size_t i=0;i<this->
sz-1;i++) {
774 double NE=fabs(umx[3+i]-umx[2+i])+fabs(umx[1+i]-umx[i]);
781 double h_i=(*this->
px)[i+1]-(*this->
px)[i];
782 double NE_next=fabs(umx[4+i]-umx[3+i])+
783 fabs(umx[2+i]-umx[1+i]);
784 double alpha_i=fabs(umx[1+i]-umx[i])/NE;
787 if (NE_next == 0.0) {
790 alpha_ip1=fabs(umx[2+i]-umx[1+i])/NE_next;
791 tL_ip1=(1.0-alpha_ip1)*umx[2+i]+alpha_ip1*umx[3+i];
793 b[i]=(1.0-alpha_i)*umx[1+i]+alpha_i*umx[2+i];
794 c[i]=(3.0*umx[2+i]-2.0*b[i]-tL_ip1)/h_i;
795 d[i]=(b[i]+tL_ip1-2.0*umx[2+i])/(h_i*h_i);
816 virtual void set(
size_t size,
const vec_t &xa,
const vec2_t &ya) {
820 " than "+
szttos(this->min_size)+
" in interp_akima::"+
824 if (size!=this->
sz) {
839 ubvector_range m(um,range(2,um.size()));
841 for (i=0;i<=size-2;i++) {
842 m[i]=(ya[i+1]-ya[i])/(xa[i+1]-xa[i]);
845 um[0]=3.0*m[0]-2.0*m[1];
847 m[this->
sz-1]=2.0*m[size-2]-m[size-3];
848 m[size]=3.0*m[size-2]-2.0*m[size-3];
850 akima_calc(xa,size,um);
856 virtual double eval(
double x0)
const {
858 size_t index=this->
svx.
find(x0);
860 double x_lo=(*this->
px)[index];
866 return (*this->
py)[index]+delx*(bb+delx*(cc+dd*delx));
870 virtual double deriv(
double x0)
const {
872 size_t index=this->
svx.
find(x0);
874 double x_lo=(*this->
px)[index];
880 return bb+delx*(2.0*cc+3.0*dd*delx);
888 size_t index=this->
svx.
find(x0);
890 double x_lo=(*this->
px)[index];
895 return 2.0*cc+6.0*dd*delx;
899 virtual double integ(
double aa,
double bb)
const {
901 size_t i, index_a, index_b;
904 if (((*this->
px)[0]<(*this->
px)[this->
sz-1] && aa>bb) ||
905 ((*this->
px)[0]>(*this->
px)[this->
sz-1] && aa<bb)) {
917 for(i=index_a; i<=index_b; i++) {
919 double x_lo=(*this->
px)[i];
920 double x_hi=(*this->
px)[i+1];
921 double y_lo=(*this->
py)[i];
926 if (i==index_a || i==index_b) {
927 double x1=(i==index_a) ? aa : x_lo;
928 double x2=(i==index_b) ? bb : x_hi;
929 result += this->
integ_eval(y_lo,b[i],c[i],d[i],x_lo,x1,x2);
931 result+=dx*(y_lo+dx*(0.5*b[i]+dx*(c[i]/3.0+0.25*d[i]*dx)));
935 double y_hi=(*this->
py)[i+1];
936 std::string str=((std::string)
"Interval of length zero ")+
939 " in interp_akima::integ().";
944 if (flip) result*=-1.0;
950 virtual const char *
type()
const {
return "interp_akima"; }
952 #ifndef DOXYGEN_INTERNAL 974 typedef boost::numeric::ublas::vector_slice<ubvector> ubvector_slice;
975 typedef boost::numeric::ublas::vector_range<ubvector> ubvector_range;
976 typedef boost::numeric::ublas::slice slice;
977 typedef boost::numeric::ublas::range range;
988 virtual const char *
type()
const {
return "interp_akima_peri"; }
991 virtual void set(
size_t size,
const vec_t &xa,
const vec2_t &ya) {
995 " than "+
szttos(this->min_size)+
" in interp_akima"+
999 if (size!=this->
sz) {
1000 this->b.resize(size);
1001 this->c.resize(size);
1002 this->d.resize(size);
1003 this->um.resize(size+4);
1014 ubvector_range m(this->um,range(2,this->um.size()));
1017 for (
size_t i=0;i<=size-2;i++) {
1018 m[i]=(ya[i+1]-ya[i])/(xa[i+1]-xa[i]);
1021 this->um[0]=m[this->
sz-3];
1022 this->um[1]=m[this->
sz-2];
1026 this->akima_calc(xa,size,this->um);
1031 #ifndef DOXYGEN_INTERNAL 1037 (
const interp_akima_peri<vec_t,vec2_t>&);
1051 #ifdef O2SCL_NEVER_DEFINED 1058 typedef boost::numeric::ublas::vector_slice<ubvector> ubvector_slice;
1059 typedef boost::numeric::ublas::vector_range<ubvector> ubvector_range;
1060 typedef boost::numeric::ublas::slice slice;
1061 typedef boost::numeric::ublas::range range;
1063 #ifndef DOXYGEN_INTERNAL 1079 if ((x < 0 && y > 0) || (x > 0 && y < 0)) {
1099 virtual void set(
size_t size,
const vec_t &xa,
const vec2_t &ya) {
1103 " than "+
szttos(this->min_size)+
" in interp_steffen::"+
1107 if (size!=this->
sz) {
1112 y_prime.resize(size);
1126 double h0=(xa[1]-xa[0]);
1127 double s0=(ya[1]-ya[0]) / h0;
1133 for (
size_t i=1; i < (size-1); i++) {
1138 double hi=(xa[i+1]-xa[i]);
1139 double him1=(xa[i]-xa[i-1]);
1142 double si=(ya[i+1]-ya[i]) / hi;
1143 double sim1=(ya[i]-ya[i-1]) / him1;
1146 pi=(sim1*hi + si*him1) / (him1 + hi);
1149 y_prime[i]=(copysign(1.0,sim1)+copysign(1.0,si))*
1150 std::min(fabs(sim1),std::min(fabs(si),0.5*fabs(pi)));
1161 y_prime[size-1]=(ya[size-1]-ya[size-2])/
1162 (xa[size-1]-xa[size-2]);
1165 for (
size_t i=0; i < (size-1); i++) {
1166 double hi=(xa[i+1]-xa[i]);
1167 double si=(ya[i+1]-ya[i]) / hi;
1170 a[i]=(y_prime[i] + y_prime[i+1]-2*si) / hi / hi;
1171 b[i]=(3*si-2*y_prime[i]-y_prime[i+1]) / hi;
1180 virtual double eval(
double x0)
const {
1182 size_t index=this->
svx.
find(x0);
1183 double x_lo=(*this->
px)[index];
1184 double delx=x0-x_lo;
1187 double y = d[index]+delx*(c[index]+delx*(b[index]+delx*a[index]));
1195 size_t index=this->
svx.
find(x0);
1196 double x_lo=(*this->
px)[index];
1197 double delx=x0-x_lo;
1199 return c[index]+delx*(2.0*b[index]+delx*3.0*a[index]);
1207 size_t index=this->
svx.
find(x0);
1208 double x_lo=(*this->
px)[index];
1209 double delx=x0-x_lo;
1211 return 2.0*b[index]+delx*6.0*a[index];
1215 virtual double integ(
double al,
double bl)
const {
1217 size_t i, index_a, index_b;
1220 if (((*this->
px)[0]<(*this->
px)[this->
sz-1] && al>bl) ||
1221 ((*this->
px)[0]>(*this->
px)[this->
sz-1] && al<bl)) {
1233 for(i=index_a; i<=index_b; i++) {
1235 double x_lo=(*this->
px)[i];
1236 double x_hi=(*this->
px)[i+1];
1237 double y_lo=(*this->
py)[i];
1238 double y_hi=(*this->
py)[i+1];
1239 double dx=x_hi-x_lo;
1243 double x1=(i == index_a) ? al-x_lo : 0.0;
1244 double x2=(i == index_b) ? bl-x_lo : x_hi-x_lo;
1245 result += (1.0/4.0)*a[i]*(x2*x2*x2*x2-x1*x1*x1*
x1)+
1246 (1.0/3.0)*b[i]*(x2*x2*x2-x1*x1*
x1)+
1247 (1.0/2.0)*c[i]*(x2*x2-x1*
x1)+d[i]*(x2-x1);
1250 std::string str=((std::string)
"Interval of length zero ")+
1253 " in interp_steffen::integ().";
1259 if (flip) result*=-1.0;
1265 virtual const char *
type()
const {
return "interp_steffen"; }
1267 #ifndef DOXYGEN_INTERNAL 1273 (
const interp_steffen<vec_t,vec2_t>&);
1306 #ifdef O2SCL_NEVER_DEFINED 1335 virtual void set(
size_t size,
const vec_t &x,
const vec2_t &y) {
1340 " than "+
szttos(this->min_size)+
" in interp_monotonic::"+
1348 if (this->
sz!=size) {
1350 Delta.resize(size-1);
1351 alpha.resize(size-1);
1352 beta.resize(size-1);
1363 for(
size_t i=0;i<size-1;i++) {
1364 Delta[i]=(y[i+1]-y[i])/(x[i+1]-x[i]);
1366 m[i]=(Delta[i]+Delta[i-1])/2.0;
1370 m[size-1]=Delta[size-2];
1373 for(
size_t i=0;i<size-1;i++) {
1381 for(
size_t i=0;i<size-1;i++) {
1382 alpha[i]=m[i]/Delta[i];
1383 beta[i]=m[i+1]/Delta[i];
1387 for(
size_t i=0;i<size-1;i++) {
1388 double norm2=alpha[i]*alpha[i]+beta[i]*beta[i];
1390 double tau=3.0/sqrt(norm2);
1391 m[i]=tau*alpha[i]*Delta[i];
1392 m[i+1]=tau*beta[i]*Delta[i];
1400 virtual double eval(
double x0)
const {
1402 size_t index=this->
svx.
find(x0);
1404 double x_lo=(*this->
px)[index];
1405 double x_hi=(*this->
px)[index+1];
1406 double y_lo=(*this->
py)[index];
1407 double y_hi=(*this->
py)[index+1];
1409 double t=(x0-x_lo)/h;
1410 double t2=t*t, t3=t2*t;
1412 double h00=2.0*t3-3.0*t2+1.0;
1413 double h10=t3-2.0*t2+t;
1414 double h01=-2.0*t3+3.0*t2;
1416 double interp=y_lo*h00+h*m[index]*h10+y_hi*h01+h*m[index+1]*h11;
1424 size_t index=this->
svx.
find(x0);
1426 double x_lo=(*this->
px)[index];
1427 double x_hi=(*this->
px)[index+1];
1428 double y_lo=(*this->
py)[index];
1429 double y_hi=(*this->
py)[index+1];
1431 double t=(x0-x_lo)/h;
1434 double dh00=6.0*t2-6.0*t;
1435 double dh10=3.0*t2-4.0*t+1.0;
1436 double dh01=-6.0*t2+6.0*t;
1437 double dh11=3.0*t2-2.0*t;
1438 double deriv=(y_lo*dh00+h*m[index]*dh10+y_hi*dh01+
1439 h*m[index+1]*dh11)/h;
1449 size_t index=this->
svx.
find(x0);
1451 double x_lo=(*this->
px)[index];
1452 double x_hi=(*this->
px)[index+1];
1453 double y_lo=(*this->
py)[index];
1454 double y_hi=(*this->
py)[index+1];
1456 double t=(x0-x_lo)/h;
1458 double ddh00=12.0*t-6.0;
1459 double ddh10=6.0*t-4.0;
1460 double ddh01=-12.0*t+6.0;
1461 double ddh11=6.0*t-2.0;
1462 double deriv2=(y_lo*ddh00+h*m[index]*ddh10+y_hi*ddh01+
1463 h*m[index+1]*ddh11)/h/h;
1469 virtual double integ(
double a,
double b)
const {
1471 size_t i, index_a, index_b;
1474 if (((*this->
px)[0]<(*this->
px)[this->
sz-1] && a>b) ||
1475 ((*this->
px)[0]>(*this->
px)[this->
sz-1] && a<b)) {
1487 for(i=index_a; i<=index_b; i++) {
1489 double x_hi=(*this->
px)[i+1];
1490 double x_lo=(*this->
px)[i];
1491 double y_lo=(*this->
py)[i];
1492 double y_hi=(*this->
py)[i+1];
1504 double t=(x_hi-x_lo)/h;
1505 double t2=t*t, t3=t2*t, t4=t3*t;
1507 double ih00=t4/2.0-t3+t;
1508 double ih10=t4/4.0-2.0*t3/3.0+t2/2.0;
1509 double ih01=-t4/2.0+t3;
1510 double ih11=t4/4.0-t3/3.0;
1511 double intres=h*(y_lo*ih00+h*m[i]*ih10+y_hi*ih01+
1516 std::string str=((std::string)
"Interval of length zero ")+
1519 " in interp_monotonic::integ().";
1525 if (flip) result*=-1.0;
1531 virtual const char *
type()
const {
return "interp_monotonic"; }
1533 #ifndef DOXYGEN_INTERNAL 1539 (
const interp_monotonic<vec_t,vec2_t>&);
1557 template<
class vec_t=boost::numeric::ublas::vector<
double>,
1560 #ifndef DOXYGEN_INTERNAL 1588 O2SCL_ERR((((std::string)
"Invalid interpolation type, ")+
1599 virtual double eval(
const double x0,
size_t n,
const vec_t &x,
1602 return itp->
eval(x0);
1606 virtual double deriv(
const double x0,
size_t n,
const vec_t &x,
1609 return itp->
deriv(x0);
1615 virtual double deriv2(
const double x0,
size_t n,
const vec_t &x,
1622 virtual double integ(
const double x1,
const double x2,
size_t n,
1623 const vec_t &x,
const vec2_t &y) {
1625 return itp->
integ(x1,x2);
1646 O2SCL_ERR((((std::string)
"Invalid interpolation type, ")+
1653 #ifndef DOXYGEN_INTERNAL 1684 template<
class vec_t=boost::numeric::ublas::vector<
double>,
1688 #ifndef DOXYGEN_INTERNAL 1710 const vec2_t &y,
size_t interp_type=
itp_cspline) {
1713 O2SCL_ERR((((std::string)
"Vector endpoints equal (value=")+
1733 O2SCL_ERR((((std::string)
"Invalid interpolation type, ")+
1735 "interp_vec::interp_vec().").c_str(),
exc_einval);
1750 void set(
size_t n,
const vec_t &x,
const vec2_t &y) {
1757 void set(
size_t n,
const vec_t &x,
1758 const vec2_t &y,
size_t interp_type) {
1761 O2SCL_ERR((((std::string)
"Vector endpoints equal (value=")+
1782 O2SCL_ERR((((std::string)
"Invalid interpolation type, ")+
1802 virtual double eval(
const double x0)
const {
1804 O2SCL_ERR(
"No vector set in interp_vec::eval().",
1807 return itp->
eval(x0);
1813 O2SCL_ERR(
"No vector set in interp_vec::operator().",
1816 return itp->
eval(x0);
1820 virtual double deriv(
const double x0)
const {
1822 O2SCL_ERR(
"No vector set in interp_vec::deriv().",
1825 return itp->
deriv(x0);
1831 virtual double deriv2(
const double x0)
const {
1833 O2SCL_ERR(
"No vector set in interp_vec::deriv2().",
1840 virtual double integ(
const double x1,
const double x2)
const {
1842 O2SCL_ERR(
"No vector set in interp_vec::integ().",
1845 return itp->
integ(x1,x2);
1850 return "interp_vec";
1853 #ifndef DOXYGEN_INTERNAL 1859 (
const interp_vec<vec_t,vec2_t> &it);
1870 public interp<double[n]> {
1876 :
interp<double[n]>(interp_type) {}
1896 size_t interp_type) :
1920 (
double level,
size_t n, vec_t &x, vec2_t &y) {
1923 O2SCL_ERR2(
"Need at least two data points in ",
1930 if (y[0]==level) count++;
1933 for(
size_t i=0;i<n-1;i++) {
1935 if ((y[i]<level && y[i+1]>=level) ||
1936 (y[i]>level && y[i+1]<=level)) {
1965 (
double level,
size_t n, vec_t &x, vec2_t &y, std::vector<double> &locs) {
1968 O2SCL_ERR2(
"Need at least two data points in ",
1977 locs.push_back(x[0]);
1981 for(
size_t i=0;i<n-1;i++) {
1983 if ((y[i]<level && y[i+1]>level) ||
1984 (y[i]>level && y[i+1]<level)) {
1987 double x0=x[i]+(x[i+1]-x[i])*(level-y[i])/(y[i+1]-y[i]);
1989 }
else if (y[i+1]==level) {
1990 locs.push_back(x[i+1]);
2010 template<
class vec_t,
class vec2_t>
2017 double total=si.
integ(x[0],x[n-1],n,x,y);
2058 (
double sum,
size_t n, vec_t &x, vec2_t &y,
double &lev,
2062 O2SCL_ERR2(
"Need at least two data points in ",
2067 O2SCL_ERR2(
"The first and last y-values must be equal in ",
2075 vector_sort<ubvector,double>(ysort.size(),ysort);
2081 std::vector<double> ylist;
2082 for(
size_t i=0;i<ysort.size()-1;i++) {
2083 if (ysort[i]!=ysort[i+1]) {
2084 ylist.push_back((ysort[i+1]+3.0*ysort[i])/4.0);
2085 ylist.push_back((ysort[i+1]*3.0+ysort[i])/4.0);
2095 std::vector<double> xi, yi;
2099 for(
size_t k=0;k<ylist.size();k++) {
2100 double lev_tmp=ylist[k];
2101 std::vector<double> locs;
2103 if ((locs.size()%2)!=0) {
2106 double sum_temp=0.0;
2107 for(
size_t i=0;i<locs.size()/2;i++) {
2108 double x0=locs[2*i];
2109 double x1=locs[2*i+1];
2110 sum_temp+=itp.
integ(x0,x1,n,x,y);
2112 xi.push_back(sum_temp);
2113 yi.push_back(lev_tmp);
2122 std::cout <<
"i, xi, yi: " << std::endl;
2123 for(
size_t i=0;i<xi.size();i++) {
2124 std::cout << i <<
" " << xi[i] <<
" " << yi[i] << std::endl;
2128 lev=itp2.
eval(sum,xi.size(),xi,yi);
2136 (
size_t n, vec_t &x, vec2_t &y,
double frac, std::vector<double> &locs,
2139 if (frac<0.0 || frac>1.0) {
2140 O2SCL_ERR2(
"Fraction must be between 0 and 1 (exclusive) in ",
2147 std::cout <<
"Total integral: " << total << std::endl;
2150 double partial=frac*total;
2152 std::cout <<
"Partial integral: " << partial << std::endl;
2158 std::cout <<
"Level from vector_invert: " << lev << std::endl;
2163 std::cout <<
"Locations from vector_find_level: ";
2164 for(
size_t i=0;i<locs.size();i++) {
2165 std::cout << locs[i];
2166 if (i!=locs.size()-1) {
2170 std::cout << std::endl;
2178 (
size_t n, vec_t &x, vec2_t &y,
double frac,
double &low,
double &high) {
2180 std::vector<double> locs;
2182 if (locs.size()==0) {
2183 O2SCL_ERR(
"Zero level crossings in vector_bound_sigma().",
2193 #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.
virtual const char * type() const
Return the type, "interp_steffen".
virtual const char * type() const
Return the type, "interp_cspline_peri".
Interpolation class for pre-specified vector.
o2scl_linalg::ubvector_5_mem p5m
Memory for the tridiagonalization.
virtual double eval(double x0) const
Give the value of the function .
virtual void set(size_t size, const vec_t &x, const vec2_t &y)=0
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 .
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 const char * type() const
Return the type, "interp_linear".
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...
virtual double operator()(double x0) const
Give the value of the function .
virtual const char * type() const =0
Return the type.
The main O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$scl names...
interp(size_t interp_type=itp_cspline)
Create with base interpolation object it.
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 deriv(double x0) const
Give the value of the derivative .
interp_base< vec_t, vec2_t > * itp
Pointer to base interpolation object.
virtual double integ(double a, double b) const =0
Give the value of the integral .
virtual double deriv2(const double x0) const
Give the value of the second derivative .
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.
Akima spline interpolation with periodic boundary conditions (GSL)
virtual double integ(double al, double bl) const
Give the value of the integral .
void clear()
Manually clear the pointer to the user-specified vector.
virtual const char * type() const
Return the type, "interp_cspline".
virtual const char * type() const
Return the type, "interp_akima".
virtual const char * type() const
Return the type, "interp_monotonic".
double copysign(const double x, const double y)
Flip the sign of x if x and y have different signs.
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 eval(double x0) const
Give the value of the function .
virtual double deriv(double x0) const
Give the value of the 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_akima_peri".
virtual double deriv(double x0) const
Give the value of the derivative .
virtual double deriv(const double x0) const
Give the value of the derivative .
Akima spline for periodic boundary conditions.
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.
virtual double integ(double a, double b) const
Give the value of the integral .
virtual double deriv2(double x0) const
Give the value of the second derivative .
interp_vec()
Blank interpolator.
virtual double deriv(double x0) const =0
Give the value of the derivative .
virtual double integ(double aa, double bb) const
Give the value of the integral .
virtual double deriv2(double x0) const
Give the value of the second derivative .
Steffen's monotonic method.
virtual double deriv2(double x0) const
Give the value of the second derivative .
virtual double integ(double a, double b) const
Give the value of the integral .
Steffen's monotonicity-preserving interpolation.
interp_akima()
Create a base interpolation object with or without periodic boundary conditions.
Cubic spline interpolation with periodic boundary conditions (GSL)
virtual double operator()(double x0) const
Give the value of the function .
virtual double deriv(double x0) const
Give the value of the derivative .
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 integ(double a, double b) const
Give the value of the integral .
Cubic spline for natural boundary conditions.
virtual double deriv(double x0) const
Give the value of the derivative .
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.
void vector_copy(const vec_t &src, vec2_t &dest)
Simple vector copy.
ubvector beta
Staggered ratio.
Allocation object for 5 arrays of equal size.
size_t find(const double x0) const
Search an increasing or decreasing vector for the interval containing x0
virtual const char * type() const
Return the type, "interp_vec".
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 double integ(const double x1, const double x2) const
Give the value of the integral .
virtual double eval(double x0) const
Give the value of the function .
const vec2_t * py
Dependent vector.
o2scl_linalg::ubvector_4_mem p4m
Memory for the tridiagonalization.
#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 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.
interp_steffen()
Create a base interpolation object.
virtual double eval(double x0) const =0
Give the value of the function .
virtual double deriv2(double x0) const
Give the value of the second derivative .
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.
Monotonicity-preserving interpolation (unfinished)
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)
interp_array(size_t interp_type)
Create with base interpolation objects it and rit.
virtual double deriv2(double x0) const =0
Give the value of the second derivative .
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.
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]
virtual double eval(const double x0) const
Give the value of the function .
static const double x1[5]
Linear interpolation (GSL)
std::string szttos(size_t x)
Convert a size_t to a string.
virtual double deriv2(double x0) const
Give the value of the second derivative (always zero)
void vector_find_level(double level, size_t n, vec_t &x, vec2_t &y, std::vector< double > &locs)
Perform inverse linear interpolation.
virtual double eval(double x0) const
Give the value of the function .
A specialization of o2scl::interp_vec for C-style arrays.
interp_base< vec_t, vec2_t > * itp
Base interpolation object.
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 .