NASA Logo
Ocean Color Science Software

ocssw V2022
int_3d.c
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include "l12_proto.h"
4 #include "l2prod.h"
5 #include "l1.h"
6 #include "get_ctht.h"
7 
8 /*
9  file int_3d.c, get index and weights to do a 4-d interpolation
10 */
11 int32_t int_3d( float *sxax[3], int32_t snax[3], int64_t n_block, float x[3],
12  int64_t ar_off[9], float ar_wt[9], float orig_wt[3] )
13 
14  /*
15  int_3d - get index and weights to do a 4-d interpolation
16 
17  Returns, int32_t status 0 is good 1 - outside range
18 
19  Parameters: (in calling order)
20  Type Name I/O Description
21  ---- ---- --- -----------
22  float *[3] sxax I array of pointers to each
23  dimension axis
24  int32_t [3] snax I size of each axis
25  int64_t n_block I size of all dimensions before
26  the ones here being used
27  float [3] x I value of point on each axis
28  int64_t [9] ar_off O linear offset to each corner pt
29  float [9] ar_wt O weight for each corner pt
30  float [3] orig_wt O the weights from the low point
31 
32  the multi-dim array, sxax, has dims [ snax[0],... snax[2] ] with a the
33  combination of the fastest dimensions Based on x's position in each
34  sxax axis, there will be a index in each axis of the start point for
35  the interpolation and also a fraction of the distance to the next
36  point. That is converted into a linear position and multiplied by a
37  to properly index the data for the offset and to a combined weight
38  to apply to all 16 corner points
39 
40  W. Robinson, SAIC, 22 Aug 2023
41 
42 */
43  {
44  int32_t ndim = 3, base_ix[3];
45  int32_t idim, idim0, idim1, idim2;
46  int32_t int_off0, int_off1, int_off2;
47  int64_t base_off, ixoff;
48  float int_wt0, int_wt1, int_wt2;
49  float base, frac_ix[3], delta[3], bounds[2];
50 
51  for( idim = 0; idim < ndim; idim++ )
52  {
53  // check for bounds violation
54  if( sxax[idim][0] < sxax[idim][snax[idim]-1] )
55  {
56  bounds[0] = sxax[idim][0];
57  bounds[1] = sxax[idim][snax[idim]-1];
58  }
59  else
60  {
61  bounds[0] = sxax[idim][snax[idim]-1];
62  bounds[1] = sxax[idim][0];
63  }
64  if( ( x[idim] < bounds[0] ) || ( x[idim] > bounds[1] ) )
65  {
66  printf( "%s - %d: E: a point is outside table bounds\n", __FILE__,
67  __LINE__ );
68  exit(1);
69  }
70  // assume equal steps, as Andy does (should be more flexible)
71  delta[idim] = sxax[idim][1] - sxax[idim][0];
72  base = ( x[idim] - sxax[idim][0] ) / delta[idim];
73  // *** for Andy's sol zen, it starts at 0.001 so I'll make it 0
74  // to match what he does FOR NOW
75  if( idim == 1 ) {
76  delta[idim] = sxax[idim][2] - sxax[idim][1];
77  base = x[idim] / delta[idim];
78  }
79  base_ix[idim] = (int32_t) base;
80  frac_ix[idim] = fmod( (double)base, 1. );
81  orig_wt[idim] = frac_ix[idim];
82  }
83  // get offset from 0 to base indicies
84  base_off = base_ix[0] + snax[0] * ( base_ix[1] + snax[1] * base_ix[2] );
85  /*
86  * compile the locations of corners and weights here
87  */
88  ixoff = 0;
89  for( idim0 = 0; idim0 < 2; idim0++ )
90  {
91  int_wt0 = ( idim0 == 0 ) ? 1 - frac_ix[0] : frac_ix[0];
92  int_off0 = ( idim0 == 0 ) ? 0 : 1;
93  for( idim1 = 0; idim1 < 2; idim1++ )
94  {
95  int_wt1 = ( idim1 == 0 ) ? 1 - frac_ix[1] : frac_ix[1];
96  int_off1 = int_off0 + ( ( idim1 == 0 ) ? 0 : snax[0] );
97  for( idim2 = 0; idim2 < 2; idim2++ )
98  {
99  int_wt2 = ( idim2 == 0 ) ? 1 - frac_ix[2] : frac_ix[2];
100  int_off2 = int_off1 + ( ( idim2 == 0 ) ? 0 : snax[0] * snax[1] );
101  ar_off[ixoff] = n_block * ( base_off + int_off2 );
102  ar_wt[ixoff++] = int_wt2 * int_wt1 * int_wt0;
103  }
104  }
105  }
106  return 0;
107  }
float32 base
Definition: maplists.h:106
dictionary bounds
const double delta
int32_t int_3d(float *sxax[3], int32_t snax[3], int64_t n_block, float x[3], int64_t ar_off[9], float ar_wt[9], float orig_wt[3])
Definition: int_3d.c:11