00001 #include "UniformPdf.hpp"
00002 #include "Random.hpp"
00003
00004 using namespace indii::ml::aux;
00005
00006 UniformPdf::UniformPdf() : p(0.0), lower(0), upper(0), mu(0),
00007 sigma(0), haveMu(false), haveSigma(false) {
00008
00009 }
00010
00011 UniformPdf::UniformPdf(const vector& lower, const vector& upper) :
00012 Pdf(lower.size()), lower(lower), upper(upper), mu(lower.size()),
00013 sigma(lower.size()), haveMu(false), haveSigma(false) {
00014
00015 assert(lower.size() == upper.size());
00016
00017 calculateDensity();
00018 }
00019
00020 UniformPdf& UniformPdf::operator=(const UniformPdf& o) {
00021
00022 assert (o.N == N);
00023
00024 haveMu = o.haveMu;
00025 haveSigma = o.haveSigma;
00026
00027 p = o.p;
00028 lower = o.lower;
00029 upper = o.upper;
00030 if (haveMu) {
00031 mu = o.mu;
00032 }
00033 if (haveSigma) {
00034 sigma = o.sigma;
00035 }
00036
00037 return *this;
00038 }
00039
00040 UniformPdf::~UniformPdf() {
00041
00042 }
00043
00044 void UniformPdf::setDimensions(const unsigned int N, const bool preserve) {
00045 this->N = N;
00046
00047 lower.resize(N, preserve);
00048 upper.resize(N, preserve);
00049 mu.resize(N, preserve);
00050 sigma.resize(N, preserve);
00051
00052 calculateDensity();
00053 }
00054
00055 const vector& UniformPdf::getExpectation() {
00056 if (!haveMu) {
00057 calculateExpectation();
00058 }
00059 return mu;
00060 }
00061
00062 const symmetric_matrix& UniformPdf::getCovariance() {
00063 if (!haveSigma) {
00064 calculateCovariance();
00065 }
00066 return sigma;
00067 }
00068
00069 vector UniformPdf::sample() {
00070 vector s(N);
00071 unsigned int i;
00072 for (i = 0; i < N; i++) {
00073 s(i) = Random::uniform(lower(i), upper(i));
00074 }
00075
00076 return s;
00077 }
00078
00079 double UniformPdf::densityAt(const vector& x) {
00080 bool inside = true;
00081 unsigned int i;
00082
00083 for (i = 0; i < N && inside; i++) {
00084 inside = inside && lower(i) <= x(i) && x(i) < upper(i);
00085 }
00086 return inside ? p : 0.0;
00087 }
00088
00089 void UniformPdf::calculateExpectation() {
00090 noalias(mu) = (lower + upper) / 2;
00091 haveMu = true;
00092
00093
00094 assert (haveMu);
00095 }
00096
00097 void UniformPdf::calculateCovariance() {
00098 vector diff(upper - lower);
00099 noalias(sigma) = outer_prod(diff, diff) / 12;
00100 haveSigma = true;
00101
00102
00103 assert (haveSigma);
00104 }
00105
00106 void UniformPdf::calculateDensity() {
00107 double volume = 1.0;
00108 vector::iterator iter, end;
00109 vector diff(upper - lower);
00110
00111 iter = diff.begin();
00112 end = diff.end();
00113 while (iter != end) {
00114 volume *= *iter;
00115 iter++;
00116 }
00117
00118 p = 1.0 / volume;
00119 }
00120