Home | History | Annotate | Download | only in ceres
      1 // Ceres Solver - A fast non-linear least squares minimizer
      2 // Copyright 2012 Google Inc. All rights reserved.
      3 // http://code.google.com/p/ceres-solver/
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are met:
      7 //
      8 // * Redistributions of source code must retain the above copyright notice,
      9 //   this list of conditions and the following disclaimer.
     10 // * Redistributions in binary form must reproduce the above copyright notice,
     11 //   this list of conditions and the following disclaimer in the documentation
     12 //   and/or other materials provided with the distribution.
     13 // * Neither the name of Google Inc. nor the names of its contributors may be
     14 //   used to endorse or promote products derived from this software without
     15 //   specific prior written permission.
     16 //
     17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     27 // POSSIBILITY OF SUCH DAMAGE.
     28 //
     29 // Author: sameeragarwal (at) google.com (Sameer Agarwal)
     30 //
     31 // Limited memory positive definite approximation to the inverse
     32 // Hessian, using the LBFGS algorithm
     33 
     34 #ifndef CERES_INTERNAL_LOW_RANK_INVERSE_HESSIAN_H_
     35 #define CERES_INTERNAL_LOW_RANK_INVERSE_HESSIAN_H_
     36 
     37 #include "ceres/internal/eigen.h"
     38 #include "ceres/linear_operator.h"
     39 
     40 namespace ceres {
     41 namespace internal {
     42 
     43 // LowRankInverseHessian is a positive definite approximation to the
     44 // Hessian using the limited memory variant of the
     45 // Broyden-Fletcher-Goldfarb-Shanno (BFGS)secant formula for
     46 // approximating the Hessian.
     47 //
     48 // Other update rules like the Davidon-Fletcher-Powell (DFP) are
     49 // possible, but the BFGS rule is considered the best performing one.
     50 //
     51 // The limited memory variant was developed by Nocedal and further
     52 // enhanced with scaling rule by Byrd, Nocedal and Schanbel.
     53 //
     54 // Nocedal, J. (1980). "Updating Quasi-Newton Matrices with Limited
     55 // Storage". Mathematics of Computation 35 (151): 773782.
     56 //
     57 // Byrd, R. H.; Nocedal, J.; Schnabel, R. B. (1994).
     58 // "Representations of Quasi-Newton Matrices and their use in
     59 // Limited Memory Methods". Mathematical Programming 63 (4):
     60 class LowRankInverseHessian : public LinearOperator {
     61  public:
     62   // num_parameters is the row/column size of the Hessian.
     63   // max_num_corrections is the rank of the Hessian approximation.
     64   // use_approximate_eigenvalue_scaling controls whether the initial
     65   // inverse Hessian used during Right/LeftMultiply() is scaled by
     66   // the approximate eigenvalue of the true inverse Hessian at the
     67   // current operating point.
     68   // The approximation uses:
     69   // 2 * max_num_corrections * num_parameters + max_num_corrections
     70   // doubles.
     71   LowRankInverseHessian(int num_parameters,
     72                         int max_num_corrections,
     73                         bool use_approximate_eigenvalue_scaling);
     74   virtual ~LowRankInverseHessian() {}
     75 
     76   // Update the low rank approximation. delta_x is the change in the
     77   // domain of Hessian, and delta_gradient is the change in the
     78   // gradient.  The update copies the delta_x and delta_gradient
     79   // vectors, and gets rid of the oldest delta_x and delta_gradient
     80   // vectors if the number of corrections is already equal to
     81   // max_num_corrections.
     82   bool Update(const Vector& delta_x, const Vector& delta_gradient);
     83 
     84   // LinearOperator interface
     85   virtual void RightMultiply(const double* x, double* y) const;
     86   virtual void LeftMultiply(const double* x, double* y) const {
     87     RightMultiply(x, y);
     88   }
     89   virtual int num_rows() const { return num_parameters_; }
     90   virtual int num_cols() const { return num_parameters_; }
     91 
     92  private:
     93   const int num_parameters_;
     94   const int max_num_corrections_;
     95   const bool use_approximate_eigenvalue_scaling_;
     96   int num_corrections_;
     97   double approximate_eigenvalue_scale_;
     98   Matrix delta_x_history_;
     99   Matrix delta_gradient_history_;
    100   Vector delta_x_dot_delta_gradient_;
    101 };
    102 
    103 }  // namespace internal
    104 }  // namespace ceres
    105 
    106 #endif  // CERES_INTERNAL_LOW_RANK_INVERSE_HESSIAN_H_
    107