22 |
|
|
23 |
|
#define RSCA 2.7 /* radius scaling factor (empirical) */ |
24 |
|
|
25 |
< |
#define R2ANG(c) (((c)+.5)*(M_PI/(1<<16))) |
25 |
> |
/* convert to/from coded radians */ |
26 |
|
#define ANG2R(r) (int)((r)*((1<<16)/M_PI)) |
27 |
+ |
#define R2ANG(c) (((c)+.5)*(M_PI/(1<<16))) |
28 |
|
|
29 |
|
typedef struct { |
30 |
|
float vsum; /* DSF sum */ |
38 |
|
unsigned char gx, gy; /* grid position */ |
39 |
|
} RBFVAL; /* radial basis function value */ |
40 |
|
|
41 |
< |
typedef struct s_rbflist { |
42 |
< |
struct s_rbflist *next; /* next in our RBF list */ |
41 |
> |
struct s_rbfnode; /* forward declaration of RBF struct */ |
42 |
> |
|
43 |
> |
typedef struct s_migration { |
44 |
> |
struct s_migration *next; /* next in global edge list */ |
45 |
> |
struct s_rbfnode *rbfv[2]; /* from,to vertex */ |
46 |
> |
struct s_migration *enxt[2]; /* next from,to sibling */ |
47 |
> |
float mtx[1]; /* matrix (extends struct) */ |
48 |
> |
} MIGRATION; /* migration link (winged edge structure) */ |
49 |
> |
|
50 |
> |
typedef struct s_rbfnode { |
51 |
> |
struct s_rbfnode *next; /* next in global RBF list */ |
52 |
> |
MIGRATION *ejl; /* edge list for this vertex */ |
53 |
|
FVECT invec; /* incident vector direction */ |
54 |
|
int nrbf; /* number of RBFs */ |
55 |
|
RBFVAL rbfa[1]; /* RBF array (extends struct) */ |
60 |
|
static GRIDVAL dsf_grid[GRIDRES][GRIDRES]; |
61 |
|
|
62 |
|
/* processed incident DSF measurements */ |
63 |
< |
static RBFLIST *dsf_list = NULL; |
63 |
> |
static RBFLIST *dsf_list = NULL; |
64 |
|
|
65 |
+ |
/* edge (linking) matrices */ |
66 |
+ |
static MIGRATION *mig_list = NULL; |
67 |
+ |
|
68 |
+ |
#define mtxval(m,i,j) (m)->mtx[(i)*(m)->rbfv[1]->nrbf+(j)] |
69 |
+ |
#define nextedge(rbf,m) (m)->enxt[(rbf)==(m)->rbfv[1]] |
70 |
+ |
|
71 |
|
/* Compute outgoing vector from grid position */ |
72 |
|
static void |
73 |
|
vec_from_pos(FVECT vec, int xpos, int ypos) |
122 |
|
static RBFLIST * |
123 |
|
make_rbfrep(void) |
124 |
|
{ |
125 |
< |
int niter = 6; |
125 |
> |
int niter = 16; |
126 |
> |
double lastVar, thisVar = 100.; |
127 |
|
int nn; |
128 |
|
RBFLIST *newnode; |
129 |
|
int i, j; |
131 |
|
nn = 0; /* count selected bins */ |
132 |
|
for (i = 0; i < GRIDRES; i++) |
133 |
|
for (j = 0; j < GRIDRES; j++) |
134 |
< |
nn += (dsf_grid[i][j].nval > 0); |
134 |
> |
nn += dsf_grid[i][j].nval; |
135 |
|
/* allocate RBF array */ |
136 |
|
newnode = (RBFLIST *)malloc(sizeof(RBFLIST) + sizeof(RBFVAL)*(nn-1)); |
137 |
|
if (newnode == NULL) { |
139 |
|
exit(1); |
140 |
|
} |
141 |
|
newnode->next = NULL; |
142 |
+ |
newnode->ejl = NULL; |
143 |
|
newnode->invec[2] = sin(M_PI/180.*theta_in_deg); |
144 |
|
newnode->invec[0] = cos(M_PI/180.*phi_in_deg)*newnode->invec[2]; |
145 |
|
newnode->invec[1] = sin(M_PI/180.*phi_in_deg)*newnode->invec[2]; |
149 |
|
for (i = 0; i < GRIDRES; i++) |
150 |
|
for (j = 0; j < GRIDRES; j++) |
151 |
|
if (dsf_grid[i][j].nval) { |
152 |
< |
newnode->rbfa[nn].peak = |
134 |
< |
dsf_grid[i][j].vsum /= |
135 |
< |
(double)dsf_grid[i][j].nval; |
136 |
< |
dsf_grid[i][j].nval = 1; |
152 |
> |
newnode->rbfa[nn].peak = dsf_grid[i][j].vsum; |
153 |
|
newnode->rbfa[nn].crad = RSCA*dsf_grid[i][j].crad + .5; |
154 |
|
newnode->rbfa[nn].gx = i; |
155 |
|
newnode->rbfa[nn].gy = j; |
156 |
|
++nn; |
157 |
|
} |
158 |
< |
/* iterate for better convergence */ |
159 |
< |
while (niter--) { |
158 |
> |
/* iterate to improve interpolation accuracy */ |
159 |
> |
do { |
160 |
|
double dsum = .0, dsum2 = .0; |
161 |
|
nn = 0; |
162 |
|
for (i = 0; i < GRIDRES; i++) |
163 |
|
for (j = 0; j < GRIDRES; j++) |
164 |
|
if (dsf_grid[i][j].nval) { |
165 |
|
FVECT odir; |
166 |
< |
/* double corr; */ |
166 |
> |
double corr; |
167 |
|
vec_from_pos(odir, i, j); |
168 |
< |
newnode->rbfa[nn++].peak *= /* corr = */ |
168 |
> |
newnode->rbfa[nn++].peak *= corr = |
169 |
|
dsf_grid[i][j].vsum / |
170 |
|
eval_rbfrep(newnode, odir); |
155 |
– |
/* |
171 |
|
dsum += corr - 1.; |
172 |
|
dsum2 += (corr-1.)*(corr-1.); |
158 |
– |
*/ |
173 |
|
} |
174 |
+ |
lastVar = thisVar; |
175 |
+ |
thisVar = dsum2/(double)nn; |
176 |
|
/* |
177 |
|
fprintf(stderr, "Avg., RMS error: %.1f%% %.1f%%\n", |
178 |
|
100.*dsum/(double)nn, |
179 |
< |
100.*sqrt(dsum2/(double)nn)); |
179 |
> |
100.*sqrt(thisVar)); |
180 |
|
*/ |
181 |
< |
} |
181 |
> |
} while (--niter > 0 && lastVar-thisVar > 0.02*lastVar); |
182 |
> |
|
183 |
|
newnode->next = dsf_list; |
184 |
|
return(dsf_list = newnode); |
185 |
|
} |
327 |
|
} |
328 |
|
} |
329 |
|
} |
330 |
< |
/* copy back averaged radii */ |
330 |
> |
/* copy back blurred radii */ |
331 |
|
for (i = 0; i < GRIDRES; i++) |
332 |
|
for (j = 0; j < GRIDRES; j++) |
333 |
|
if (fill_cnt[i][j]) |
334 |
|
dsf_grid[i][j].crad = fill_grid[i][j]/fill_cnt[i][j]; |
335 |
|
} |
336 |
|
|
337 |
< |
/* Cull points for more uniform distribution */ |
337 |
> |
/* Cull points for more uniform distribution, leave all nval 0 or 1 */ |
338 |
|
static void |
339 |
|
cull_values(void) |
340 |
|
{ |
371 |
|
dsf_grid[i][j].vsum += dsf_grid[ii][jj].vsum; |
372 |
|
dsf_grid[i][j].nval += dsf_grid[ii][jj].nval; |
373 |
|
/* keep value, though */ |
374 |
< |
dsf_grid[ii][jj].vsum /= (double)dsf_grid[ii][jj].nval; |
374 |
> |
dsf_grid[ii][jj].vsum /= (float)dsf_grid[ii][jj].nval; |
375 |
|
dsf_grid[ii][jj].nval = 0; |
376 |
|
} |
377 |
|
} |
378 |
|
} |
379 |
+ |
/* final averaging pass */ |
380 |
+ |
for (i = 0; i < GRIDRES; i++) |
381 |
+ |
for (j = 0; j < GRIDRES; j++) |
382 |
+ |
if (dsf_grid[i][j].nval > 1) { |
383 |
+ |
dsf_grid[i][j].vsum /= (float)dsf_grid[i][j].nval; |
384 |
+ |
dsf_grid[i][j].nval = 1; |
385 |
+ |
} |
386 |
|
} |
387 |
|
|
388 |
|
|