/* Author: G. Jungman * RCS: $Id: gsl_interp.h,v 1.9 1999/10/06 05:43:43 jungman Exp $ */ #ifndef GSL_INTERP_H_ #define GSL_INTERP_H_ #include /* evaluation accelerator */ typedef struct { size_t cache; /* cache of index */ size_t miss_count; /* keep statistics */ size_t hit_count; } gsl_interp_accel; /* general interpolation object */ struct _gsl_interp_obj_struct { int (*eval_impl) (const struct _gsl_interp_obj_struct *, const double xa[], const double ya[], double x, gsl_interp_accel *, double * y); int (*eval_d_impl) (const struct _gsl_interp_obj_struct *, const double xa[], const double ya[], double x, gsl_interp_accel *, double * dydx); int (*eval_i_impl) (const struct _gsl_interp_obj_struct *, const double xa[], const double ya[], gsl_interp_accel *, double a, double b, double * result); void (*free) (struct _gsl_interp_obj_struct *); double xmin; double xmax; size_t size; }; typedef struct _gsl_interp_obj_struct gsl_interp_obj; /* interpolation object factory */ typedef struct { const char * name; gsl_interp_obj * (*create) (const double x_array[], const double y_array[], size_t size); } gsl_interp_factory; /* available factories */ extern const gsl_interp_factory gsl_interp_factory_linear; extern const gsl_interp_factory gsl_interp_factory_cspline_natural; extern const gsl_interp_factory gsl_interp_factory_cspline_periodic; extern const gsl_interp_factory gsl_interp_factory_akima_natural; extern const gsl_interp_factory gsl_interp_factory_akima_periodic; gsl_interp_accel * gsl_interp_accel_new(void); size_t gsl_interp_accel_find(gsl_interp_accel * a, const double x_array[], size_t size, double x); void gsl_interp_accel_free(gsl_interp_accel * a); int gsl_interp_eval_impl(const gsl_interp_obj * obj, const double xa[], const double ya[], double x, gsl_interp_accel * a, double * y ); int gsl_interp_eval_e(const gsl_interp_obj * obj, const double xa[], const double ya[], double x, gsl_interp_accel * a, double * y ); double gsl_interp_eval(const gsl_interp_obj * obj, const double xa[], const double ya[], double x, gsl_interp_accel * a ); int gsl_interp_eval_deriv_impl(const gsl_interp_obj * obj, const double xa[], const double ya[], double x, gsl_interp_accel * a, double * y ); int gsl_interp_eval_deriv_e(const gsl_interp_obj * obj, const double xa[], const double ya[], double x, gsl_interp_accel * a, double * y ); double gsl_interp_eval_deriv(const gsl_interp_obj * obj, const double xa[], const double ya[], double x, gsl_interp_accel * a ); int gsl_interp_eval_integ_impl(const gsl_interp_obj * obj, const double xa[], const double ya[], double a, double b, gsl_interp_accel * acc, double * y ); int gsl_interp_eval_integ_e(const gsl_interp_obj * obj, const double xa[], const double ya[], double a, double b, gsl_interp_accel * acc, double * y ); double gsl_interp_eval_integ(const gsl_interp_obj * obj, const double xa[], const double ya[], double a, double b, gsl_interp_accel * acc ); void gsl_interp_obj_free(gsl_interp_obj * interp_obj); size_t gsl_interp_bsearch(const double x_array[], double x, size_t index_lo, size_t index_hi ); #ifdef HAVE_INLINE extern inline size_t gsl_interp_bsearch(const double x_array[], double x, size_t index_lo, size_t index_hi ); extern inline size_t gsl_interp_bsearch(const double x_array[], double x, size_t index_lo, size_t index_hi ) { size_t ilo = index_lo; size_t ihi = index_hi; while(ihi > ilo + 1) { size_t i = (ihi + ilo)/2; if(x_array[i] > x) ihi = i; else ilo = i; } return ilo; } #endif size_t gsl_interp_accel_find(gsl_interp_accel * a, const double xa[], size_t len, double x); #ifdef HAVE_INLINE extern inline size_t gsl_interp_accel_find(gsl_interp_accel * a, const double xa[], size_t len, double x) { size_t x_index = a->cache; if(x < xa[x_index]) { a->miss_count++; a->cache = gsl_interp_bsearch(xa, x, 0, x_index); } else if(x > xa[x_index + 1]) { a->miss_count++; a->cache = gsl_interp_bsearch(xa, x, x_index, len-1); } else { a->hit_count++; } return a->cache; } #endif /* HAVE_INLINE */ #endif /* !GSL_INTERP_H_ */