// Copyright (C) 1998-1999 Jean-Marc Valin
#include "covariance.h"
#include <math.h>
#include "misc.h"
#include <string>
using namespace std;
namespace FD {
DECLARE_TYPE(DiagonalCovariance)
//@implements GMM
void DiagonalCovariance::processMean(RCPtr<Mean> mean)
{
if (mode == inverted) return;
if (mode != accum) throw string("DiagonalCovariance::processMean");
Mean &v=*mean;
double accum_1 = 1.0/(.001+v.getAccum());
for(int i = 0; i < dimension; i++ )
data[i] -= sqr(v[i])*accum_1;
}
void DiagonalCovariance::invert()
{
if (mode == inverted) return;
if (mode != accum) throw string("DiagonalCovariance::invert");
double accum_1 = 1.0/(.001+accum_count);
for(int i = 0; i < data.size(); i++ )
{
data[i] = 1.0 / (.001 + data[i] * accum_1);
}
mode = inverted;
}
double DiagonalCovariance::mahalanobisDistance(const float *x1, const double *x2) const
{
if (mode != inverted) throw string ("DiagonalCovariance::mahalanobisDistance");
double dist=0;
for (int i=0;i<dimension;i++)
dist += sqr(x1[i]-x2[i]) * data[i];
return dist-getDeterminant();
}
void DiagonalCovariance::compute_determinant() const
{
if (mode != inverted) throw string ("DiagonalCovariance::compute_determinant");
determinant=0;
for (unsigned int i=0;i<dimension;i++)
determinant += .5*log(data[i]);
determinant_is_valid = true;
}
void DiagonalCovariance::reset()
{
determinant_is_valid=false;
for (unsigned int i=0;i<dimension;i++)
data[i]=0.0;
mode = accum;
accum_count=0;
}
void DiagonalCovariance::printOn(ostream &out) const
{
out << "<DiagonalCovariance" << endl;
out << "<dimension " << dimension << ">" << endl;
out << "<mode " << mode << ">" << endl;
if (mode == accum)
out << "<accum_count " << accum_count << "> " << endl;
out << "<data";
for (int i=0;i<dimension;i++)
out << " " << data[i];
out << ">\n";
out << ">\n";
return;
}
void DiagonalCovariance::readFrom (istream &in)
{
dimension=-1;
string tag;
while (1)
{
char ch;
in >> ch;
if (ch == '>') break;
in >> tag;
if (tag == "dimension")
{
in >> dimension;
data.resize(dimension);
} else if (tag == "mode")
in >> mode;
else if (tag == "accum_count")
in >> accum_count;
else if (tag == "data")
{
if (dimension==-1)
throw new ParsingException("DiagonalCovariance::readFrom : dimension must be specified before data");
for (int i=0;i<dimension;i++)
in >> data[i];
} else
throw new ParsingException ("DiagonalCovariance::readFrom : unknown argument: " + tag);
if (!in) throw new ParsingException ("DiagonalCovariance::readFrom : Parse error trying to build " + tag);
in >> tag;
if (tag != ">") throw new ParsingException ("DiagonalCovariance::readFrom : Parse error: '>' expected ");
}
};
istream &operator >> (istream &in, DiagonalCovariance &cov)
{
if (!isValidType(in, "DiagonalCovariance")) return in;
cov.readFrom(in);
return in;
}
}//namespace FD
syntax highlighted by Code2HTML, v. 0.9.1