Ceres Solver 中文文档
  • 😜Ceres Solver 中文文档
  • Why Ceres ?
  • Installation
  • Tutorial
    • Non-linear Least Squares
      • Introduction
      • Hello World
      • Derivatives
        • Numeric Derivatives
        • Analytic Derivatives
        • More About Derivatives
      • Powell’s Function
      • Curve Fitting
      • Robust Curve Fitting
      • Bundle Adjustment
      • Other Examples
    • General Unconstrained Minimization
      • General Unconstrained Minimization
  • On Derivatives
    • Spivak Notation
    • Analytic Derivatives
    • Numeric Derivatives
    • Automatic Derivatives
    • Interfacing with Automatic Differentiation
    • Using Inverse & Implicit Function Theorems
  • Modeling Non-linear Least Squares
    • Introduction
    • Main Class Interface
      • CostFunction
      • SizeCostFunction
      • AutoDiffCostFunction
      • DynamicAutoDiffCostFunction
      • NumericDiffCostFunction
      • DynamicNumericDifferCostFunction
      • CostFunctionToFunctor
      • DynamicCostFunctionToFunctor
      • ConditionedCostFunction
      • GradientChecker
      • NormalPrior
      • LossFunction
      • Manifold
      • AutoDIffManifold
      • Problem
      • EvaluatationCallback
      • Rotation
      • Cubic Interpolation
        • CubicInterpolator
        • BiCubicInterpolator
  • Solveing Non-linear Least Squares
    • Introduction
    • Trust Region Methodd
    • Line Search Methods
    • Linear Solvers
    • Mixed Precision Solves
    • Preconditioners
    • Ordering
    • Main Class Interfaces
      • Solver::Options
      • ParameterBlockOrdering
      • IterationSummary
      • IterationCallback
      • CRSMatrix
      • Solver::Summary
  • Covariance Estimation
    • Introduction
    • Gauge Invariance
    • Covariance
    • Rank of the Jacobian
      • Options
      • Covariance
      • GetCovarianceBlock
      • GetCovarianceBlockInTangentSpace
    • Example Usage
Powered by GitBook
On this page
  • Example of Analytic Derivatives
  • When should you use analytical derivatives?
  1. On Derivatives

Analytic Derivatives

PreviousSpivak NotationNextNumeric Derivatives

Last updated 1 year ago

Example of Analytic Derivatives

考虑通过样本数据对如下问题 () 进行曲线拟合

y=b1(1+eb2−b3x)1/b4y=\frac{b_{1}}{\left(1+e^{b_{2}-b_{3} x}\right)^{1 / b_{4}}}y=(1+eb2​−b3​x)1/b4​b1​​

给定一些样本数据 {xi,yi},∀i=1,…,n\left\{x_{i}, y_{i}\right\}, \forall i=1, \ldots, n{xi​,yi​},∀i=1,…,n ,估计参数 b1,b2,b3,b4b_{1}, b_{2}, b_{3},b_{4}b1​,b2​,b3​,b4​ 。可以建模成寻找使得如下目标函数取得最小值时, b1,b2,b3,b4b_{1}, b_{2}, b_{3},b_{4}b1​,b2​,b3​,b4​ 的值:

E(b1,b2,b3,b4)=∑if2(b1,b2,b3,b4;xi,yi)=∑i(b1(1+eb2−b3xi)1/b4−yi)2\begin{aligned} E\left(b_{1}, b_{2}, b_{3}, b_{4}\right) & =\sum_{i} f^{2}\left(b_{1}, b_{2}, b_{3}, b_{4} ; x_{i}, y_{i}\right) \\ & =\sum_{i}\left(\frac{b_{1}}{\left(1+e^{b_{2}-b_{3} x_{i}}\right)^{1 / b_{4}}}-y_{i}\right)^{2} \end{aligned}E(b1​,b2​,b3​,b4​)​=i∑​f2(b1​,b2​,b3​,b4​;xi​,yi​)=i∑​((1+eb2​−b3​xi​)1/b4​b1​​−yi​)2​

使用 Ceres 解决该问题,我们需要定义一个 costFunction,用于计算给定 xxx 和 yyy 的残差 fff 及其相对于 b1、b2、b3b_{1}、b_{2}、b_{3}b1​、b2​、b3​ 和 b4b_{4}b4​ 的导数。

D1f(b1,b2,b3,b4;x,y)=1(1+eb2−b3x)1/b4D2f(b1,b2,b3,b4;x,y)=−b1eb2−b3xb4(1+eb2−b3x)1/b4+1D3f(b1,b2,b3,b4;x,y)=b1xeb2−b3xb4(1+eb2−b3x)1/b4+1D4f(b1,b2,b3,b4;x,y)=b1log⁡(1+eb2−b3x)b42(1+eb2−b3x)1/b4\begin{array}{l} D_{1} f\left(b_{1}, b_{2}, b_{3}, b_{4} ; x, y\right)=\frac{1}{\left(1+e^{b_{2}-b_{3} x}\right)^{1 / b_{4}}} \\ D_{2} f\left(b_{1}, b_{2}, b_{3}, b_{4} ; x, y\right)=\frac{-b_{1} e^{b_{2}-b_{3} x}}{b_{4}\left(1+e^{b_{2}-b_{3} x}\right)^{1 / b_{4}+1}} \\ D_{3} f\left(b_{1}, b_{2}, b_{3}, b_{4} ; x, y\right)=\frac{b_{1} x e^{b_{2}-b_{3} x}}{b_{4}\left(1+e^{b_{2}-b_{3} x}\right)^{1 / b_{4}+1}} \\ D_{4} f\left(b_{1}, b_{2}, b_{3}, b_{4} ; x, y\right)=\frac{b_{1} \log \left(1+e^{b_{2}-b_{3} x}\right)}{b_{4}^{2}\left(1+e^{b_{2}-b_{3} x}\right)^{1 / b_{4}}} \end{array}D1​f(b1​,b2​,b3​,b4​;x,y)=(1+eb2​−b3​x)1/b4​1​D2​f(b1​,b2​,b3​,b4​;x,y)=b4​(1+eb2​−b3​x)1/b4​+1−b1​eb2​−b3​x​D3​f(b1​,b2​,b3​,b4​;x,y)=b4​(1+eb2​−b3​x)1/b4​+1b1​xeb2​−b3​x​D4​f(b1​,b2​,b3​,b4​;x,y)=b42​(1+eb2​−b3​x)1/b4​b1​log(1+eb2​−b3​x)​​

有了这些导数,我们现在可以将 CostFunction 实现为:

class Rat43Analytic : public SizedCostFunction<1,4> {
   public:
     Rat43Analytic(const double x, const double y) : x_(x), y_(y) {}
     virtual ~Rat43Analytic() {}
     virtual bool Evaluate(double const* const* parameters,
                           double* residuals,
                           double** jacobians) const {
       const double b1 = parameters[0][0];
       const double b2 = parameters[0][1];
       const double b3 = parameters[0][2];
       const double b4 = parameters[0][3];

       residuals[0] = b1 *  pow(1 + exp(b2 -  b3 * x_), -1.0 / b4) - y_;

       if (!jacobians) return true;
       double* jacobian = jacobians[0];
       if (!jacobian) return true;

       jacobian[0] = pow(1 + exp(b2 - b3 * x_), -1.0 / b4);
       jacobian[1] = -b1 * exp(b2 - b3 * x_) *
                     pow(1 + exp(b2 - b3 * x_), -1.0 / b4 - 1) / b4;
       jacobian[2] = x_ * b1 * exp(b2 - b3 * x_) *
                     pow(1 + exp(b2 - b3 * x_), -1.0 / b4 - 1) / b4;
       jacobian[3] = b1 * log(1 + exp(b2 - b3 * x_)) *
                     pow(1 + exp(b2 - b3 * x_), -1.0 / b4) / (b4 * b4);
       return true;
     }

    private:
     const double x_;
     const double y_;
 };

这些难以阅读并且有很多冗余。因此在实践中我们会用一些子表达式来提高其效率,这会给我们带来类似的结果:

class Rat43AnalyticOptimized : public SizedCostFunction<1,4> {
   public:
     Rat43AnalyticOptimized(const double x, const double y) : x_(x), y_(y) {}
     virtual ~Rat43AnalyticOptimized() {}
     virtual bool Evaluate(double const* const* parameters,
                           double* residuals,
                           double** jacobians) const {
       const double b1 = parameters[0][0];
       const double b2 = parameters[0][1];
       const double b3 = parameters[0][2];
       const double b4 = parameters[0][3];

       const double t1 = exp(b2 -  b3 * x_);
       const double t2 = 1 + t1;
       const double t3 = pow(t2, -1.0 / b4);
       residuals[0] = b1 * t3 - y_;

       if (!jacobians) return true;
       double* jacobian = jacobians[0];
       if (!jacobian) return true;

       const double t4 = pow(t2, -1.0 / b4 - 1);
       jacobian[0] = t3;
       jacobian[1] = -b1 * t1 * t4 / b4;
       jacobian[2] = -x_ * jacobian[1];
       jacobian[3] = b1 * log(t2) * t3 / (b4 * b4);
       return true;
     }

   private:
     const double x_;
     const double y_;
 };

两种实现的区别如下:

CostFunction
Times(ns)

Rat43Analytic

255

Rat43Analytic

92

When should you use analytical derivatives?

  • 表达式很简单,例如大多是线性的。

  • 您喜欢链式法则,并且喜欢手工计算所有导数。

可以使用 、 或 等计算机代数系统对目标函数进行微分,并生成 C++ 对其进行评估。

性能是最先考虑的,可以利用计算中的代数结构来获得比自动微分更好的性能。尽管如此,要想从 analytical derivatives 中获得最佳性能,还需要做大量的工作。在采用这种方法之前,最好先估算一下求解 jacobian 所花费的时间占总求解时间的比例,使用 即可。

There is no other way to compute the derivatives, e.g. you wish to compute the derivative of the root of a polynomial, a3(x,y)z3+a2(x,y)z2+a1(x,y)z+a0(x,y)=0a_{3}(x, y) z^{3}+a_{2}(x, y) z^{2}+a_{1}(x, y) z+a_{0}(x, y)=0a3​(x,y)z3+a2​(x,y)z2+a1​(x,y)z+a0​(x,y)=0, with respect to x,yx,yx,y, This requires the use of the .

Maple
Mathematica
SymPy
Amdahl’s Law
Rat43
Inverse Function Theorem