ref #39 #40 moved all stuff left in KLib into Indoor. We are now able to perform localization without the need of KLib. Only K::Gnuplot is needed for drawing, but this will be separated into an own project in the future
This commit is contained in:
@@ -10,5 +10,6 @@
|
||||
#include "distribution/Triangle.h"
|
||||
#include "distribution/NormalN.h"
|
||||
#include "distribution/Rectangular.h"
|
||||
#include "distribution/NormalCDF.h"
|
||||
|
||||
#endif // DISTRIBUTIONS_H
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "Random.h"
|
||||
#include "random/RandomGenerator.h"
|
||||
#include "../Assertions.h"
|
||||
|
||||
/**
|
||||
@@ -41,13 +41,13 @@ private:
|
||||
std::vector<Entry> elements;
|
||||
|
||||
/** the used random number generator */
|
||||
RandomGenerator& gen;
|
||||
Random::RandomGenerator& gen;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
/** default random generator. fallback */
|
||||
RandomGenerator defRndGen;
|
||||
Random::RandomGenerator defRndGen;
|
||||
|
||||
|
||||
public:
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
}
|
||||
|
||||
/** ctor with custom RandomNumberGenerator */
|
||||
DrawList(RandomGenerator& gen) : cumProbability(0), gen(gen) {
|
||||
DrawList(Random::RandomGenerator& gen) : cumProbability(0), gen(gen) {
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
#ifndef RANDOM_H
|
||||
#define RANDOM_H
|
||||
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
#include "../misc/Time.h"
|
||||
|
||||
#ifdef USE_FIXED_SEED
|
||||
#define RANDOM_SEED 1234
|
||||
#else
|
||||
#define RANDOM_SEED ( std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1) )
|
||||
#endif
|
||||
|
||||
//using RandomGenerator = std::minstd_rand;
|
||||
|
||||
class RandomGenerator : public std::minstd_rand {
|
||||
|
||||
public:
|
||||
|
||||
/** ctor with default seed */
|
||||
RandomGenerator() : std::minstd_rand(RANDOM_SEED) {;}
|
||||
|
||||
/** ctor with custom seed */
|
||||
RandomGenerator(result_type seed) : std::minstd_rand(seed) {;}
|
||||
|
||||
};
|
||||
|
||||
#endif // RANDOM_H
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
#include "../Random.h"
|
||||
#include "../random/RandomGenerator.h"
|
||||
|
||||
namespace Distribution {
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Distribution {
|
||||
|
||||
const T lambda;
|
||||
|
||||
RandomGenerator gen;
|
||||
Random::RandomGenerator gen;
|
||||
std::exponential_distribution<T> dist;
|
||||
|
||||
public:
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <eigen3/Eigen/Dense>
|
||||
|
||||
#include "../../Assertions.h"
|
||||
#include "../Random.h"
|
||||
#include "../random/RandomGenerator.h"
|
||||
|
||||
|
||||
namespace Distribution {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
#include "../Random.h"
|
||||
#include "../random/RandomGenerator.h"
|
||||
#include "../../Assertions.h"
|
||||
|
||||
namespace Distribution {
|
||||
@@ -17,7 +17,7 @@ namespace Distribution {
|
||||
const T sigma;
|
||||
const T _a;
|
||||
|
||||
RandomGenerator gen;
|
||||
Random::RandomGenerator gen;
|
||||
std::normal_distribution<T> dist;
|
||||
|
||||
public:
|
||||
|
||||
65
math/distribution/NormalCDF.h
Normal file
65
math/distribution/NormalCDF.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef NORMALCDF_H
|
||||
#define NORMALCDF_H
|
||||
|
||||
#include <algorithm>
|
||||
#include <random>
|
||||
#include "../../Assertions.h"
|
||||
|
||||
namespace Distribution {
|
||||
|
||||
/** cumulative density version of the normal distribution */
|
||||
template <typename T> class NormalCDF {
|
||||
|
||||
private:
|
||||
|
||||
const T mu;
|
||||
const T sigma;
|
||||
|
||||
static T RationalApproximation(T t)
|
||||
{
|
||||
// Abramowitz and Stegun formula 26.2.23.
|
||||
// The absolute value of the error should be less than 4.5 e-4.
|
||||
T c[] = {2.515517, 0.802853, 0.010328};
|
||||
T d[] = {1.432788, 0.189269, 0.001308};
|
||||
return t - ((c[2]*t + c[1])*t + c[0]) /
|
||||
(((d[2]*t + d[1])*t + d[0])*t + 1.0);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/** create a new normally distributed CDF */
|
||||
NormalCDF(const T mu, const T sigma) : mu(mu), sigma(sigma) {
|
||||
;
|
||||
}
|
||||
|
||||
/** get the probability for val within the underlying CDF */
|
||||
T getProbability(const T val) const {
|
||||
return getProbability(mu, sigma, val);
|
||||
}
|
||||
|
||||
/** calculate the probability within the underlying CDF */
|
||||
static T getProbability(const T mu, const T sigma, const T val) {
|
||||
return (1.0 + std::exp( (val - mu) / (sigma * std::sqrt(2)) ) ) / 2.0;
|
||||
}
|
||||
|
||||
/** get the inverse CDF (https://en.wikipedia.org/wiki/Probit)*/
|
||||
static T getProbit(T p){
|
||||
|
||||
Assert::isBetween(p, 0.0, 1.0, "value not between");
|
||||
|
||||
// See: https://www.johndcook.com/blog/normal_cdf_inverse/
|
||||
if (p < 0.5)
|
||||
{
|
||||
// F^-1(p) = - G^-1(p)
|
||||
return -RationalApproximation( sqrt(-2.0*log(p)) );
|
||||
}
|
||||
else
|
||||
{
|
||||
// F^-1(p) = G^-1(1-p)
|
||||
return RationalApproximation( sqrt(-2.0*log(1-p)) );
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // NORMALCDF_H
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <eigen3/Eigen/Dense>
|
||||
|
||||
#include "../../Assertions.h"
|
||||
#include "../Random.h"
|
||||
#include "../random/RandomGenerator.h"
|
||||
|
||||
namespace Distribution {
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Distribution {
|
||||
const Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eigenSolver;
|
||||
Eigen::MatrixXd transform; //can i make this const?
|
||||
|
||||
RandomGenerator gen;
|
||||
Random::RandomGenerator gen;
|
||||
std::normal_distribution<> dist;
|
||||
|
||||
public:
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
#include "../Random.h"
|
||||
#include "../random/RandomGenerator.h"
|
||||
#include "../../Assertions.h"
|
||||
#include "Normal.h"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
#include "../Random.h"
|
||||
#include "../random/RandomGenerator.h"
|
||||
#include "../../Assertions.h"
|
||||
#include "Normal.h"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
#include "../Random.h"
|
||||
#include "../random/RandomGenerator.h"
|
||||
#include "../../Assertions.h"
|
||||
#include "Normal.h"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include <cmath>
|
||||
#include <random>
|
||||
#include "../Random.h"
|
||||
#include "../random/RandomGenerator.h"
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Distribution {
|
||||
|
||||
private:
|
||||
|
||||
RandomGenerator gen;
|
||||
Random::RandomGenerator gen;
|
||||
|
||||
/** depending on T, Dist is either a uniform_real or uniform_int distribution */
|
||||
typedef typename std::conditional< std::is_floating_point<T>::value, std::uniform_real_distribution<T>, std::uniform_int_distribution<T> >::type Dist;
|
||||
|
||||
169
math/stats/Statistics.h
Normal file
169
math/stats/Statistics.h
Normal file
@@ -0,0 +1,169 @@
|
||||
#ifndef STATISTICS_H
|
||||
#define STATISTICS_H
|
||||
|
||||
#include <set>
|
||||
#include <cstdint>
|
||||
#include <sstream>
|
||||
#include <cmath>
|
||||
|
||||
namespace Stats {
|
||||
|
||||
/**
|
||||
* store values here and get statistics about their
|
||||
* avg, median, std-dev, etc.
|
||||
*/
|
||||
template <typename T> class Statistics {
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
Statistics() : sum(), sumSquared(), cnt() {;}
|
||||
|
||||
/** dtor */
|
||||
~Statistics() {;}
|
||||
|
||||
/** add a new value */
|
||||
void add(T value) {
|
||||
++cnt;
|
||||
sum += value;
|
||||
sumSquared += (value*value);
|
||||
values.insert(value);
|
||||
}
|
||||
|
||||
/** add all values from the given statistics instance */
|
||||
void add(const Statistics<T>& other) {
|
||||
for (const T val : other.values) {
|
||||
this->add(val);
|
||||
}
|
||||
}
|
||||
|
||||
/** get the std-dev of all values */
|
||||
T getStdDev() const {
|
||||
double E1 = sumSquared / (double) cnt;
|
||||
double E2 = getAvg();
|
||||
return std::sqrt(E1 - (E2*E2));
|
||||
}
|
||||
|
||||
/** get average value */
|
||||
T getAvg() const {
|
||||
return sum / (double) cnt;
|
||||
}
|
||||
|
||||
/** get the given quantile (e.g. 0.5 for median) */
|
||||
T getQuantile(const double q) const {
|
||||
if (q < 0) {return *values.begin();}
|
||||
if (q >= 1) {return *(--values.end());}
|
||||
uint32_t pos = cnt * q;
|
||||
uint32_t curPos = 0;
|
||||
for (auto val : values) {
|
||||
if (curPos == pos) {return val;}
|
||||
++curPos;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** get the median value (= Quantile 0.5) */
|
||||
T getMedian() const {
|
||||
return getQuantile(0.5f);
|
||||
}
|
||||
|
||||
/** get smallest value */
|
||||
T getMin() const {
|
||||
if (values.empty()) {return -1;}
|
||||
return *(values.begin());
|
||||
}
|
||||
|
||||
/** get largest value */
|
||||
T getMax() const {
|
||||
if (values.empty()) {return -1;}
|
||||
return *(--values.end());
|
||||
}
|
||||
|
||||
/** get the range between min an max */
|
||||
T getRange() const {
|
||||
return getMax() - getMin();
|
||||
}
|
||||
|
||||
/** get the squared sum */
|
||||
T getSquaredSum() const {
|
||||
return sumSquared;
|
||||
}
|
||||
|
||||
|
||||
/** get the sum of all values */
|
||||
T getSum() const {
|
||||
return sum;
|
||||
}
|
||||
|
||||
/** get number of stored values */
|
||||
uint32_t getCount() const {
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/** get the number of values that are below "val" */
|
||||
T getNumValuesBelow(uint32_t val) const {
|
||||
uint32_t numFound = 0;
|
||||
for (auto curVal : values) {
|
||||
if (curVal > val) {return numFound;}
|
||||
++numFound;
|
||||
}
|
||||
return numFound;
|
||||
}
|
||||
|
||||
/** get all contained values in ascending order */
|
||||
const std::multiset<T>& getAll() const {
|
||||
return values;
|
||||
}
|
||||
|
||||
/** get as string */
|
||||
std::string asString() const {
|
||||
std::stringstream ss;
|
||||
appendTo(ss);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
/** send to the given stream */
|
||||
void appendTo(std::ostream& out) const {
|
||||
out.precision(6);
|
||||
out.setf( std::ios::fixed, std:: ios::floatfield );
|
||||
out << "cnt(" << getCount() << ")\t";
|
||||
out << "min(" << getMin() << ")\t";
|
||||
out << "max(" << getMax() << ")\t";
|
||||
out << "range(" << getRange() << ")\t";
|
||||
out << "med(" << getMedian() << ")\t";
|
||||
out << "avg(" << getAvg() << ")\t";
|
||||
out << "stdDev(" << getStdDev() << ")\t";
|
||||
}
|
||||
|
||||
/** send to stream */
|
||||
inline std::ostream& operator << (std::ostream& out) const {
|
||||
appendTo(out); return out;
|
||||
}
|
||||
|
||||
/** reset all statistics */
|
||||
void reset() {
|
||||
sum = T();
|
||||
sumSquared = T();
|
||||
cnt = 0;
|
||||
values.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/** sum of all added values */
|
||||
T sum;
|
||||
|
||||
/** squared sum of all added values (for std-dev) */
|
||||
T sumSquared;
|
||||
|
||||
/** the number of added values */
|
||||
uint32_t cnt;
|
||||
|
||||
/** multiset to sort all values */
|
||||
std::multiset<T> values;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // STATISTICS_H
|
||||
Reference in New Issue
Block a user