HARM
harm and utilities
 All Data Structures Files Functions Variables Typedefs Macros Pages
math.tools.c
Go to the documentation of this file.
1 
7 #include "decs.h"
8 
9 
10 #define DO_ASSERTS 0 // similar parameter as in some init.h's
11 
20 FTYPE interpn( int order, FTYPE x_eval, FTYPE x1, FTYPE f1, FTYPE x2, FTYPE f2, FTYPE x3, FTYPE f3, FTYPE x4, FTYPE f4, FTYPE x5, FTYPE f5, FTYPE x6, FTYPE f6 )
21 {
22  int i, j; //iterator through the abscissa points
23 #define max_interp_order 6 //should be equal to the number of points input to the function; degree of interpolation is only limited by the number of arguments to the function --
24  //so increase that number if require a higher order; also, modify the definitions of x[] and f[] to include the added arguments
25 
26  FTYPE f_eval = 0.0; //interpolated value to be returned
27  FTYPE x[] = { x1, x2, x3, x4, x5, x6};
28  FTYPE f[] = { f1, f2, f3, f4, f5, f6};
29  FTYPE x_a, x_b; //temporary variables
30  FTYPE delta_f_eval;
31 
32  if( order < 1 || order > max_interp_order) {
33  trifprintf( "interpn: requested order of interpolation non-positive or too high.\n" );
34  myexit( 1 );
35  }
36 
37  //test if the supplied x-values are valid: there should be no identical values
38 #if(DO_ASSERTS)
39  for( i = 1; i < order; i++ ) {
40  for( j = 0; j < i; j++ ) {
41  if( x[i] - x[j] == 0.0 ) {
42  fprintf( stderr, "interpn: abscissas of values to be interpolated are to be all different\n" );
43  return 0.;
44  }
45  }
46  }
47 #endif
48 
49  for( i = 0; i < order; i++ ) {
50  //construct a polynomial that would be equal to f[i] at x[i] and equal to 0 at other x-points ( x[(i + j) % order], j = 1..order )
51  x_a = x[i];
52  delta_f_eval = f[i];
53 
54  for( j = 1; j < order; j++ ) {
55  x_b = x[(i + j) % order];
56  delta_f_eval *= (x_eval - x_b) / (x_a - x_b);
57  }
58 
59  //add up the value of this polynomial at x = x_eval to the final result
60  f_eval += delta_f_eval;
61 
62  }
63 
64  return f_eval;
65 }
66 
67 
68 
69 
70 
71 
73 FTYPE roundprecision(FTYPE value, int precision)
74 {
75  FTYPE fraction,
76  temp;
77 
78 
79  value = value*pow(10, precision);
80 
81  fraction = modf(value, &temp);
82  if(fraction>=0.5) temp+=1.0;
83  if(fraction<=-0.5) temp-=1.0;
84 
85  return temp*pow(0.1, precision);
86 }
87 
88 
91 void interpfun(int interptype, int numpoints, int i, FTYPE pos, FTYPE *xfun, FTYPE *fun, FTYPE *answer)
92 {
93  FTYPE slope,intercept;
94  FTYPE slope1,slope2,xminusx0;
95  FTYPE f0,f1,f2,x0,x1,x2;
96  FTYPE linslope1,linslope2;
97 
98 
100  //
101  // First setup points to use. Restrict if near edge of data
102  //
104  if(interptype==LINEARTYPE || interptype==LOGTYPE){
105  if(i-1<0){
106  f0=fun[i];
107  f1=fun[i+1];
108  x0=xfun[i];
109  x1=xfun[i+1];
110  }
111  else if(i+1>=numpoints){
112  f0=fun[i-1];
113  f1=fun[i];
114  x0=xfun[i-1];
115  x1=xfun[i];
116  }
117  else{
118  f0=fun[i-1];
119  f1=fun[i];
120  x0=xfun[i-1];
121  x1=xfun[i];
122  }
123  }
124  else if(interptype==QUADRATICTYPE){
125 
126  // quadratically interpolate fun using xfun
127  if(i-1<0){
128  f0=fun[i];
129  f1=fun[i+1];
130  f2=fun[i+2];
131  x0=xfun[i];
132  x1=xfun[i+1];
133  x2=xfun[i+2];
134  }
135  else if(i+1>=numpoints){
136  f0=fun[i-2];
137  f1=fun[i-1];
138  f2=fun[i];
139  x0=xfun[i-2];
140  x1=xfun[i-1];
141  x2=xfun[i];
142  }
143  else{
144  f0=fun[i-1];
145  f1=fun[i];
146  f2=fun[i+1];
147  x0=xfun[i-1];
148  x1=xfun[i];
149  x2=xfun[i+1];
150  }
151  }
152 
153 
155  //
156  // Interpolate
157  //
159 
160 
162  // LINEAR
164  if(interptype==LINEARTYPE){
165  // linearly interpolate fun using pos
166  slope = (f1-f0)/(x1-x0);
167  intercept = f0;
168  *answer = slope*(pos-x0) + intercept;
169  }
171  // Quadratic with limiters
173  else if(interptype==QUADRATICTYPE){
174 
175  slope2 = ((f0-f2)/(x0-x2) - (f2-f1)/(x2-x1))/(x0-x1);
176  slope1 = (f0-f1)/(x0-x1) + (f0-f2)/(x0-x2) - (f2-f1)/(x2-x1);
177 
178  linslope1=(f1-f0)/(x1-x0);
179  linslope2=(f2-f1)/(x2-x1);
180 
181  // MINM truncation:
182  if(linslope1*linslope2<0.0){
183 #if(0)
184  if(pos<=x0){
185  *answer=f0;
186  }
187  else if(pos>=x0 && pos<=x1){
188  if(fabs(pos-x0)<fabs(pos-x1)) *answer=f0;
189  else *answer=f1;
190  }
191  else if(pos>=x1 && pos<=x2){
192  if(fabs(pos-x1)<fabs(pos-x2)) *answer=f1;
193  else *answer=f2;
194  }
195  else *answer=f2;
196 #elif(1)
197  if(fabs(linslope1)<fabs(linslope2)){
198  slope = (f1-f0)/(x1-x0);
199  intercept = f0;
200  *answer = slope*(pos-x0) + intercept;
201  }
202  else{
203  slope = (f2-f1)/(x2-x1);
204  intercept = f1;
205  *answer = slope*(pos-x1) + intercept;
206  }
207 #elif(0)
208  *answer=f1;
209 #endif
210  }
211  else{
212  xminusx0 = (pos-x0);
213  *answer = slope2*pow(xminusx0,2.0) + slope1*xminusx0 + f0;
214  }
215 
216 #if(1)
217  // limit to original values' ranges
218  if(*answer>f0 && *answer>f1 && *answer>f2){
219  if(f0>f1 && f0>f2){
220  *answer=f0;
221  }
222  else if(f1>f0 && f1>f2){
223  *answer=f1;
224  }
225  else if(f2>f0 && f2>f1){
226  *answer=f2;
227  }
228  }
229  else if(*answer<f0 && *answer<f1 && *answer<f2){
230  if(f0<f1 && f0<f2){
231  *answer=f0;
232  }
233  else if(f1<f0 && f1<f2){
234  *answer=f1;
235  }
236  else if(f2<f0 && f2<f1){
237  *answer=f2;
238  }
239  }
240 #endif
241 
242  }
244  // Linear in Log
246  else if(interptype==LOGTYPE){
247  // log interpolate fun using xfun
248  slope = log(f1/f0)/log(x1/f0);
249  if(fabs(slope)<1E-10) *answer=f1;
250  else if(f0<0.0){
251  // assume bi-log
252  *answer=-exp( slope*log(pos/x0)+log(-f0) );
253  }
254  else *answer=exp( slope*log(pos/x0)+log(f0) );
255 
256  //dualfprintf(fail_file,"ii=%d jj=%d slope=%g myXfun=%g\n",ii,jj,slope,myXfun);
257  }
258 
259 
260 
261 }
262 
263 
264 
265