mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.2.0 Gauss
This commit is contained in:
parent
33e70b036d
commit
2551f5efe1
@ -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
|
||||
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
@ -19,7 +18,6 @@ public:
|
||||
Gauss()
|
||||
{
|
||||
_mean = 0;
|
||||
_stddev = 1;
|
||||
_reciprokeSD = 1;
|
||||
}
|
||||
|
||||
@ -27,8 +25,8 @@ public:
|
||||
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);
|
||||
}
|
||||
|
||||
@ -41,14 +39,13 @@ public:
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -61,18 +58,25 @@ public:
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
@ -88,18 +92,32 @@ public:
|
||||
}
|
||||
|
||||
|
||||
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,
|
||||
@ -112,24 +130,37 @@ private:
|
||||
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
|
||||
};
|
||||
bool neg = false;
|
||||
if (x < 0)
|
||||
{
|
||||
neg = true;
|
||||
x = -x;
|
||||
}
|
||||
|
||||
// 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);
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
# Gauss
|
||||
|
||||
Library for the Gauss probability math.
|
||||
Library for the Gauss probability math. (Normal Distribution).
|
||||
|
||||
|
||||
## Description
|
||||
@ -17,31 +17,47 @@ Gauss is an experimental Arduino library to approximate the probability that a v
|
||||
smaller or larger than a given value.
|
||||
These under the premises of a Gaussian distribution with parameters **mean** and **stddev**
|
||||
(a.k.a. average / mu / µ and standard deviation / sigma / σ).
|
||||
If these parameters are not given, 0 and 1 are used by default (normalized Gaussian distribution).
|
||||
If these parameters are not given, mean == 0 and stddev == 1 are used by default.
|
||||
This is the normalized Gaussian distribution.
|
||||
|
||||
The values are approximated with **MultiMap()** using a 32 points interpolated lookup.
|
||||
Therefore the **MultiMap** library need to be downloaded too (see related below).
|
||||
The number of lookup points might chance in the future.
|
||||
The values of the functions are approximated with a **MultiMap()** based lookup
|
||||
using a 34 points interpolated lookup.
|
||||
- Version 0.1.x used the **MultiMap** library need to be downloaded too (see related below).
|
||||
- Version 0.2.0 and above embeds an optimized version, so no need to use **MultiMap**.
|
||||
|
||||
Return values are given as floats, if one needs percentages, just multiply by 100.0.
|
||||
Note: The number of lookup points might chance in the future, keeping a balance between
|
||||
accuracy and footprint.
|
||||
|
||||
|
||||
#### Accuracy
|
||||
#### Accuracy / precision
|
||||
|
||||
The lookup table has 34 points with 8 decimals.
|
||||
The version 0.2.0 lookup table has 34 points with 8 decimals.
|
||||
This matches the precision of float data type.
|
||||
Do not expect a very high accuracy / precision as interpolation is linear.
|
||||
For many applications this accuracy is sufficient.
|
||||
Do not expect an 8 decimals accuracy / precision as interpolation is linear.
|
||||
|
||||
Values of the table are calculated with ```NORM.DIST(mean, stddev, x, true)```.
|
||||
A first investigation (part 0.0 - 1.3) shows:
|
||||
- maximum error ~ 0.0003016 <= 0.031%
|
||||
- average error ~ 0.0001433 <= 0.015%
|
||||
|
||||
I expect that for many applications this accuracy is probably sufficient.
|
||||
|
||||
The 34 points are in a (mostly) equidistant table.
|
||||
Searching the interpolation points is optimized in version 0.2.0.
|
||||
The table uses the symmetry of the distribution to reduce the number of points.
|
||||
|
||||
Values of the table are calculated with ```NORM.DIST(x, mean, stddev, true)```
|
||||
spreadsheet function.
|
||||
|
||||
Note: 0.1.0 was 32 points 4 decimals. Need to investigate reduction of points.
|
||||
|
||||
|
||||
#### Applications
|
||||
|
||||
- use as a filter? do not allow > 3 sigma
|
||||
- compare historic data to current data
|
||||
- compare population data with individual
|
||||
- use as a filter e.g. detect above N1 sigma and under N2 sigma
|
||||
- compare historic data to current data e.g. temperature.
|
||||
- transforming to sigma makes it scale C / F / K independent.
|
||||
- fill a bag (etc) until a certain weight is reached (+- N sigma)
|
||||
- compare population data with individual, e.g. Body Mass Index (BMI).
|
||||
|
||||
|
||||
#### Character
|
||||
@ -50,6 +66,7 @@ Note: 0.1.0 was 32 points 4 decimals. Need to investigate reduction of points.
|
||||
|:-----------:|:------:|:----------:|:-----:|
|
||||
| mean | mu | ALT-230 | µ |
|
||||
| stddev | sigma | ALT-229 | σ |
|
||||
| CDF | phi | ALT-232 | Φ | ALT-237 for lower case
|
||||
|
||||
- https://altcodesguru.com/greek-alt-codes.html
|
||||
|
||||
@ -74,38 +91,51 @@ Note: 0.1.0 was 32 points 4 decimals. Need to investigate reduction of points.
|
||||
- **Gauss()** constructor. Uses mean = 0 and stddev = 1 by default.
|
||||
- **bool begin(float mean = 0, float stddev = 1)** set the mean and stddev.
|
||||
Returns true if stddev > 0 which should be so.
|
||||
Returns false if stddev <= 0, which could be a user choice.
|
||||
Returns false if stddev <= 0, however it could be a user choice to use this.
|
||||
Note that if ```stddev == 0```, probabilities cannot be calculated
|
||||
as the distribution is not Gaussian.
|
||||
The default values (0,1) gives the normalized Gaussian distribution.
|
||||
**begin()** can be called at any time to change the mean or stddev.
|
||||
The default values (0, 1) gives the normalized Gaussian distribution.
|
||||
**begin()** can be called at any time to change the mean and/or stddev.
|
||||
- **float getMean()** returns current mean.
|
||||
- **float getStddev()** returns current stddev.
|
||||
|
||||
|
||||
#### Probability
|
||||
|
||||
Probability functions return NAN if stddev == 0.
|
||||
Probability functions return NAN if stddev == 0.
|
||||
Return values are given as a float 0.0 .. 1.0.
|
||||
Multiply probabilities by 100.0 to get the value as a percentage.
|
||||
|
||||
- **float P_smaller(float f)** returns probability **P(x < f)**.
|
||||
Multiply by 100.0 to get the value as a percentage.
|
||||
A.k.a. **CDF()** Cumulative Distribution Function.
|
||||
- **float P_larger(float f)** returns probability **P(x > f)**.
|
||||
Multiply by 100.0 to get the value as a percentage.
|
||||
As the distribution is continuous **P_larger(f) == 1 - P_smaller(f)**.
|
||||
- **float P_between(float f, float g)** returns probability **P(f < x < g)**.
|
||||
Multiply by 100.0 to get the value as a percentage.
|
||||
- if f >= g ==> returns 1.0
|
||||
- **float P_equal(float f)** returns probability **P(x == f)**.
|
||||
This uses the bell curve formula.
|
||||
- **float P_outside(float f, float g)** returns probability **P(x < f) + P(g < x)**.
|
||||
- note that f should be smaller or equal to g
|
||||
- **P_outside() = 1 - P_between()**
|
||||
|
||||
|
||||
#### Normalize
|
||||
|
||||
- **float normalize(float f)** normalize a value to normalized distribution.
|
||||
E.g if mean == 50 and stddev == 14, then 71 ==> +1.5 sigma.
|
||||
Is equal to number of **stddevs()**.
|
||||
- **float denormalize(float f)** reverses normalize().
|
||||
What value would have a deviation of 1.73 stddev.
|
||||
- **float stddevs(float f)** returns the number of stddevs from the mean.
|
||||
Identical to **normalize()**.
|
||||
|
||||
|
||||
#### Other
|
||||
|
||||
- **float normalize(float f)** normalize a value to normalized distribution.
|
||||
Is equal to number of **stddevs()**.
|
||||
- **float stddevs(float f)** returns the number of stddevs from the mean.
|
||||
E.g if mean == 50 and stddev == 14, then 71 ==> +1.5 sigma.
|
||||
wrapper functions:
|
||||
|
||||
- **float bellCurve(float f)** returns probability **P(x == f)**.
|
||||
- **float CDF(float f)** returns probability **P(x < f)**.
|
||||
|
||||
|
||||
## Performance
|
||||
@ -114,26 +144,26 @@ Indicative numbers for 1000 calls, timing in micros.
|
||||
|
||||
Arduino UNO, 16 MHz, IDE 1.8.19
|
||||
|
||||
| function | 0.1.0 | 0.1.1 | notes |
|
||||
|:--------------|:--------:|:--------:|:--------|
|
||||
| P_smaller | 375396 | 365964 |
|
||||
| P_larger | 384368 | 375032 |
|
||||
| P_between | 265624 | 269176 |
|
||||
| normalize | 44172 | 23024 |
|
||||
| bellCurve | 255728 | 205460 |
|
||||
| approx.bell | 764028 | 719184 | see examples
|
||||
| function | 0.1.0 | 0.1.1 | 0.2.0 | notes |
|
||||
|:--------------|:--------:|:--------:|:--------:|:--------|
|
||||
| P_smaller | 375396 | 365964 | 159536 |
|
||||
| P_larger | 384368 | 375032 | 169056 |
|
||||
| P_between | 265624 | 269176 | 150148 |
|
||||
| normalize | 44172 | 23024 | 23024 |
|
||||
| bellCurve | 255728 | 205460 | 192524 |
|
||||
| approx.bell | 764028 | 719184 | 333172 | see examples
|
||||
|
||||
|
||||
ESP32, 240 MHz, IDE 1.8.19
|
||||
|
||||
| function | 0.1.0 | 0.1.1 | notes |
|
||||
|:--------------|:--------:|:--------:|:--------|
|
||||
| P_smaller | - | 4046 |
|
||||
| P_larger | - | 4043 |
|
||||
| P_between | - | 3023 |
|
||||
| normalize | - | 592 |
|
||||
| bellCurve | - | 13522 |
|
||||
| approx.bell | - | 7300 |
|
||||
| function | 0.1.0 | 0.1.1 | 0.2.0 | notes |
|
||||
|:--------------|:--------:|:--------:|:--------:|:--------|
|
||||
| P_smaller | - | 4046 | 1498 |
|
||||
| P_larger | - | 4043 | 1516 |
|
||||
| P_between | - | 3023 | 1569 |
|
||||
| normalize | - | 592 | 585 |
|
||||
| bellCurve | - | 13522 | 13133 |
|
||||
| approx.bell | - | 7300 | 2494 |
|
||||
|
||||
|
||||
## Future
|
||||
@ -141,33 +171,19 @@ ESP32, 240 MHz, IDE 1.8.19
|
||||
#### Must
|
||||
|
||||
- documentation
|
||||
|
||||
- test test test
|
||||
|
||||
#### Should
|
||||
|
||||
- optimize accuracy
|
||||
- revisit lookup of MultiMap
|
||||
- (-10 .. 0) might be more accurate (significant digits)?
|
||||
- double instead of floats? (good table?)
|
||||
- make use of equidistant \_\_z\[] table
|
||||
|
||||
|
||||
#### Could
|
||||
|
||||
- add examples
|
||||
- e.g. temperature (DS18B20 or DHT22)
|
||||
- e.g. loadcell (HX711)
|
||||
- embed MultiMap hardcoded instead of library dependency
|
||||
- add unit tests
|
||||
- remove **\_stddev** as **\_reciprokeSD** holds same information.
|
||||
- reverse normalization
|
||||
- G(100,25) which value has stddev 0.735?
|
||||
- **VAL(probability = 0.75)** ==> 134 whatever
|
||||
- Returns the value of the distribution for which the **CDF()** is at least probability.
|
||||
- Inverse of **P_smaller()**
|
||||
- **float P_outside(float f, float g)** returns probability **P(x < f) + P(g < x)**.
|
||||
- assuming no overlap. Use **P_outside() = 1 - P_between()**
|
||||
|
||||
- Returns the value for which the **CDF()** is at least probability.
|
||||
- Inverse of **P_smaller()** (how? binary search)
|
||||
|
||||
|
||||
#### Won't (unless requested)
|
||||
|
||||
@ -177,5 +193,5 @@ ESP32, 240 MHz, IDE 1.8.19
|
||||
- move code to .cpp file? (rather small lib).
|
||||
- **void setMean(float f)** can be done with begin()
|
||||
- **void setStddev(float f)** can be done with begin()
|
||||
|
||||
|
||||
- optimize accuracy
|
||||
- (-6 .. 0) might be more accurate (significant digits)?
|
||||
|
74
libraries/Gauss/examples/Gauss_BMI/Gauss_BMI.ino
Normal file
74
libraries/Gauss/examples/Gauss_BMI/Gauss_BMI.ino
Normal file
@ -0,0 +1,74 @@
|
||||
//
|
||||
// FILE: Gauss_BMI.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo - not a medical program
|
||||
|
||||
#include "Gauss.h"
|
||||
|
||||
Gauss G;
|
||||
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("GAUSS_LIB_VERSION:\t");
|
||||
Serial.println(GAUSS_LIB_VERSION);
|
||||
Serial.println();
|
||||
|
||||
// BMI - adjust to your local situation
|
||||
// https://en.wikipedia.org/wiki/List_of_sovereign_states_by_body_mass_index
|
||||
// stddev is assumption.
|
||||
G.begin(25.0, 2.5);
|
||||
}
|
||||
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
// flush
|
||||
while (Serial.available()) Serial.read();
|
||||
|
||||
Serial.println("Enter your weight in kg: ");
|
||||
while (!Serial.available());
|
||||
float weight = Serial.parseFloat();
|
||||
if (weight == 0) return;
|
||||
|
||||
while (Serial.available()) Serial.read();
|
||||
Serial.println("Enter your length in cm: ");
|
||||
while (!Serial.available());
|
||||
float length = Serial.parseFloat();
|
||||
if (length == 0) return;
|
||||
|
||||
float BMI = (10000.0 * weight) / (length * length);
|
||||
|
||||
float stddev = G.normalize(BMI);
|
||||
Serial.print("\tWeight:\t\t");
|
||||
Serial.println(weight);
|
||||
|
||||
Serial.print("\tLength:\t\t");
|
||||
Serial.println(length);
|
||||
|
||||
Serial.print("\tBMI:\t\t");
|
||||
Serial.println(BMI);
|
||||
|
||||
Serial.print("\tStddev:\t\t");
|
||||
if (stddev >= 0) Serial.print('+');
|
||||
Serial.println(stddev, 2);
|
||||
|
||||
Serial.print("\tSmaller:\t");
|
||||
Serial.print(100.0 * G.P_smaller(BMI));
|
||||
Serial.println("%");
|
||||
|
||||
Serial.print("\tLarger:\t\t");
|
||||
Serial.print(100.0 * G.P_larger(BMI));
|
||||
Serial.println("%");
|
||||
|
||||
Serial.print("\tSame:\t\t");
|
||||
Serial.print(100.0 * G.P_between(BMI - 0.1, BMI + 0.1));
|
||||
Serial.print("%");
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
35
libraries/Gauss/examples/Gauss_DS18B20/.arduino-ci.yml
Normal file
35
libraries/Gauss/examples/Gauss_DS18B20/.arduino-ci.yml
Normal file
@ -0,0 +1,35 @@
|
||||
platforms:
|
||||
rpipico:
|
||||
board: rp2040:rp2040:rpipico
|
||||
package: rp2040:rp2040
|
||||
gcc:
|
||||
features:
|
||||
defines:
|
||||
- ARDUINO_ARCH_RP2040
|
||||
warnings:
|
||||
flags:
|
||||
|
||||
packages:
|
||||
rp2040:rp2040:
|
||||
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
|
||||
|
||||
compile:
|
||||
# Choosing to run compilation tests on 2 different Arduino platforms
|
||||
platforms:
|
||||
- uno
|
||||
# - due
|
||||
# - zero
|
||||
# - leonardo
|
||||
- m4
|
||||
#- esp32
|
||||
- esp8266
|
||||
# - mega2560
|
||||
- rpipico
|
||||
libraries:
|
||||
- MultiMap
|
||||
- DS18B20_RT
|
||||
|
||||
unittest:
|
||||
# These dependent libraries will be installed
|
||||
libraries:
|
||||
- MultiMap
|
59
libraries/Gauss/examples/Gauss_DS18B20/Gauss_DS18B20.ino
Normal file
59
libraries/Gauss/examples/Gauss_DS18B20/Gauss_DS18B20.ino
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// FILE: Gauss_DS18B20.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo
|
||||
//
|
||||
// can be used with plotter
|
||||
|
||||
|
||||
#include "DS18B20.h"
|
||||
#include "Gauss.h"
|
||||
|
||||
#define ONE_WIRE_BUS 2
|
||||
|
||||
OneWire oneWire(ONE_WIRE_BUS);
|
||||
DS18B20 sensor(&oneWire);
|
||||
|
||||
Gauss G;
|
||||
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("GAUSS_LIB_VERSION:\t");
|
||||
Serial.println(GAUSS_LIB_VERSION);
|
||||
Serial.print("DS18B20_LIB_VERSION:\t");
|
||||
Serial.println(DS18B20_LIB_VERSION);
|
||||
Serial.println();
|
||||
|
||||
// default temperature + stddev
|
||||
// adjust to your local situation
|
||||
G.begin(26.00, 0.2);
|
||||
sensor.begin();
|
||||
sensor.setResolution(12);
|
||||
|
||||
Serial.println("\ndone...");
|
||||
}
|
||||
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
// simulation
|
||||
// float temp = 18 + random(800) * 0.01;
|
||||
|
||||
sensor.requestTemperatures();
|
||||
while (!sensor.isConversionComplete());
|
||||
float temp = sensor.getTempC();
|
||||
float stddev = G.normalize(temp);
|
||||
|
||||
Serial.print("TEMP: ");
|
||||
Serial.print(temp, 2);
|
||||
Serial.print("\tSTDDEV: ");
|
||||
if (stddev >= 0) Serial.print('+');
|
||||
Serial.print(stddev, 2);
|
||||
Serial.println();
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
35
libraries/Gauss/examples/Gauss_HX711/.arduino-ci.yml
Normal file
35
libraries/Gauss/examples/Gauss_HX711/.arduino-ci.yml
Normal file
@ -0,0 +1,35 @@
|
||||
platforms:
|
||||
rpipico:
|
||||
board: rp2040:rp2040:rpipico
|
||||
package: rp2040:rp2040
|
||||
gcc:
|
||||
features:
|
||||
defines:
|
||||
- ARDUINO_ARCH_RP2040
|
||||
warnings:
|
||||
flags:
|
||||
|
||||
packages:
|
||||
rp2040:rp2040:
|
||||
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
|
||||
|
||||
compile:
|
||||
# Choosing to run compilation tests on 2 different Arduino platforms
|
||||
platforms:
|
||||
- uno
|
||||
# - due
|
||||
# - zero
|
||||
# - leonardo
|
||||
- m4
|
||||
- esp32
|
||||
- esp8266
|
||||
# - mega2560
|
||||
- rpipico
|
||||
libraries:
|
||||
- MultiMap
|
||||
- HX711
|
||||
|
||||
unittest:
|
||||
# These dependent libraries will be installed
|
||||
libraries:
|
||||
- MultiMap
|
69
libraries/Gauss/examples/Gauss_HX711/Gauss_HX711.ino
Normal file
69
libraries/Gauss/examples/Gauss_HX711/Gauss_HX711.ino
Normal file
@ -0,0 +1,69 @@
|
||||
//
|
||||
// FILE: Gauss_HX711.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo
|
||||
//
|
||||
// can be used with plotter
|
||||
|
||||
|
||||
#include "HX711.h"
|
||||
#include "Gauss.h"
|
||||
|
||||
HX711 scale;
|
||||
uint8_t dataPin = 6;
|
||||
uint8_t clockPin = 7;
|
||||
|
||||
Gauss G;
|
||||
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("GAUSS_LIB_VERSION:\t");
|
||||
Serial.println(GAUSS_LIB_VERSION);
|
||||
Serial.print("HX711_LIB_VERSION:\t");
|
||||
Serial.println(HX711_LIB_VERSION);
|
||||
Serial.println();
|
||||
|
||||
// default weight in grams + stddev
|
||||
// adjust to your local situation
|
||||
G.begin(100.0, 0.75);
|
||||
|
||||
scale.begin(dataPin, clockPin);
|
||||
|
||||
// load cell factor 5 KG
|
||||
// TODO: calibrate the load cell.
|
||||
scale.set_scale(420.0983);
|
||||
|
||||
// reset the scale to zero = 0
|
||||
scale.tare();
|
||||
|
||||
Serial.println("you may now add weights.");
|
||||
}
|
||||
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
// simulation
|
||||
// float weight = 249 + random(20) * 0.1;
|
||||
|
||||
float weight = scale.get_units(5);
|
||||
float stddev = G.normalize(weight);
|
||||
|
||||
Serial.print("WEIGHT: ");
|
||||
Serial.print(weight, 1);
|
||||
Serial.print("\tSTDDEV: ");
|
||||
if (stddev >= 0) Serial.print('+');
|
||||
Serial.print(stddev, 2);
|
||||
Serial.print("\t");
|
||||
if (stddev < -1) Serial.print("LOW."); // TOO LOW
|
||||
else if (stddev > 1) Serial.print("HIGH.");
|
||||
else Serial.print("OK.");
|
||||
Serial.println();
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -150,5 +150,4 @@ void test_6()
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -- END OF FILE --
|
||||
|
@ -0,0 +1,17 @@
|
||||
Arduino UNO
|
||||
IDE 1.8.19
|
||||
|
||||
Gauss_performance.ino
|
||||
GAUSS_LIB_VERSION: 0.2.0
|
||||
|
||||
Timing in micros (1000 calls)
|
||||
|
||||
P_smaller: 159536
|
||||
P_larger: 169056
|
||||
P_between: 150148
|
||||
normalize: 23024
|
||||
bellCurve: 192524
|
||||
approx.bell: 333172
|
||||
|
||||
done...
|
||||
|
@ -17,9 +17,9 @@ void setup(void)
|
||||
Serial.println();
|
||||
|
||||
test_1();
|
||||
// test_2();
|
||||
// test_3();
|
||||
// test_4();
|
||||
test_2();
|
||||
test_3();
|
||||
test_4();
|
||||
|
||||
Serial.println("\ndone...");
|
||||
}
|
||||
|
@ -2,7 +2,8 @@
|
||||
// FILE: Gauss_test_bell_curve.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: demo
|
||||
|
||||
//
|
||||
// use plotter to create the graph in two ways
|
||||
|
||||
#include "Gauss.h"
|
||||
|
||||
@ -42,6 +43,7 @@ void get_bell_curve()
|
||||
}
|
||||
|
||||
|
||||
// approximation of the bell curve
|
||||
void approximate()
|
||||
{
|
||||
G.begin(0, 1);
|
||||
@ -49,8 +51,9 @@ void approximate()
|
||||
for (float f = -5.0; f <= 5.0; f += 0.01)
|
||||
{
|
||||
// width == 2x 0.5233 == 1.0466
|
||||
// 0.0466 heuristic correction factor to match peak of bellCurve()
|
||||
// not exact match but almost perfect
|
||||
// 0.0466 heuristic correction factor to match peak of the bell curve()
|
||||
// not an exact match but almost perfect
|
||||
// cf found with separate function below
|
||||
float cf = 0.52330751;
|
||||
float a = G.P_smaller(f - cf);
|
||||
float b = G.P_smaller(f + cf);
|
||||
@ -60,7 +63,7 @@ void approximate()
|
||||
}
|
||||
|
||||
|
||||
// find the correction factor for the appoximate function
|
||||
// find the correction factor for the approximate function
|
||||
// so the peak matches the bell curve function.
|
||||
// ==> 0.52330751
|
||||
void find_correction_factor()
|
||||
|
@ -15,15 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/Gauss.git"
|
||||
},
|
||||
"dependencies":
|
||||
[
|
||||
{
|
||||
"owner": "Rob Tillaart",
|
||||
"name": "MultiMap",
|
||||
"version": "^0.1.7"
|
||||
}
|
||||
],
|
||||
"version": "0.1.1",
|
||||
"version": "0.2.0",
|
||||
"license": "MIT",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*",
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=Gauss
|
||||
version=0.1.1
|
||||
version=0.2.0
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Library for the Gauss probability math.
|
||||
@ -8,5 +8,5 @@ category=Data Processing
|
||||
url=https://github.com/RobTillaart/Gauss
|
||||
architectures=*
|
||||
includes=Gauss.h
|
||||
depends=MultiMap
|
||||
depends=
|
||||
|
||||
|
@ -103,6 +103,22 @@ unittest(test_P_between)
|
||||
}
|
||||
|
||||
|
||||
unittest(test_P_outside)
|
||||
{
|
||||
Gauss G;
|
||||
|
||||
G.begin(0, 1);
|
||||
|
||||
assertEqualFloat(0.5013, G.P_outside(-3.0, 0.0), 0.0001);
|
||||
assertEqualFloat(0.5228, G.P_outside(-2.0, 0.0), 0.0001);
|
||||
assertEqualFloat(0.6587, G.P_outside(-1.0, 0.0), 0.0001);
|
||||
assertEqualFloat(1.0000, G.P_outside(0.0, 0.0), 0.0001);
|
||||
assertEqualFloat(0.6587, G.P_outside(0.0, 1.0), 0.0001);
|
||||
assertEqualFloat(0.5228, G.P_outside(0.0, 2.0), 0.0001);
|
||||
assertEqualFloat(0.5013, G.P_outside(0.0, 3.0), 0.0001);
|
||||
}
|
||||
|
||||
|
||||
unittest(test_P_equal)
|
||||
{
|
||||
Gauss G;
|
||||
@ -132,6 +148,14 @@ unittest(test_normailze)
|
||||
assertEqualFloat(1.0, G.normalize(125), 0.0001);
|
||||
assertEqualFloat(2.0, G.normalize(150), 0.0001);
|
||||
assertEqualFloat(3.0, G.normalize(175), 0.0001);
|
||||
|
||||
assertEqualFloat(25, G.denormalize(-3.0), 0.0001);
|
||||
assertEqualFloat(50, G.denormalize(-2.0), 0.0001);
|
||||
assertEqualFloat(75, G.denormalize(-1.0), 0.0001);
|
||||
assertEqualFloat(100, G.denormalize(0.0), 0.0001);
|
||||
assertEqualFloat(125, G.denormalize(1.0), 0.0001);
|
||||
assertEqualFloat(150, G.denormalize(2.0), 0.0001);
|
||||
assertEqualFloat(175, G.denormalize(3.0), 0.0001);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user