Skip to content

Commit

Permalink
0.2.0 Gauss
Browse files Browse the repository at this point in the history
  • Loading branch information
RobTillaart committed Jul 10, 2023
1 parent 33e70b0 commit 2551f5e
Show file tree
Hide file tree
Showing 16 changed files with 475 additions and 108 deletions.
17 changes: 15 additions & 2 deletions libraries/Gauss/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.2.0] - 2023-07-10
- improve performance => faster lookup.
- removed __z[] saves 136 bytes RAM
- remove MultiMap dependency.
- - remove **\_stddev** as **\_reciprokeSD** holds same information.
- add **float P_outside(float f, float g)**
- returns **P(x < f) + P(g < x)** under condition (f < g).
- add **float denormalize(float value)** (reverse normalize).
- add examples DS18B20 and HX711 and BMI
- update readme.md
- minor edits.


----

## [0.1.1] - 2023-07-07
- improve performance => reciprokeSD = 1.0/stddev
- update readme.md
Expand All @@ -19,8 +34,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- add **float getStdDev()** convenience function.
- clean up a bit



## [0.1.0] - 2023-07-06
- initial version

2 changes: 1 addition & 1 deletion libraries/Gauss/Gauss.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// FILE: Gauss.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// VERSION: 0.2.0
// PURPOSE: Library for the Gauss probability math.
// DATE: 2023-07-06

Expand Down
85 changes: 58 additions & 27 deletions libraries/Gauss/Gauss.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
//
// FILE: Gauss.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.1
// VERSION: 0.2.0
// PURPOSE: Library for the Gauss probability math.
// DATE: 2023-07-06


#include "Arduino.h"
#include "MultiMap.h"

#define GAUSS_LIB_VERSION (F("0.1.1"))
#define GAUSS_LIB_VERSION (F("0.2.0"))


class Gauss
Expand All @@ -19,16 +18,15 @@ class Gauss
Gauss()
{
_mean = 0;
_stddev = 1;
_reciprokeSD = 1;
}

// stddev should be positive.
bool begin(float mean = 0, float stddev = 1)
{
_mean = mean;
_stddev = stddev; // should be positive
_reciprokeSD = 1.0 / _stddev;
if (stddev == 0) _reciprokeSD = NAN;
else _reciprokeSD = 1.0 / stddev;
return (stddev > 0);
}

Expand All @@ -41,14 +39,13 @@ class Gauss

float getStdDev()
{
return _stddev;
return 1.0 / _reciprokeSD;
}


float P_smaller(float value)
{
if (_stddev == 0) return NAN;
// normalize(value)
if (_reciprokeSD == NAN) return NAN;
return _P_smaller((value - _mean) * _reciprokeSD);
}

Expand All @@ -61,18 +58,25 @@ class Gauss

float P_between(float p, float q)
{
if (_stddev == 0) return NAN;
if (_reciprokeSD == NAN) return NAN;
if (p >= q) return 0;
return P_smaller(q) - P_smaller(p);
}


float P_outside(float p, float q)
{
return 1.0 - P_between(p, q);
}


float P_equal(float value)
{
if (_stddev == 0) return NAN;
if (_reciprokeSD == NAN) return NAN;
float n = (value - _mean) * _reciprokeSD;
// gain of ~10% if we allocate a global var for 'constant' c
float c = _reciprokeSD * (1.0 / sqrt(TWO_PI));
return c * exp(-0.5 * n * n);
return c * exp(-0.5 * (n * n));
}


Expand All @@ -88,18 +92,32 @@ class Gauss
}


float denormalize(float value)
{
return value / _reciprokeSD + _mean;
}


float bellCurve(float value)
{
return P_equal(value);
}


float CDF(float value)
{
return P_smaller(value);
}



private:

float _P_smaller(float x)
{
// NORM.DIST(mean, stddev, x, true)
// these points correspond with
// 0.0 .. 3.0 in steps of 0.1 followed by 4.0, 5.0 and 6.0
float __gauss[] = {
0.50000000, 0.53982784, 0.57925971, 0.61791142,
0.65542174, 0.69146246, 0.72574688, 0.75803635,
Expand All @@ -112,24 +130,37 @@ class Gauss
0.99999971, 1.00000000
};

// 0..60000 uint16_t = 68 bytes less
float __z[] = {
0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7,
0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5,
1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3,
2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 4,0,
5.0, 6.0
};

// a dedicated MultiMap could exploit the fact that
// the __z[] array is largely equidistant.
// that could remove the __z[] array (almost) completely.
if (x < 0) return 1.0 - multiMap<float>(-x, __z, __gauss, 34);
return multiMap<float>(x, __z, __gauss, 34);
bool neg = false;
if (x < 0)
{
neg = true;
x = -x;
}

if (x >= 6.0)
{
if (neg) return 0.0;
return 1.0;
}

if (x <= 3.0)
{
int idx = x * 10;
float rv = __gauss[idx] + ((x * 10) - idx) * (__gauss[idx+1] - __gauss[idx]);
if (neg) return 1.0 - rv;
return rv;
}

// 3.0 .. 6.0
int xint = x;
int idx = 27 + xint;
float rv = __gauss[idx] + (x - xint) * (__gauss[idx+1] - __gauss[idx]);
if (neg) return 1.0 - rv;
return rv;
}

float _mean = 0;
float _stddev = 1; // not needed as _reciprokeSD holds same info?
// reciprokeSD = 1.0 / stddev is faster in most math (MUL vs DIV)
float _reciprokeSD = 1;
};

Expand Down
Loading

0 comments on commit 2551f5e

Please sign in to comment.