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:
toni
2017-11-15 17:43:32 +01:00
parent 72932ad90f
commit c8063bc862
35 changed files with 340 additions and 100 deletions

View File

@@ -10,5 +10,6 @@
#include "distribution/Triangle.h"
#include "distribution/NormalN.h"
#include "distribution/Rectangular.h"
#include "distribution/NormalCDF.h"
#endif // DISTRIBUTIONS_H

View File

@@ -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) {
;
}

View File

@@ -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

View File

@@ -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:

View File

@@ -8,7 +8,7 @@
#include <eigen3/Eigen/Dense>
#include "../../Assertions.h"
#include "../Random.h"
#include "../random/RandomGenerator.h"
namespace Distribution {

View File

@@ -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:

View 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

View File

@@ -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:

View File

@@ -4,7 +4,7 @@
#include <cmath>
#include <random>
#include "../Random.h"
#include "../random/RandomGenerator.h"
#include "../../Assertions.h"
#include "Normal.h"

View File

@@ -3,7 +3,7 @@
#include <cmath>
#include <random>
#include "../Random.h"
#include "../random/RandomGenerator.h"
#include "../../Assertions.h"
#include "Normal.h"

View File

@@ -3,7 +3,7 @@
#include <cmath>
#include <random>
#include "../Random.h"
#include "../random/RandomGenerator.h"
#include "../../Assertions.h"
#include "Normal.h"

View File

@@ -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
View 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