1 /* interpolation/test.c
3 * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or (at
8 * your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
28 #include <gsl/gsl_test.h>
29 #include <gsl/gsl_errno.h>
30 #include <gsl/gsl_interp.h>
31 #include <gsl/gsl_ieee_utils.h>
36 double x_array[5] = { 0.0, 1.0, 2.0, 3.0, 4.0 };
41 /* check an interior point */
42 index_result = gsl_interp_bsearch(x_array, 1.5, 0, 4);
43 s = (index_result != 1);
45 gsl_test (s, "simple bsearch");
47 /* check that we get the last interval if x == last value */
48 index_result = gsl_interp_bsearch(x_array, 4.0, 0, 4);
49 s = (index_result != 3);
51 gsl_test (s, "upper endpoint bsearch");
53 /* check that we get the first interval if x == first value */
54 index_result = gsl_interp_bsearch(x_array, 0.0, 0, 4);
55 s = (index_result != 0);
57 gsl_test (s, "lower endpoint bsearch");
59 /* check that we get correct interior boundary behaviour */
60 index_result = gsl_interp_bsearch(x_array, 2.0, 0, 4);
61 s = (index_result != 2);
63 gsl_test (s, "degenerate bsearch");
65 /* check out of bounds above */
66 index_result = gsl_interp_bsearch(x_array, 10.0, 0, 4);
67 s = (index_result != 3);
69 gsl_test (s, "out of bounds bsearch +");
71 /* check out of bounds below */
72 index_result = gsl_interp_bsearch(x_array, -10.0, 0, 4);
73 s = (index_result != 0);
75 gsl_test (s, "out of bounds bsearch -");
82 typedef double TEST_FUNC (double);
83 typedef struct _xy_table xy_table;
92 xy_table make_xy_table (double x[], double y[], size_t n);
95 make_xy_table (double x[], double y[], size_t n)
106 const xy_table * data_table,
107 const gsl_interp_type * T,
108 xy_table * test_table,
109 xy_table * test_d_table,
110 xy_table * test_i_table
113 int status = 0, s1, s2, s3;
116 gsl_interp_accel *a = gsl_interp_accel_alloc ();
117 gsl_interp *interp = gsl_interp_alloc (T, data_table->n);
119 gsl_interp_init (interp, data_table->x, data_table->y, data_table->n);
121 for (i = 0; i < test_table->n; i++)
123 double x = test_table->x[i];
127 double diff_y, diff_deriv, diff_integ;
128 s1 = gsl_interp_eval_e (interp, data_table->x, data_table->y, x, a, &y);
129 s2 = gsl_interp_eval_deriv_e (interp, data_table->x, data_table->y, x, a, &deriv);
130 s3 = gsl_interp_eval_integ_e (interp, data_table->x, data_table->y, test_table->x[0], x, a, &integ);
132 gsl_test (s1, "gsl_interp_eval_e %s", gsl_interp_name(interp));
133 gsl_test (s2, "gsl_interp_eval_deriv_e %s", gsl_interp_name(interp));
134 gsl_test (s3, "gsl_interp_eval_integ_e %s", gsl_interp_name(interp));
136 gsl_test_abs (y, test_table->y[i], 1e-10, "%s %d", gsl_interp_name(interp), i);
137 gsl_test_abs (deriv, test_d_table->y[i], 1e-10, "%s deriv %d", gsl_interp_name(interp), i);
138 gsl_test_abs (integ, test_i_table->y[i], 1e-10, "%s integ %d", gsl_interp_name(interp), i);
140 diff_y = y - test_table->y[i];
141 diff_deriv = deriv - test_d_table->y[i];
142 diff_integ = integ - test_i_table->y[i];
143 if (fabs (diff_y) > 1.e-10 || fabs(diff_deriv) > 1.0e-10 || fabs(diff_integ) > 1.0e-10) {
148 gsl_interp_accel_free (a);
149 gsl_interp_free (interp);
159 double data_x[4] = { 0.0, 1.0, 2.0, 3.0 };
160 double data_y[4] = { 0.0, 1.0, 2.0, 3.0 };
161 double test_x[6] = { 0.0, 0.5, 1.0, 1.5, 2.5, 3.0 };
162 double test_y[6] = { 0.0, 0.5, 1.0, 1.5, 2.5, 3.0 };
163 double test_dy[6] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
164 double test_iy[6] = { 0.0, 0.125, 0.5, 9.0/8.0, 25.0/8.0, 9.0/2.0 };
166 xy_table data_table = make_xy_table(data_x, data_y, 4);
167 xy_table test_table = make_xy_table(test_x, test_y, 6);
168 xy_table test_d_table = make_xy_table(test_x, test_dy, 6);
169 xy_table test_i_table = make_xy_table(test_x, test_iy, 6);
171 s = test_interp (&data_table, gsl_interp_linear, &test_table, &test_d_table, &test_i_table);
172 gsl_test (s, "linear interpolation");
177 test_polynomial (void)
181 double data_x[4] = { 0.0, 1.0, 2.0, 3.0 };
182 double data_y[4] = { 0.0, 1.0, 2.0, 3.0 };
183 double test_x[6] = { 0.0, 0.5, 1.0, 1.5, 2.5, 3.0 };
184 double test_y[6] = { 0.0, 0.5, 1.0, 1.5, 2.5, 3.0 };
185 double test_dy[6] = { 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
186 double test_iy[6] = { 0.0, 0.125, 0.5, 9.0/8.0, 25.0/8.0, 9.0/2.0 };
188 xy_table data_table = make_xy_table(data_x, data_y, 4);
189 xy_table test_table = make_xy_table(test_x, test_y, 6);
190 xy_table test_d_table = make_xy_table(test_x, test_dy, 6);
191 xy_table test_i_table = make_xy_table(test_x, test_iy, 6);
193 s = test_interp (&data_table, gsl_interp_polynomial, &test_table, &test_d_table, &test_i_table);
194 gsl_test (s, "polynomial interpolation");
204 double data_x[3] = { 0.0, 1.0, 2.0 };
205 double data_y[3] = { 0.0, 1.0, 2.0 };
206 double test_x[4] = { 0.0, 0.5, 1.0, 2.0 };
207 double test_y[4] = { 0.0, 0.5, 1.0, 2.0 };
208 double test_dy[4] = { 1.0, 1.0, 1.0, 1.0 };
209 double test_iy[4] = { 0.0, 0.125, 0.5, 2.0 };
211 xy_table data_table = make_xy_table(data_x, data_y, 3);
212 xy_table test_table = make_xy_table(test_x, test_y, 4);
213 xy_table test_d_table = make_xy_table(test_x, test_dy, 4);
214 xy_table test_i_table = make_xy_table(test_x, test_iy, 4);
216 s = test_interp (&data_table, gsl_interp_cspline, &test_table, &test_d_table, &test_i_table);
217 gsl_test (s, "cspline interpolation");
224 /* Test taken from Young & Gregory, A Survey of Numerical
225 Mathematics, Vol 1 Chapter 6.8 */
229 double data_x[6] = { 0.0, 0.2, 0.4, 0.6, 0.8, 1.0 };
231 double data_y[6] = { 1.0,
232 0.961538461538461, 0.862068965517241,
233 0.735294117647059, 0.609756097560976,
234 0.500000000000000 } ;
236 double test_x[50] = {
237 0.00, 0.02, 0.04, 0.06, 0.08, 0.10, 0.12, 0.14, 0.16, 0.18,
238 0.20, 0.22, 0.24, 0.26, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38,
239 0.40, 0.42, 0.44, 0.46, 0.48, 0.50, 0.52, 0.54, 0.56, 0.58,
240 0.60, 0.62, 0.64, 0.66, 0.68, 0.70, 0.72, 0.74, 0.76, 0.78,
241 0.80, 0.82, 0.84, 0.86, 0.88, 0.90, 0.92, 0.94, 0.96, 0.98 };
243 double test_y[50] = {
244 1.000000000000000, 0.997583282975581, 0.995079933416512,
245 0.992403318788142, 0.989466806555819, 0.986183764184894,
246 0.982467559140716, 0.978231558888635, 0.973389130893999,
247 0.967853642622158, 0.961538461538461, 0.954382579685350,
248 0.946427487413627, 0.937740299651188, 0.928388131325928,
249 0.918438097365742, 0.907957312698524, 0.897012892252170,
250 0.885671950954575, 0.874001603733634, 0.862068965517241,
251 0.849933363488199, 0.837622973848936, 0.825158185056786,
252 0.812559385569085, 0.799846963843167, 0.787041308336369,
253 0.774162807506023, 0.761231849809467, 0.748268823704033,
254 0.735294117647059, 0.722328486073082, 0.709394147325463,
255 0.696513685724764, 0.683709685591549, 0.671004731246381,
256 0.658421407009825, 0.645982297202442, 0.633709986144797,
257 0.621627058157454, 0.609756097560976, 0.598112015427308,
258 0.586679029833925, 0.575433685609685, 0.564352527583445,
259 0.553412100584061, 0.542588949440392, 0.531859618981294,
260 0.521200654035625, 0.510588599432241};
262 double test_dy[50] = {
263 -0.120113913432180, -0.122279726798445, -0.128777166897241,
264 -0.139606233728568, -0.154766927292426, -0.174259247588814,
265 -0.198083194617734, -0.226238768379184, -0.258725968873165,
266 -0.295544796099676, -0.336695250058719, -0.378333644186652,
267 -0.416616291919835, -0.451543193258270, -0.483114348201955,
268 -0.511329756750890, -0.536189418905076, -0.557693334664512,
269 -0.575841504029200, -0.590633926999137, -0.602070603574326,
270 -0.611319695518765, -0.619549364596455, -0.626759610807396,
271 -0.632950434151589, -0.638121834629033, -0.642273812239728,
272 -0.645406366983674, -0.647519498860871, -0.648613207871319,
273 -0.648687494015019, -0.647687460711257, -0.645558211379322,
274 -0.642299746019212, -0.637912064630930, -0.632395167214473,
275 -0.625749053769843, -0.617973724297039, -0.609069178796061,
276 -0.599035417266910, -0.587872439709585, -0.576731233416743,
277 -0.566762785681043, -0.557967096502484, -0.550344165881066,
278 -0.543893993816790, -0.538616580309654, -0.534511925359660,
279 -0.531580028966807, -0.529820891131095};
281 double test_iy[50] = {
282 0.000000000000000, 0.019975905023535, 0.039902753768792,
283 0.059777947259733, 0.079597153869625, 0.099354309321042,
284 0.119041616685866, 0.138649546385285, 0.158166836189794,
285 0.177580491219196, 0.196875783942601, 0.216036382301310,
286 0.235045759060558, 0.253888601161251, 0.272550937842853,
287 0.291020140643388, 0.309284923399436, 0.327335342246135,
288 0.345162795617181, 0.362760024244829, 0.380121111159890,
289 0.397241442753010, 0.414117280448683, 0.430745332379281,
290 0.447122714446318, 0.463246950320456, 0.479115971441505,
291 0.494728117018421, 0.510082134029305, 0.525177177221407,
292 0.540012809111123, 0.554589001813881, 0.568906157172889,
293 0.582965126887879, 0.596767214344995, 0.610314174616794,
294 0.623608214462242, 0.636651992326715, 0.649448618342004,
295 0.662001654326309, 0.674315113784241, 0.686393423540581,
296 0.698241001711602, 0.709861835676399, 0.721259443710643,
297 0.732436874986582, 0.743396709573044, 0.754141058435429,
298 0.764671563435718, 0.774989397332469 };
300 xy_table data_table = make_xy_table(data_x, data_y, 6);
301 xy_table test_table = make_xy_table(test_x, test_y, 50);
302 xy_table test_d_table = make_xy_table(test_x, test_dy, 50);
303 xy_table test_i_table = make_xy_table(test_x, test_iy, 50);
305 s = test_interp (&data_table, gsl_interp_cspline, &test_table, &test_d_table, &test_i_table);
306 gsl_test (s, "cspline 1/(1+x^2) interpolation");
313 /* This data has been chosen to be random (uneven spacing in x and y)
314 and the exact cubic spine solution computed using Octave */
329 -0.00453877449035645,
333 -0.21595209836959839,
338 double test_x[19] = {
360 double test_y[19] = {
361 -0.00453877449035645,
372 -0.09656315924697809,
373 -0.21595209836959839,
374 -0.13551147728045118,
382 double test_dy[19] = {
404 double test_iy[19] = {
426 xy_table data_table = make_xy_table(data_x, data_y, 7);
427 xy_table test_table = make_xy_table(test_x, test_y, 19);
428 xy_table test_d_table = make_xy_table(test_x, test_dy, 19);
429 xy_table test_i_table = make_xy_table(test_x, test_iy, 19);
431 s = test_interp (&data_table, gsl_interp_cspline, &test_table, &test_d_table, &test_i_table);
432 gsl_test (s, "cspline arbitrary data interpolation");
439 /* This data has been chosen to be random (uneven spacing in x and y)
440 and the exact cubic spine solution computed using Octave */
444 double data_x[11] = {
458 double data_y[11] = {
472 double test_x[31] = {
506 double test_y[31] = {
540 double test_dy[31] = {
574 double test_iy[31] = {
608 xy_table data_table = make_xy_table(data_x, data_y, 11);
609 xy_table test_table = make_xy_table(test_x, test_y, 31);
610 xy_table test_d_table = make_xy_table(test_x, test_dy, 31);
611 xy_table test_i_table = make_xy_table(test_x, test_iy, 31);
613 s = test_interp (&data_table, gsl_interp_cspline_periodic, &test_table, &test_d_table, &test_i_table);
614 gsl_test (s, "cspline periodic sine interpolation");
619 test_csplinep2 (void)
621 /* This data tests the periodic case n=3 */
637 double test_x[61] = {
701 double test_y[61] = {
765 double test_dy[61] = {
829 double test_iy[61] = {
893 xy_table data_table = make_xy_table(data_x, data_y, 3);
894 xy_table test_table = make_xy_table(test_x, test_y, 61);
895 xy_table test_d_table = make_xy_table(test_x, test_dy, 61);
896 xy_table test_i_table = make_xy_table(test_x, test_iy, 61);
898 s = test_interp (&data_table, gsl_interp_cspline_periodic, &test_table, &test_d_table, &test_i_table);
899 gsl_test (s, "cspline periodic 3pt interpolation");
910 double data_x[5] = { 0.0, 1.0, 2.0, 3.0, 4.0 };
911 double data_y[5] = { 0.0, 1.0, 2.0, 3.0, 4.0 };
912 double test_x[4] = { 0.0, 0.5, 1.0, 2.0 };
913 double test_y[4] = { 0.0, 0.5, 1.0, 2.0 };
914 double test_dy[4] = { 1.0, 1.0, 1.0, 1.0 };
915 double test_iy[4] = { 0.0, 0.125, 0.5, 2.0 };
917 xy_table data_table = make_xy_table(data_x, data_y, 5);
918 xy_table test_table = make_xy_table(test_x, test_y, 4);
919 xy_table test_d_table = make_xy_table(test_x, test_dy, 4);
920 xy_table test_i_table = make_xy_table(test_x, test_iy, 4);
922 s = test_interp (&data_table, gsl_interp_akima, &test_table, &test_d_table, &test_i_table);
923 gsl_test (s, "akima interpolation");
929 main (int argc, char **argv)
933 gsl_ieee_env_setup ();
935 argc = 0; /* prevent warnings about unused parameters */
938 status += test_bsearch();
939 status += test_linear();
940 status += test_polynomial();
941 status += test_cspline();
942 status += test_cspline2();
943 status += test_cspline3();
944 status += test_csplinep();
945 status += test_csplinep2();
946 status += test_akima();
948 exit (gsl_test_summary());