noise in robust should be gaussian, change variable names
parent
9e4be90111
commit
12930acdf6
|
@ -137,12 +137,12 @@ Fair::Fair(double c, const ReweightScheme reweight) : Base(reweight), c_(c) {
|
|||
}
|
||||
}
|
||||
|
||||
double Fair::weight(double error) const {
|
||||
return 1.0 / (1.0 + std::abs(error) / c_);
|
||||
double Fair::weight(double distance) const {
|
||||
return 1.0 / (1.0 + std::abs(distance) / c_);
|
||||
}
|
||||
|
||||
double Fair::loss(double error) const {
|
||||
const double absError = std::abs(error);
|
||||
double Fair::loss(double distance) const {
|
||||
const double absError = std::abs(distance);
|
||||
const double normalizedError = absError / c_;
|
||||
const double c_2 = c_ * c_;
|
||||
return c_2 * (normalizedError - std::log1p(normalizedError));
|
||||
|
@ -170,15 +170,15 @@ Huber::Huber(double k, const ReweightScheme reweight) : Base(reweight), k_(k) {
|
|||
}
|
||||
}
|
||||
|
||||
double Huber::weight(double error) const {
|
||||
const double absError = std::abs(error);
|
||||
double Huber::weight(double distance) const {
|
||||
const double absError = std::abs(distance);
|
||||
return (absError <= k_) ? (1.0) : (k_ / absError);
|
||||
}
|
||||
|
||||
double Huber::loss(double error) const {
|
||||
const double absError = std::abs(error);
|
||||
double Huber::loss(double distance) const {
|
||||
const double absError = std::abs(distance);
|
||||
if (absError <= k_) { // |x| <= k
|
||||
return error*error / 2;
|
||||
return distance*distance / 2;
|
||||
} else { // |x| > k
|
||||
return k_ * (absError - (k_/2));
|
||||
}
|
||||
|
@ -208,12 +208,12 @@ Cauchy::Cauchy(double k, const ReweightScheme reweight) : Base(reweight), k_(k),
|
|||
}
|
||||
}
|
||||
|
||||
double Cauchy::weight(double error) const {
|
||||
return ksquared_ / (ksquared_ + error*error);
|
||||
double Cauchy::weight(double distance) const {
|
||||
return ksquared_ / (ksquared_ + distance*distance);
|
||||
}
|
||||
|
||||
double Cauchy::loss(double error) const {
|
||||
const double val = std::log1p(error * error / ksquared_);
|
||||
double Cauchy::loss(double distance) const {
|
||||
const double val = std::log1p(distance * distance / ksquared_);
|
||||
return ksquared_ * val * 0.5;
|
||||
}
|
||||
|
||||
|
@ -241,18 +241,18 @@ Tukey::Tukey(double c, const ReweightScheme reweight) : Base(reweight), c_(c), c
|
|||
}
|
||||
}
|
||||
|
||||
double Tukey::weight(double error) const {
|
||||
if (std::abs(error) <= c_) {
|
||||
const double one_minus_xc2 = 1.0 - error*error/csquared_;
|
||||
double Tukey::weight(double distance) const {
|
||||
if (std::abs(distance) <= c_) {
|
||||
const double one_minus_xc2 = 1.0 - distance*distance/csquared_;
|
||||
return one_minus_xc2 * one_minus_xc2;
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double Tukey::loss(double error) const {
|
||||
double absError = std::abs(error);
|
||||
double Tukey::loss(double distance) const {
|
||||
double absError = std::abs(distance);
|
||||
if (absError <= c_) {
|
||||
const double one_minus_xc2 = 1.0 - error*error/csquared_;
|
||||
const double one_minus_xc2 = 1.0 - distance*distance/csquared_;
|
||||
const double t = one_minus_xc2*one_minus_xc2*one_minus_xc2;
|
||||
return csquared_ * (1 - t) / 6.0;
|
||||
} else {
|
||||
|
@ -280,13 +280,13 @@ Tukey::shared_ptr Tukey::Create(double c, const ReweightScheme reweight) {
|
|||
|
||||
Welsch::Welsch(double c, const ReweightScheme reweight) : Base(reweight), c_(c), csquared_(c * c) {}
|
||||
|
||||
double Welsch::weight(double error) const {
|
||||
const double xc2 = (error*error)/csquared_;
|
||||
double Welsch::weight(double distance) const {
|
||||
const double xc2 = (distance*distance)/csquared_;
|
||||
return std::exp(-xc2);
|
||||
}
|
||||
|
||||
double Welsch::loss(double error) const {
|
||||
const double xc2 = (error*error)/csquared_;
|
||||
double Welsch::loss(double distance) const {
|
||||
const double xc2 = (distance*distance)/csquared_;
|
||||
return csquared_ * 0.5 * -std::expm1(-xc2);
|
||||
}
|
||||
|
||||
|
@ -311,16 +311,16 @@ GemanMcClure::GemanMcClure(double c, const ReweightScheme reweight)
|
|||
: Base(reweight), c_(c) {
|
||||
}
|
||||
|
||||
double GemanMcClure::weight(double error) const {
|
||||
double GemanMcClure::weight(double distance) const {
|
||||
const double c2 = c_*c_;
|
||||
const double c4 = c2*c2;
|
||||
const double c2error = c2 + error*error;
|
||||
const double c2error = c2 + distance*distance;
|
||||
return c4/(c2error*c2error);
|
||||
}
|
||||
|
||||
double GemanMcClure::loss(double error) const {
|
||||
double GemanMcClure::loss(double distance) const {
|
||||
const double c2 = c_*c_;
|
||||
const double error2 = error*error;
|
||||
const double error2 = distance*distance;
|
||||
return 0.5 * (c2 * error2) / (c2 + error2);
|
||||
}
|
||||
|
||||
|
@ -345,8 +345,8 @@ DCS::DCS(double c, const ReweightScheme reweight)
|
|||
: Base(reweight), c_(c) {
|
||||
}
|
||||
|
||||
double DCS::weight(double error) const {
|
||||
const double e2 = error*error;
|
||||
double DCS::weight(double distance) const {
|
||||
const double e2 = distance*distance;
|
||||
if (e2 > c_)
|
||||
{
|
||||
const double w = 2.0*c_/(c_ + e2);
|
||||
|
@ -356,10 +356,10 @@ double DCS::weight(double error) const {
|
|||
return 1.0;
|
||||
}
|
||||
|
||||
double DCS::loss(double error) const {
|
||||
double DCS::loss(double distance) const {
|
||||
// This is the simplified version of Eq 9 from (Agarwal13icra)
|
||||
// after you simplify and cancel terms.
|
||||
const double e2 = error*error;
|
||||
const double e2 = distance*distance;
|
||||
const double e4 = e2*e2;
|
||||
const double c2 = c_*c_;
|
||||
|
||||
|
@ -391,17 +391,17 @@ L2WithDeadZone::L2WithDeadZone(double k, const ReweightScheme reweight)
|
|||
}
|
||||
}
|
||||
|
||||
double L2WithDeadZone::weight(double error) const {
|
||||
double L2WithDeadZone::weight(double distance) const {
|
||||
// note that this code is slightly uglier than residual, because there are three distinct
|
||||
// cases to handle (left of deadzone, deadzone, right of deadzone) instead of the two
|
||||
// cases (deadzone, non-deadzone) in residual.
|
||||
if (std::abs(error) <= k_) return 0.0;
|
||||
else if (error > k_) return (-k_+error)/error;
|
||||
else return (k_+error)/error;
|
||||
if (std::abs(distance) <= k_) return 0.0;
|
||||
else if (distance > k_) return (-k_+distance)/distance;
|
||||
else return (k_+distance)/distance;
|
||||
}
|
||||
|
||||
double L2WithDeadZone::loss(double error) const {
|
||||
const double abs_error = std::abs(error);
|
||||
double L2WithDeadZone::loss(double distance) const {
|
||||
const double abs_error = std::abs(distance);
|
||||
return (abs_error < k_) ? 0.0 : 0.5*(k_-abs_error)*(k_-abs_error);
|
||||
}
|
||||
|
||||
|
|
|
@ -80,10 +80,10 @@ class GTSAM_EXPORT Base {
|
|||
* functions. It would be better for this function to accept the vector and
|
||||
* internally call the norm if necessary.
|
||||
*/
|
||||
virtual double loss(double error) const { return 0; };
|
||||
virtual double loss(double distance) const { return 0; };
|
||||
|
||||
#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V4
|
||||
virtual double residual(double error) const { return loss(error); };
|
||||
virtual double residual(double distance) const { return loss(distance); };
|
||||
#endif
|
||||
/*
|
||||
* This method is responsible for returning the weight function for a given
|
||||
|
@ -93,12 +93,12 @@ class GTSAM_EXPORT Base {
|
|||
* for details. This method is required when optimizing cost functions with
|
||||
* robust penalties using iteratively re-weighted least squares.
|
||||
*/
|
||||
virtual double weight(double error) const = 0;
|
||||
virtual double weight(double distance) const = 0;
|
||||
|
||||
virtual void print(const std::string &s) const = 0;
|
||||
virtual bool equals(const Base &expected, double tol = 1e-8) const = 0;
|
||||
|
||||
double sqrtWeight(double error) const { return std::sqrt(weight(error)); }
|
||||
double sqrtWeight(double distance) const { return std::sqrt(weight(distance)); }
|
||||
|
||||
/** produce a weight vector according to an error vector and the implemented
|
||||
* robust function */
|
||||
|
@ -157,8 +157,8 @@ class GTSAM_EXPORT Fair : public Base {
|
|||
typedef boost::shared_ptr<Fair> shared_ptr;
|
||||
|
||||
Fair(double c = 1.3998, const ReweightScheme reweight = Block);
|
||||
double weight(double error) const override;
|
||||
double loss(double error) const override;
|
||||
double weight(double distance) const override;
|
||||
double loss(double distance) const override;
|
||||
void print(const std::string &s) const override;
|
||||
bool equals(const Base &expected, double tol = 1e-8) const override;
|
||||
static shared_ptr Create(double c, const ReweightScheme reweight = Block);
|
||||
|
@ -182,8 +182,8 @@ class GTSAM_EXPORT Huber : public Base {
|
|||
typedef boost::shared_ptr<Huber> shared_ptr;
|
||||
|
||||
Huber(double k = 1.345, const ReweightScheme reweight = Block);
|
||||
double weight(double error) const override;
|
||||
double loss(double error) const override;
|
||||
double weight(double distance) const override;
|
||||
double loss(double distance) const override;
|
||||
void print(const std::string &s) const override;
|
||||
bool equals(const Base &expected, double tol = 1e-8) const override;
|
||||
static shared_ptr Create(double k, const ReweightScheme reweight = Block);
|
||||
|
@ -212,8 +212,8 @@ class GTSAM_EXPORT Cauchy : public Base {
|
|||
typedef boost::shared_ptr<Cauchy> shared_ptr;
|
||||
|
||||
Cauchy(double k = 0.1, const ReweightScheme reweight = Block);
|
||||
double weight(double error) const override;
|
||||
double loss(double error) const override;
|
||||
double weight(double distance) const override;
|
||||
double loss(double distance) const override;
|
||||
void print(const std::string &s) const override;
|
||||
bool equals(const Base &expected, double tol = 1e-8) const override;
|
||||
static shared_ptr Create(double k, const ReweightScheme reweight = Block);
|
||||
|
@ -237,8 +237,8 @@ class GTSAM_EXPORT Tukey : public Base {
|
|||
typedef boost::shared_ptr<Tukey> shared_ptr;
|
||||
|
||||
Tukey(double c = 4.6851, const ReweightScheme reweight = Block);
|
||||
double weight(double error) const override;
|
||||
double loss(double error) const override;
|
||||
double weight(double distance) const override;
|
||||
double loss(double distance) const override;
|
||||
void print(const std::string &s) const override;
|
||||
bool equals(const Base &expected, double tol = 1e-8) const override;
|
||||
static shared_ptr Create(double k, const ReweightScheme reweight = Block);
|
||||
|
@ -262,8 +262,8 @@ class GTSAM_EXPORT Welsch : public Base {
|
|||
typedef boost::shared_ptr<Welsch> shared_ptr;
|
||||
|
||||
Welsch(double c = 2.9846, const ReweightScheme reweight = Block);
|
||||
double weight(double error) const override;
|
||||
double loss(double error) const override;
|
||||
double weight(double distance) const override;
|
||||
double loss(double distance) const override;
|
||||
void print(const std::string &s) const override;
|
||||
bool equals(const Base &expected, double tol = 1e-8) const override;
|
||||
static shared_ptr Create(double k, const ReweightScheme reweight = Block);
|
||||
|
@ -298,8 +298,8 @@ class GTSAM_EXPORT GemanMcClure : public Base {
|
|||
|
||||
GemanMcClure(double c = 1.0, const ReweightScheme reweight = Block);
|
||||
~GemanMcClure() {}
|
||||
double weight(double error) const override;
|
||||
double loss(double error) const override;
|
||||
double weight(double distance) const override;
|
||||
double loss(double distance) const override;
|
||||
void print(const std::string &s) const override;
|
||||
bool equals(const Base &expected, double tol = 1e-8) const override;
|
||||
static shared_ptr Create(double k, const ReweightScheme reweight = Block);
|
||||
|
@ -328,8 +328,8 @@ class GTSAM_EXPORT DCS : public Base {
|
|||
|
||||
DCS(double c = 1.0, const ReweightScheme reweight = Block);
|
||||
~DCS() {}
|
||||
double weight(double error) const override;
|
||||
double loss(double error) const override;
|
||||
double weight(double distance) const override;
|
||||
double loss(double distance) const override;
|
||||
void print(const std::string &s) const override;
|
||||
bool equals(const Base &expected, double tol = 1e-8) const override;
|
||||
static shared_ptr Create(double k, const ReweightScheme reweight = Block);
|
||||
|
@ -361,8 +361,8 @@ class GTSAM_EXPORT L2WithDeadZone : public Base {
|
|||
typedef boost::shared_ptr<L2WithDeadZone> shared_ptr;
|
||||
|
||||
L2WithDeadZone(double k = 1.0, const ReweightScheme reweight = Block);
|
||||
double weight(double error) const override;
|
||||
double loss(double error) const override;
|
||||
double weight(double distance) const override;
|
||||
double loss(double distance) const override;
|
||||
void print(const std::string &s) const override;
|
||||
bool equals(const Base &expected, double tol = 1e-8) const override;
|
||||
static shared_ptr Create(double k, const ReweightScheme reweight = Block);
|
||||
|
|
|
@ -654,6 +654,13 @@ void Robust::WhitenSystem(Matrix& A1, Matrix& A2, Matrix& A3, Vector& b) const{
|
|||
robust_->reweight(A1,A2,A3,b);
|
||||
}
|
||||
|
||||
Robust::shared_ptr Robust::Create(const RobustModel::shared_ptr& robust,
|
||||
const noiseModel::Base::shared_ptr noise) {
|
||||
SharedGaussian gaussian;
|
||||
gaussian = boost::dynamic_pointer_cast<noiseModel::Gaussian>(noise);
|
||||
return shared_ptr(new Robust(robust, gaussian));
|
||||
}
|
||||
|
||||
Robust::shared_ptr Robust::Create(
|
||||
const RobustModel::shared_ptr &robust, const NoiseModel::shared_ptr noise){
|
||||
return shared_ptr(new Robust(robust,noise));
|
||||
|
|
|
@ -90,7 +90,7 @@ namespace gtsam {
|
|||
/// Unwhiten an error vector.
|
||||
virtual Vector unwhiten(const Vector& v) const = 0;
|
||||
|
||||
/// calculate the error value given error vector
|
||||
/// calculate the error value given measurement error vector
|
||||
virtual double error(const Vector& v) const = 0;
|
||||
|
||||
#ifdef GTSAM_ALLOW_DEPRECATED_SINCE_V4
|
||||
|
@ -677,7 +677,7 @@ namespace gtsam {
|
|||
|
||||
protected:
|
||||
typedef mEstimator::Base RobustModel;
|
||||
typedef noiseModel::Base NoiseModel;
|
||||
typedef noiseModel::Gaussian NoiseModel;
|
||||
|
||||
const RobustModel::shared_ptr robust_; ///< robust error function used
|
||||
const NoiseModel::shared_ptr noise_; ///< noise model used
|
||||
|
@ -712,9 +712,7 @@ namespace gtsam {
|
|||
{ throw std::invalid_argument("unwhiten is not currently supported for robust noise models."); }
|
||||
// Fold the use of the m-estimator loss(...) function into error(...)
|
||||
inline virtual double error(const Vector& v) const
|
||||
{ return robust_->loss(this->unweightedWhiten(v).norm()); }
|
||||
// inline virtual double distance_non_whitened(const Vector& v) const
|
||||
// { return robust_->loss(v.norm()); }
|
||||
{ return robust_->loss(noise_->mahalanobisDistance(v)); }
|
||||
// TODO: these are really robust iterated re-weighting support functions
|
||||
virtual void WhitenSystem(Vector& b) const;
|
||||
virtual void WhitenSystem(std::vector<Matrix>& A, Vector& b) const;
|
||||
|
@ -723,13 +721,16 @@ namespace gtsam {
|
|||
virtual void WhitenSystem(Matrix& A1, Matrix& A2, Matrix& A3, Vector& b) const;
|
||||
|
||||
virtual Vector unweightedWhiten(const Vector& v) const {
|
||||
return noise_->unweightedWhiten(v);
|
||||
return noise_->whiten(v);
|
||||
}
|
||||
virtual double weight(const Vector& v) const {
|
||||
// Todo(mikebosse): make the robust weight function input a vector.
|
||||
return robust_->weight(v.norm());
|
||||
}
|
||||
|
||||
static shared_ptr Create(
|
||||
const RobustModel::shared_ptr &robust, const noiseModel::Base::shared_ptr noise);
|
||||
|
||||
static shared_ptr Create(
|
||||
const RobustModel::shared_ptr &robust, const NoiseModel::shared_ptr noise);
|
||||
|
||||
|
|
Loading…
Reference in New Issue