MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
test_interp.c
Go to the documentation of this file.
1 #include <stdarg.h>
2 #include <stddef.h>
3 #include <setjmp.h>
4 #include <cmocka.h>
5 #include <math.h>
6 #include <stdio.h>
7 #include <stdint.h>
8 #include "stub.h"
9 #include "../utils/interp.h"
10 
11 #define DMAX(x,y) ((x) > (y) ? (x) : (y))
12 #define DMIN(x,y) ((x) < (y) ? (x) : (y))
13 
14 /*Modified modulus function which deals with negative numbers better*/
15 double modulus(double x, double mod) {
16  if (x >= 0)
17  return fmod(x,mod);
18  else
19  return fmod(x+mod,mod);
20 }
21 
22 #define DSIZE 3
23 
24 static void test_interp(void ** state) {
25  Interp ip;
26  int64_t dims[] = {DSIZE, DSIZE};
27  double ydata[DSIZE][DSIZE], ydata_sum[DSIZE][DSIZE];
28  interp_init(&ip, 2, dims);
29  interp_init_dim(&ip, 0, 0, DSIZE-1);
30  interp_init_dim(&ip, 1, 0, DSIZE-1);
31  /*Initialise the data*/
32  {
33  int i, j;
34  for(i = 0; i < DSIZE; i++) {
35  for(j = 0; j < DSIZE; j++) {
36  ydata[i][j] = fabs((1. - j) * (1. - i));
37  ydata_sum[i][j] = i+j;
38  }
39  }
40  }
41 
42  double i, j;
43  int status[2];
44  for(i = -0.4; i <= DSIZE; i += 0.4) {
45  for(j = -0.4; j <= DSIZE; j += 0.4) {
46  double x[] = {i, j};
47  double y = interp_eval(&ip, x, (double*) ydata, status);
48  assert_true(status[0] == -1*(i < 0) + (i > DSIZE-1));
49  assert_true(status[1] == -1*(j < 0) + (j > DSIZE-1));
50  double yp = interp_eval_periodic (&ip, x, (double*) ydata);
51  /*Note boundaries: without periodic use the maximum, with no remainers.*/
52  double y_truth = fabs((1.-DMAX(DMIN(i,DSIZE-1),0))*(1.-DMAX(DMIN(j,DSIZE-1),0)));
53  /* With a periodic boundary we normally use the modulus. However for this specific case
54  * the boundaries happen to be identical so variation in the bin between them
55  * is ignored by the interpolator and y == yp. This is not true if you increase the range on i.*/
56 /* printf("(%g %g ) %3.2f/%3.2f/%3.2f \n", i,j, y, yp, yp_truth); */
57  assert_true(fabs(y - y_truth) <= 1e-5*y);
58  assert_true(fabs(yp - y_truth) <= 1e-5*yp);
59  }
60  }
61  i=0;
62  for(i = -0.4; i <= 3.0; i += 0.4) {
63  for(j = -0.4; j <= 3.0; j += 0.4) {
64  double x[] = {i, j};
65  double y = interp_eval(&ip, x, (double*) ydata_sum, status);
66  double yp = interp_eval_periodic (&ip, x, (double*) ydata_sum);
67  double y_truth = DMAX(DMIN(i,DSIZE-1),0)+DMAX(DMIN(j,DSIZE-1),0);
68  double yp_truth = modulus(i,DSIZE)+ modulus(j, DSIZE);
69 /* printf("(%g %g ) %3.2f/%3.2f/%3.2f \n", i,j, y, yp, yp_truth); */
70  /*Linear interpolation is very inaccurate outside the boundaries in the periodic case!*/
71  if(i >= 0 && j >= 0 && i <= DSIZE-1 && j <= DSIZE-1)
72  assert_true(fabs(yp - yp_truth) <= 1e-5*yp);
73  assert_true(fabs(y - y_truth) <= 1e-5*y);
74  }
75  }
76  interp_destroy(&ip);
77 }
78 
79 int main(void) {
80  const struct CMUnitTest tests[] = {
81  cmocka_unit_test(test_interp),
82  };
83  return cmocka_run_group_tests_mpi(tests, NULL, NULL);
84 }
double interp_eval(Interp *obj, double *x, double *ydata, int *status)
Definition: interp.c:72
void interp_init(Interp *obj, int Ndim, int64_t *dims)
Definition: interp.c:9
void interp_destroy(Interp *obj)
Definition: interp.c:172
void interp_init_dim(Interp *obj, int d, double Min, double Max)
Definition: interp.c:50
double interp_eval_periodic(Interp *obj, double *x, double *ydata)
Definition: interp.c:134
Definition: interp.h:6
#define DMIN(x, y)
Definition: test_interp.c:12
double modulus(double x, double mod)
Definition: test_interp.c:15
#define DSIZE
Definition: test_interp.c:22
static void test_interp(void **state)
Definition: test_interp.c:24
int main(void)
Definition: test_interp.c:79
#define DMAX(x, y)
Definition: test_interp.c:11