]> www.wagner.pp.ru Git - oss/fgis.git/blob - epu/outtable_func.c
First checked in version
[oss/fgis.git] / epu / outtable_func.c
1 #include "outtable.h"
2 #include <limits.h>
3 #include <math.h>
4 /* Data structures for functions */
5 typedef struct n_info {
6        int count;
7        int value;
8       } n_info;
9 /* Sum of the all cells in combination */
10 double OuttableSum(FuncAction action, FuncData data, struct record *record,
11                 int index)
12 { struct n_info *info=(struct n_info *)data;
13   switch (action) {
14      case FuncInit:
15          info->value=0;
16          info->count=0;
17          return 0;
18      case FuncIterate:
19          if (record->classes[index]!=fileinfo[index]->offsite) {
20              info->value+=record->classes[index]*record->count;
21              info->count+=record->count;
22          }
23          return 0;
24      case FuncResult:
25          return zUnit*info->value+zOffset*info->count;
26   
27   }
28   return 0;
29 }
30    
31 /* Count of the non-offsite cells for given file in combination */
32 double OuttableCount(FuncAction action, FuncData data, struct record *record,
33                 int index)
34 { int *sum=(int *)data;
35   switch (action) {
36      case FuncInit:
37          *sum=0;
38          return 0;
39      case FuncIterate:
40          if (record->classes[index]!=fileinfo[index]->offsite)
41              *sum+=record->count;
42          return 0;
43      case FuncResult:
44          return *sum*cellArea;
45   
46   }
47   return 0;
48 }
49 /* Average of the all cells in combination */
50 struct avg_info {
51       long sum;
52       int count;
53       };
54 double OuttableAvg(FuncAction action, FuncData data, struct record *record,
55                 int index)
56 { struct avg_info *info=(struct avg_info *)data;
57   switch (action) {
58      case FuncInit:
59          info->sum=0;
60          info->count=0;
61          return 0;
62      case FuncIterate:
63          if (record->classes[index]!=fileinfo[index]->offsite) {
64              info->sum+=record->classes[index]*record->count;
65              info->count+=record->count;
66          }
67          return 0;
68      case FuncResult:
69          if (info->count)
70             return (zUnit*info->sum/info->count)+zOffset;
71          else return 0;
72   
73   }
74   return 0;
75 }
76 /* Minimal cell value  in combination */
77 double OuttableMin(FuncAction action, FuncData data, struct record *record,
78                 int index)
79 { int *min=(int *)data;
80   switch (action) {
81      case FuncInit:
82          *min=65536;
83          return 0;
84      case FuncIterate:
85          if (record->classes[index]!=fileinfo[index]->offsite &&
86              record->classes[index]<*min)
87              *min=record->classes[index];
88          return 0;
89      case FuncResult:
90          return *min*zUnit+zOffset;
91   
92   }
93   return 0;
94 }
95
96 /* Count of cell with minimal  value  in combination */
97 double OuttableNMin(FuncAction action, FuncData data, struct record *record,
98                 int index)
99 { struct n_info *info=(n_info *)data;
100   switch (action) {
101      case FuncInit:
102          info->value=65536;
103          info->count=0;
104          return 0;
105      case FuncIterate:
106          if (record->classes[index]!=fileinfo[index]->offsite &&
107              record->classes[index]<info->value) {
108                info->value=record->classes[index];
109                info->count=record->count;
110              }
111          return 0;
112      case FuncResult:
113          return info->count*cellArea;
114   
115   }
116   return 0;
117 }
118
119 /* Maximal cell value  in combination */
120 double OuttableMax(FuncAction action, FuncData data, struct record *record,
121                 int index)
122 { int *max=(int *)data;
123   switch (action) {
124      case FuncInit:
125          *max=-1;
126          return 0;
127      case FuncIterate:
128          if (record->classes[index]!=fileinfo[index]->offsite &&
129              record->classes[index]>*max)
130              *max=record->classes[index];
131          return 0;
132      case FuncResult:
133          return *max*zUnit+zOffset;
134   
135   }
136   return 0;
137 }
138
139 /* Count of cell with maximal  value  in combination */
140 double OuttableNMax(FuncAction action, FuncData data, struct record *record,
141                 int index)
142 { struct n_info *info=(n_info *)data;
143   switch (action) {
144      case FuncInit:
145          info->value=-1;
146          info->count=0;
147          return 0;
148      case FuncIterate:
149          if (record->classes[index]!=fileinfo[index]->offsite &&
150              record->classes[index]>info->value) {
151                info->value=record->classes[index];
152                info->count=record->count;
153              }
154          return 0;
155      case FuncResult:
156          return info->count*cellArea;
157   
158   }
159   return 0;
160 }
161 /* Count of cells with most frequent value  in combination */
162 double OuttableNMode(FuncAction action, FuncData data, struct record *record,
163                 int index)
164 { int *max=(int *)data;
165   switch (action) {
166      case FuncInit:
167          *max=-1;
168          return 0;
169      case FuncIterate:
170          if (record->classes[index]!=fileinfo[index]->offsite &&
171              record->count>*max)
172              *max=record->count;
173          return 0;
174      case FuncResult:
175          return *max*cellArea;
176   
177   }
178   return 0;
179 }
180
181 /* Most frequent cell value  in combination */
182 double OuttableMode(FuncAction action, FuncData data, struct record *record,
183                 int index)
184 { struct n_info *info=(n_info *)data;
185   switch (action) {
186      case FuncInit:
187          info->value=-1;
188          info->count=0;
189          return 0;
190      case FuncIterate:
191          if (record->classes[index]!=fileinfo[index]->offsite &&
192              record->count>info->count) {
193                info->value=record->classes[index];
194                info->count=record->count;
195              }
196          return 0;
197      case FuncResult:
198          return info->value*zUnit+zOffset;
199   
200   }
201   return 0;
202 }
203 /* Count of cells with rarest value in combination */
204 double OuttableNFewest(FuncAction action, FuncData data, struct record *record,
205                 int index)
206 { int *min=(int *)data;
207   switch (action) {
208      case FuncInit:
209          *min=INT_MAX;
210          return 0;
211      case FuncIterate:
212          if (record->classes[index]!=fileinfo[index]->offsite &&
213              record->count<*min)
214              *min=record->count;
215          return 0;
216      case FuncResult:
217          return *min*cellArea;
218   
219   }
220   return 0;
221 }
222
223 /* Rarest cell value in combination  */
224 double OuttableFewest(FuncAction action, FuncData data, struct record *record,
225                 int index)
226 { struct n_info *info=(n_info *)data;
227   switch (action) {
228      case FuncInit:
229          info->value=0;
230          info->count=INT_MAX;
231          return 0;
232      case FuncIterate:
233          if (record->classes[index]!=fileinfo[index]->offsite &&
234              record->count<info->count) {
235                info->value=record->classes[index];
236                info->count=record->count;
237              }
238          return 0;
239      case FuncResult:
240          return info->value*zUnit+zOffset;
241   
242   }
243   return 0;
244 }
245 /* Range of classes in cell */
246 typedef struct r_info {
247        int max,min;
248     } r_info;
249 double OuttableRange(FuncAction action, FuncData data, struct record *record,
250                 int index)
251 { struct r_info *info=(r_info *)data;
252   switch (action) {
253      case FuncInit:
254          info->max=0;
255          info->min=INT_MAX;
256          return 0;
257      case FuncIterate:
258          if (record->classes[index]!=fileinfo[index]->offsite) {
259             if (record->classes[index]<info->min) 
260                info->min=record->classes[index];
261             if (record->classes[index]>info->max)
262                info->max=record->classes[index];
263          }
264          return 0;
265      case FuncResult:
266          return (info->max-info->min)*zUnit;
267   
268   }
269   return 0;
270 }
271
272 /* count of distinct classes. Note that function can be called more than once
273    for each distinct class (if there are more functions), so we need to 
274    keep track on found classes in bit table */
275 #define BIT_TABLE_LENGTH (8192/sizeof(int))
276 struct c_info {
277         int found; 
278         int bittable[BIT_TABLE_LENGTH];
279        }; 
280 double OuttableClasses(FuncAction action, FuncData data, struct record *record,
281                 int index)
282 { struct c_info *info=(struct c_info*) data;
283   int i,mask;
284   switch (action) {
285      case FuncInit:
286          info->found=0;
287          for (i=0;i<BIT_TABLE_LENGTH;i++) info->bittable[i]=0;
288          return 0;
289      case FuncIterate:
290          if (record->classes[index]!=fileinfo[index]->offsite) {
291            i=record->classes[index]/(sizeof(int)*8);
292            mask=1<<record->classes[index]%(sizeof(int)*8);
293            if (!(info->bittable[i]&mask)) {
294               info->found++;
295               info->bittable[i]|=mask;
296            }  
297          }
298          return 0;
299      case FuncResult:
300          return info->found;
301   
302   }
303   return 0;
304 }
305 /* Bitwise OR of all values. Why Pete Olson was so proud of this
306    function adding it in EPPL ver 2.1? */
307 double OuttableOr(FuncAction action, FuncData data, struct record *record,
308                 int index)
309 { int *res=(int *)data;
310   switch (action) {
311      case FuncInit:
312          *res=0;
313          return 0;
314      case FuncIterate:
315          if (record->classes[index]!=fileinfo[index]->offsite)
316              *res|=record->classes[index];
317          return 0;
318      case FuncResult:
319          return *res;
320   
321   }
322   return 0;
323 }
324
325 /* Bitwise And of all values in combination  */
326 double OuttableAnd(FuncAction action, FuncData data, struct record *record,
327                 int index)
328 { int *res=(int *)data;
329   switch (action) {
330      case FuncInit:
331          *res=65535;
332          return 0;
333      case FuncIterate:
334          if (record->classes[index]!=fileinfo[index]->offsite)
335              *res&=record->classes[index];
336          return 0;
337      case FuncResult:
338          return *res;
339   
340   }
341   return 0;
342 }
343
344 /* Standard deviation of all values in combination, biased */
345 struct var_info {
346          double sum;
347          double sumsq;
348          int count;
349        };
350 double OuttableStd(FuncAction action, FuncData data, struct record *record,
351                 int index)
352 { struct var_info *info=(struct var_info *)data;
353   switch (action) {
354      case FuncInit:
355          info->count=0;
356          info->sum=0;
357          info->sumsq=0;
358          return 0;
359      case FuncIterate:
360          if (record->classes[index]!=fileinfo[index]->offsite) { 
361               info->count +=record->count;
362               info->sum   +=record->count*record->classes[index];
363               info->sumsq +=record->count*record->classes[index]*record->
364                              classes[index];
365          }
366          return 0;
367      case FuncResult:
368          if (info->count<2) return 0;
369          return sqrt((info->sumsq-(info->sum*info->sum/info->count))/
370                        (info->count))*zUnit;
371           
372   }
373   return 0;
374 }
375 /*Variance of cell values, biased*/
376 double OuttableVar(FuncAction action, FuncData data, struct record *record,
377                 int index)
378 { struct var_info *info=(struct var_info *)data;
379   switch (action) {
380      case FuncInit:
381          info->count=0;
382          info->sum=0;
383          info->sumsq=0;
384          return 0;
385      case FuncIterate:
386          if (record->classes[index]!=fileinfo[index]->offsite) { 
387               info->count +=record->count;
388               info->sum   +=record->count*record->classes[index];
389               info->sumsq +=record->count*record->classes[index]*record->
390                              classes[index];
391          }
392          return 0;
393      case FuncResult:
394          if (info->count<2) return 0;
395          return ((info->sumsq-(info->sum*info->sum/info->count))/
396                        (info->count-1))*zUnit*zUnit;
397           
398   }
399   return 0;
400 }
401
402 /* correlation of cell values in files index and index+1, multiplied by 100 */
403 typedef struct cov_info {
404          double sumx;
405          double sumy;
406          double sumxy;
407          double sumxsq;
408          double sumysq;
409          int count;
410        } cov_info; 
411 double OuttableCorr(FuncAction action, FuncData data, struct record *record,
412                 int index)
413 { struct cov_info *info=(struct cov_info *)data;
414   switch (action) {
415      case FuncInit:
416          info->count=0;
417          info->sumx=0;
418          info->sumxsq=0;
419          info->sumy=0;
420          info->sumysq=0;
421          info->sumxy=0;
422          return 0;
423      case FuncIterate:
424          if (record->classes[index]!=fileinfo[index]->offsite&&
425              record->classes[index+1]!=fileinfo[index+1]->offsite) { 
426               info->count +=record->count;
427               info->sumx   +=record->count*record->classes[index];
428               info->sumxsq +=record->count*record->classes[index]*record->
429                              classes[index];
430               info->sumy   +=record->count*record->classes[index+1];
431               info->sumysq +=record->count*record->classes[index+1]*record->
432                              classes[index+1];
433               info->sumxy  +=record->count*record->classes[index]*
434                                            record->classes[index+1];
435          }
436          return 0;
437      case FuncResult:
438          if (info->count<2) return 0;
439          return (info->sumxy-(info->sumx*info->sumy/info->count))/
440                sqrt((info->sumxsq-(info->sumx*info->sumx/info->count))*
441                     (info->sumysq-(info->sumy*info->sumy/info->count)));
442           
443   }
444   return 0;
445 }
446
447 struct FuncInfo funcTable[]={
448 {"sum",OuttableSum,1,sizeof(int)},
449 {"cnt",OuttableCount,1,sizeof(int)},
450 {"avg",OuttableAvg,1,sizeof(struct avg_info)},
451 {"min",OuttableMin,1,sizeof(int)},
452 {"nmin",OuttableNMin,1,sizeof(struct n_info)},
453 {"max",OuttableMax,1,sizeof(int)},
454 {"nmax",OuttableNMax,1,sizeof(struct n_info)},
455 {"mode",OuttableMode,1,sizeof(struct n_info)},
456 {"nmode",OuttableNMode,1,sizeof(int)},
457 {"fewest",OuttableFewest,1,sizeof(struct n_info)},
458 {"nfewest",OuttableNFewest,1,sizeof(int)},
459 {"range",OuttableRange,1,sizeof(struct r_info)},
460 {"classes",OuttableClasses,1,sizeof(struct c_info)},
461 {"or",OuttableOr,1,sizeof(int)},
462 {"and",OuttableAnd,1,sizeof(int)},
463 {"std",OuttableStd,1,sizeof(struct var_info)},
464 {"var",OuttableVar,1,sizeof(struct var_info)},
465 {"corr",OuttableCorr,2,sizeof(struct cov_info)},
466 {"",NULL,0,0},
467 };