1// Ceres Solver - A fast non-linear least squares minimizer 2// Copyright 2010, 2011, 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: keir@google.com (Keir Mierle) 30 31#ifndef CERES_INTERNAL_PROGRAM_H_ 32#define CERES_INTERNAL_PROGRAM_H_ 33 34#include <set> 35#include <string> 36#include <vector> 37#include "ceres/internal/port.h" 38 39namespace ceres { 40namespace internal { 41 42class ParameterBlock; 43class ProblemImpl; 44class ResidualBlock; 45class TripletSparseMatrix; 46 47// A nonlinear least squares optimization problem. This is different from the 48// similarly-named "Problem" object, which offers a mutation interface for 49// adding and modifying parameters and residuals. The Program contains the core 50// part of the Problem, which is the parameters and the residuals, stored in a 51// particular ordering. The ordering is critical, since it defines the mapping 52// between (residual, parameter) pairs and a position in the jacobian of the 53// objective function. Various parts of Ceres transform one Program into 54// another; for example, the first stage of solving involves stripping all 55// constant parameters and residuals. This is in contrast with Problem, which is 56// not built for transformation. 57class Program { 58 public: 59 Program(); 60 explicit Program(const Program& program); 61 62 // The ordered parameter and residual blocks for the program. 63 const vector<ParameterBlock*>& parameter_blocks() const; 64 const vector<ResidualBlock*>& residual_blocks() const; 65 vector<ParameterBlock*>* mutable_parameter_blocks(); 66 vector<ResidualBlock*>* mutable_residual_blocks(); 67 68 // Serialize to/from the program and update states. 69 // 70 // NOTE: Setting the state of a parameter block can trigger the 71 // computation of the Jacobian of its local parameterization. If 72 // this computation fails for some reason, then this method returns 73 // false and the state of the parameter blocks cannot be trusted. 74 bool StateVectorToParameterBlocks(const double *state); 75 void ParameterBlocksToStateVector(double *state) const; 76 77 // Copy internal state to the user's parameters. 78 void CopyParameterBlockStateToUserState(); 79 80 // Set the parameter block pointers to the user pointers. Since this 81 // runs parameter block set state internally, which may call local 82 // parameterizations, this can fail. False is returned on failure. 83 bool SetParameterBlockStatePtrsToUserStatePtrs(); 84 85 // Update a state vector for the program given a delta. 86 bool Plus(const double* state, 87 const double* delta, 88 double* state_plus_delta) const; 89 90 // Set the parameter indices and offsets. This permits mapping backward 91 // from a ParameterBlock* to an index in the parameter_blocks() vector. For 92 // any parameter block p, after calling SetParameterOffsetsAndIndex(), it 93 // is true that 94 // 95 // parameter_blocks()[p->index()] == p 96 // 97 // If a parameter appears in a residual but not in the parameter block, then 98 // it will have an index of -1. 99 // 100 // This also updates p->state_offset() and p->delta_offset(), which are the 101 // position of the parameter in the state and delta vector respectively. 102 void SetParameterOffsetsAndIndex(); 103 104 // Check if the internal state of the program (the indexing and the 105 // offsets) are correct. 106 bool IsValid() const; 107 108 bool ParameterBlocksAreFinite(string* message) const; 109 110 // Returns true if the program has any non-constant parameter blocks 111 // which have non-trivial bounds constraints. 112 bool IsBoundsConstrained() const; 113 114 // Returns false, if the program has any constant parameter blocks 115 // which are not feasible, or any variable parameter blocks which 116 // have a lower bound greater than or equal to the upper bound. 117 bool IsFeasible(string* message) const; 118 119 // Loop over each residual block and ensure that no two parameter 120 // blocks in the same residual block are part of 121 // parameter_blocks as that would violate the assumption that it 122 // is an independent set in the Hessian matrix. 123 bool IsParameterBlockSetIndependent(const set<double*>& independent_set) const; 124 125 // Create a TripletSparseMatrix which contains the zero-one 126 // structure corresponding to the block sparsity of the transpose of 127 // the Jacobian matrix. 128 // 129 // Caller owns the result. 130 TripletSparseMatrix* CreateJacobianBlockSparsityTranspose() const; 131 132 // Create a copy of this program and removes constant parameter 133 // blocks and residual blocks with no varying parameter blocks while 134 // preserving their relative order. 135 // 136 // removed_parameter_blocks on exit will contain the list of 137 // parameter blocks that were removed. 138 // 139 // fixed_cost will be equal to the sum of the costs of the residual 140 // blocks that were removed. 141 // 142 // If there was a problem, then the function will return a NULL 143 // pointer and error will contain a human readable description of 144 // the problem. 145 Program* CreateReducedProgram(vector<double*>* removed_parameter_blocks, 146 double* fixed_cost, 147 string* error) const; 148 149 // See problem.h for what these do. 150 int NumParameterBlocks() const; 151 int NumParameters() const; 152 int NumEffectiveParameters() const; 153 int NumResidualBlocks() const; 154 int NumResiduals() const; 155 156 int MaxScratchDoublesNeededForEvaluate() const; 157 int MaxDerivativesPerResidualBlock() const; 158 int MaxParametersPerResidualBlock() const; 159 int MaxResidualsPerResidualBlock() const; 160 161 // A human-readable dump of the parameter blocks for debugging. 162 // TODO(keir): If necessary, also dump the residual blocks. 163 string ToString() const; 164 165 private: 166 // Remove constant parameter blocks and residual blocks with no 167 // varying parameter blocks while preserving their relative order. 168 // 169 // removed_parameter_blocks on exit will contain the list of 170 // parameter blocks that were removed. 171 // 172 // fixed_cost will be equal to the sum of the costs of the residual 173 // blocks that were removed. 174 // 175 // If there was a problem, then the function will return false and 176 // error will contain a human readable description of the problem. 177 bool RemoveFixedBlocks(vector<double*>* removed_parameter_blocks, 178 double* fixed_cost, 179 string* message); 180 181 // The Program does not own the ParameterBlock or ResidualBlock objects. 182 vector<ParameterBlock*> parameter_blocks_; 183 vector<ResidualBlock*> residual_blocks_; 184 185 friend class ProblemImpl; 186}; 187 188} // namespace internal 189} // namespace ceres 190 191#endif // CERES_INTERNAL_PROGRAM_H_ 192