Fixed indentation
parent
ed338300a1
commit
ea9b44ea15
690
cpp/NoiseModel.h
690
cpp/NoiseModel.h
|
@ -15,387 +15,387 @@
|
||||||
|
|
||||||
namespace gtsam {
|
namespace gtsam {
|
||||||
|
|
||||||
class SharedDiagonal; // forward declare, defined at end
|
class SharedDiagonal; // forward declare, defined at end
|
||||||
|
|
||||||
namespace noiseModel {
|
namespace noiseModel {
|
||||||
|
|
||||||
/**
|
|
||||||
* noiseModel::Base is the abstract base class for all noise models.
|
|
||||||
*
|
|
||||||
* Noise models must implement a 'whiten' function to normalize an error vector,
|
|
||||||
* and an 'unwhiten' function to unnormalize an error vector.
|
|
||||||
*/
|
|
||||||
class Base : public Testable<Base> {
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
size_t dim_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Base(size_t dim):dim_(dim) {}
|
|
||||||
virtual ~Base() {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dimensionality
|
|
||||||
*/
|
|
||||||
inline size_t dim() const { return dim_;}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whiten an error vector.
|
|
||||||
*/
|
|
||||||
virtual Vector whiten(const Vector& v) const = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unwhiten an error vector.
|
|
||||||
*/
|
|
||||||
virtual Vector unwhiten(const Vector& v) const = 0;
|
|
||||||
|
|
||||||
/** in-place whiten, override if can be done more efficiently */
|
|
||||||
virtual void whitenInPlace(Vector& v) const {
|
|
||||||
v = whiten(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** in-place unwhiten, override if can be done more efficiently */
|
|
||||||
virtual void unwhitenInPlace(Vector& v) const {
|
|
||||||
v = unwhiten(v);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gaussian implements the mathematical model
|
|
||||||
* |R*x|^2 = |y|^2 with R'*R=inv(Sigma)
|
|
||||||
* where
|
|
||||||
* y = whiten(x) = R*x
|
|
||||||
* x = unwhiten(x) = inv(R)*y
|
|
||||||
* as indeed
|
|
||||||
* |y|^2 = y'*y = x'*R'*R*x
|
|
||||||
* Various derived classes are available that are more efficient.
|
|
||||||
*/
|
|
||||||
struct Gaussian: public Base {
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// TODO: store as boost upper-triangular or whatever is passed from above
|
|
||||||
/* Matrix square root of information matrix (R) */
|
|
||||||
boost::optional<Matrix> sqrt_information_;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return R itself, but note that Whiten(H) is cheaper than R*H
|
|
||||||
*/
|
|
||||||
const Matrix& thisR() const {
|
|
||||||
// should never happen
|
|
||||||
if (!sqrt_information_) throw std::runtime_error("Gaussian: has no R matrix");
|
|
||||||
return *sqrt_information_;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/** protected constructor takes square root information matrix */
|
|
||||||
Gaussian(size_t dim, const boost::optional<Matrix>& sqrt_information = boost::none) :
|
|
||||||
Base(dim), sqrt_information_(sqrt_information) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef boost::shared_ptr<Gaussian> shared_ptr;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Gaussian noise model created by specifying a square root information matrix.
|
|
||||||
* @param smart, check if can be simplified to derived class
|
|
||||||
*/
|
|
||||||
static shared_ptr SqrtInformation(const Matrix& R) {
|
|
||||||
return shared_ptr(new Gaussian(R.size1(),R));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Gaussian noise model created by specifying a covariance matrix.
|
|
||||||
* @param smart, check if can be simplified to derived class
|
|
||||||
*/
|
|
||||||
static shared_ptr Covariance(const Matrix& covariance, bool smart=false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Gaussian noise model created by specifying an information matrix.
|
|
||||||
*/
|
|
||||||
static shared_ptr Information(const Matrix& Q) {
|
|
||||||
return shared_ptr(new Gaussian(Q.size1(),square_root_positive(Q)));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void print(const std::string& name) const;
|
|
||||||
virtual bool equals(const Base& expected, double tol) const;
|
|
||||||
virtual Vector whiten(const Vector& v) const;
|
|
||||||
virtual Vector unwhiten(const Vector& v) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mahalanobis distance v'*R'*R*v = <R*v,R*v>
|
|
||||||
*/
|
|
||||||
virtual double Mahalanobis(const Vector& v) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Multiply a derivative with R (derivative of whiten)
|
|
||||||
* Equivalent to whitening each column of the input matrix.
|
|
||||||
*/
|
|
||||||
virtual Matrix Whiten(const Matrix& H) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* In-place version
|
|
||||||
*/
|
|
||||||
virtual void WhitenInPlace(Matrix& H) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whiten a system, in place as well
|
|
||||||
*/
|
|
||||||
inline void WhitenSystem(Matrix& A, Vector& b) const {
|
|
||||||
WhitenInPlace(A);
|
|
||||||
whitenInPlace(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply appropriately weighted QR factorization to the system [A b]
|
|
||||||
* Q' * [A b] = [R d]
|
|
||||||
* Dimensions: (r*m) * m*(n+1) = r*(n+1)
|
|
||||||
* @param Ab is the m*(n+1) augmented system matrix [A b]
|
|
||||||
* @return in-place QR factorization [R d]. Below-diagonal is undefined !!!!!
|
|
||||||
*/
|
|
||||||
virtual SharedDiagonal QR(Matrix& Ab) const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return R itself, but note that Whiten(H) is cheaper than R*H
|
|
||||||
*/
|
|
||||||
virtual Matrix R() const { return thisR();}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple check for constrained-ness
|
|
||||||
*/
|
|
||||||
virtual bool isConstrained() const {return false;}
|
|
||||||
|
|
||||||
}; // Gaussian
|
|
||||||
|
|
||||||
|
|
||||||
// FD: does not work, ambiguous overload :-(
|
|
||||||
// inline Vector operator*(const Gaussian& R, const Vector& v) {return R.whiten(v);}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A diagonal noise model implements a diagonal covariance matrix, with the
|
|
||||||
* elements of the diagonal specified in a Vector. This class has no public
|
|
||||||
* constructors, instead, use the static constructor functions Sigmas etc...
|
|
||||||
*/
|
|
||||||
class Diagonal : public Gaussian {
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/** sigmas and reciprocal */
|
|
||||||
Vector sigmas_, invsigmas_;
|
|
||||||
|
|
||||||
/** protected constructor takes sigmas */
|
|
||||||
Diagonal(const Vector& sigmas);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef boost::shared_ptr<Diagonal> shared_ptr;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A diagonal noise model created by specifying a Vector of sigmas, i.e.
|
|
||||||
* standard devations, the diagonal of the square root covariance matrix.
|
|
||||||
*/
|
|
||||||
static shared_ptr Sigmas(const Vector& sigmas, bool smart=false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A diagonal noise model created by specifying a Vector of variances, i.e.
|
|
||||||
* i.e. the diagonal of the covariance matrix.
|
|
||||||
* @param smart, check if can be simplified to derived class
|
|
||||||
*/
|
|
||||||
static shared_ptr Variances(const Vector& variances, bool smart = false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A diagonal noise model created by specifying a Vector of precisions, i.e.
|
|
||||||
* i.e. the diagonal of the information matrix, i.e., weights
|
|
||||||
*/
|
|
||||||
static shared_ptr Precisions(const Vector& precisions) {
|
|
||||||
return Variances(reciprocal(precisions));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void print(const std::string& name) const;
|
|
||||||
virtual Vector whiten(const Vector& v) const;
|
|
||||||
virtual Vector unwhiten(const Vector& v) const;
|
|
||||||
virtual Matrix Whiten(const Matrix& H) const;
|
|
||||||
virtual void WhitenInPlace(Matrix& H) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return standard deviations (sqrt of diagonal)
|
* noiseModel::Base is the abstract base class for all noise models.
|
||||||
*/
|
*
|
||||||
inline const Vector& sigmas() const { return sigmas_; }
|
* Noise models must implement a 'whiten' function to normalize an error vector,
|
||||||
inline double sigma(size_t i) const { return sigmas_(i); }
|
* and an 'unwhiten' function to unnormalize an error vector.
|
||||||
|
|
||||||
/**
|
|
||||||
* generate random variate
|
|
||||||
*/
|
|
||||||
virtual Vector sample() const;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return R itself, but note that Whiten(H) is cheaper than R*H
|
|
||||||
*/
|
*/
|
||||||
virtual Matrix R() const {
|
class Base : public Testable<Base> {
|
||||||
return diag(invsigmas_);
|
|
||||||
}
|
|
||||||
}; // Diagonal
|
|
||||||
|
|
||||||
/**
|
protected:
|
||||||
* A Constrained constrained model is a specialization of Diagonal which allows
|
|
||||||
* some or all of the sigmas to be zero, forcing the error to be zero there.
|
|
||||||
* All other Gaussian models are guaranteed to have a non-singular square-root
|
|
||||||
* information matrix, but this class is specifically equipped to deal with
|
|
||||||
* singular noise models, specifically: whiten will return zero on those
|
|
||||||
* components that have zero sigma *and* zero error, infinity otherwise.
|
|
||||||
*/
|
|
||||||
class Constrained : public Diagonal {
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// Constrained does not have member variables
|
size_t dim_;
|
||||||
// Instead (possibly zero) sigmas are stored in Diagonal Base class
|
|
||||||
|
|
||||||
/** protected constructor takes sigmas */
|
public:
|
||||||
Constrained(const Vector& sigmas) :Diagonal(sigmas) {}
|
|
||||||
|
|
||||||
public:
|
Base(size_t dim):dim_(dim) {}
|
||||||
|
virtual ~Base() {}
|
||||||
|
|
||||||
typedef boost::shared_ptr<Constrained> shared_ptr;
|
/**
|
||||||
|
* Dimensionality
|
||||||
|
*/
|
||||||
|
inline size_t dim() const { return dim_;}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A diagonal noise model created by specifying a Vector of
|
* Whiten an error vector.
|
||||||
* standard devations, some of which might be zero
|
*/
|
||||||
* TODO: make smart - check for zeros
|
virtual Vector whiten(const Vector& v) const = 0;
|
||||||
*/
|
|
||||||
static shared_ptr MixedSigmas(const Vector& sigmas, bool smart = false) {
|
|
||||||
return shared_ptr(new Constrained(sigmas));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A diagonal noise model created by specifying a Vector of
|
* Unwhiten an error vector.
|
||||||
* standard devations, some of which might be zero
|
*/
|
||||||
*/
|
virtual Vector unwhiten(const Vector& v) const = 0;
|
||||||
static shared_ptr MixedVariances(const Vector& variances) {
|
|
||||||
return shared_ptr(new Constrained(esqrt(variances)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/** in-place whiten, override if can be done more efficiently */
|
||||||
* A diagonal noise model created by specifying a Vector of
|
virtual void whitenInPlace(Vector& v) const {
|
||||||
* precisions, some of which might be inf
|
v = whiten(v);
|
||||||
*/
|
}
|
||||||
static shared_ptr MixedPrecisions(const Vector& precisions) {
|
|
||||||
return MixedVariances(reciprocal(precisions));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/** in-place unwhiten, override if can be done more efficiently */
|
||||||
* Fully constrained. TODO: subclass ?
|
virtual void unwhitenInPlace(Vector& v) const {
|
||||||
*/
|
v = unwhiten(v);
|
||||||
static shared_ptr All(size_t dim) {
|
}
|
||||||
return MixedSigmas(repeat(dim,0));
|
};
|
||||||
}
|
|
||||||
|
|
||||||
virtual void print(const std::string& name) const;
|
/**
|
||||||
virtual Vector whiten(const Vector& v) const;
|
* Gaussian implements the mathematical model
|
||||||
|
* |R*x|^2 = |y|^2 with R'*R=inv(Sigma)
|
||||||
|
* where
|
||||||
|
* y = whiten(x) = R*x
|
||||||
|
* x = unwhiten(x) = inv(R)*y
|
||||||
|
* as indeed
|
||||||
|
* |y|^2 = y'*y = x'*R'*R*x
|
||||||
|
* Various derived classes are available that are more efficient.
|
||||||
|
*/
|
||||||
|
struct Gaussian: public Base {
|
||||||
|
|
||||||
// Whitening Jacobians does not make sense for possibly constrained
|
private:
|
||||||
// noise model and will throw an exception.
|
|
||||||
|
|
||||||
virtual Matrix Whiten(const Matrix& H) const;
|
// TODO: store as boost upper-triangular or whatever is passed from above
|
||||||
virtual void WhitenInPlace(Matrix& H) const;
|
/* Matrix square root of information matrix (R) */
|
||||||
|
boost::optional<Matrix> sqrt_information_;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply QR factorization to the system [A b], taking into account constraints
|
* Return R itself, but note that Whiten(H) is cheaper than R*H
|
||||||
*/
|
*/
|
||||||
virtual SharedDiagonal QR(Matrix& Ab) const;
|
const Matrix& thisR() const {
|
||||||
|
// should never happen
|
||||||
|
if (!sqrt_information_) throw std::runtime_error("Gaussian: has no R matrix");
|
||||||
|
return *sqrt_information_;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
protected:
|
||||||
* Check constrained is always true
|
|
||||||
*/
|
|
||||||
virtual bool isConstrained() const {return true;}
|
|
||||||
|
|
||||||
}; // Constrained
|
/** protected constructor takes square root information matrix */
|
||||||
|
Gaussian(size_t dim, const boost::optional<Matrix>& sqrt_information = boost::none) :
|
||||||
|
Base(dim), sqrt_information_(sqrt_information) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
public:
|
||||||
* An isotropic noise model corresponds to a scaled diagonal covariance
|
|
||||||
* To construct, use one of the static methods
|
|
||||||
*/
|
|
||||||
class Isotropic : public Diagonal {
|
|
||||||
protected:
|
|
||||||
double sigma_, invsigma_;
|
|
||||||
|
|
||||||
/** protected constructor takes sigma */
|
typedef boost::shared_ptr<Gaussian> shared_ptr;
|
||||||
Isotropic(size_t dim, double sigma) :
|
|
||||||
Diagonal(repeat(dim, sigma)),sigma_(sigma),invsigma_(1.0/sigma) {}
|
|
||||||
|
|
||||||
public:
|
/**
|
||||||
|
* A Gaussian noise model created by specifying a square root information matrix.
|
||||||
|
* @param smart, check if can be simplified to derived class
|
||||||
|
*/
|
||||||
|
static shared_ptr SqrtInformation(const Matrix& R) {
|
||||||
|
return shared_ptr(new Gaussian(R.size1(),R));
|
||||||
|
}
|
||||||
|
|
||||||
typedef boost::shared_ptr<Isotropic> shared_ptr;
|
/**
|
||||||
|
* A Gaussian noise model created by specifying a covariance matrix.
|
||||||
|
* @param smart, check if can be simplified to derived class
|
||||||
|
*/
|
||||||
|
static shared_ptr Covariance(const Matrix& covariance, bool smart=false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An isotropic noise model created by specifying a standard devation sigma
|
* A Gaussian noise model created by specifying an information matrix.
|
||||||
*/
|
*/
|
||||||
static shared_ptr Sigma(size_t dim, double sigma) {
|
static shared_ptr Information(const Matrix& Q) {
|
||||||
return shared_ptr(new Isotropic(dim, sigma));
|
return shared_ptr(new Gaussian(Q.size1(),square_root_positive(Q)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
virtual void print(const std::string& name) const;
|
||||||
* An isotropic noise model created by specifying a variance = sigma^2.
|
virtual bool equals(const Base& expected, double tol) const;
|
||||||
* @param smart, check if can be simplified to derived class
|
virtual Vector whiten(const Vector& v) const;
|
||||||
*/
|
virtual Vector unwhiten(const Vector& v) const;
|
||||||
static shared_ptr Variance(size_t dim, double variance, bool smart = false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An isotropic noise model created by specifying a precision
|
* Mahalanobis distance v'*R'*R*v = <R*v,R*v>
|
||||||
*/
|
*/
|
||||||
static shared_ptr Precision(size_t dim, double precision) {
|
virtual double Mahalanobis(const Vector& v) const;
|
||||||
return Variance(dim, 1.0/precision);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void print(const std::string& name) const;
|
/**
|
||||||
virtual double Mahalanobis(const Vector& v) const;
|
* Multiply a derivative with R (derivative of whiten)
|
||||||
virtual Vector whiten(const Vector& v) const;
|
* Equivalent to whitening each column of the input matrix.
|
||||||
virtual Vector unwhiten(const Vector& v) const;
|
*/
|
||||||
virtual Matrix Whiten(const Matrix& H) const;
|
virtual Matrix Whiten(const Matrix& H) const;
|
||||||
virtual void WhitenInPlace(Matrix& H) const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return standard deviation
|
* In-place version
|
||||||
*/
|
*/
|
||||||
inline double sigma() const { return sigma_; }
|
virtual void WhitenInPlace(Matrix& H) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* generate random variate
|
* Whiten a system, in place as well
|
||||||
*/
|
*/
|
||||||
virtual Vector sample() const;
|
inline void WhitenSystem(Matrix& A, Vector& b) const {
|
||||||
|
WhitenInPlace(A);
|
||||||
|
whitenInPlace(b);
|
||||||
|
}
|
||||||
|
|
||||||
};
|
/**
|
||||||
|
* Apply appropriately weighted QR factorization to the system [A b]
|
||||||
|
* Q' * [A b] = [R d]
|
||||||
|
* Dimensions: (r*m) * m*(n+1) = r*(n+1)
|
||||||
|
* @param Ab is the m*(n+1) augmented system matrix [A b]
|
||||||
|
* @return in-place QR factorization [R d]. Below-diagonal is undefined !!!!!
|
||||||
|
*/
|
||||||
|
virtual SharedDiagonal QR(Matrix& Ab) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit: i.i.d. unit-variance noise on all m dimensions.
|
* Return R itself, but note that Whiten(H) is cheaper than R*H
|
||||||
*/
|
*/
|
||||||
class Unit : public Isotropic {
|
virtual Matrix R() const { return thisR();}
|
||||||
protected:
|
|
||||||
|
|
||||||
Unit(size_t dim): Isotropic(dim,1.0) {}
|
/**
|
||||||
|
* Simple check for constrained-ness
|
||||||
|
*/
|
||||||
|
virtual bool isConstrained() const {return false;}
|
||||||
|
|
||||||
public:
|
}; // Gaussian
|
||||||
|
|
||||||
typedef boost::shared_ptr<Unit> shared_ptr;
|
|
||||||
|
|
||||||
/**
|
// FD: does not work, ambiguous overload :-(
|
||||||
* Create a unit covariance noise model
|
// inline Vector operator*(const Gaussian& R, const Vector& v) {return R.whiten(v);}
|
||||||
*/
|
|
||||||
static shared_ptr Create(size_t dim) {
|
|
||||||
return shared_ptr(new Unit(dim));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void print(const std::string& name) const;
|
/**
|
||||||
virtual double Mahalanobis(const Vector& v) const {return inner_prod(v,v); }
|
* A diagonal noise model implements a diagonal covariance matrix, with the
|
||||||
virtual Vector whiten(const Vector& v) const { return v; }
|
* elements of the diagonal specified in a Vector. This class has no public
|
||||||
virtual Vector unwhiten(const Vector& v) const { return v; }
|
* constructors, instead, use the static constructor functions Sigmas etc...
|
||||||
virtual Matrix Whiten(const Matrix& H) const { return H; }
|
*/
|
||||||
virtual void WhitenInPlace(Matrix& H) const {}
|
class Diagonal : public Gaussian {
|
||||||
};
|
protected:
|
||||||
|
|
||||||
} // namespace noiseModel
|
/** sigmas and reciprocal */
|
||||||
|
Vector sigmas_, invsigmas_;
|
||||||
|
|
||||||
using namespace noiseModel;
|
/** protected constructor takes sigmas */
|
||||||
|
Diagonal(const Vector& sigmas);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<Diagonal> shared_ptr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A diagonal noise model created by specifying a Vector of sigmas, i.e.
|
||||||
|
* standard devations, the diagonal of the square root covariance matrix.
|
||||||
|
*/
|
||||||
|
static shared_ptr Sigmas(const Vector& sigmas, bool smart=false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A diagonal noise model created by specifying a Vector of variances, i.e.
|
||||||
|
* i.e. the diagonal of the covariance matrix.
|
||||||
|
* @param smart, check if can be simplified to derived class
|
||||||
|
*/
|
||||||
|
static shared_ptr Variances(const Vector& variances, bool smart = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A diagonal noise model created by specifying a Vector of precisions, i.e.
|
||||||
|
* i.e. the diagonal of the information matrix, i.e., weights
|
||||||
|
*/
|
||||||
|
static shared_ptr Precisions(const Vector& precisions) {
|
||||||
|
return Variances(reciprocal(precisions));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void print(const std::string& name) const;
|
||||||
|
virtual Vector whiten(const Vector& v) const;
|
||||||
|
virtual Vector unwhiten(const Vector& v) const;
|
||||||
|
virtual Matrix Whiten(const Matrix& H) const;
|
||||||
|
virtual void WhitenInPlace(Matrix& H) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return standard deviations (sqrt of diagonal)
|
||||||
|
*/
|
||||||
|
inline const Vector& sigmas() const { return sigmas_; }
|
||||||
|
inline double sigma(size_t i) const { return sigmas_(i); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate random variate
|
||||||
|
*/
|
||||||
|
virtual Vector sample() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return R itself, but note that Whiten(H) is cheaper than R*H
|
||||||
|
*/
|
||||||
|
virtual Matrix R() const {
|
||||||
|
return diag(invsigmas_);
|
||||||
|
}
|
||||||
|
}; // Diagonal
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Constrained constrained model is a specialization of Diagonal which allows
|
||||||
|
* some or all of the sigmas to be zero, forcing the error to be zero there.
|
||||||
|
* All other Gaussian models are guaranteed to have a non-singular square-root
|
||||||
|
* information matrix, but this class is specifically equipped to deal with
|
||||||
|
* singular noise models, specifically: whiten will return zero on those
|
||||||
|
* components that have zero sigma *and* zero error, infinity otherwise.
|
||||||
|
*/
|
||||||
|
class Constrained : public Diagonal {
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Constrained does not have member variables
|
||||||
|
// Instead (possibly zero) sigmas are stored in Diagonal Base class
|
||||||
|
|
||||||
|
/** protected constructor takes sigmas */
|
||||||
|
Constrained(const Vector& sigmas) :Diagonal(sigmas) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<Constrained> shared_ptr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A diagonal noise model created by specifying a Vector of
|
||||||
|
* standard devations, some of which might be zero
|
||||||
|
* TODO: make smart - check for zeros
|
||||||
|
*/
|
||||||
|
static shared_ptr MixedSigmas(const Vector& sigmas, bool smart = false) {
|
||||||
|
return shared_ptr(new Constrained(sigmas));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A diagonal noise model created by specifying a Vector of
|
||||||
|
* standard devations, some of which might be zero
|
||||||
|
*/
|
||||||
|
static shared_ptr MixedVariances(const Vector& variances) {
|
||||||
|
return shared_ptr(new Constrained(esqrt(variances)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A diagonal noise model created by specifying a Vector of
|
||||||
|
* precisions, some of which might be inf
|
||||||
|
*/
|
||||||
|
static shared_ptr MixedPrecisions(const Vector& precisions) {
|
||||||
|
return MixedVariances(reciprocal(precisions));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fully constrained. TODO: subclass ?
|
||||||
|
*/
|
||||||
|
static shared_ptr All(size_t dim) {
|
||||||
|
return MixedSigmas(repeat(dim,0));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void print(const std::string& name) const;
|
||||||
|
virtual Vector whiten(const Vector& v) const;
|
||||||
|
|
||||||
|
// Whitening Jacobians does not make sense for possibly constrained
|
||||||
|
// noise model and will throw an exception.
|
||||||
|
|
||||||
|
virtual Matrix Whiten(const Matrix& H) const;
|
||||||
|
virtual void WhitenInPlace(Matrix& H) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply QR factorization to the system [A b], taking into account constraints
|
||||||
|
*/
|
||||||
|
virtual SharedDiagonal QR(Matrix& Ab) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check constrained is always true
|
||||||
|
*/
|
||||||
|
virtual bool isConstrained() const {return true;}
|
||||||
|
|
||||||
|
}; // Constrained
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An isotropic noise model corresponds to a scaled diagonal covariance
|
||||||
|
* To construct, use one of the static methods
|
||||||
|
*/
|
||||||
|
class Isotropic : public Diagonal {
|
||||||
|
protected:
|
||||||
|
double sigma_, invsigma_;
|
||||||
|
|
||||||
|
/** protected constructor takes sigma */
|
||||||
|
Isotropic(size_t dim, double sigma) :
|
||||||
|
Diagonal(repeat(dim, sigma)),sigma_(sigma),invsigma_(1.0/sigma) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<Isotropic> shared_ptr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An isotropic noise model created by specifying a standard devation sigma
|
||||||
|
*/
|
||||||
|
static shared_ptr Sigma(size_t dim, double sigma) {
|
||||||
|
return shared_ptr(new Isotropic(dim, sigma));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An isotropic noise model created by specifying a variance = sigma^2.
|
||||||
|
* @param smart, check if can be simplified to derived class
|
||||||
|
*/
|
||||||
|
static shared_ptr Variance(size_t dim, double variance, bool smart = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An isotropic noise model created by specifying a precision
|
||||||
|
*/
|
||||||
|
static shared_ptr Precision(size_t dim, double precision) {
|
||||||
|
return Variance(dim, 1.0/precision);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void print(const std::string& name) const;
|
||||||
|
virtual double Mahalanobis(const Vector& v) const;
|
||||||
|
virtual Vector whiten(const Vector& v) const;
|
||||||
|
virtual Vector unwhiten(const Vector& v) const;
|
||||||
|
virtual Matrix Whiten(const Matrix& H) const;
|
||||||
|
virtual void WhitenInPlace(Matrix& H) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return standard deviation
|
||||||
|
*/
|
||||||
|
inline double sigma() const { return sigma_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generate random variate
|
||||||
|
*/
|
||||||
|
virtual Vector sample() const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit: i.i.d. unit-variance noise on all m dimensions.
|
||||||
|
*/
|
||||||
|
class Unit : public Isotropic {
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Unit(size_t dim): Isotropic(dim,1.0) {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<Unit> shared_ptr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a unit covariance noise model
|
||||||
|
*/
|
||||||
|
static shared_ptr Create(size_t dim) {
|
||||||
|
return shared_ptr(new Unit(dim));
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void print(const std::string& name) const;
|
||||||
|
virtual double Mahalanobis(const Vector& v) const {return inner_prod(v,v); }
|
||||||
|
virtual Vector whiten(const Vector& v) const { return v; }
|
||||||
|
virtual Vector unwhiten(const Vector& v) const { return v; }
|
||||||
|
virtual Matrix Whiten(const Matrix& H) const { return H; }
|
||||||
|
virtual void WhitenInPlace(Matrix& H) const {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace noiseModel
|
||||||
|
|
||||||
|
using namespace noiseModel;
|
||||||
} // namespace gtsam
|
} // namespace gtsam
|
||||||
|
|
Loading…
Reference in New Issue