Linuxpops  3.01.04
Spectral Anaysis Package for Single Dish Data
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
interp.c
Go to the documentation of this file.
1 #include "ds_extern.h"
2 
3 /*
4  2d array interpolation routine
5  swiped from Darrel, converted to 'C' by Jeff
6 */
7 
8 
9 /*
10  version 1.0 mpifr cyber edition 22 MAY 1977.
11  see nod 2 manual page m 2.1
12  C.G Haslam mar 1969.
13  This routine interpolates the amplitude z at the point y which lies
14  between the points b and c. y=0.0 corresponds to b and y=1.0
15  corresponds to c. a,b,c,d are the amplitudes at 4 points spaced at
16  unit intervals.
17 */
18 
19 
20 static float yintpn();
21 static int xinterp();
22 
23 
24 static float yintpn(a, b, c, d, y)
25 double a, b, c, d, y;
26 {
27  double e, f, g;
28 
29  if(y == 0.0)
30  return((float)b);
31 
32  e = b-a; /* exact copy case */
33  f = b-c;
34  g = e + f + f + d - c;
35  g = g*y- e - f - g;
36  g = g*y - a + c;
37 
38  return( (float)(0.5*g*y + b));
39 }
40 
41 /*
42  interp interpolates a 2-d array array into parray.
43  uses lots of memory; PC gymnastics deleted
44 */
45 
46 int interp(array, nx, ny, parray, npx, npy )
47 float *array;
48 int nx, ny;
49 float *parray;
50 int npx, npy;
51 {
52  float *one, *two, *three, *four, *save, *done;
53  float *xone, *xtwo, *xthree, *xfour;
54  int k, i, iy;
55  double y, dy, lasty;
56  double oversampy, oversampx, oversamp;
57 
58  one = (float *)malloc( (unsigned)(sizeof(float) * npx));
59  two = (float *)malloc( (unsigned)(sizeof(float) * npx));
60  three = (float *)malloc( (unsigned)(sizeof(float) * npx));
61  four = (float *)malloc( (unsigned)(sizeof(float) * npx));
62 
63  if( !one || !two || !three || !four ) {
64  fprintf( stderr, "no memory for interpolation\n");
65  return(1);
66  }
67 
68  xone = &array[0];
69  xtwo = &array[nx];
70  xthree = &array[nx*2];
71 
72  oversampy = (npy-1.0)/(ny-1.0);
73  oversampx = (npx-1.0)/(nx-1.0);
74  oversamp = oversampx < oversampy ? oversampx:oversampy;
75 
76 /*
77  npx = 1 + (int)rint(oversamp * ((float)nx - 1.0));
78  npy = 1 + (int)rint(oversamp * ((float)ny - 1.0));
79  */
80 
81 /* check that we need to interpolate */
82 
83  if(fabs(oversamp - 1.0) < 0.001 ) {
84  fprintf(stderr,"interpolation not needed - oversamp is %f\n", oversamp );
85  return(0);
86  }
87 
88  xinterp( xone, nx, two, npx );
89  xinterp( xtwo, nx, three, npx );
90  xinterp( xthree, nx, four, npx );
91  lasty = 0;
92 
93 /* create first row by extrapolation */
94 
95  for( i=0; i< npx; i++ )
96  one[i] = two[i] - three[i] + two[i];
97 
98  for( k = 0; k<npy; k++ ) { /* for each new row, interpolate in y */
99 
100  y = (double)k/oversampy;
101  iy = (int)y;
102 
103  if( iy != lasty ) { /* check to see if it is time to move the pointers */
104 
105  save = one;
106  one = two;
107  two = three;
108  three = four;
109  four = save;
110 
111  if( iy+2 < ny ) { /* interpolate along x */
112  xfour = &array[(iy+2)*nx];
113  xinterp( xfour, nx, four, npx );
114  } else { /* otherwize extrapolate */
115  for( i=0; i< npx; i++ )
116  four[i] = three[i] - two[i] + three[i];
117  }
118  lasty = iy;
119  }
120  done = &parray[npx*k];
121  dy = y - (double)iy;
122 
123  for( i=0 ; i<npx; i++ )
124  done[i] = yintpn( one[i], two[i], three[i], four[i], dy );
125  }
126 
127  free((char *)one);
128  free((char *)two);
129  free((char *)three);
130  free((char *)four);
131 
132  return(0);
133 }
134 
135 /*
136  subroutine xinterp interpolates the input array x1 onto the output
137  array x2, with nx2 points, oversampling the input array by oversamp
138 */
139 
140 static int xinterp(x1, nx1, x2, nx2)
141 float *x1;
142 int nx1;
143 float *x2;
144 int nx2;
145 {
146  float oversamp, x, a, b, c, d, dx;
147  int jx, ix, inx;
148 
149  oversamp = (float)(nx2-1)/(float)(nx1-1);
150  for( jx=0; jx<nx2; jx++ ) { /* jx is address of interpolated array */
151  x = jx/oversamp;
152  inx=(int)rint(x);
153  if(fabs(x-(float)inx) < 0.0001)
154  x2[jx]=x1[inx];
155  else {
156  ix= (int)x;
157  dx=x-ix;
158  b=x1[ix];
159  c=x1[ix+1];
160  if(ix > 0)
161  a=x1[ix-1];
162  else
163  a=b-c+b; /* linear extrapolation for first point */
164 
165  if(ix+2 < nx1 )
166  d=x1[ix+2];
167  else
168  d=c-b+c; /* linear extrapolation for last point */
169 
170  x2[jx]= yintpn(a, b, c, d, dx);
171  }
172  }
173 
174  return(0);
175 }
int interp(double *array, int nx, int ny, double *parray, int npx, int npy)
Definition: interp.c:102
int xinterp(double *x1, int nx1, double *x2, int nx2)
Definition: interp.c:206
double yintpn(double a, double b, double c, double d, double y)
Definition: interp.c:79
#define dy(i)
#define dx(i)