00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "stack-c.h"
00010 #include <math.h>
00011
00012 enum {NOT_A_KNOT, NATURAL, CLAMPED, PERIODIC, FAST, FAST_PERIODIC,
00013 MONOTONE, BY_ZERO, C0, LINEAR, BY_NAN};
00014
00015 #ifdef _MSC_VER
00016 extern int C2F(isanan)();
00017 extern double C2F(returnanan)();
00018 #endif
00019
00020 static int isearch(double t, double x[], int n)
00021 {
00022
00023
00024
00025
00026
00027
00028
00029
00030 int i1, i2, i;
00031 if ( x[0] <= t && t <= x[n-1] )
00032 {
00033 i1 = 0; i2 = n-1;
00034 while ( i2 - i1 > 1 )
00035 {
00036 i = (i1 + i2)/2;
00037 if ( t <= x[i] )
00038 i2 = i;
00039 else
00040 i1 = i;
00041 }
00042 return (i1);
00043 }
00044 else
00045 return (-1);
00046 }
00047
00048 static void fast_int_search(double xx, double x[], int nx, int *i)
00049 {
00050 if ( *i == -1 )
00051 *i = isearch(xx, x, nx);
00052 else if ( ! (x[*i] <= xx && xx <= x[*i+1]) )
00053 *i = isearch(xx, x, nx);
00054 }
00055
00056
00057 static void coord_by_periodicity(double *t, double x[], int n, int *i)
00058 {
00059
00060
00061
00062
00063
00064 double r, L;
00065 L = x[n-1] - x[0];
00066 r = (*t - x[0]) / L;
00067 if (r >= 0.0)
00068 *t = x[0] + (r - floor(r))*L;
00069 else
00070 *t = x[n-1] + (r - ceil(r))*L;
00071
00072
00073 if (*t < x[0])
00074 {
00075 *t = x[0];
00076 *i = 0;
00077 }
00078 else if (*t > x[n-1])
00079 {
00080 *t = x[n-1];
00081 *i = n-2;
00082 }
00083 else
00084 *i = isearch(*t, x, n);
00085 }
00086 void nlinear_interp(double **x , double val[], int dim[], int n,
00087 double **xp, double yp[], int np, int outmode,
00088 double u[], double v[], int ad[], int k[])
00089 {
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 int i, j, l, p, temp, b, two_p_n;
00116 double xx;
00117
00118
00119
00120
00121
00122 ad[0] = 0; ad[1] = 1;
00123 temp = 1 ; p = 1;
00124 for ( j = 0; j < n-1; j++)
00125 {
00126 temp = temp * dim[j];
00127 p = 2*p;
00128 for ( i = 0; i < p; i++ )
00129 ad[p+i] = ad[i] + temp;
00130 };
00131
00132 two_p_n = 2*p;
00133
00134
00135 for ( j = 0; j < n; j++ ) k[j] = -1;
00136
00137 for ( i = 0; i < np; i++ )
00138 {
00139
00140
00141
00142 for ( j = 0; j < n; j++ )
00143 {
00144 xx = xp[j][i];
00145 if ( C2F(isanan)(&xx) )
00146 {
00147 v[0] = C2F(returnanan)(); goto fin;
00148 }
00149 fast_int_search(xx, x[j], dim[j], &(k[j]));
00150 if ( k[j] == -1 )
00151 switch (outmode)
00152 {
00153 case BY_NAN :
00154 v[0] = C2F(returnanan)();
00155 goto fin;
00156
00157 case BY_ZERO :
00158 v[0] = 0.0;
00159 goto fin;
00160
00161 case NATURAL :
00162 if (xx < x[j][0])
00163 k[j] = 0;
00164 else
00165 k[j] = dim[j]-2;
00166 break;
00167
00168 case C0 :
00169 if (xx < x[j][0])
00170 {
00171 u[j] = 0.0; k[j] = 0;
00172 }
00173 else
00174 {
00175 u[j] = 1.0; k[j] = dim[j]-2;
00176 }
00177 continue;
00178
00179 case PERIODIC :
00180 coord_by_periodicity(&xx, x[j], dim[j], &(k[j]));
00181 break;
00182
00183 }
00184 u[j] = (xx - x[j][k[j]])/( x[j][k[j]+1] - x[j][k[j]]);
00185 }
00186
00187
00188 b = k[n-1];
00189 for ( j = n-2; j >= 0; j-- )
00190 b = k[j] + dim[j]*b;
00191
00192
00193 for ( j = 0; j < two_p_n; j++ )
00194 v[j] = val[b + ad[j]];
00195
00196
00197 temp = 1; p = two_p_n;
00198 for ( j = 0; j < n ; j++ )
00199 {
00200 for ( l = 0; l < two_p_n; l+=2*temp)
00201 {
00202 v[l] = v[l]*(1.0 - u[j]) + v[l+temp]*u[j];
00203 }
00204 p = p/2;
00205 temp = 2*temp;
00206 }
00207
00208
00209 fin:
00210 yp[i] = v[0];
00211
00212 }
00213 }
00214
00215
00216
00217
00218
00219
00220
00221