[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
gsl Interpolation Question
From: |
Elias Posoukidis |
Subject: |
gsl Interpolation Question |
Date: |
Tue, 10 Mar 2020 01:26:15 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.4.1 |
Hi,
while i was interpolation some test-data i got the following results.
3.736 0.0298362 -2.66867
3.737 0.0271675 -2.66867
3.738 0.0244988 -2.66868
3.739 0.0218302 -2.66865
3.74 0.0191615 -2.66875
3.741 0.0164928 -2.6684
3.742 0.0138242 -2.66969
3.743 0.0111555 -2.66489
3.744 0.0084868 -2.68281
3.745 0.00581813 -2.61591
3.746 0.00314946 -2.8656
3.747 0.000480783 -1.93374
3.748 -0.000604339 -0.660811
--------------------------------------
3.736 0.0298362 -2.66867
3.737 0.0271675 -2.66867
3.738 0.0244988 -2.66867
3.739 0.0218302 -2.66867
3.74 0.0191615 -2.66867
3.741 0.0164928 -2.66867
3.742 0.0138242 -2.66867
3.743 0.0111555 -2.66867
3.744 0.0084868 -2.66867
3.745 0.00581813 -2.66867
3.746 0.00314946 -2.66867
3.747 0.000480783 -2.66867
3.748 -0.000604339 -1.08512
The data where generated with the following C++ program. I used the
usual gsl-functions with spline interpolation and got the first part of
the data. For the second part of the data i used internal gsl-functions
from the file "cspline.c". The second part of the data contains the
expected result (the third column should give a constant value) while
the first part contains almost identical results. For 3.745 we get 3.745
0.00581813 -2.61591 which makes no sense. I included these internal
functions in the program, so that everyone can reproduce the results. As
far as i know these internal function which produced the expected
results are used by those produces the wrong ones. What is going wrong?
#include <gsl/gsl_errno.h>
#include <gsl/gsl_spline.h>
#include <stdio.h>
namespace gslcode {
typedef struct {
double *c;
double *g;
double *diag;
double *offdiag;
} cspline_state_t;
/* function for common coefficient determination
*/
inline void coeff_calc(const double c_array[], double dy, double dx,
size_t index, double *b, double *c, double *d) {
const double c_i = c_array[index];
const double c_ip1 = c_array[index + 1];
*b = (dy / dx) - dx * (c_ip1 + 2.0 * c_i) / 3.0;
*c = c_i;
*d = (c_ip1 - c_i) / (3.0 * dx);
}
int cspline_eval(const void *vstate, const double x_array[],
const double y_array[], size_t size, double x,
gsl_interp_accel *a, double *y) {
const cspline_state_t *state = (const cspline_state_t *)vstate;
double x_lo, x_hi;
double dx;
size_t index;
if (a != 0) {
index = gsl_interp_accel_find(a, x_array, size, x);
} else {
index = gsl_interp_bsearch(x_array, x, 0, size - 1);
}
/* evaluate */
x_hi = x_array[index + 1];
x_lo = x_array[index];
dx = x_hi - x_lo;
if (dx > 0.0) {
const double y_lo = y_array[index];
const double y_hi = y_array[index + 1];
const double dy = y_hi - y_lo;
double delx = x - x_lo;
double b_i, c_i, d_i;
coeff_calc(state->c, dy, dx, index, &b_i, &c_i, &d_i);
*y = y_lo + delx * (b_i + delx * (c_i + delx * d_i));
return GSL_SUCCESS;
} else {
*y = 0.0;
return GSL_EINVAL;
}
}
static int cspline_eval_deriv(const void *vstate, const double x_array[],
const double y_array[], size_t size,
double x,
gsl_interp_accel *a, double *dydx) {
const cspline_state_t *state = (const cspline_state_t *)vstate;
double x_lo, x_hi;
double dx;
size_t index;
if (a != 0) {
index = gsl_interp_accel_find(a, x_array, size, x);
} else {
index = gsl_interp_bsearch(x_array, x, 0, size - 1);
}
/* evaluate */
x_hi = x_array[index + 1];
x_lo = x_array[index];
dx = x_hi - x_lo;
if (dx > 0.0) {
const double y_lo = y_array[index];
const double y_hi = y_array[index + 1];
const double dy = y_hi - y_lo;
double delx = x - x_lo;
double b_i, c_i, d_i;
coeff_calc(state->c, dy, dx, index, &b_i, &c_i, &d_i);
*dydx = b_i + delx * (2.0 * c_i + 3.0 * d_i * delx);
return GSL_SUCCESS;
} else {
*dydx = 0.0;
return GSL_EINVAL;
}
}
} // namespace gslcode
int main() {
const size_t N = 13;
const double t[] = {3.736, 3.737, 3.738, 3.739, 3.740, 3.741, 3.742,
3.743, 3.744, 3.745, 3.746, 3.747, 3.748};
const double v[] = {0.02983619, 0.027167517, 0.024498843, 0.02183017,
0.019161497, 0.016492823, 0.01382415, 0.011155476,
0.008486803, 0.00581813, 0.003149456, 0.000480783,
-0.000604339};
gsl_interp_accel *acc = gsl_interp_accel_alloc();
gsl_interp *spline = gsl_interp_alloc(gsl_interp_cspline, N);
gsl_interp_init(spline, t, v, N);
for (double xi = 3.736; xi < 3.748; xi += 0.001) {
double val1 = gsl_interp_eval(spline, t, v, xi, acc);
double val2 = gsl_interp_eval_deriv(spline, t, v, xi, acc);
printf("%g %g %g\n", xi, val1, val2);
}
printf("--------------------------------------\n");
for (double xi = 3.736; xi < 3.748; xi += 0.001) {
double val1, val2;
gslcode::cspline_eval(spline, t, v, N, xi, acc, &val1);
gslcode::cspline_eval_deriv(spline, t, v, N, xi, acc, &val2);
printf("%g %g %g\n", xi, val1, val2);
}
gsl_interp_free(spline);
gsl_interp_accel_free(acc);
}
Elias
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- gsl Interpolation Question,
Elias Posoukidis <=