mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
+ updated to version 0.1.03
+ testing + removed bug in find() + cascades + example test sketches added for PMF(), VAL(), CDF().
This commit is contained in:
parent
a9e0b6775b
commit
f94989f97f
91
libraries/Histogram/examples/hist_test/hist_test.ino
Normal file
91
libraries/Histogram/examples/hist_test/hist_test.ino
Normal file
@ -0,0 +1,91 @@
|
||||
//
|
||||
// FILE: hist_test.pde
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2012-12-23
|
||||
//
|
||||
// PUPROSE: test histogram frequency
|
||||
//
|
||||
|
||||
#include "histogram.h"
|
||||
|
||||
// double b[] = { 0, 100, 200, 300, 325, 350, 375, 400, 500, 600, 700, 800, 900, 1000 };
|
||||
|
||||
double b[] = {
|
||||
0, 100, 200, 300, 325, 350, 375 };
|
||||
|
||||
Histogram hist(7, b);
|
||||
|
||||
unsigned long lastTime = 0;
|
||||
const unsigned long threshold = 50; // milliseconds, for updating display
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.print("\nHistogram version: ");
|
||||
Serial.println(HISTOGRAM_LIB_VERSION);
|
||||
|
||||
Serial.print("# buckets: ");
|
||||
Serial.println(hist.size());
|
||||
|
||||
for (int i = 0; i < hist.size()-1; i++)
|
||||
{
|
||||
Serial.print("\t");
|
||||
Serial.print(b[i], 2);
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
for (int i = 0; i < hist.size()-1; i++)
|
||||
{
|
||||
Serial.print("\t");
|
||||
Serial.print(hist.find(b[i]));
|
||||
}
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
// choose a "generator" for histogram data
|
||||
// int x = analogRead(A0);
|
||||
|
||||
int x = random(600) - 50; // below lower limit
|
||||
|
||||
// int x = random(25);
|
||||
// x = x*x;
|
||||
|
||||
|
||||
// Serial.print(x);
|
||||
// Serial.print("\t");
|
||||
// Serial.println(hist.find(x));
|
||||
hist.add(x);
|
||||
|
||||
// update output
|
||||
unsigned long now = millis();
|
||||
if (now - lastTime > threshold)
|
||||
{
|
||||
lastTime = now;
|
||||
Serial.print(hist.count());
|
||||
for (int i = 0; i < hist.size(); i++)
|
||||
{
|
||||
Serial.print("\t");
|
||||
// gives percentage per bucket
|
||||
// Serial.print(hist.bucket(i));
|
||||
Serial.print(hist.frequency(i), 2);
|
||||
}
|
||||
// quartiles
|
||||
// to get at least 25% of the values you must count all values < hist.VAL(0.25);
|
||||
Serial.print("\t");
|
||||
Serial.print(hist.VAL(0.25), 2);
|
||||
// to get at least 50% of the values you must count all values < hist.VAL(0.50);
|
||||
Serial.print("\t");
|
||||
Serial.print(hist.VAL(0.50), 2);
|
||||
Serial.print("\t");
|
||||
Serial.print(hist.VAL(0.75), 2);
|
||||
Serial.print("\t");
|
||||
Serial.print(hist.VAL(1.0), 2);
|
||||
Serial.println();
|
||||
|
||||
if (hist.count() > 10000UL) hist.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
42
libraries/Histogram/examples/hist_test_cdf/hist_test_cdf.ino
Normal file
42
libraries/Histogram/examples/hist_test_cdf/hist_test_cdf.ino
Normal file
@ -0,0 +1,42 @@
|
||||
//
|
||||
// FILE: hist_test_cdf.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2012-11-10
|
||||
//
|
||||
// PUPROSE: test histogram library
|
||||
//
|
||||
|
||||
#include "histogram.h"
|
||||
|
||||
double b[] = {
|
||||
0, 300, 325, 350, 375, 400, 1000 };
|
||||
|
||||
Histogram hist(7, b);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("\ntest CDF");
|
||||
Serial.print("Histogram version: ");
|
||||
Serial.println(HISTOGRAM_LIB_VERSION);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
int x = random(1000);
|
||||
hist.add(x);
|
||||
|
||||
Serial.print(hist.count());
|
||||
Serial.print("\t");
|
||||
for (int i = 0; i < (hist.size() -1); i++)
|
||||
{
|
||||
Serial.print(hist.CDF(b[i]), 2);
|
||||
Serial.print("\t");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
if (hist.count() > 1000) hist.clear();
|
||||
|
||||
delay(10);
|
||||
}
|
||||
|
44
libraries/Histogram/examples/hist_test_pmf/hist_test_pmf.ino
Normal file
44
libraries/Histogram/examples/hist_test_pmf/hist_test_pmf.ino
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// FILE: hist_test_pmf.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2012-11-10
|
||||
//
|
||||
// PUPROSE: test histogram library
|
||||
//
|
||||
|
||||
#include "histogram.h"
|
||||
|
||||
double b[] = {
|
||||
0, 50, 100, 150, 200, 250,
|
||||
300, 350, 400, 450, 500,
|
||||
600, 700, 800, 900, 1000 };
|
||||
|
||||
Histogram hist(16, b);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("\ntest PMF");
|
||||
Serial.print("Histogram version: ");
|
||||
Serial.println(HISTOGRAM_LIB_VERSION);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
int x = random(1000);
|
||||
hist.add(x);
|
||||
|
||||
Serial.print(hist.count());
|
||||
Serial.print("\t");
|
||||
for (int i = 0; i < hist.size()-1; i++)
|
||||
{
|
||||
Serial.print(hist.PMF(b[i]), 2);
|
||||
Serial.print("\t");
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
if (hist.count() > 1000) hist.clear();
|
||||
|
||||
delay(10);
|
||||
}
|
||||
|
56
libraries/Histogram/examples/hist_test_val/hist_test_val.ino
Normal file
56
libraries/Histogram/examples/hist_test_val/hist_test_val.ino
Normal file
@ -0,0 +1,56 @@
|
||||
//
|
||||
// FILE: hist_test_val.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2012-11-11
|
||||
//
|
||||
// PUPROSE: test histogram library
|
||||
//
|
||||
|
||||
#include "histogram.h"
|
||||
|
||||
double b[] = {
|
||||
0, 50, 100, 150, 200, 250,
|
||||
300, 350, 400, 450, 500,
|
||||
600, 700, 800, 900, 1000 };
|
||||
|
||||
Histogram hist(16, b);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println("\ntest VAL");
|
||||
Serial.print("Histogram version: ");
|
||||
Serial.println(HISTOGRAM_LIB_VERSION);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
int x = random(800);
|
||||
hist.add(x);
|
||||
|
||||
Serial.print(hist.count());
|
||||
Serial.print(", ");
|
||||
float f = 0.5;
|
||||
Serial.print(f, 2);
|
||||
Serial.print(" : ");
|
||||
|
||||
Serial.print(hist.VAL(f), 2);
|
||||
Serial.print("\t");
|
||||
|
||||
float sum = 0;
|
||||
int i = 0;
|
||||
for (i = 0; i< hist.size(); i++)
|
||||
{
|
||||
sum += hist.frequency(i);
|
||||
Serial.print(sum, 2);
|
||||
Serial.print("\t");
|
||||
if (sum >= f) break;
|
||||
}
|
||||
Serial.print(b[i]);
|
||||
Serial.println();
|
||||
|
||||
if (hist.count() > 1000) hist.clear();
|
||||
|
||||
delay(10);
|
||||
}
|
||||
|
@ -1,126 +1,142 @@
|
||||
//
|
||||
// FILE: histogram.cpp
|
||||
// AUTHOR: Rob dot Tillaart at gmail dot com
|
||||
// VERSION: see HISTOGRAM_LIB_VERSION in .h
|
||||
//
|
||||
// FILE: Histogram.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.03
|
||||
// PURPOSE: Histogram library for Arduino
|
||||
// DATE: 2012-11-10
|
||||
//
|
||||
// Released to the public domain
|
||||
//
|
||||
// HISTORY:
|
||||
// 0.1.0 - 2012-11-10 initial version
|
||||
// 0.1.1 - 2012-11-10 added PMF() and CDF()
|
||||
// 0.1.2 - 2012-12-23 changed float to double; some comments
|
||||
// 0.1.03 - 2013-09-29 testing a lot & refactoring
|
||||
//
|
||||
// Released to the public domain
|
||||
//
|
||||
|
||||
#include "histogram.h"
|
||||
|
||||
Histogram::Histogram(uint8_t len, double *bounds)
|
||||
Histogram::Histogram(int len, double *bounds)
|
||||
{
|
||||
_bounds = bounds;
|
||||
_len = len;
|
||||
_data = (long*) malloc((len+1) * sizeof(long));
|
||||
clear();
|
||||
_bounds = bounds;
|
||||
_len = len+1;
|
||||
_data = (long*) malloc((_len) * sizeof(long));
|
||||
clear();
|
||||
}
|
||||
|
||||
Histogram::~Histogram()
|
||||
{
|
||||
free(_data); // free may still has a bug :(
|
||||
free(_data); // free may still has a bug :(
|
||||
}
|
||||
|
||||
// resets all counters
|
||||
void Histogram::clear()
|
||||
{
|
||||
for (uint8_t i = 0; i < _len+1; i++)
|
||||
{
|
||||
_data[i] = 0;
|
||||
}
|
||||
_cnt = 0;
|
||||
{
|
||||
for (uint8_t i = 0; i < _len; i++)
|
||||
{
|
||||
_data[i] = 0;
|
||||
}
|
||||
_cnt = 0;
|
||||
}
|
||||
|
||||
// adds a new value to the histogram - increasing
|
||||
void Histogram::add(double f)
|
||||
{
|
||||
_data[find(f)]++;
|
||||
_cnt++;
|
||||
_data[find(f)]++;
|
||||
_cnt++;
|
||||
}
|
||||
|
||||
// adds a new value to the histogram - decreasing
|
||||
void Histogram::sub(double f)
|
||||
{
|
||||
_data[find(f)]--;
|
||||
_cnt++;;
|
||||
_data[find(f)]--;
|
||||
_cnt++;;
|
||||
}
|
||||
|
||||
// returns the number of buckets
|
||||
uint8_t Histogram::size()
|
||||
{
|
||||
return _len+1;
|
||||
return _len;
|
||||
}
|
||||
|
||||
// returns the number of values added
|
||||
unsigned long Histogram::count()
|
||||
{
|
||||
return _cnt;
|
||||
return _cnt;
|
||||
}
|
||||
|
||||
// returns the count of a bucket
|
||||
long Histogram::bucket(uint8_t idx)
|
||||
{
|
||||
if (idx > _len+1) return 0;
|
||||
return _data[idx];
|
||||
if (idx > _len) return 0;
|
||||
return _data[idx];
|
||||
}
|
||||
|
||||
// returns the relative frequency of a bucket
|
||||
double Histogram::frequency(uint8_t idx)
|
||||
{
|
||||
if (_cnt == 0) return NAN;
|
||||
if (idx > _len+1) return 0;
|
||||
return (1.0 * _data[idx]) / _cnt;
|
||||
}
|
||||
|
||||
// returns the probability of the bucket of a value
|
||||
double Histogram::PMF(double val)
|
||||
{
|
||||
if (_cnt == 0) return NAN;
|
||||
uint8_t idx = find(val);
|
||||
return (1.0 *_data[idx]) / _cnt;
|
||||
}
|
||||
|
||||
// returns the cummulative probability of
|
||||
// values <= value
|
||||
double Histogram::CDF(double val)
|
||||
{
|
||||
if (_cnt == 0) return NAN;
|
||||
uint8_t idx = find(val);
|
||||
long sum = 0;
|
||||
for (uint8_t i=0; i<= idx; i++) sum += _data[i];
|
||||
return (1.0 * sum) / _cnt;
|
||||
if (_cnt == 0) return NAN;
|
||||
if (idx > _len) return 0; // diff with PMF
|
||||
return (1.0 * _data[idx]) / _cnt;
|
||||
}
|
||||
|
||||
// EXPERIMENTAL
|
||||
// returns the value of the original array for
|
||||
// returns the probability of the bucket of a value
|
||||
double Histogram::PMF(double val)
|
||||
{
|
||||
if (_cnt == 0) return NAN;
|
||||
uint8_t idx = find(val);
|
||||
return (1.0 *_data[idx]) / _cnt;
|
||||
}
|
||||
|
||||
// EXPERIMENTAL
|
||||
// returns the cummulative probability of
|
||||
// values <= value
|
||||
double Histogram::CDF(double val)
|
||||
{
|
||||
if (_cnt == 0) return NAN;
|
||||
uint8_t idx = find(val);
|
||||
long sum = 0;
|
||||
for (uint8_t i=0; i<= idx; i++)
|
||||
{
|
||||
sum += _data[i];
|
||||
}
|
||||
return (1.0 * sum) / _cnt;
|
||||
}
|
||||
|
||||
// EXPERIMENTAL
|
||||
// returns the value of the original array for
|
||||
// which the CDF is at least prob.
|
||||
double Histogram::VAL(double prob)
|
||||
{
|
||||
if (_cnt == 0) return NAN;
|
||||
if (prob < 0.0) prob = 0.0;
|
||||
if (prob > 1.0) prob = 1.0;
|
||||
|
||||
long sum = 0;
|
||||
for (uint8_t i = 0; i <= _len; i++)
|
||||
{
|
||||
sum += _data[i];
|
||||
if (sum >= (prob * _cnt)) return _bounds[i];
|
||||
}
|
||||
return INFINITY;
|
||||
if (_cnt == 0) return NAN;
|
||||
if (prob < 0.0) prob = 0.0;
|
||||
if (prob > 1.0) prob = 1.0;
|
||||
|
||||
double value = prob * _cnt;
|
||||
long sum = 0;
|
||||
for (uint8_t i = 0; i < _len; i++)
|
||||
{
|
||||
sum += _data[i];
|
||||
if (sum >= value && (i <(_len-1)) ) return _bounds[i];
|
||||
}
|
||||
return INFINITY;
|
||||
}
|
||||
|
||||
// returns the bucket number for value f
|
||||
uint8_t Histogram::find(double f)
|
||||
// returns the bucket number for value val
|
||||
uint8_t Histogram::find(double val)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
while(i < _len && f > _bounds[i]) i++;
|
||||
return i;
|
||||
for (uint8_t i = 0; i< (_len-1); i++)
|
||||
{
|
||||
if (_bounds[i] >= val) return i;
|
||||
}
|
||||
return _len-1;
|
||||
// uint8_t i = 0;
|
||||
// while ((i < (_len-1)) && (_bounds[i] < val)) i++;
|
||||
// return i;
|
||||
}
|
||||
|
||||
// END OF FILE
|
@ -1,10 +1,11 @@
|
||||
#ifndef Histogram_h
|
||||
#define Histogram_h
|
||||
//
|
||||
//
|
||||
// FILE: Histogram.h
|
||||
// AUTHOR: Rob dot Tillaart at gmail dot com
|
||||
// AUTHOR: Rob Tillaart
|
||||
// VERSION: 0.1.03
|
||||
// PURPOSE: Histogram library for Arduino
|
||||
// HISTORY: See Histogram.cpp
|
||||
// DATE: 2012-11-10
|
||||
//
|
||||
// Released to the public domain
|
||||
//
|
||||
@ -13,31 +14,40 @@
|
||||
#include <math.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#define HISTOGRAM_LIB_VERSION "0.1.1"
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
class Histogram
|
||||
#define HISTOGRAM_LIB_VERSION "0.1.03"
|
||||
|
||||
class Histogram
|
||||
{
|
||||
public:
|
||||
Histogram(uint8_t len, double *bounds);
|
||||
~Histogram();
|
||||
void clear();
|
||||
void add(double val);
|
||||
void sub(double val);
|
||||
uint8_t size();
|
||||
unsigned long count();
|
||||
long bucket(uint8_t idx);
|
||||
double frequency(uint8_t idx);
|
||||
double PMF(double val);
|
||||
double CDF(double val);
|
||||
double VAL(double prob);
|
||||
uint8_t find(double f);
|
||||
// void strategy();
|
||||
public:
|
||||
Histogram(int len, double *bounds);
|
||||
~Histogram();
|
||||
|
||||
void clear();
|
||||
void add(double val);
|
||||
void sub(double val);
|
||||
|
||||
uint8_t size();
|
||||
unsigned long count();
|
||||
long bucket(uint8_t idx);
|
||||
|
||||
double frequency(uint8_t idx);
|
||||
double PMF(double val);
|
||||
double CDF(double val);
|
||||
double VAL(double prob);
|
||||
uint8_t find(double f);
|
||||
// void strategy();
|
||||
|
||||
protected:
|
||||
double * _bounds;
|
||||
long * _data;
|
||||
uint8_t _len;
|
||||
unsigned long _cnt;
|
||||
double * _bounds;
|
||||
long * _data;
|
||||
uint8_t _len;
|
||||
unsigned long _cnt;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user