Example #1
0
void dftint(float (*func)(float), float a, float b, float w, float *cosint,
	float *sinint)
{
	void dftcor(float w, float delta, float a, float b, float endpts[],
		float *corre, float *corim, float *corfac);
	void polint(float xa[], float ya[], int n, float x, float *y, float *dy);
	void realft(float data[], unsigned long n, int isign);
	static int init=0;
	int j,nn;
	static float aold = -1.e30,bold = -1.e30,delta,(*funcold)(float);
	static float data[NDFT+1],endpts[9];
	float c,cdft,cerr,corfac,corim,corre,en,s;
	float sdft,serr,*cpol,*spol,*xpol;

	cpol=vector(1,MPOL);
	spol=vector(1,MPOL);
	xpol=vector(1,MPOL);
	if (init != 1 || a != aold || b != bold || func != funcold) {
		init=1;
		aold=a;
		bold=b;
		funcold=func;
		delta=(b-a)/M;
		for (j=1;j<=M+1;j++)
			data[j]=(*func)(a+(j-1)*delta);
		for (j=M+2;j<=NDFT;j++)
			data[j]=0.0;
		for (j=1;j<=4;j++) {
			endpts[j]=data[j];
			endpts[j+4]=data[M-3+j];
		}
		realft(data,NDFT,1);
		data[2]=0.0;
	}
	en=w*delta*NDFT/TWOPI+1.0;
	nn=IMIN(IMAX((int)(en-0.5*MPOL+1.0),1),NDFT/2-MPOL+1);
	for (j=1;j<=MPOL;j++,nn++) {
		cpol[j]=data[2*nn-1];
		spol[j]=data[2*nn];
		xpol[j]=nn;
	}
	polint(xpol,cpol,MPOL,en,&cdft,&cerr);
	polint(xpol,spol,MPOL,en,&sdft,&serr);
	dftcor(w,delta,a,b,endpts,&corre,&corim,&corfac);
	cdft *= corfac;
	sdft *= corfac;
	cdft += corre;
	sdft += corim;
	c=delta*cos(w*a);
	s=delta*sin(w*a);
	*cosint=c*cdft-s*sdft;
	*sinint=s*cdft+c*sdft;
	free_vector(cpol,1,MPOL);
	free_vector(spol,1,MPOL);
	free_vector(xpol,1,MPOL);
}
Example #2
0
void polin2(float x1a[], float x2a[], float **ya, int m, int n, float x1,
	float x2, float *y, float *dy)
{
	void polint(float xa[], float ya[], int n, float x, float *y, float *dy);
	int j;
	float *ymtmp;

	ymtmp=vector(1,m);
	for (j=1;j<=m;j++) {
		polint(x2a,ya[j],n,x2,&ymtmp[j],dy);
	}
	polint(x1a,ymtmp,m,x1,y,dy);
	free_vector(ymtmp,1,m);
}
Example #3
0
void polcof(float xa[], float ya[], int n, float cof[])
{
	void polint(float xa[], float ya[], int n, float x, float *y, float *dy);
	int k,j,i;
	float xmin,dy,*x,*y;

	x=vector(0,n);
	y=vector(0,n);
	for (j=0;j<=n;j++) {
		x[j]=xa[j];
		y[j]=ya[j];
	}
	for (j=0;j<=n;j++) {
		polint(x-1,y-1,n+1-j,0.0,&cof[j],&dy);
		xmin=1.0e38;
		k = -1;
		for (i=0;i<=n-j;i++) {
			if (fabs(x[i]) < xmin) {
				xmin=fabs(x[i]);
				k=i;
			}
			if (x[i]) y[i]=(y[i]-cof[j])/x[i];
		}
		for (i=k+1;i<=n-j;i++) {
			y[i-1]=y[i];
			x[i-1]=x[i];
		}
	}
	free_vector(y,0,n);
	free_vector(x,0,n);
}
Example #4
0
File: CMesh.cpp Project: MADAI/RHIC
double CMesh::qromb(meshMemFunc mf, double a, double b) {
	const int JMAX=20, JMAXP=JMAX+1, K=5;
	const double EPS=1E-10;
	
	double ss, dss;
	std::vector<double> s, h, s_t, h_t;
	int i,j;
	
	h.push_back(1.0);
	for (j=1;j<=JMAX;j++){
		s.push_back(trapzd(mf,a,b,j));
		
		if (j>=K){
			for (i=0;i<K;i++){
				h_t.push_back(h[j-K+i]);
				s_t.push_back(s[j-K+i]);
			}
			polint(h_t,s_t,0.0,ss,dss);
			if (fabs(dss) <= EPS*fabs(ss)) {
				return ss;
			}
			
			h_t.clear();
			s_t.clear();
		}
		h.push_back(0.25*h[j-1]);
	} 
	
	fprintf(stderr,"Too many steps in routine qromb\n");
	exit(1);
	return 0.0;
}
Example #5
0
double qromo( double a, double b, double eps, 
	    double (*kgvfnc)(double,int,double,double),
	    double (*choose)(double (*)(double, int, double, double), 
			     double, double, int, int, double, double),
	    int nk, double ppot, double sigma2)
{
    int j,Jmax = 14, Jmaxp = Jmax +1, K=5, Km=K-1;
    double ss,dss;
    double *h = ALLOC(Jmaxp, double);
    double *s = ALLOC(Jmaxp, double);

    h[0] = 1;
    for( j=0; j<Jmax; j++ ){
	s[j]=(*choose)(kgvfnc,a,b,j, nk, ppot, sigma2);
	if (j >= K) {
	    polint( &h[j-K], &s[j-K], K, 0., &ss, &dss);
	    if (fabs(dss) <= eps*fabs(ss)){
		free(h); free(s);
		return ss;
	    }
	}
	h[j+1]=h[j]/9.0;
    }
    printf("Too many steps in routing qromo\n");
    exit(EXIT_FAILURE);
}
Example #6
0
double qromb(double (*funcd)(), double es, double Wind, double AirDens, double ZO, 
	     double EactAir, double F, double hsalt, double phi_r, double ushear, double Zrh, 
	     double a, double b)
     // Returns the integral of the function func from a to b.  Integration is performed 
     // by Romberg's method:  Numerical Recipes in C Section 4.3
{
  void polint(double xa[], double ya[], int n, double x, double *y, double *dy);
  double trapzd(double (*funcd)(), double es, double Wind, double AirDens, 
		double ZO, double EactAir, double F, double hsalt, double phi_r, 
		double ushear, double Zrh, double a, double b, int n);

  double ss, dss;
  double s[MAX_ITER+1], h[MAX_ITER+2];
  int j;

  h[1] = 1.0;
  for(j=1; j<=MAX_ITER; j++) {
    s[j]=trapzd(funcd,es, Wind, AirDens, ZO, EactAir, F, hsalt, phi_r, 
		ushear, Zrh, a,b,j);
    if(j >= K) {
      polint(&h[j-K],&s[j-K],K,0.0,&ss,&dss);
      if (fabs(dss) <= MACHEPS*fabs(ss)) return ss;
    }
    h[j+1]=0.25*h[j];
  }
  nrerror("Too many steps in routine qromb");
  return 0.0;
}
Example #7
0
/*==========================================================================
 * calc_a: calculate a(t) via interpolation
 *==========================================================================*/
double calc_a(double t)
{
   int    IORD=2;
   int    j,jl,ju,jm;
   double a,da;
   double *t_array, *a_array;
   
   t_array = &(simu.timeline.t[0]);
   a_array = &(simu.timeline.a[0]);
   
   /* find correct index within timeline */
   jl = 0;
   ju = MAXTIME+1;
   while(ju-jl > 1)
     {
      jm = (ju+jl)/2;
      if(t > t_array[jm]) 
         jl=jm;
      else
         ju=jm;
     }
   j=jl;
   
   if(j >= MAXTIME-IORD)
      j = MAXTIME-IORD-1;
   
   /* interpolate using IORD points around t_array[j] and a_array[j] */
   polint(&t_array[j],&a_array[j],IORD,t,&a,&da);
   
   return(a);
}
//! Numerical recipe Chapiter 3
//! Two-dimensional polynomial interpolation
void polin2(std::vector<double>& x1a,
			std::vector<double>& x2a,
			std::vector<std::vector<double>>& ya,  // les points fix connues
			const double x1,const double x2, double &y, double &dy)   // les points a interpoler
{
	int j,k;

	int m= (int)x1a.size();
	int n= (int)x2a.size();
	std::vector<double> ymtmp(m);
	std::vector<double>  ya_t(n);
	for (j=0;j<m;j++) {
		for (k=0;k<n;k++) 
			ya_t[k]=ya[j][k];
		polint(x2a,ya_t,x2,ymtmp[j],dy);
	}
	polint(x1a,ymtmp,x1,y,dy);
}
Example #9
0
static VALUE gp_polinterpolate(VALUE self, VALUE sxa, VALUE sya, VALUE sx) {
  rb_io_puts(1, &sxa, rb_stdout); 
  rb_io_puts(1, &sya, rb_stdout); 
  rb_io_puts(1, &sx, rb_stdout); 
  GEN xa = geval(strtoGENstr(StringValueCStr(sxa)));
  GEN ya = geval(strtoGENstr(StringValueCStr(sya)));
  GEN x = geval(strtoGENstr(StringValueCStr(sx)));
  char* pol = GENtostr(polint(xa, ya, x, NULL));
  return rb_str_new2(pol);
}
Example #10
0
double
qromb(double (*func)(double), double a, double b, double eps, int imax)
{
    double ss = 0;
    double dss;
    int i;

    /* allocate enough storage */
    if (imax+1 > nmax) {
#ifdef DEBUG
	(void)fprintf(stdout, "qromb: malloc %d cells %d bytes\n",
		imax+1, (imax+1) * sizeof(double));
#endif
	if (h != NULL) {
	    free(h);
	}
	h = (double *)malloc((imax+1) * sizeof(double));
	if (s != NULL) {
	    free(s);
	}
	s = (double *)malloc((imax+1) * sizeof(double));

	nmax = imax+1;
    }

    h[0] = 1;

    for (i = 0; i < imax; i++) {
	s[i] = trapzd(func, a, b, i);
	if (i >= K-1) {
	    ss = polint(&h[i-(K-1)], &s[i-(K-1)], K, 0.0, &dss);
#ifdef DEBUG
	    (void)fprintf(stdout, "qromb: a %.15e b %.15e i %d ss %.15e dss %.15e eps %.15e\n",
			a, b, i, ss, dss, eps);
#endif
	    if (fabs(dss) < eps * fabs(ss)) {
		return(ss);
	    }
	}
	h[i+1] = 0.25 * h[i];
	s[i+1] = s[i];
    }

#ifdef DEBUG
    (void)fprintf(stdout, "qromb: a %.15e b %.15e i %d ss %.15e\n", a, b, i, ss);
#endif

    return(ss);
}
Example #11
0
/* ---------------------------------------------------------------------- */
LDBLE
qromb_midpnt (LDBLE x1, LDBLE x2)
/* ---------------------------------------------------------------------- */
{
  LDBLE ss, dss;
  LDBLE sv[MAX_QUAD + 2], h[MAX_QUAD + 2];
  int j;

  h[0] = 1.0;
  sv[0] = midpnt (x1, x2, 1);
  for (j = 1; j < MAX_QUAD; j++)
  {
    sv[j] = midpnt (x1, x2, j + 1);
    h[j] = h[j - 1] / 9.0;

    if (fabs (sv[j] - sv[j - 1]) <= G_TOL * fabs (sv[j]))
    {
      sv[j] *= surface_charge_ptr->grams * surface_charge_ptr->specific_area * alpha / F_C_MOL;	/* (ee0RT/2)**1/2, (L/mol)**1/2 C / m**2 */
      if ((x2 - 1) < 0.0)
	sv[j] *= -1.0;
      if (debug_diffuse_layer == TRUE)
      {
	output_msg (OUTPUT_MESSAGE, "Iterations in qromb_midpnt: %d\n", j);
      }
      return (sv[j]);
    }

    if (j >= K_POLY - 1)
    {
      polint (&h[j - K_POLY], &sv[j - K_POLY], K_POLY, 0.0, &ss, &dss);
      if (fabs (dss) <= G_TOL * fabs (ss) || fabs (dss) < G_TOL)
      {
	ss *= surface_charge_ptr->grams * surface_charge_ptr->specific_area * alpha / F_C_MOL;	/* (ee0RT/2)**1/2, (L/mol)**1/2 C / m**2 */
	if ((x2 - 1) < 0.0)
	  ss *= -1.0;
	if (debug_diffuse_layer == TRUE)
	{
	  output_msg (OUTPUT_MESSAGE, "Iterations in qromb_midpnt: %d\n", j);
	}
	return (ss);
      }
    }

  }
  sprintf (error_string,
	   "\nToo many iterations integrating diffuse layer.\n");
  error_msg (error_string, STOP);
  return (-999.9);
}
Example #12
0
/* a quick-and-dirty hack for the VDE model which requires H in a table */
double calc_Hubble_VDE(double a)
{
  FILE   *fhubble;
  double *a_array, *h_array;
  double  h, dh;
  int     n_array;
  char    dummyline[MAXSTRING];
  int     jl,ju,jm,j,IORD=2;
  
  fhubble = fopen("hubble_vde.dat","r");
  n_array = -1;
  a_array = calloc(1,sizeof(double));
  h_array = calloc(1,sizeof(double));
  while(fgets(dummyline,MAXSTRING,fhubble) != NULL)
   {
    n_array++;
    a_array = realloc(a_array, (n_array+1)*sizeof(double));
    h_array = realloc(h_array, (n_array+1)*sizeof(double));
    sscanf(dummyline,"%lf %lf", &(a_array[n_array]), &(h_array[n_array]));
    
    /* possible conversions of what has just been read in */
    a_array[n_array]  = 1./(1.+a_array[n_array]);
    h_array[n_array] *= H0;
   }
  
  /* interpolate using IORD points around a_array[j] and h_array[j] */
  jl = 0;
  ju = n_array+1;
  while(ju-jl > 1)
   {
    jm = (ju+jl)/2;
    if(a < a_array[jm]) 
      jl=jm;
    else
      ju=jm;
   }
  j=jl;
  if(j >= n_array-IORD)
    j = n_array-IORD-1;
  polint(&a_array[j],&h_array[j],IORD,a,&h,&dh);
  
  //fprintf(stderr,"%d %g %g\n",j,a,a_array[j],h_array[j]);

  fclose(fhubble);
  
  return(h);
}
Example #13
0
double get_delay(int in, double tau) {
  double x = tau / fabs(DELTA_T);
  double dd = fabs(DELTA_T);
  double y, ya[4], xa[4], dy;
  int n1 = (int)x;
  int n2 = n1 + 1;
  int nodes = NODE;
  int n0 = n1;
  int n3 = n2 + 1;
  int i0, i1, i2, i3;

  if (tau < 0.0 || tau > DELAY) {
    err_msg("Delay negative or too large");
    stop_integration();
    return (0.0);
  }
  xa[1] = n1 * dd;
  xa[0] = xa[1] - dd;
  xa[2] = xa[1] + dd;
  xa[3] = xa[2] + dd;
  i1 = (n1 + LatestDelay) % MaxDelay;
  i2 = (n2 + LatestDelay) % MaxDelay;
  i0 = (n0 + LatestDelay) % MaxDelay;
  i3 = (n3 + LatestDelay) % MaxDelay;
  if (i1 < 0)
    i1 += MaxDelay;
  if (i2 < 0)
    i2 += MaxDelay;
  if (i3 < 0)
    i3 += MaxDelay;
  if (i0 < 0)
    i0 += MaxDelay;

  ya[1] = DelayWork[in + (nodes)*i1];
  ya[2] = DelayWork[in + (nodes)*i2];
  ya[0] = DelayWork[in + (nodes)*i0];
  ya[3] = DelayWork[in + (nodes)*i3];
  polint(xa, ya, 4, tau, &y, &dy);

  return (y);
}
Example #14
0
float qromb(float (*func)(float), float a, float b)
{
	void polint(float xa[], float ya[], int n, float x, float *y, float *dy);
	float trapzd(float (*func)(float), float a, float b, int n);
	float ss,dss;
	float s[JMAXP+1],h[JMAXP+1];
	int j;

	h[1]=1.0;
	for (j=1;j<=JMAX;j++) {
		s[j]=trapzd(func,a,b,j);
		if (j >= K) {
			polint(&h[j-K],&s[j-K],K,0.0,&ss,&dss);
			if (fabs(dss) < EPS*fabs(ss)) return ss;
		}
		s[j+1]=s[j];
		h[j+1]=0.25*h[j];
	}
	error("Too many steps in routine qromb");
	return 0.0;
}
Example #15
0
/*==========================================================================
* calc_super_a: calculate a(super_t) via interpolation
*==========================================================================*/
double calc_super_a(double super_t)
{
   int    IORD=2;
   int    j,jl,ju,jm;
   double a,da;
   double *t_array, *a_array;
   
#ifdef NO_EXPANSION
   
   return (1.0);
   
#else /* NO_EXPANSION */
   
   t_array = &(simu.timeline.super_t[0]);
   a_array = &(simu.timeline.a[0]);
   
   /* find correct index within timeline */
   jl = 0;
   ju = MAXTIME+1;
   
   while(ju-jl > 1)
     {
      jm = (ju+jl)/2;
      if(super_t > t_array[jm]) 
         jl=jm;
      else
         ju=jm;
     }
   j=jl;
   
   if(j >= MAXTIME-IORD)
      j = MAXTIME-IORD-1;
   
   /* interpolate using IORD points around t_array[j] and a_array[j] */
   polint(&t_array[j],&a_array[j],IORD,super_t,&a,&da);
   
   return(a);
#endif
}
Example #16
0
/******************************************************************************
 * @brief    Integration is performed by Romberg's method:  Numerical Recipes
 *           in C Section 4.3
 *****************************************************************************/
double
qromb(double (*funcd)(),
      double   es,
      double   Wind,
      double   AirDens,
      double   ZO,
      double   EactAir,
      double   F,
      double   hsalt,
      double   phi_r,
      double   ushear,
      double   Zrh,
      double   a,
      double   b)
{
    extern parameters_struct param;

    double                   ss, dss;
    double                   s[param.BLOWING_MAX_ITER + 1];
    double                   h[param.BLOWING_MAX_ITER + 2];
    int                      j;

    h[1] = 1.0;
    for (j = 1; j <= param.BLOWING_MAX_ITER; j++) {
        s[j] = trapzd(funcd, es, Wind, AirDens, ZO, EactAir, F, hsalt, phi_r,
                      ushear, Zrh, a, b, j);
        if (j >= param.BLOWING_K) {
            polint(&h[j - param.BLOWING_K], &s[j - param.BLOWING_K],
                   param.BLOWING_K, 0.0, &ss, &dss);
            if (fabs(dss) <= DBL_EPSILON * fabs(ss)) {
                return ss;
            }
        }
        h[j + 1] = 0.25 * h[j];
    }
    log_err("Too many steps");
    return 0.; // To avoid warnings.
}
Example #17
0
double interpolate(double *x_array, double *y_array, int n_array, double x)
{
  /* interpolate using IORD points around x_array[j] and y_array[j] */
  int     jl,ju,jm,j,IORD=6;
  double  h, dh;
  
  jl = 0;
  ju = n_array+1;
  while(ju-jl > 1)
   {
    jm = (ju+jl)/2;
    if(x < x_array[jm])
      jl=jm;
    else
      ju=jm;
   }
  j=jl;
  if(j >= n_array-IORD)
    j = n_array-IORD-1;
  polint(&x_array[j],&y_array[j],IORD,x,&h,&dh);
  
  return(h);
}
// Using Numerical Recipes. This is Romberg Integration method.
int Integration::romberg()
{
    d_area = 0.0;
	double *s = new double[d_max_iterations + 1];
	double *h = new double[d_max_iterations + 2];
	h[1] = 1.0;
	int j;
	for(j = 1; j <= d_max_iterations; j++){
        s[j] = trapezf(j);
		if(j > d_method){
		    double ss, dss;
			polint(&h[j-d_method], &s[j-d_method], d_method, 0.0, &ss, &dss);
			if (fabs(dss) <= d_tolerance * fabs(ss)){
                d_area = ss;
                break;
			}
		}
		h[j+1] = 0.25*h[j];
	}
    delete[] s;
    delete[] h;
    return j;
}
template < class T > T qromb( T (*func)(T), T a, T b )
{
	T		ss, dss;
	T		s [JMAXP+1], h[JMAXP+1];
	int	j;
	
	h[1-1] = T(1.0);
	for( j=1; j<=JMAX; j++ )
	{
		s[j-1] = trapzd(func, a, b, j);
		if( j >= K )
		{
			polint(&h[j-K-1], &s[j-K-1], K, T(0.0), &ss, &dss );
			if( fabs(dss) <= EPS*fabs(ss) )
				return ss;
		}

		s[j+1-1] = s[j-1];
		h[j+1-1] = 0.25 * h[j-1];
	}

	puts("To many steps in qromb");
	return T(0.0);
}
Example #20
0
bool testpolynomialinterpolation(bool silent)
{
    bool result;
    bool waserrors;
    bool guardedaccerrors;
    bool geninterrors;
    bool nevinterrors;
    bool nevdinterrors;
    bool equidistantinterrors;
    bool chebyshev1interrors;
    bool chebyshev2interrors;
    double epstol;
    int n;
    int maxn;
    int i;
    int j;
    int pass;
    int passcount;
    double a;
    double b;
    double p;
    double dp;
    double d2p;
    double q;
    double dq;
    double d2q;
    ap::real_1d_array x;
    ap::real_1d_array y;
    ap::real_1d_array w;
    double v1;
    double v2;
    double v3;
    double h;
    double maxerr;

    waserrors = false;
    maxn = 5;
    passcount = 20;
    epstol = 1.0E+4;

    //
    // Testing general barycentric formula
    //

    //
    // Crash test: three possible types of overflow
    //
    x.setbounds(0, 2);
    y.setbounds(0, 2);
    w.setbounds(0, 2);
    x(0) = -1;
    y(0) = 1;
    w(0) = 1;
    x(1) = 0;
    y(1) = 0.002;
    w(1) = 1;
    x(2) = 1;
    y(2) = 1;
    w(2) = 1;
    v2 = barycentricinterpolation(x, y, w, 3, double(0));
    v2 = equidistantpolynomialinterpolation(-1.0, 1.0, y, 3, double(0));
    v1 = 0.5;
    while(v1>0)
    {
        v2 = barycentricinterpolation(x, y, w, 3, v1);
        v2 = equidistantpolynomialinterpolation(-1.0, 1.0, y, 3, v1);
        v1 = ap::sqr(v1);
    }
    y(1) = 200;
    v1 = 0.5;
    while(v1>0)
    {
        v2 = barycentricinterpolation(x, y, w, 3, v1);
        v2 = equidistantpolynomialinterpolation(-1.0, 1.0, y, 3, v1);
        v1 = ap::sqr(v1);
    }

    //
    // Accuracy test of guarded formula (near-overflow task)
    //
    x.setbounds(0, 2);
    y.setbounds(0, 2);
    w.setbounds(0, 2);
    x(0) = -1;
    y(0) = -1;
    w(0) = 1;
    x(1) = 0;
    y(1) = 0;
    w(1) = -2;
    x(2) = 1;
    y(2) = 1;
    w(2) = 1;
    v1 = 0.5;
    maxerr = 0;
    while(v1>0)
    {
        v2 = barycentricinterpolation(x, y, w, 3, v1);
        maxerr = ap::maxreal(maxerr, fabs(v2-v1)/fabs(v1));
        v2 = equidistantpolynomialinterpolation(-1.0, 1.0, y, 3, v1);
        maxerr = ap::maxreal(maxerr, fabs(v2-v1)/fabs(v1));
        v1 = ap::sqr(v1);
    }
    guardedaccerrors = maxerr>epstol*ap::machineepsilon;

    //
    // Testing polynomial interpolation using a
    // general barycentric formula. Test on Chebyshev nodes
    // (to avoid big condition numbers).
    //
    maxerr = 0;
    h = 0.0001;
    for(n = 1; n <= maxn; n++)
    {
        x.setbounds(0, n-1);
        y.setbounds(0, n-1);
        w.setbounds(0, n-1);
        for(pass = 1; pass <= passcount; pass++)
        {

            //
            // Prepare task
            //
            v1 = 0.7*ap::randomreal()+0.3;
            for(i = 0; i <= n-1; i++)
            {
                x(i) = cos(i*ap::pi()/n);
                y(i) = cos(v1*x(i))+2.3*x(i)-2;
            }
            for(i = 0; i <= n-1; i++)
            {
                w(i) = 1.0;
                for(j = 0; j <= n-1; j++)
                {
                    if( j!=i )
                    {
                        w(i) = w(i)/(x(i)-x(j));
                    }
                }
            }

            //
            // Test at intermediate points
            //
            v1 = -1;
            while(v1<=1.0001)
            {
                v2 = polint(x, y, n, v1);
                v3 = barycentricinterpolation(x, y, w, n, v1);
                maxerr = ap::maxreal(maxerr, fabs(v2-v3));
                v1 = v1+0.01;
            }

            //
            // Test at nodes
            //
            for(i = 0; i <= n-1; i++)
            {
                maxerr = ap::maxreal(maxerr, fabs(barycentricinterpolation(x, y, w, n, x(i))-y(i)));
            }
        }
    }
    geninterrors = maxerr>epstol*ap::machineepsilon;

    //
    // Testing polynomial interpolation using a Neville's algorithm.
    // Test on Chebyshev nodes (don't want to work with big condition numbers).
    //
    maxerr = 0;
    for(n = 1; n <= maxn; n++)
    {
        x.setbounds(0, n-1);
        y.setbounds(0, n-1);
        for(pass = 1; pass <= passcount; pass++)
        {

            //
            // Prepare task
            //
            v1 = 0.7*ap::randomreal()+0.3;
            for(i = 0; i <= n-1; i++)
            {
                x(i) = cos(i*ap::pi()/n);
                y(i) = cos(v1*x(i))+2.3*x(i)-2;
            }

            //
            // Test
            //
            v1 = -1;
            while(v1<=1.0001)
            {
                v2 = polint(x, y, n, v1);
                v3 = nevilleinterpolation(x, y, n, v1);
                maxerr = ap::maxreal(maxerr, fabs(v2-v3));
                v1 = v1+0.01;
            }
        }
    }
    nevinterrors = maxerr>epstol*ap::machineepsilon;

    //
    // Testing polynomial interpolation using an
    // equidistant barycentric algorithm.
    //
    maxerr = 0;
    for(n = 1; n <= maxn; n++)
    {
        x.setbounds(0, n-1);
        y.setbounds(0, n-1);
        for(pass = 1; pass <= passcount; pass++)
        {

            //
            // Prepare task
            //
            v1 = 0.7*ap::randomreal()+0.3;
            a = -(0.5+0.5*ap::randomreal());
            b = +(0.5+0.5*ap::randomreal());
            for(i = 0; i <= n-1; i++)
            {
                x(i) = a+(b-a)*i/ap::maxint(n-1, 1);
                y(i) = cos(v1*x(i))+2.3*x(i)-2;
            }

            //
            // Test
            //
            v1 = -1;
            while(v1<=1.0001)
            {
                v2 = polint(x, y, n, v1);
                v3 = equidistantpolynomialinterpolation(a, b, y, n, v1);
                maxerr = ap::maxreal(maxerr, fabs(v2-v3));
                v1 = v1+0.01;
            }
        }
    }
    equidistantinterrors = maxerr>epstol*ap::machineepsilon;

    //
    // Testing polynomial interpolation using
    // Chebyshev-1 barycentric algorithm.
    //
    maxerr = 0;
    for(n = 1; n <= maxn; n++)
    {
        x.setbounds(0, n-1);
        y.setbounds(0, n-1);
        for(pass = 1; pass <= passcount; pass++)
        {

            //
            // Prepare task
            //
            v1 = 0.7*ap::randomreal()+0.3;
            a = -(0.5+0.5*ap::randomreal());
            b = +(0.5+0.5*ap::randomreal());
            for(i = 0; i <= n-1; i++)
            {
                x(i) = 0.5*(a+b)+0.5*(b-a)*cos(ap::pi()*(2*i+1)/(2*(n-1)+2));
                y(i) = cos(v1*x(i))+2.3*x(i)-2;
            }

            //
            // Test
            //
            v1 = a;
            while(v1<=b)
            {
                v2 = polint(x, y, n, v1);
                v3 = chebyshev1interpolation(a, b, y, n, v1);
                maxerr = ap::maxreal(maxerr, fabs(v2-v3));
                v1 = v1+0.01;
            }
        }
    }
    chebyshev1interrors = maxerr>epstol*ap::machineepsilon;

    //
    // Testing polynomial interpolation using
    // Chebyshev-2 barycentric algorithm.
    //
    maxerr = 0;
    for(n = 2; n <= maxn; n++)
    {
        x.setbounds(0, n-1);
        y.setbounds(0, n-1);
        for(pass = 1; pass <= passcount; pass++)
        {

            //
            // Prepare task
            //
            v1 = 0.7*ap::randomreal()+0.3;
            a = -(0.5+0.5*ap::randomreal());
            b = +(0.5+0.5*ap::randomreal());
            for(i = 0; i <= n-1; i++)
            {
                x(i) = 0.5*(a+b)+0.5*(b-a)*cos(ap::pi()*i/(n-1));
                y(i) = cos(v1*x(i))+2.3*x(i)-2;
            }

            //
            // Test
            //
            v1 = a;
            while(v1<=b)
            {
                v2 = polint(x, y, n, v1);
                v3 = chebyshev2interpolation(a, b, y, n, v1);
                maxerr = ap::maxreal(maxerr, fabs(v2-v3));
                v1 = v1+0.01;
            }
        }
    }
    chebyshev2interrors = maxerr>epstol*ap::machineepsilon;

    //
    // Testing polynomial interpolation using a Neville's algorithm.
    // with derivatives. Test on Chebyshev nodes (don't want to work
    // with big condition numbers).
    //
    maxerr = 0;
    h = 0.0001;
    for(n = 1; n <= maxn; n++)
    {
        x.setbounds(0, n-1);
        y.setbounds(0, n-1);
        for(pass = 1; pass <= passcount; pass++)
        {

            //
            // Prepare task
            //
            v2 = 0.7*ap::randomreal()+0.3;
            for(i = 0; i <= n-1; i++)
            {
                x(i) = cos(i*ap::pi()/n);
                y(i) = cos(v2*x(i));
            }

            //
            // Test
            //
            v1 = -1;
            while(v1<=1.0001)
            {
                p = polint(x, y, n, v1);
                dp = (polint(x, y, n, v1+h)-polint(x, y, n, v1-h))/(2*h);
                d2p = (polint(x, y, n, v1-h)-2*polint(x, y, n, v1)+polint(x, y, n, v1+h))/ap::sqr(h);
                nevilledifferentiation(x, y, n, v1, q, dq, d2q);
                maxerr = ap::maxreal(maxerr, fabs(p-q));
                maxerr = ap::maxreal(maxerr, fabs(dp-dq));
                maxerr = ap::maxreal(maxerr, fabs(d2p-d2q));
                v1 = v1+0.01;
            }
        }
    }
    nevdinterrors = maxerr>0.001;

    //
    // report
    //
    waserrors = guardedaccerrors||geninterrors||nevinterrors||equidistantinterrors||chebyshev1interrors||chebyshev2interrors||nevdinterrors;
    if( !silent )
    {
        printf("TESTING POLYNOMIAL INTERPOLATION\n");

        //
        // Normal tests
        //
        printf("BARYCENTRIC INTERPOLATION TEST:          ");
        if( geninterrors )
        {
            printf("FAILED\n");
        }
        else
        {
            printf("OK\n");
        }
        printf("NEVILLE INTERPOLATON TEST:               ");
        if( nevinterrors )
        {
            printf("FAILED\n");
        }
        else
        {
            printf("OK\n");
        }
        printf("EQUIDISTANT INTERPOLATON TEST:           ");
        if( equidistantinterrors )
        {
            printf("FAILED\n");
        }
        else
        {
            printf("OK\n");
        }
        printf("CHEBYSHEV-1 INTERPOLATON TEST:           ");
        if( chebyshev1interrors )
        {
            printf("FAILED\n");
        }
        else
        {
            printf("OK\n");
        }
        printf("CHEBYSHEV-2 INTERPOLATON TEST:           ");
        if( chebyshev2interrors )
        {
            printf("FAILED\n");
        }
        else
        {
            printf("OK\n");
        }
        printf("NEVILLE DIFFERENTIATION TEST:            ");
        if( nevdinterrors )
        {
            printf("FAILED\n");
        }
        else
        {
            printf("OK\n");
        }
        printf("GUARDED FORMULA ACCURACY TEST:           ");
        if( guardedaccerrors )
        {
            printf("FAILED\n");
        }
        else
        {
            printf("OK\n");
        }

        //
        // if we are here then crash test is passed :)
        //
        printf("CRASH TEST:                              OK\n");
        if( waserrors )
        {
            printf("TEST FAILED\n");
        }
        else
        {
            printf("TEST PASSED\n");
        }
        printf("\n\n");
    }

    //
    // end
    //
    result = !waserrors;
    return result;
}
Example #21
0
/***********************************************************************//**
 * @brief Perform Romberg integration
 *
 * @param[in] a Left integration boundary.
 * @param[in] b Right integration boundary.
 * @param[in] k Integration order (default: k=5)
 *
 * Returns the integral of the integrand from a to b. Integration is
 * performed by Romberg's method of order 2K, where e.g. K=2 in Simpson's
 * rule.
 * The number of iterations is limited by m_max_iter. m_eps specifies the
 * requested fractional accuracy. By default it is set to 1e-6.
 *
 * @todo Check that k is smaller than m_max_iter
 * @todo Make use of std::vector class
 ***************************************************************************/
double GIntegral::romb(const double& a, const double& b, const int& k)
{
    // Initialise result
    double result = 0.0;
    
    // Continue only if integration range is valid
    if (b > a) {

        // Initialise variables
        bool   converged = false;
        double ss        = 0.0;
        double dss       = 0.0;

        // Allocate temporal storage
        double* s = new double[m_max_iter+2];
        double* h = new double[m_max_iter+2];

        // Initialise step size
        h[1] = 1.0;
        s[0] = 0.0;

        // Iterative loop
        for (m_iter = 1; m_iter <= m_max_iter; ++m_iter) {

            // Integration using Trapezoid rule
            s[m_iter] = trapzd(a, b, m_iter, s[m_iter-1]);

            // Compile option: Check for NaN/Inf
            #if defined(G_NAN_CHECK)
            if (is_notanumber(s[m_iter]) || is_infinite(s[m_iter])) {
                std::cout << "*** ERROR: GIntegral::romb";
                std::cout << "(a=" << a << ", b=" << b << ", k=" << k << "):";
                std::cout << " NaN/Inf encountered";
                std::cout << " (s[" << m_iter << "]=" << s[m_iter] << ")";
                std::cout << std::endl;
            }
            #endif

            // Starting from iteration k on, use polynomial interpolation
            if (m_iter >= k) {
                ss = polint(&h[m_iter-k], &s[m_iter-k], k, 0.0, &dss);
                if (std::abs(dss) <= m_eps * std::abs(ss)) {
                    converged = true;
                    result    = ss;
                    break;
                }
            }

            // Reduce step size
            h[m_iter+1]= 0.25 * h[m_iter];

        } // endfor: iterative loop

        // Free temporal storage
        delete [] s;
        delete [] h;

        // Dump warning
        if (!m_silent) {
            if (!converged) {
                std::string msg = "Integration uncertainty "+
                                  gammalib::str(std::abs(dss))+
                                  " exceeds tolerance of "+
                                  gammalib::str(m_eps * std::abs(ss))+
                                  " after "+gammalib::str(m_iter)+
                                  " iterations. Result "+
                                  gammalib::str(result)+
                                  " is inaccurate.";
                gammalib::warning(G_ROMB, msg);
            }
        }
    
    } // endif: integration range was valid

    // Return result
    return result;
}
Example #22
0
/***********************************************************************//**
 * @brief Perform Romberg integration
 *
 * @param[in] a Left integration boundary.
 * @param[in] b Right integration boundary.
 * @param[in] k Integration order (default: k=5)
 *
 * Returns the integral of the integrand from a to b. Integration is
 * performed by Romberg's method of order 2K, where e.g. K=2 in Simpson's
 * rule.
 * The number of iterations is limited by m_max_iter. m_eps specifies the
 * requested fractional accuracy. By default it is set to 1e-6.
 *
 * @todo Check that k is smaller than m_max_iter
 * @todo Make use of std::vector class
 ***************************************************************************/
double GIntegral::romb(double a, double b, int k)
{
    // Initialise result
    bool   converged = false;
    double result    = 0.0;
    double ss        = 0.0;
    double dss       = 0.0;
    
    // Continue only if integration range is valid
    if (b > a) {

        // Allocate temporal storage
        double* s = new double[m_max_iter+2];
        double* h = new double[m_max_iter+2];

        // Initialise step size
        h[1] = 1.0;
        s[0] = 0.0;

        // Iterative loop
        for (m_iter = 1; m_iter <= m_max_iter; ++m_iter) {

            // Integration using Trapezoid rule
            s[m_iter] = trapzd(a, b, m_iter, s[m_iter-1]);

            // Compile option: Check for NaN/Inf
            #if defined(G_NAN_CHECK)
            if (isnotanumber(s[m_iter]) || isinfinite(s[m_iter])) {
                std::cout << "*** ERROR: GIntegral::romb";
                std::cout << "(a=" << a << ", b=" << b << ", k=" << k << "):";
                std::cout << " NaN/Inf encountered";
                std::cout << " (s[" << m_iter << "]=" << s[m_iter] << ")";
                std::cout << std::endl;
            }
            #endif

            // Starting from iteration k on, use polynomial interpolation
            if (m_iter >= k) {
                ss = polint(&h[m_iter-k], &s[m_iter-k], k, 0.0, &dss);
                if (std::abs(dss) <= m_eps * std::abs(ss)) {
                    converged = true;
                    result    = ss;
                    break;
                }
            }

            // Reduce step size
            h[m_iter+1]= 0.25 * h[m_iter];

        } // endfor: iterative loop

        // Free temporal storage
        delete [] s;
        delete [] h;

        // Dump warning
        if (!m_silent) {
            if (!converged) {
                std::cout << "*** WARNING: GIntegral::romb: ";
                std::cout << "Integration did not converge ";
                std::cout << "(iter=" << m_iter;
                std::cout << ", result=" << ss;
                std::cout << ", d=" << std::abs(dss);
                std::cout << " > " << m_eps * std::abs(ss) << ")";
                std::cout << std::endl;
                //throw;
            }
        }
    
    } // endif: integration range was valid

    // Return result
    return result;
}
Example #23
0
double dpoly(int n, double x, double *xp, double *yp)
{
  double value, err;
  polint (xp - 1, yp - 1, n, x, &value, &err);
  return value;
}