OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
numerical.c
Go to the documentation of this file.
1 /* Copyright (C) 2004 Marc Rehmsmeier, Peter Steffen, Matthias Hoechsmann */
2 
3 /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. */
4 
5 /* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */
6 
7 /* You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
8 
9 #include "globals.h"
10 #include "minmax.h"
11 #include "math.h"
12 #include <stdio.h>
13 #include <stdlib.h>
14 
15 int compare_floats(const void *a, const void *b) {
16  const float *da = (const float *) a;
17  const float *db = (const float *) b;
18 
19  return (*da > *db) - (*da < *db);
20 }
21 
22 void ecdf_(float *xcdf, float *ycdf, int32_t *bin_number, float *xs, int32_t *sample_size) {
23  float min_e;
24  float max_e;
25 
26  double bin_width, bin;
27 
28  int k, i;
29 
30  //printf("RJH: In ecdf\n");
31 
32  qsort(xs, *sample_size, sizeof (float), compare_floats);
33 
34  //for (i=0;i<*sample_size;i++) printf("xs[%d]=%f\n",i,xs[i]);
35 
36  // (*bin_number) = min(*sample_size,BINNUMBER);
37  if (*bin_number > *sample_size) *bin_number = *sample_size;
38 
39  if (*bin_number != *sample_size) {
40  min_e = xs[0];
41  max_e = xs[*sample_size - 1];
42 
43  bin_width = fabs(max_e - min_e) / ((float) (*bin_number));
44 
45  k = 0;
46  ycdf[0] = 0.0;
47 
48  bin = xs[0];
49 
50  i = 0;
51 
52  for (k = 1; k <= (*bin_number); k++) {
53  bin = bin + bin_width;
54  xcdf[k - 1] = bin;
55  ycdf[k] = ycdf[k - 1];
56  while (i<*sample_size && xs[i] <= bin) {
57  ycdf[k]++;
58  i++;
59  }
60  }
61 
62  } else {
63  k = 0;
64  ycdf[0] = 0.0;
65 
66  xcdf[0] = xs[0];
67 
68  for (k = 1; k <= (*bin_number); k++) {
69  xcdf[k] = xs[k - 1];
70  ycdf[k] = ycdf[k - 1] + 1;
71  }
72  }
73 
74  for (k = 1; k <= (*bin_number); k++) {
75  // printf("RJH: xcdf=%f ycdf[%d]=%f xs[%d]=%f binwidth=%f sampsize=%d ",xcdf[k],k,ycdf[k],k-1,xs[k-1],bin_width,*sample_size);
76  ycdf[k] /= *sample_size;
77  // printf(" After ycdf[%d]=%f\n",k,ycdf[k]);
78  }
79 }
80 
81 float mean(float *xs, int sample_size) {
82  float sum = 0.0;
83 
84  int k;
85  for (k = 0; k < sample_size; k++)
86  sum += xs[k];
87 
88  return (sum / sample_size);
89 }
90 
91 float variance(float *xs, int sample_size) {
92  float m = mean(xs, sample_size);
93 
94  float sum = 0.0;
95  int k;
96  for (k = 0; k < sample_size; k++)
97  sum += pow(m - xs[k], 2);
98 
99  return (sum / (sample_size - 1));
100 }
101 
102 void linear_regression(float *slope, float *intercept, float *xs, float *ys, int sample_size) {
103  float var, s, sx, sy, sxx, sxy, delta;
104  int k;
105 
106  var = variance(ys, sample_size);
107  s = 0.0;
108  for (k = 0; k < sample_size; k++)
109  s += 1.0 / var;
110  sx = 0.0;
111  for (k = 0; k < sample_size; k++)
112  sx += xs[k] / var;
113  sy = 0.0;
114  for (k = 0; k < sample_size; k++)
115  sy += ys[k] / var;
116  sxx = 0.0;
117  for (k = 0; k < sample_size; k++)
118  sxx += xs[k] * xs[k] / var;
119  sxy = 0.0;
120  for (k = 0; k < sample_size; k++)
121  sxy += xs[k] * ys[k] / var;
122  delta = s * sxx - sx*sx;
123  (*slope) = (s * sxy - sx * sy) / delta;
124  (*intercept) = (sxx * sy - sx * sxy) / delta;
125 }
126 
127 void estimate_evd_parameters(int *used_sample_size, float *xi, float *theta, float *normalised_energies, int sample_size) {
128  float *xcdf, *ycdf;
129  int32_t bin_number;
130  int32_t start, end;
131 
132  /* calculate empirical cdf: */
133  xcdf = (float *) calloc(BINNUMBER, sizeof (float));
134  ycdf = (float *) calloc(BINNUMBER + 1, sizeof (float));
135  ecdf_(xcdf, ycdf, &bin_number, normalised_energies, &sample_size);
136 
137  /* delete values below normalised energy of FITLOWERCUTOFFABSOLUTE: */
138  start = 0;
139 
140  while (start < bin_number && xcdf[start] < FITLOWERCUTOFFABSOLUTE)
141  start++;
142 
143  /* delete top FITUPPERCUTOFFPERCENT values: */
144  end = bin_number * (100.0 - FITUPPERCUTOFFPERCENT) / 100.0 - 1;
145 
146  (*used_sample_size) = end - start + 1;
147 
148  if (end <= start) {
149  (*xi) = 0.0;
150  (*theta) = 0.0;
151  } else {
152  /* do linear regression on log(-log) transformed cdf: */
153  float slope, intercept;
154  int k;
155  for (k = start; k <= end; k++)
156  ycdf[k + 1] = log(-log(ycdf[k + 1]));
157 
158  linear_regression(&slope, &intercept, xcdf + start, ycdf + start + 1, end - start + 1);
159 
160  (*theta) = -1.0 / slope;
161  (*xi) = intercept * (*theta);
162  }
163 
164  free(xcdf);
165  free(ycdf);
166 }
167 
168 
169 #define GOLD 1.618034
170 #define GLIMIT 100.0
171 #define TINY 1.0e-20
172 #define MAX(a,b) ((a) > (b) ? (a) : (b))
173 #define SIGN(a,b) ((b) > 0.0 ? fabs(a) : -fabs(a))
174 #define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d);
175 
176 void mnbrak(float *ax, float *bx, float *cx, float *fa, float *fb, float *fc, float (*func)(float)) {
177  float ulim, u, r, q, fu, dum;
178 
179  *fa = (*func)(*ax);
180  *fb = (*func)(*bx);
181  if (*fb > *fa) {
182  SHFT(dum, *ax, *bx, dum)
183  SHFT(dum, *fb, *fa, dum)
184  }
185  *cx = (*bx) + GOLD * (*bx - *ax);
186  *fc = (*func)(*cx);
187  while (*fb > *fc) {
188  r = (*bx - *ax)*(*fb - *fc);
189  q = (*bx - *cx)*(*fb - *fa);
190  u = (*bx)-((*bx - *cx) * q - (*bx - *ax) * r) /
191  (2.0 * SIGN(MAX(fabs(q - r), TINY), q - r));
192  ulim = (*bx) + GLIMIT * (*cx - *bx);
193  if ((*bx - u)*(u - *cx) > 0.0) {
194  fu = (*func)(u);
195  if (fu < *fc) {
196  *ax = (*bx);
197  *bx = u;
198  *fa = (*fb);
199  *fb = fu;
200  return;
201  } else if (fu > *fb) {
202  *cx = u;
203  *fc = fu;
204  return;
205  }
206  u = (*cx) + GOLD * (*cx - *bx);
207  fu = (*func)(u);
208  } else if ((*cx - u)*(u - ulim) > 0.0) {
209  fu = (*func)(u);
210  if (fu < *fc) {
211  SHFT(*bx, *cx, u, *cx + GOLD * (*cx - *bx))
212  SHFT(*fb, *fc, fu, (*func)(u))
213  }
214  } else if ((u - ulim)*(ulim - *cx) >= 0.0) {
215  u = ulim;
216  fu = (*func)(u);
217  } else {
218  u = (*cx) + GOLD * (*cx - *bx);
219  fu = (*func)(u);
220  }
221  SHFT(*ax, *bx, *cx, u)
222  SHFT(*fa, *fb, *fc, fu)
223  }
224 }
225 
226 
227 #undef GOLD
228 #undef GLIMIT
229 #undef TINY
230 #undef MAX
231 #undef SIGN
232 #undef SHFT
233 
234 #define ITMAX 100
235 #define CGOLD 0.3819660
236 #define ZEPS 1.0e-10
237 #define SIGN(a,b) ((b) > 0.0 ? fabs(a) : -fabs(a))
238 #define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d);
239 
240 float brent(float ax, float bx, float cx, float (*f)(float), float tol, float *xmin) {
241  int iter;
242  float a, b, d, etemp, fu, fv, fw, fx, p, q, r, tol1, tol2, u, v, w, x, xm;
243  float e = 0.0;
244 
245  a = ((ax < cx) ? ax : cx);
246  b = ((ax > cx) ? ax : cx);
247  x = w = v = bx;
248  fw = fv = fx = (*f)(x);
249  for (iter = 1; iter <= ITMAX; iter++) {
250  xm = 0.5 * (a + b);
251  tol2 = 2.0 * (tol1 = tol * fabs(x) + ZEPS);
252  if (fabs(x - xm) <= (tol2 - 0.5 * (b - a))) {
253  *xmin = x;
254  return fx;
255  }
256  if (fabs(e) > tol1) {
257  r = (x - w)*(fx - fv);
258  q = (x - v)*(fx - fw);
259  p = (x - v) * q - (x - w) * r;
260  q = 2.0 * (q - r);
261  if (q > 0.0) p = -p;
262  q = fabs(q);
263  etemp = e;
264  e = d;
265  if (fabs(p) >= fabs(0.5 * q * etemp) || p <= q * (a - x) || p >= q * (b - x))
266  d = CGOLD * (e = (x >= xm ? a - x : b - x));
267  else {
268  d = p / q;
269  u = x + d;
270  if (u - a < tol2 || b - u < tol2)
271  d = SIGN(tol1, xm - x);
272  }
273  } else {
274  d = CGOLD * (e = (x >= xm ? a - x : b - x));
275  }
276  u = (fabs(d) >= tol1 ? x + d : x + SIGN(tol1, d));
277  fu = (*f)(u);
278  if (fu <= fx) {
279  if (u >= x) a = x;
280  else b = x;
281  SHFT(v, w, x, u)
282  SHFT(fv, fw, fx, fu)
283  } else {
284  if (u < x) a = u;
285  else b = u;
286  if (fu <= fw || w == x) {
287  v = w;
288  w = u;
289  fv = fw;
290  fw = fu;
291  } else if (fu <= fv || v == x || v == w) {
292  v = u;
293  fv = fu;
294  }
295  }
296  }
297  printf("Too many iterations in BRENT\n");
298  *xmin = x;
299  return fx;
300 }
301 
302 
303 #undef ITMAX
304 #undef CGOLD
305 #undef ZEPS
306 #undef SIGN
data_t q
Definition: decode_rs.h:74
int r
Definition: decode_rs.h:73
#define GOLD
Definition: numerical.c:169
#define SHFT(a, b, c, d)
Definition: numerical.c:238
#define CGOLD
Definition: numerical.c:235
float mean(float *xs, int sample_size)
Definition: numerical.c:81
void mnbrak(float *ax, float *bx, float *cx, float *fa, float *fb, float *fc, float(*func)(float))
Definition: numerical.c:176
float brent(float ax, float bx, float cx, float(*f)(float), float tol, float *xmin)
Definition: numerical.c:240
float variance(float *xs, int sample_size)
Definition: numerical.c:91
#define MAX(a, b)
Definition: numerical.c:172
double precision function f(R1)
Definition: tmd.lp.f:1454
int compare_floats(const void *a, const void *b)
Definition: numerical.c:15
#define SIGN(a, b)
Definition: numerical.c:237
subroutine func(x, conec, n, bconecno, bn, units, u, inno, i, outno, o, Input, Targ, p, sqerr)
Definition: ffnet.f:287
float32 slope[]
Definition: l2lists.h:30
#define ITMAX
Definition: numerical.c:234
float tol
const double delta
#define TINY
Definition: numerical.c:171
float32 intercept[]
Definition: l2lists.h:44
#define BINNUMBER
Definition: globals.h:33
data_t b[NROOTS+1]
Definition: decode_rs.h:77
#define FITUPPERCUTOFFPERCENT
Definition: globals.h:35
data_t u
Definition: decode_rs.h:74
#define fabs(a)
Definition: misc.h:93
#define GLIMIT
Definition: numerical.c:170
#define FITLOWERCUTOFFABSOLUTE
Definition: globals.h:34
data_t s[NROOTS]
Definition: decode_rs.h:75
#define ZEPS
Definition: numerical.c:236
void ecdf_(float *xcdf, float *ycdf, int32_t *bin_number, float *xs, int32_t *sample_size)
Definition: numerical.c:22
int i
Definition: decode_rs.h:71
PGE01 indicating that PGE02 PGE01 V6 for and PGE01 V2 for MOD03 were used to produce the granule By convention adopted in all MODIS Terra PGE02 code versions are The fourth digit of the PGE02 version denotes the LUT version used to produce the granule The source of the metadata environment variable ProcessingCenter was changed from a QA LUT value to the Process Configuration A sign used in error in the second order term was changed to a
Definition: HISTORY.txt:424
int k
Definition: decode_rs.h:73
void estimate_evd_parameters(int *used_sample_size, float *xi, float *theta, float *normalised_energies, int sample_size)
Definition: numerical.c:127
float p[MODELMAX]
Definition: atrem_corl1.h:131
void linear_regression(float *slope, float *intercept, float *xs, float *ys, int sample_size)
Definition: numerical.c:102