MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
Functions
interp.c File Reference
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <math.h>
#include "interp.h"
#include "mymalloc.h"
Include dependency graph for interp.c:

Go to the source code of this file.

Functions

void interp_init (Interp *obj, int Ndim, int64_t *dims)
 
void interp_init_dim (Interp *obj, int d, double Min, double Max)
 
static ptrdiff_t linearindex (ptrdiff_t *strides, int *xi, int Ndim)
 
double interp_eval (Interp *obj, double *x, double *ydata, int *status)
 
double interp_eval_periodic (Interp *obj, double *x, double *ydata)
 
void interp_destroy (Interp *obj)
 

Function Documentation

◆ interp_destroy()

void interp_destroy ( Interp obj)

Definition at line 172 of file interp.c.

172  {
173  myfree(obj->data);
174 }
#define myfree(x)
Definition: mymalloc.h:19
void * data
Definition: interp.h:14

References Interp::data, and myfree.

Referenced by test_interp().

Here is the caller graph for this function:

◆ interp_eval()

double interp_eval ( Interp obj,
double *  x,
double *  ydata,
int *  status 
)

Definition at line 72 of file interp.c.

72  {
73  int d;
74  if(status == NULL) {
75  status = (int *) alloca(sizeof(int) * obj->Ndim);
76  }
77  int * xi = (int *) alloca(sizeof(int) * obj->Ndim);
78  double * f = (double *) alloca(sizeof(double) * obj->Ndim);
79 
80  for(d = 0; d < obj->Ndim; d++) {
81  double xd = (x[d] - obj->Min[d]) / obj->Step[d];
82  if (x[d] < obj->Min[d]) {
83  status[d] = -1;
84  xi[d] = 0;
85  f[d] = 0;
86  } else
87  if (x[d] > obj->Max[d]) {
88  status[d] = 1;
89  xi[d] = obj->dims[d] - 1;
90  f[d] = 0;
91  } else {
92  xi[d] = floor(xd);
93  f[d] = xd - xi[d];
94  status[d] = 0;
95  }
96  }
97 
98  double ret = 0;
99  /* the origin, "this point" */
100  ptrdiff_t l0 = linearindex(obj->strides, xi, obj->Ndim);
101 
102  int i;
103  /* for each point covered by the filter */
104  for(i = 0; i < obj->fsize; i ++) {
105  double filter = 1.0;
106  ptrdiff_t l = l0;
107  int skip = 0;
108  for(d = 0; d < obj->Ndim; d++ ) {
109  int foffset = (i & (1 << d))?1:0;
110  if(f[d] == 0 && foffset == 1) {
111  /* on this dimension the second data point
112  * is not needed */
113  skip = 1;
114  break;
115  }
116 
117  /*
118  * are we on this point or next point?
119  *
120  * weight on next point is f[d]
121  * weight on this point is 1 - f[d]
122  * */
123  filter *= foffset?f[d] : (1 - f[d]);
124  l += foffset * obj->strides[d];
125  }
126  if(!skip) {
127  ret += ydata[l] * filter;
128  }
129  }
130  return ret;
131 }
static ptrdiff_t linearindex(ptrdiff_t *strides, int *xi, int Ndim)
Definition: interp.c:57
int Ndim
Definition: interp.h:7
ptrdiff_t * strides
Definition: interp.h:9
double * Max
Definition: interp.h:12
double * Step
Definition: interp.h:11
int * dims
Definition: interp.h:8
int fsize
Definition: interp.h:15
double * Min
Definition: interp.h:10

References Interp::dims, Interp::fsize, linearindex(), Interp::Max, Interp::Min, Interp::Ndim, Interp::Step, and Interp::strides.

Referenced by TableMetalCoolingRate(), and test_interp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ interp_eval_periodic()

double interp_eval_periodic ( Interp obj,
double *  x,
double *  ydata 
)

Definition at line 134 of file interp.c.

134  {
135  int * xi = (int *) alloca(sizeof(int) * obj->Ndim);
136  int * xi1 = (int *) alloca(sizeof(int) * obj->Ndim);
137  double * f = (double *) alloca(sizeof(double) * obj->Ndim);
138 
139  int d;
140  for(d = 0; d < obj->Ndim; d++) {
141  double xd = (x[d] - obj->Min[d]) / obj->Step[d];
142  xi[d] = floor(xd);
143  f[d] = xd - xi[d];
144  }
145 
146  double ret = 0;
147  /* the origin, "this point" */
148 
149  int i;
150  /* for each point covered by the filter */
151  for(i = 0; i < obj->fsize; i ++) {
152  double filter = 1.0;
153  for(d = 0; d < obj->Ndim; d++ ) {
154  int foffset = (i & (1 << d))?1:0;
155  xi1[d] = xi[d] + foffset;
156  while(xi1[d] >= obj->dims[d]) xi1[d] -= obj->dims[d];
157  while(xi1[d] < 0 ) xi1[d] += obj->dims[d];
158  /*
159  * are we on this point or next point?
160  *
161  * weight on next point is f[d]
162  * weight on this point is 1 - f[d]
163  * */
164  filter *= foffset?f[d] : (1 - f[d]);
165  }
166  ptrdiff_t l = linearindex(obj->strides, xi1, obj->Ndim);
167  ret += ydata[l] * filter;
168  }
169  return ret;
170 }

References Interp::dims, Interp::fsize, linearindex(), Interp::Min, Interp::Ndim, Interp::Step, and Interp::strides.

Referenced by test_interp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ interp_init()

void interp_init ( Interp obj,
int  Ndim,
int64_t *  dims 
)

Definition at line 9 of file interp.c.

9  {
10  ptrdiff_t N = 1;
11  int d;
12  for(d = 0 ; d < Ndim; d ++) {
13  N *= dims[d];
14  }
15 
16  /* alloc memory */
17  obj->Ndim = Ndim;
18  obj->data = mymalloc("interp_data", 0
19  + sizeof(double) * Ndim * 3
20  + sizeof(ptrdiff_t) * Ndim
21  + sizeof(int) * Ndim);
22 
23  obj->dims = (int *) obj->data;
24  obj->strides = (ptrdiff_t*) (obj->dims + Ndim);
25  obj->Min = (double*) (obj->strides + Ndim);
26  obj->Step = obj->Min + Ndim;
27  obj->Max = obj->Step + Ndim;
28 
29  /* fillin strides */
30  N = 1;
31  for(d = Ndim - 1 ; d >= 0; d --) {
32  obj->dims[d] = dims[d];
33  /* column first, C ordering */
34  obj->strides[d] = N;
35  N *= dims[d];
36  }
37 
38  int fsize = 1;
39  for(d = 0; d < obj->Ndim; d++) {
40  fsize *= 2;
41  }
42  obj->fsize = fsize;
43 }
#define mymalloc(name, size)
Definition: mymalloc.h:15

References Interp::data, Interp::dims, Interp::fsize, Interp::Max, Interp::Min, mymalloc, Interp::Ndim, Interp::Step, and Interp::strides.

Referenced by get_local_UVBG(), InitMetalCooling(), and test_interp().

Here is the caller graph for this function:

◆ interp_init_dim()

void interp_init_dim ( Interp obj,
int  d,
double  Min,
double  Max 
)

Definition at line 50 of file interp.c.

50  {
51  obj->Min[d] = Min;
52  obj->Max[d] = Max;
53  obj->Step[d] = (Max - Min) / (obj->dims[d] - 1);
54 }

References Interp::dims, Interp::Max, Interp::Min, and Interp::Step.

Referenced by get_local_UVBG(), InitMetalCooling(), and test_interp().

Here is the caller graph for this function:

◆ linearindex()

static ptrdiff_t linearindex ( ptrdiff_t *  strides,
int *  xi,
int  Ndim 
)
static

Definition at line 57 of file interp.c.

57  {
58  int d;
59  ptrdiff_t rt = 0;
60  for(d = 0; d < Ndim; d++) {
61  rt += strides[d] * xi[d] ;
62  }
63  return rt;
64 }

Referenced by interp_eval(), and interp_eval_periodic().

Here is the caller graph for this function: