📄 mestimator.h
字号:
// -*- c++ -*-// Copyright 2008 Isis Innovation Limited// MEstimator.h//// Defines various MEstimators which can be used by the Tracker and// the Bundle adjuster. Not that some of the inputs are square// quantities!#ifndef __MESTIMATOR_H#define __MESTIMATOR_H#include <TooN/numerics.h>#include <vector>#include <algorithm>struct Tukey{ inline static double FindSigmaSquared(std::vector<double> &vdErrorSquared); inline static double SquareRootWeight(double dErrorSquared, double dSigmaSquared); inline static double Weight(double dErrorSquared, double dSigmaSquared); inline static double ObjectiveScore(double dErrorSquared, double dSigmaSquared);};struct Cauchy{ inline static double FindSigmaSquared(std::vector<double> &vdErrorSquared); inline static double SquareRootWeight(double dErrorSquared, double dSigmaSquared); inline static double Weight(double dErrorSquared, double dSigmaSquared); inline static double ObjectiveScore(double dErrorSquared, double dSigmaSquared);};struct Huber{ inline static double FindSigmaSquared(std::vector<double> &vdErrorSquared); inline static double SquareRootWeight(double dErrorSquared, double dSigmaSquared); inline static double Weight(double dErrorSquared, double dSigmaSquared); inline static double ObjectiveScore(double dErrorSquared, double dSigmaSquared);};struct LeastSquares{ inline static double FindSigmaSquared(std::vector<double> &vdErrorSquared); inline static double SquareRootWeight(double dErrorSquared, double dSigmaSquared); inline static double Weight(double dErrorSquared, double dSigmaSquared); inline static double ObjectiveScore(double dErrorSquared, double dSigmaSquared);};inline double Tukey::Weight(double dErrorSquared, double dSigmaSquared){ double dSqrt = SquareRootWeight(dErrorSquared, dSigmaSquared); return dSqrt * dSqrt;}inline double Tukey::SquareRootWeight(double dErrorSquared, double dSigmaSquared){ if(dErrorSquared > dSigmaSquared) return 0.0; else return 1.0 - (dErrorSquared / dSigmaSquared);}inline double Tukey::ObjectiveScore(double dErrorSquared, const double dSigmaSquared){ // NB All returned are scaled because // I'm not multiplying by sigmasquared/6.0 if(dErrorSquared > dSigmaSquared) return 1.0; double d = 1.0 - dErrorSquared / dSigmaSquared; return (1.0 - d*d*d);}inline double Tukey::FindSigmaSquared(std::vector<double> &vdErrorSquared){ double dSigmaSquared; assert(vdErrorSquared.size() > 0); std::sort(vdErrorSquared.begin(), vdErrorSquared.end()); double dMedianSquared = vdErrorSquared[vdErrorSquared.size() / 2]; double dSigma = 1.4826 * (1 + 5.0 / (vdErrorSquared.size() * 2 - 6)) * sqrt(dMedianSquared); dSigma = 4.6851 * dSigma; dSigmaSquared = dSigma * dSigma; return dSigmaSquared;}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////inline double Cauchy::Weight(double dErrorSquared, double dSigmaSquared){ return 1.0 / (1.0 + dErrorSquared / dSigmaSquared);}inline double Cauchy::SquareRootWeight(double dErrorSquared, double dSigmaSquared){ return sqrt(Weight(dErrorSquared, dSigmaSquared));}inline double Cauchy::ObjectiveScore(double dErrorSquared, const double dSigmaSquared){ return log(1.0 + dErrorSquared / dSigmaSquared);}inline double Cauchy::FindSigmaSquared(std::vector<double> &vdErrorSquared){ double dSigmaSquared; assert(vdErrorSquared.size() > 0); std::sort(vdErrorSquared.begin(), vdErrorSquared.end()); double dMedianSquared = vdErrorSquared[vdErrorSquared.size() / 2]; double dSigma = 1.4826 * (1 + 5.0 / (vdErrorSquared.size() * 2 - 6)) * sqrt(dMedianSquared); dSigma = 4.6851 * dSigma; dSigmaSquared = dSigma * dSigma; return dSigmaSquared;}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////inline double Huber::Weight(double dErrorSquared, double dSigmaSquared){ if(dErrorSquared < dSigmaSquared) return 1; else return sqrt(dSigmaSquared / dErrorSquared);}inline double Huber::SquareRootWeight(double dErrorSquared, double dSigmaSquared){ return sqrt(Weight(dErrorSquared, dSigmaSquared));}inline double Huber::ObjectiveScore(double dErrorSquared, const double dSigmaSquared){ if(dErrorSquared< dSigmaSquared) return 0.5 * dErrorSquared; else { double dSigma = sqrt(dSigmaSquared); double dError = sqrt(dErrorSquared); return dSigma * ( dError - 0.5 * dSigma); }}inline double Huber::FindSigmaSquared(std::vector<double> &vdErrorSquared){ double dSigmaSquared; assert(vdErrorSquared.size() > 0); std::sort(vdErrorSquared.begin(), vdErrorSquared.end()); double dMedianSquared = vdErrorSquared[vdErrorSquared.size() / 2]; double dSigma = 1.4826 * (1 + 5.0 / (vdErrorSquared.size() * 2 - 6)) * sqrt(dMedianSquared); dSigma = 1.345 * dSigma; dSigmaSquared = dSigma * dSigma; return dSigmaSquared;}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////inline double LeastSquares::Weight(double dErrorSquared, double dSigmaSquared){ return 1.0;}inline double LeastSquares::SquareRootWeight(double dErrorSquared, double dSigmaSquared){ return 1.0;}inline double LeastSquares::ObjectiveScore(double dErrorSquared, const double dSigmaSquared){ return dErrorSquared;}inline double LeastSquares::FindSigmaSquared(std::vector<double> &vdErrorSquared){ if(vdErrorSquared.size() == 0) return 0.0; double dSum = 0.0; for(unsigned int i=0; i<vdErrorSquared.size(); i++) dSum+=vdErrorSquared[i]; return dSum / vdErrorSquared.size();}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -