0.1.4 Correlation

This commit is contained in:
rob tillaart 2021-08-26 17:18:52 +02:00
parent 9d0e558a1c
commit 2e46b6f582
11 changed files with 121 additions and 67 deletions

View File

@ -4,10 +4,14 @@ name: Arduino CI
on: [push, pull_request]
jobs:
arduino_ci:
runTest:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: Arduino-CI/action@master
# Arduino-CI/action@v0.1.1
- uses: ruby/setup-ruby@v1
with:
ruby-version: 2.6
- run: |
gem install arduino_ci
arduino_ci.rb

View File

@ -1,10 +1,12 @@
//
// FILE: Correlation.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.1.3
// VERSION: 0.1.4
// PURPOSE: Arduino Library to determine correlation between X and Y dataset
//
// HISTORY:
// 0.1.4 2021-08-26 improve performance calculate
//
// 0.1.3 2021-01-16 add size in constructor,
// add statistical + debug functions
// 0.1.2 2020-12-17 add arduino-CI + unit tests
@ -73,40 +75,52 @@ bool Correlation::calculate()
if (!_needRecalculate) return true;
// CALC AVERAGE X, AVERAGE Y
_avgX = 0;
_avgY = 0;
float avgx = 0;
float avgy = 0;
for (uint8_t i = 0; i < _count; i++)
{
_avgX += _x[i];
_avgY += _y[i];
avgx += _x[i];
avgy += _y[i];
}
_avgX /= _count;
_avgY /= _count;
avgx /= _count;
avgy /= _count;
_avgX = avgx;
_avgY = avgy;
// CALC A and B ==> formula Y = A + B*X
_sumXiYi = 0;
_sumXi2 = 0;
_sumYi2 = 0;
float sumXiYi = 0;
float sumXi2 = 0;
float sumYi2 = 0;
for (uint8_t i = 0; i < _count; i++)
{
float xi = _x[i] - _avgX;
float yi = _y[i] - _avgY;
_sumXiYi += (xi * yi);
_sumXi2 += (xi * xi);
_sumYi2 += (yi * yi);
float xi = _x[i] - avgx;
float yi = _y[i] - avgy;
sumXiYi += (xi * yi);
sumXi2 += (xi * xi);
sumYi2 += (yi * yi);
}
_b = _sumXiYi / _sumXi2;
_a = _avgY - _b * _avgX;
_rSquare = _sumXiYi * _sumXiYi / (_sumXi2 * _sumYi2);
float b = sumXiYi / sumXi2;
float a = avgy - b * avgx;
// bool CORLIB_CALC_R_SQUARE
_rSquare = sumXiYi * sumXiYi / (sumXi2 * sumYi2);
_a = a;
_b = b;
_sumXiYi = sumXiYi;
_sumXi2 = sumXi2;
_sumYi2 = sumYi2;
// bool CORLIB_CALC_E_SQUARE
// CALC _sumErrorSquare
_sumErrorSquare = 0;
float sumErrorSquare = 0;
for (uint8_t i = 0; i < _count; i++)
{
float EY = _a + _b * _x[i];
float EY = a + b * _x[i];
float ei = _y[i] - EY;
_sumErrorSquare += (ei * ei);
sumErrorSquare += (ei * ei);
}
_sumErrorSquare = sumErrorSquare;
_needRecalculate = false;
return true;
}

View File

@ -2,7 +2,7 @@
//
// FILE: Correlation.h
// AUTHOR: Rob Tillaart
// VERSION: 0.1.3
// VERSION: 0.1.4
// PURPOSE: Calculate Correlation from a small dataset.
// HISTORY: See Correlation.cpp
//
@ -11,7 +11,7 @@
#include "Arduino.h"
#define CORRELATION_LIB_VERSION (F("0.1.3"))
#define CORRELATION_LIB_VERSION (F("0.1.4"))
class Correlation

View File

@ -1,5 +1,7 @@
[![Arduino CI](https://github.com/RobTillaart/Correlation/workflows/Arduino%20CI/badge.svg)](https://github.com/marketplace/actions/arduino_ci)
[![Arduino-lint](https://github.com/RobTillaart/Correlation/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/RobTillaart/Correlation/actions/workflows/arduino-lint.yml)
[![JSON check](https://github.com/RobTillaart/Correlation/actions/workflows/jsoncheck.yml/badge.svg)](https://github.com/RobTillaart/Correlation/actions/workflows/jsoncheck.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/RobTillaart/Correlation/blob/master/LICENSE)
[![GitHub release](https://img.shields.io/github/release/RobTillaart/Correlation.svg?maxAge=3600)](https://github.com/RobTillaart/Correlation/releases)
@ -13,7 +15,7 @@ Arduino Library to determine linear correlation between X and Y datasets.
This library calculates the coefficients of the linear correlation
between two (relative small) datasets. The size of these datasets is
20 by default, but this can be set in the constructor.
20 by default. The size can be set in the constructor.
The formula of the correlation is expressed as **Y = A + B \* X**,
@ -35,7 +37,7 @@ Use with care.
### Base functions
- **bool add(x, y)** adds a pair of **floats** to the internal storage.
- **bool add(float x, float y)** adds a pair of **floats** to the internal storage.
Returns true if the value is added, returns false when internal array is full.
When running correlation is set, it will replace the oldest element and return true.
- **uint8_t count()** returns the amount of items in the internal arrays.
@ -56,19 +58,20 @@ Most often the R squared **sqr(R)** is used.
quality of the relation.
- **float getAvgX()** returns the average of all elements in the X dataset.
- **float getAvgY()** returns the average of all elements in the Y dataset.
- **float getEstimateX(y)** use to calculate the estimated X for a certain Y.
- **float getEstimateY(x)** use to calculate the estimated Y for a certain X.
- **float getEstimateX(float y)** use to calculate the estimated X for a given Y.
- **float getEstimateY(float x)** use to calculate the estimated Y for a given X.
### Running correlation
- **setRunningCorrelation(true | false)** sets the internal variable
- **void setRunningCorrelation(bool rc)** sets the internal variable
runningMode which allows **add()** to overwrite old elements in the
internal arrays.
- **bool getRunningCorrelation()** returns the runningMOde flag.
The running correlation will be calculated over the last **count** elements.
This allows for more adaptive formula finding e.g. find the relation between
temperature and humidity for per hour.
temperature and humidity per hour.
### Statistical

View File

@ -1,31 +0,0 @@
- calculateAfterAdd flag - useful ?
- precalculate 1/_b for faster estimate X
extra mem // could be commented code.
- optimize loops? possible?
- flag for calculation of _sumErrorSquare
gain ~900 uSec
- flag for calculation of _Rsquare
gain ~400 uSec
- merge booleans/ flags into a config byte?
saves some mem
#define CORLIB_RECALC 0x01
#define CORLIB_RUNMODE_CONT 0x02
#define CORLIB_CALC_E_SQUARE 0x04
#define CORLIB_CALC_R_SQUARE 0x08
---------------------------------------
- use of dynamic memory for the datasets so runtime size is possible.
- Type as parameter.

View File

@ -2,7 +2,7 @@
// FILE: correlation_performance.ino
// AUTHOR: Rob Tillaart
// DATE: 2020-05-18
// VERSION: 0.1.0
// VERSION: 0.1.1
// PUPROSE: demo of the Correlation Library
// performance test: only ADD and CALCULATE as these are the most used
@ -11,7 +11,7 @@
#include "Correlation.h"
Correlation C;
Correlation C(100);
uint32_t start, stop, sum = 0;
@ -21,6 +21,8 @@ void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("CORRELATION_LIB_VERSION: ");
Serial.println(CORRELATION_LIB_VERSION);
Serial.println("ADD");
delay(10);
@ -67,6 +69,13 @@ void setup()
Serial.println(stop - start);
Serial.println("\ngetMaxX");
delay(10);
start = micros();
f = C.getMaxX();
stop = micros();
Serial.println(stop - start);
Serial.println("\nDone...");
}

View File

@ -0,0 +1,17 @@
ADD
10.60
CALCULATE - needed
2780
CALCULATE - no new values added
12
getEstimateX
44
getEstimateY
20
Done...

View File

@ -0,0 +1,22 @@
CORRELATION_LIB_VERSION: 0.1.4
ADD
10.60
CALCULATE - needed
2720
CALCULATE - no new values added
12
getEstimateX
44
getEstimateY
20
getMaxX
92
Done...

View File

@ -10,6 +10,7 @@ size KEYWORD2
clear KEYWORD2
setRunningCorrelation KEYWORD2
getRunningCorrelation KEYWORD2
calculate KEYWORD2
getA KEYWORD2
@ -23,6 +24,21 @@ getAvgY KEYWORD2
getEstimateY KEYWORD2
getEstimateX KEYWORD2
getMinX KEYWORD2
getMaxX KEYWORD2
getMinY KEYWORD2
getMaxY KEYWORD2
setXY KEYWORD2
setX KEYWORD2
setY KEYWORD2
getX KEYWORD2
getY KEYWORD2
getSumXiYi KEYWORD2
getSumXi2 KEYWORD2
getSumYi2 KEYWORD2
# Constants (LITERAL1)
CORRELATION_LIB_VERSION LITERAL1

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/Correlation.git"
},
"version": "0.1.3",
"version": "0.1.4",
"license": "MIT",
"frameworks": "arduino",
"platforms": "*"

View File

@ -1,5 +1,5 @@
name=Correlation
version=0.1.3
version=0.1.4
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Arduino Library to determine correlation between X and Y dataset