Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "problib/pdfs/Gaussian.h"
00038 #include "problib/pdfs/Uniform.h"
00039
00040 using namespace pbl;
00041
00042 Gaussian::Gaussian(int dim) : PDF(dim, PDF::GAUSSIAN), ptr_(0) {
00043 }
00044
00045 Gaussian::Gaussian(const arma::vec& mu, const arma::mat& cov) : PDF(mu.n_elem, PDF::GAUSSIAN), ptr_(new GaussianStruct(mu, cov)) {
00046 }
00047
00048 Gaussian::Gaussian(const Gaussian& orig) : PDF(orig.ptr_->mu_.n_elem, PDF::GAUSSIAN), ptr_(orig.ptr_) {
00049 if (ptr_) {
00050 ++ptr_->n_ptrs_;
00051 }
00052 }
00053
00054 Gaussian::~Gaussian() {
00055 if (ptr_) {
00056 --ptr_->n_ptrs_;
00057
00058 if (ptr_->n_ptrs_ == 0) {
00059 delete ptr_;
00060 }
00061 }
00062 }
00063
00064 Gaussian& Gaussian::operator=(const Gaussian& other) {
00065 if (this != &other) {
00066 if (ptr_) {
00067 --ptr_->n_ptrs_;
00068 if (ptr_->n_ptrs_ == 0) {
00069 delete ptr_;
00070 }
00071 }
00072 ptr_ = other.ptr_;
00073 ++ptr_->n_ptrs_;
00074
00075 dimensions_ = other.dimensions_;
00076 }
00077 return *this;
00078 }
00079
00080 Gaussian* Gaussian::clone() const {
00081 return new Gaussian(*this);
00082 }
00083
00084 void Gaussian::cloneStruct() {
00085 if (ptr_->n_ptrs_ > 1) {
00086 --ptr_->n_ptrs_;
00087 ptr_ = new GaussianStruct(*ptr_);
00088 }
00089 }
00090
00091 double Gaussian::getLikelihood(const PDF& pdf) const {
00092 CHECK_INITIALIZED
00093
00094 if (pdf.type() == PDF::GAUSSIAN) {
00095 const Gaussian* G = static_cast<const pbl::Gaussian*>(&pdf);
00096 return getDensity(*G);
00097 } else if (pdf.type() == PDF::UNIFORM) {
00098 const Uniform* U = static_cast<const pbl::Uniform*>(&pdf);
00099 return U->getLikelihood(*this);
00100 }
00101
00102 assert_msg(false, "Gaussian: Likelihood can only be calculated with another Gaussian or Uniform pdf.");
00103 return 0;
00104 }
00105
00106 double Gaussian::getDensity(const arma::vec& v, double max_mah_dist) const {
00107 CHECK_INITIALIZED
00108 return getDensity(v, ptr_->mu_, ptr_->cov_, max_mah_dist);
00109 }
00110
00111 double Gaussian::getDensity(const Gaussian& G, double max_mah_dist) const {
00112 CHECK_INITIALIZED
00113 arma::mat S = G.getCovariance() + ptr_->cov_;
00114 return getDensity(ptr_->mu_, G.getMean(), S);
00115 }
00116
00117 double Gaussian::getMaxDensity() const {
00118 CHECK_INITIALIZED
00119 return getDensity(ptr_->mu_, ptr_->mu_, ptr_->cov_);
00120 }
00121
00122 bool Gaussian::getExpectedValue(arma::vec& v) const {
00123 CHECK_INITIALIZED
00124 v = ptr_->mu_;
00125 return true;
00126 }
00127
00128 double Gaussian::getDensity(const arma::vec& v1, const arma::vec& v2, const arma::mat& S, double max_mah_dist) const {
00129
00130 assert(v1.n_elem == v2.n_elem && v1.n_elem == S.n_rows);
00131
00132 double det = arma::det(S);
00133
00134
00135 assert(det != 0);
00136
00137
00138 arma::vec diff = v2 - v1;
00139
00140
00141 double mahalanobis_dist_sq = arma::dot(arma::inv(S) * diff, diff);
00142
00143
00144 assert(mahalanobis_dist_sq >= 0);
00145
00146
00147 if (max_mah_dist > 0 && mahalanobis_dist_sq > (max_mah_dist * max_mah_dist)) {
00148 return 0;
00149 }
00150
00151 double pi2_pow = 1;
00152 for(unsigned int d = 0; d < S.n_rows; ++d) {
00153 pi2_pow *= 2 * M_PI;
00154 }
00155
00156
00157 double pos_sqrt_pow = 1 / sqrt(pi2_pow * det);
00158 return exp(-0.5 * mahalanobis_dist_sq) * pos_sqrt_pow;
00159 }
00160
00161 void Gaussian::setMean(const arma::vec& mu) {
00162 if (ptr_) {
00163 cloneStruct();
00164 } else {
00165 ptr_ = new GaussianStruct(mu, arma::zeros(mu.n_elem, mu.n_elem));
00166 }
00167
00168 ptr_->mu_ = mu;
00169 }
00170
00171 void Gaussian::setCovariance(const arma::mat& cov) {
00172 if (ptr_) {
00173 cloneStruct();
00174 } else {
00175 ptr_ = new GaussianStruct(arma::zeros(cov.n_cols), cov);
00176 }
00177
00178 ptr_->cov_ = cov;
00179 }
00180
00181 const arma::vec& Gaussian::getMean() const {
00182 CHECK_INITIALIZED
00183 return ptr_->mu_;
00184 }
00185
00186 const arma::mat& Gaussian::getCovariance() const {
00187 CHECK_INITIALIZED
00188 return ptr_->cov_;
00189 }
00190
00191 std::string Gaussian::toString(const std::string& indent) const {
00192 if (!ptr_) {
00193 return "N(-)";
00194 }
00195
00196 std::stringstream s;
00197
00198 s << "N( [";
00199 for(int i = 0; i < dimensions_; ++i) {
00200 s << " " << ptr_->mu_(i);
00201 }
00202
00203 s << "], [";
00204 for(int i = 0; i < dimensions_; ++i) {
00205 for(int j = 0; j < dimensions_; ++j) {
00206 s << " " << ptr_->cov_(i, j);
00207 }
00208 s << ";";
00209 }
00210 s << "] )";
00211
00212 return s.str();
00213 }