aboutsummaryrefslogtreecommitdiffstats
path: root/src/hal/components/histobins.comp
blob: 6a5a486a5f430a236dcff2b5b2f0f7e55c59c9dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
component histobins
"""histogram bins utility for scripts/hal-histogram

Usage:
  Read availablebins pin for the number of bins available.
  Set the minvalue, binsize, and nbins pins.
    Ensure nbins <= availablebins
    For nbins = N, the bins are numbered: 0 ... N\-1 
  Iterate:
    Set index pin to a bin number: 0 <= index < nbins.
    Read check pin and verify that check pin == index pin.
    Read outputs: binvalue, pextra, nextra pins.
         (binvalue is count for the indexed bin)
         (pextra   is count for all inputs > maxvalue)
         (nextra   is count for all bins   < minvalue)

 If index is out of range (index < 0 or index > maxbinnumber)
 then binvalue == \-1.
 The input-error pin is set when input rules are violated
 and updates cease.
 The reset pin may be used to restart.
 The input used is selected based on pintype:
   pintype  inputpin
   -------  -----------
         0  input
         1  input-s32
         2  input-u32
         3  input-bit
 Additional output statistics pins:
   input-min
   input-max
   nsamples
   variance
   mean
 The method input pin selects an alternate variance calculation.

Maintainers note: hardcoded for MAXBINNUMBER==200
""";

pin in   u32   pintype;
pin in   float input;
pin in   s32   input_s32;
pin in   u32   input_u32;
pin in   bit   input_bit;

pin in   u32   nbins    = 20; // must be < MAXBINNUMBER
pin in   float binsize  = 1;
pin in   float minvalue = 0;

pin in   s32   index; // use s32 to avoid 0x hex display in hal
pin out  s32   check; // use s32 to avoid 0x hex display in hal
pin in   bit   reset;
pin in   bit   method;

pin out bit    input_error;
pin out float  binvalue;
pin out float  pextra;
pin out float  nextra;
pin out float  input_min;
pin out float  input_max;

pin out u32    nsamples;
pin out float  variance;
pin out float  mean;

// user may interrogate availablebins to determine this compiled-in limit
pin out s32 availablebins = 200; //MAXBINNUMBER

function _ fp;

variable int bin[200]; // MAXBINNUMBER
variable int first = 1;
variable int last_nbins    = 0;

variable hal_float_t maxvalue;

variable hal_float_t last_binsize  = 0;
variable hal_float_t last_minvalue = 0;

variable hal_float_t sum;
variable hal_float_t sq_sum;
variable hal_float_t m2;

license "GPL";
author "Dewey Garrett";
;;

hal_float_t invalue;
int i;
int idx;
check = index;
if (   (nbins > availablebins)
    || (nbins < 1)
   ) {
  input_error = 1;
  check = index; // allow continue with no updates
  return;
}
input_error = 0;
if (reset) {first = 1;}

//pintype    "0:float, 1:s32, 2:u32 3:bit";
switch (pintype) {
  case 0:  invalue = input;     break;
  case 1:  invalue = input_s32; break;
  case 2:  invalue = input_u32; break;
  case 3:  invalue = input_bit; break;
  default: invalue = input;     break;
}

if (  first
    || nbins    != last_nbins
    || binsize  != last_binsize
    || minvalue != last_minvalue
   ) {
  maxvalue = minvalue + nbins * binsize;
  first = 0;
  pextra = 0; nextra = 0;
  for (i = 0; i < nbins; i++) {
    bin[i] = 0;
  }
  nsamples = 0;
  mean = 0;
  sum = 0;
  sq_sum = 0;
  variance = 0;
  input_min =  1e99; //dng
  input_max = -1e99; //dng
  m2 = 0;
} else {
  
  if (invalue < minvalue) {
    nextra++;
  } else if (invalue > maxvalue) {
    pextra++;
  } else {
    idx = (invalue - minvalue)/binsize;
    bin[idx]++;
  }
}

check = index; // user should verify check==index for reading values
// -1 value indicates illegal index
if (index < 0) {
  binvalue = -1;
} else if (index < nbins) {
  binvalue = bin[index];
} else {
  binvalue = -1;
}

if (invalue < input_min) input_min = invalue;
if (invalue > input_max) input_max = invalue;

nsamples++;
if (nsamples >= 2) {
  if (method == 0 ) {
    hal_float_t delta;
    delta    = invalue - mean;
    mean     = mean + delta / nsamples;
    m2       = m2 + delta * (invalue - mean);
    variance = m2/(nsamples - 1);
  } else {
    sum     += invalue;
    sq_sum  += invalue * invalue;
    variance = (sq_sum - (sum * sum)/nsamples)/(nsamples -1);
    mean     = sum/nsamples;
  }
}

last_nbins = nbins;
last_binsize = binsize;
last_minvalue = minvalue;
bues.ch cgit interface