worked on 3d models within map
adjusted grid factory adjusted nav mesh factory minoor changes/fixes new helper classes refactoring
This commit is contained in:
59
math/distribution/ChiSquared.h
Normal file
59
math/distribution/ChiSquared.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#ifndef CHISQUARED_H
|
||||
#define CHISQUARED_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace Distribution {
|
||||
|
||||
/**
|
||||
* https://en.wikipedia.org/wiki/Chi-squared_distribution
|
||||
* @brief The ChiSquared class
|
||||
*/
|
||||
template <typename Scalar> class ChiSquared {
|
||||
|
||||
private:
|
||||
|
||||
// degrees of freedom
|
||||
int k;
|
||||
|
||||
public:
|
||||
|
||||
/** ctor */
|
||||
ChiSquared(const int k) : k(k) {
|
||||
;
|
||||
}
|
||||
|
||||
Scalar get(const Scalar val) const {
|
||||
|
||||
const Scalar k2 = k/((Scalar)2);
|
||||
const Scalar k2_1 = k2 - 1;
|
||||
const Scalar gamma = std::tgamma(k2);
|
||||
|
||||
return 1.0 / (std::pow(2, k2)*gamma) * std::pow(val, k2_1) * std::exp(-val/2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Scalar getInvCDF(const Scalar val) const {
|
||||
|
||||
// brute-force get the inverse CDF...
|
||||
|
||||
const Scalar ss = 0.002;
|
||||
Scalar sum = 0;
|
||||
|
||||
for (float t = 0; t < 20; t += ss) {
|
||||
sum += get(t) * ss;
|
||||
if (sum >= val) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
throw "failed";
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // CHISQUARED_H
|
||||
@@ -17,7 +17,7 @@ namespace Distribution {
|
||||
const T sigma;
|
||||
const T _a;
|
||||
|
||||
Random::RandomGenerator gen;
|
||||
Random::RandomGenerator gen;
|
||||
std::normal_distribution<T> dist;
|
||||
|
||||
public:
|
||||
@@ -32,6 +32,11 @@ namespace Distribution {
|
||||
mu(mu), sigma(sigma), _a(1.0 / (sigma * std::sqrt(2.0 * M_PI))), gen(seed), dist(mu,sigma) {
|
||||
}
|
||||
|
||||
/** mu = 0, sigma = 1 */
|
||||
static Normal unit() {
|
||||
return Normal(0,1);
|
||||
}
|
||||
|
||||
/** do not allow copy. this will not work as expected for std::normal_distribution when using draw() ?! */
|
||||
//Normal(const Normal& o) = delete;
|
||||
|
||||
@@ -51,15 +56,15 @@ namespace Distribution {
|
||||
gen.seed(seed);
|
||||
}
|
||||
|
||||
/** get the mean value */
|
||||
const T getMu() {
|
||||
return this->mu;
|
||||
}
|
||||
/** get the mean value */
|
||||
const T getMu() {
|
||||
return this->mu;
|
||||
}
|
||||
|
||||
/** get the standard deviation */
|
||||
const T getSigma() {
|
||||
return this->sigma;
|
||||
}
|
||||
/** get the standard deviation */
|
||||
const T getSigma() {
|
||||
return this->sigma;
|
||||
}
|
||||
|
||||
/** get the probability for the given value */
|
||||
static T getProbability(const T mu, const T sigma, const T val) {
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#include "../../Assertions.h"
|
||||
#include "../random/RandomGenerator.h"
|
||||
#include "../../geo/Point2.h"
|
||||
#include "ChiSquared.h"
|
||||
|
||||
namespace Distribution {
|
||||
|
||||
@@ -96,6 +98,43 @@ namespace Distribution {
|
||||
return NormalDistributionN(mean, cov);
|
||||
}
|
||||
|
||||
std::vector<Point2> getContour2(const double percentWithin) {
|
||||
|
||||
const int degreesOfFreedom = 2; // 2D distribution
|
||||
const ChiSquared<double> chi(degreesOfFreedom);
|
||||
|
||||
// https://people.richland.edu/james/lecture/m170/tbl-chi.html
|
||||
Assert::isNear(0.103, chi.getInvCDF(0.05), 0.01, "error within chi-squared distribution");
|
||||
Assert::isNear(0.211, chi.getInvCDF(0.10), 0.01, "error within chi-squared distribution");
|
||||
Assert::isNear(4.605, chi.getInvCDF(0.90), 0.01, "error within chi-squared distribution");
|
||||
Assert::isNear(5.991, chi.getInvCDF(0.95), 0.03, "error within chi-squared distribution");
|
||||
|
||||
// size of the ellipse using confidence intervals
|
||||
const float mul = chi.getInvCDF(percentWithin);
|
||||
|
||||
std::vector<Point2> res;
|
||||
|
||||
std::cout << sigma << std::endl;
|
||||
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(this->sigma);
|
||||
|
||||
Eigen::Vector2d evec1 = solver.eigenvectors().col(0);
|
||||
Eigen::Vector2d evec2 = solver.eigenvectors().col(1);
|
||||
|
||||
double eval1 = solver.eigenvalues()(0);
|
||||
double eval2 = solver.eigenvalues()(1);
|
||||
|
||||
for (int deg = 0; deg <= 360; deg += 5) {
|
||||
const float rad = deg / 180.0f * M_PI;
|
||||
Eigen::Vector2d pos =
|
||||
std::cos(rad) * std::sqrt(mul * eval1) * evec1 +
|
||||
std::sin(rad) * std::sqrt(mul * eval2) * evec2;
|
||||
res.push_back(Point2(pos(0), pos(1)));
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Distribution {
|
||||
|
||||
private:
|
||||
|
||||
Random::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;
|
||||
@@ -33,6 +33,11 @@ namespace Distribution {
|
||||
|
||||
}
|
||||
|
||||
/** -1 to +1 */
|
||||
static Uniform unit() {
|
||||
return Uniform(-1, +1);
|
||||
}
|
||||
|
||||
/** get a uniformaly distributed random number */
|
||||
T draw() {
|
||||
return dist(gen);
|
||||
|
||||
Reference in New Issue
Block a user