Clean up documentation and code examples in public headers - Fix code examples in comments across autodiff_cost_function.h, numeric_diff_cost_function.h, conditioned_cost_function.h, cubic_interpolation.h, dynamic_cost_function_to_functor.h, dynamic_numeric_diff_cost_function.h, gradient_problem.h, loss_function.h, and numeric_diff_first_order_function.h. - Fix function_tolerance sign and gradient_tolerance formula in solver.h, gradient_problem_solver.h, tiny_solver.h, and types.h. - Fix outdated option/parameter references in comments across gradient_checker.h, gradient_problem_solver.h, numeric_diff_options.h, solver.h, and types.h. - Fix include path for ceres/internal/parameter_dims.h and static_assert message in sized_cost_function.h. - Fix typos, duplicate words, grammar, and capitalization in header comments. Change-Id: I11cb8fca41117654bf872196c97bd6b007cda637
diff --git a/include/ceres/autodiff_cost_function.h b/include/ceres/autodiff_cost_function.h index 667b385..c10556c 100644 --- a/include/ceres/autodiff_cost_function.h +++ b/include/ceres/autodiff_cost_function.h
@@ -30,7 +30,7 @@ // // Create CostFunctions as needed by the least squares framework, with // Jacobians computed via automatic differentiation. For more -// information on automatic differentiation, see the wikipedia article +// information on automatic differentiation, see the Wikipedia article // at http://en.wikipedia.org/wiki/Automatic_differentiation // // To get an auto differentiated cost function, you must define a class with a @@ -43,7 +43,7 @@ // The function must write the computed value in the last argument // (the only non-const one) and return true to indicate // success. Please see cost_function.h for details on how the return -// value maybe used to impose simple constraints on the parameter +// value may be used to impose simple constraints on the parameter // block. // // For example, consider a scalar error e = k - x'y, where both x and y are @@ -61,11 +61,12 @@ // define the object // // class MyScalarCostFunctor { +// public: // MyScalarCostFunctor(double k): k_(k) {} // // template <typename T> -// bool operator()(const T* const x , const T* const y, T* e) const { -// e[0] = T(k_) - x[0] * y[0] + x[1] * y[1]; +// bool operator()(const T* const x, const T* const y, T* e) const { +// e[0] = T(k_) - (x[0] * y[0] + x[1] * y[1]); // return true; // } // @@ -137,7 +138,7 @@ namespace ceres { // A cost function which computes the derivative of the cost with respect to -// the parameters (a.k.a. the jacobian) using an auto differentiation framework. +// the parameters (a.k.a. the Jacobian) using an auto differentiation framework. // The first template argument is the functor object, described in the header // comment. The second argument is the dimension of the residual (or // ceres::DYNAMIC to indicate it will be set at runtime), and subsequent @@ -165,7 +166,7 @@ "be provided as a constructor argument."); } - // Constructs the CostFunctor on the heap and takes the ownership. + // Constructs the CostFunctor on the heap and takes ownership. // Invocable only if the number of residuals is known at compile-time. template <typename... Args, typename = std::enable_if_t<
diff --git a/include/ceres/autodiff_first_order_function.h b/include/ceres/autodiff_first_order_function.h index d29c8d6..e51bf8b 100644 --- a/include/ceres/autodiff_first_order_function.h +++ b/include/ceres/autodiff_first_order_function.h
@@ -45,13 +45,13 @@ // Create FirstOrderFunctions as needed by the GradientProblem // framework, with gradients computed via automatic // differentiation. For more information on automatic differentiation, -// see the wikipedia article at +// see the Wikipedia article at // http://en.wikipedia.org/wiki/Automatic_differentiation // // To get an auto differentiated function, you must define a class // with a templated operator() (a functor) that computes the cost // function in terms of the template parameter T. The autodiff -// framework substitutes appropriate "jet" objects for T in order to +// framework substitutes appropriate "Jet" objects for T in order to // compute the derivative when necessary, but this is hidden, and you // should write the function as if T were a scalar type (e.g. a // double-precision floating point number). @@ -112,7 +112,7 @@ static_assert(kNumParameters > 0, "kNumParameters must be positive"); } - // Constructs the FirstOrderFunctor on the heap and takes the ownership. + // Constructs the FirstOrderFunctor on the heap and takes ownership. template <typename... Args, typename = std::enable_if_t< std::is_constructible_v<FirstOrderFunctor, Args&&...>>> @@ -124,6 +124,7 @@ std::make_unique<FirstOrderFunctor>(std::forward<Args>(args)...), TAKE_OWNERSHIP) {} + // Takes ownership of functor if ownership == TAKE_OWNERSHIP. explicit AutoDiffFirstOrderFunction(FirstOrderFunctor* functor, Ownership ownership = TAKE_OWNERSHIP) : AutoDiffFirstOrderFunction(std::unique_ptr<FirstOrderFunctor>(functor),
diff --git a/include/ceres/conditioned_cost_function.h b/include/ceres/conditioned_cost_function.h index 1edc006..a2647c9 100644 --- a/include/ceres/conditioned_cost_function.h +++ b/include/ceres/conditioned_cost_function.h
@@ -64,9 +64,9 @@ // CostFunction* f_N = ... // conditioners.push_back(f_N); // ConditionedCostFunction* ccf = -// new ConditionedCostFunction(my_cost_function, conditioners); +// new ConditionedCostFunction(my_cost_function, conditioners, TAKE_OWNERSHIP); // -// Now ccf's residual i (i=0..N-1) will be passed though the i'th conditioner. +// Now ccf's residual i (i=0..N-1) will be passed through the i'th conditioner. // // ccf_residual[i] = f_i(my_cost_function_residual[i]) //
diff --git a/include/ceres/cost_function.h b/include/ceres/cost_function.h index 2e5b1dd..1fcebf9 100644 --- a/include/ceres/cost_function.h +++ b/include/ceres/cost_function.h
@@ -27,7 +27,7 @@ // POSSIBILITY OF SUCH DAMAGE. // // Author: sameeragarwal@google.com (Sameer Agarwal) -// keir@google.m (Keir Mierle) +// keir@google.com (Keir Mierle) // // This is the interface through which the least squares solver accesses the // residual and Jacobian of the least squares problem. Users are expected to @@ -74,33 +74,33 @@ // parameters is an array of pointers to arrays containing the // various parameter blocks. parameters has the same number of // elements as parameter_block_sizes_. Parameter blocks are in the - // same order as parameter_block_sizes_.i.e., + // same order as parameter_block_sizes_, i.e., // - // parameters_[i] = double[parameter_block_sizes_[i]] + // parameters[i] = double[parameter_block_sizes_[i]] // // Outputs: // // residuals is an array of size num_residuals_. // // jacobians is an array of size parameter_block_sizes_ containing - // pointers to storage for jacobian blocks corresponding to each + // pointers to storage for Jacobian blocks corresponding to each // parameter block. Jacobian blocks are in the same order as - // parameter_block_sizes, i.e. jacobians[i], is an - // array that contains num_residuals_* parameter_block_sizes_[i] - // elements. Each jacobian block is stored in row-major order, i.e., + // parameter_block_sizes_, i.e., jacobians[i] is an + // array that contains num_residuals_ * parameter_block_sizes_[i] + // elements. Each Jacobian block is stored in row-major order, i.e., // - // jacobians[i][r*parameter_block_size_[i] + c] = + // jacobians[i][r * parameter_block_sizes_[i] + c] = // d residual[r] / d parameters[i][c] // // If jacobians is nullptr, then no derivatives are returned; this is // the case when computing cost only. If jacobians[i] is nullptr, then - // the jacobian block corresponding to the i'th parameter block must - // not to be returned. + // the Jacobian block corresponding to the i'th parameter block must + // not be returned. // // The return value indicates whether the computation of the // residuals and/or jacobians was successful or not. // - // This can be used to communicate numerical failures in jacobian + // This can be used to communicate numerical failures in Jacobian // computations for instance. // // A more interesting and common use is to impose constraints on the
diff --git a/include/ceres/cost_function_to_functor.h b/include/ceres/cost_function_to_functor.h index 9505159..f8aeba6 100644 --- a/include/ceres/cost_function_to_functor.h +++ b/include/ceres/cost_function_to_functor.h
@@ -46,7 +46,7 @@ // is a cost function that implements the projection of a point in its // local coordinate system onto its image plane and subtracts it from // the observed point projection. It can compute its residual and -// jacobians either via analytic or numerical differentiation. +// Jacobians either via analytic or numerical differentiation. // // Now we would like to compose the action of this CostFunction with // the action of camera extrinsics, i.e., rotation and
diff --git a/include/ceres/covariance.h b/include/ceres/covariance.h index d477f31..76e20a8 100644 --- a/include/ceres/covariance.h +++ b/include/ceres/covariance.h
@@ -126,7 +126,7 @@ // // Rank of the Jacobian // -------------------- -// As we noted above, if the jacobian is rank deficient, then the +// As we noted above, if the Jacobian is rank deficient, then the // inverse of J'J is not defined and instead a pseudo inverse needs to // be computed. // @@ -335,7 +335,7 @@ // the application of the loss function to the output of the cost // function and in turn its effect on the covariance. // - // TODO(sameergaarwal): Expand this based on Jim's experiments. + // TODO(sameeragarwal): Expand this based on Jim's experiments. bool apply_loss_function = true; }; @@ -447,7 +447,7 @@ // // Compute must be called before calling GetCovarianceMatrix and all // parameter_blocks must have been present in the vector - // parameters_blocks when Compute was called. Otherwise + // parameter_blocks when Compute was called. Otherwise // GetCovarianceMatrix returns false. // // covariance_matrix must point to a memory location that can store
diff --git a/include/ceres/cubic_interpolation.h b/include/ceres/cubic_interpolation.h index e3797d1..c495ce8 100644 --- a/include/ceres/cubic_interpolation.h +++ b/include/ceres/cubic_interpolation.h
@@ -119,11 +119,11 @@ // // Example usage: // -// const double data[] = {1.0, 2.0, 5.0, 6.0}; -// Grid1D<double, 1> grid(data, 0, 4); -// CubicInterpolator<Grid1D<double, 1>> interpolator(grid); -// double f, dfdx; -// interpolator.Evaluator(1.5, &f, &dfdx); +// const double data[] = {1.0, 2.0, 5.0, 6.0}; +// Grid1D<double, 1> grid(data, 0, 4); +// CubicInterpolator<Grid1D<double, 1>> interpolator(grid); +// double f, dfdx; +// interpolator.Evaluate(1.5, &f, &dfdx); template <typename Grid> class CubicInterpolator { public: @@ -170,12 +170,11 @@ // [begin, ..., end - 1] // // Since the input array is finite and the grid is infinite, values -// outside this interval needs to be computed. Grid1D uses the value -// from the nearest edge. +// outside this interval are computed by clamping to the nearest edge. // // The function being provided can be vector valued, in which case -// kDataDimension > 1. The dimensional slices of the function maybe -// interleaved, or they maybe stacked, i.e., if the function has +// kDataDimension > 1. The dimensional slices of the function may be +// interleaved, or they may be stacked, i.e., if the function has // kDataDimension = 2, if kInterleaved = true, then it is stored as // // f01, f02, f11, f12 .... @@ -265,8 +264,8 @@ CHECK_GE(+Grid::DATA_DIMENSION, 1); } - // Evaluate the interpolated function value and/or its - // derivative. Uses the nearest point on the grid boundary if r or + // Evaluates the interpolated function value and/or its + // derivatives. Uses the nearest point on the grid boundary if r or // c is out of bounds. void Evaluate( double r, double c, double* f, double* dfdr, double* dfdc) const { @@ -358,18 +357,17 @@ // by the BiCubicInterpolator where the source of the function values // is a grid of type T on the grid // -// [(row_start, col_start), ..., (row_start, col_end - 1)] -// [ ... ] -// [(row_end - 1, col_start), ..., (row_end - 1, col_end - 1)] +// [(row_begin, col_begin), ..., (row_begin, col_end - 1)] +// [ ... ] +// [(row_end - 1, col_begin), ..., (row_end - 1, col_end - 1)] // // Since the input grid is finite and the grid is infinite, values -// outside this interval needs to be computed. Grid2D uses the value -// from the nearest edge. +// outside this interval are computed by clamping to the nearest edge. // // The function being provided can be vector valued, in which case -// kDataDimension > 1. The data maybe stored in row or column major -// format and the various dimensional slices of the function maybe -// interleaved, or they maybe stacked, i.e., if the function has +// kDataDimension > 1. The data may be stored in row or column major +// format and the various dimensional slices of the function may be +// interleaved, or they may be stacked, i.e., if the function has // kDataDimension = 2, is stored in row-major format and if // kInterleaved = true, then it is stored as //
diff --git a/include/ceres/dynamic_autodiff_cost_function.h b/include/ceres/dynamic_autodiff_cost_function.h index 05b13bc..b9912be 100644 --- a/include/ceres/dynamic_autodiff_cost_function.h +++ b/include/ceres/dynamic_autodiff_cost_function.h
@@ -85,7 +85,7 @@ static_assert(Stride > 0, "Stride must be positive"); } - // Constructs the CostFunctor on the heap and takes the ownership. + // Constructs the CostFunctor on the heap and takes ownership. template <typename... Args, typename = std::enable_if_t< std::is_constructible_v<CostFunctor, Args&&...>>> @@ -146,7 +146,7 @@ // depends on. // // To work around this issue, the solution here is to evaluate the - // jacobians in a series of passes, each one computing Stride * + // Jacobians in a series of passes, each one computing Stride * // num_residuals() derivatives. This is done with small, fixed-size jets. const int num_parameter_blocks = static_cast<int>(parameter_block_sizes().size()); @@ -251,7 +251,7 @@ return false; } - // Copy the pieces of the jacobians into their final place. + // Copy the pieces of the Jacobians into their final place. active_parameter_count = 0; current_derivative_section = initial_derivative_section;
diff --git a/include/ceres/dynamic_cost_function_to_functor.h b/include/ceres/dynamic_cost_function_to_functor.h index 9226cf4..8030eff 100644 --- a/include/ceres/dynamic_cost_function_to_functor.h +++ b/include/ceres/dynamic_cost_function_to_functor.h
@@ -64,7 +64,7 @@ // local coordinate system onto its image plane and subtracts it from // the observed point projection. It can compute its residual and // either via analytic or numerical differentiation can compute its -// jacobians. The intrinsics are passed in as parameters[0] and the point as +// Jacobians. The intrinsics are passed in as parameters[0] and the point as // parameters[1]. // // Now we would like to compose the action of this CostFunction with @@ -72,14 +72,16 @@ // translation. Say we have a templated function // // template<typename T> -// void RotateAndTranslatePoint(double const* const* parameters, -// double* residuals); +// void RotateAndTranslatePoint(const T* rotation, +// const T* translation, +// const T* point, +// T* result); // // Then we can now do the following, // // struct CameraProjection { // CameraProjection(const double* observation) -// : intrinsic_projection_.(new IntrinsicProjection(observation)) { +// : intrinsic_projection_(new IntrinsicProjection(observation)) { // } // template <typename T> // bool operator()(T const* const* parameters, @@ -129,7 +131,7 @@ absl::FixedArray<double*> jacobian_blocks(num_parameter_blocks); absl::FixedArray<double> residuals(num_residuals); - // Build a set of arrays to get the residuals and jacobians from + // Build a set of arrays to get the residuals and Jacobians from // the CostFunction wrapped by this functor. double* parameter_ptr = parameters.data(); double* jacobian_ptr = jacobians.data(); @@ -149,9 +151,9 @@ } // Now that we have the incoming Jets, which are carrying the - // partial derivatives of each of the inputs w.r.t to some other + // partial derivatives of each of the inputs w.r.t. some other // underlying parameters. The derivative of the outputs of the - // cost function w.r.t to the same underlying parameters can now + // cost function w.r.t. the same underlying parameters can now // be computed by applying the chain rule. // // d output[i] d output[i] d input[j] @@ -165,7 +167,7 @@ // outputJet[i] = sum_k jacobian[i][k] * inputJet[k] // // The following loop, iterates over the residuals, computing one - // output jet at a time. + // output Jet at a time. for (int i = 0; i < num_residuals; ++i) { output[i].a = residuals[i]; output[i].v.setZero();
diff --git a/include/ceres/dynamic_numeric_diff_cost_function.h b/include/ceres/dynamic_numeric_diff_cost_function.h index a25bd8f..f09f680 100644 --- a/include/ceres/dynamic_numeric_diff_cost_function.h +++ b/include/ceres/dynamic_numeric_diff_cost_function.h
@@ -52,7 +52,7 @@ namespace ceres { // This numeric diff implementation differs from the one found in -// numeric_diff_cost_function.h by supporting numericdiff on cost +// numeric_diff_cost_function.h by supporting numeric diff on cost // functions with variable numbers of parameters with variable // sizes. With the other implementation, all the sizes (both the // number of parameter blocks and the size of each block) must be @@ -67,7 +67,7 @@ // double* residuals) const { // // Use parameters[i] to access the i'th parameter block. // } -// } +// }; // // Since the sizing of the parameters is done at runtime, you must // also specify the sizes after creating the @@ -87,7 +87,7 @@ : DynamicNumericDiffCostFunction( std::move(functor), TAKE_OWNERSHIP, options) {} - // Constructs the CostFunctor on the heap and takes the ownership. + // Constructs the CostFunctor on the heap and takes ownership. template <class... Args, typename = std::enable_if_t<std::is_constructible_v<CostFunctor, Args&&...>>>
diff --git a/include/ceres/evaluation_callback.h b/include/ceres/evaluation_callback.h index e582dc8..d7933a2 100644 --- a/include/ceres/evaluation_callback.h +++ b/include/ceres/evaluation_callback.h
@@ -36,14 +36,14 @@ namespace ceres { // Using this callback interface, Ceres can notify you when it is -// about to evaluate the residuals or jacobians. With the callback, +// about to evaluate the residuals or Jacobians. With the callback, // you can share computation between residual blocks by doing the // shared computation in PrepareForEvaluation() before Ceres calls // CostFunction::Evaluate(). It also enables caching results between a -// pure residual evaluation and a residual & jacobian evaluation, via +// pure residual evaluation and a residual & Jacobian evaluation, via // the new_evaluation_point argument. // -// One use case for this callback is if the cost function compute is +// One use case for this callback is if the cost function computation is // moved to the GPU. In that case, the prepare call does the actual // cost function evaluation, and subsequent calls from Ceres to the // actual cost functions merely copy the results from the GPU onto the @@ -64,7 +64,7 @@ public: virtual ~EvaluationCallback(); - // Called before Ceres requests residuals or jacobians for a given setting of + // Called before Ceres requests residuals or Jacobians for a given setting of // the parameters. User parameters (the double* values provided to the cost // functions) are fixed until the next call to PrepareForEvaluation(). // @@ -73,7 +73,7 @@ // // If new_evaluation_point == true, then this is a new point that is different // from the last evaluated point. Otherwise, it is the same point that was - // evaluated previously (either jacobian or residual) and the user can use + // evaluated previously (either Jacobian or residual) and the user can use // cached results from previous evaluations. virtual void PrepareForEvaluation(bool evaluate_jacobians, bool new_evaluation_point) = 0;
diff --git a/include/ceres/gradient_checker.h b/include/ceres/gradient_checker.h index 7490cd6..a4dd1de 100644 --- a/include/ceres/gradient_checker.h +++ b/include/ceres/gradient_checker.h
@@ -25,7 +25,6 @@ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -// Copyright 2023 Google Inc. All Rights Reserved. // // Authors: wjr@google.com (William Rucklidge), // keir@google.com (Keir Mierle), @@ -57,8 +56,8 @@ // max(J_actual(i, j), J_numeric(i, j)) // // where J_actual(i, j) is the Jacobian as computed by the supplied cost -// function (by the user) multiplied by the manifold Jacobian and J_numeric is -// the Jacobian as computed by finite differences, multiplied by the manifold +// function (by the user) multiplied by the Manifold Jacobian and J_numeric is +// the Jacobian as computed by finite differences, multiplied by the Manifold // Jacobian as well. // // How to use: Fill in an array of pointers to parameter blocks for your @@ -88,7 +87,7 @@ // The sizes of the Jacobians below are dictated by the cost function's // parameter block size and residual block sizes. If a parameter block has a - // manifold associated with it, the size of the "local" Jacobian will be + // Manifold associated with it, the size of the "local" Jacobian will be // determined by the dimension of the manifold (which is the same as the // dimension of the tangent space) and residual block size, otherwise it // will be identical to the regular Jacobian. @@ -114,11 +113,11 @@ }; // Call the cost function, compute alternative Jacobians using finite - // differencing and compare results. If manifolds are given, the Jacobians - // will be multiplied by the manifold Jacobians before performing the check, + // differencing and compare results. If Manifolds are given, the Jacobians + // will be multiplied by the Manifold Jacobians before performing the check, // which effectively means that all errors along the null space of the - // manifold will be ignored. Returns false if the Jacobians don't match, the - // cost function return false, or if a cost function returns a different + // Manifold will be ignored. Returns false if the Jacobians don't match, the + // cost function returns false, or if a cost function returns a different // residual when called with a Jacobian output argument vs. calling it // without. Otherwise returns true. // @@ -130,7 +129,7 @@ // here. May be nullptr. // // Returns true if no problems are detected and the difference between the - // Jacobians is less than error_tolerance. + // Jacobians is less than relative_precision. bool Probe(double const* const* parameters, double relative_precision, ProbeResults* results) const;
diff --git a/include/ceres/gradient_problem.h b/include/ceres/gradient_problem.h index 3d8567c..e6e1364 100644 --- a/include/ceres/gradient_problem.h +++ b/include/ceres/gradient_problem.h
@@ -63,17 +63,17 @@ // // Example usage: // -// The following demonstrate the problem construction for Rosenbrock's function +// The following demonstrates the problem construction for Rosenbrock's function // // f(x,y) = (1-x)^2 + 100(y - x^2)^2; // // class Rosenbrock : public ceres::FirstOrderFunction { // public: -// virtual ~Rosenbrock() {} +// ~Rosenbrock() override {} // -// virtual bool Evaluate(const double* parameters, -// double* cost, -// double* gradient) const { +// bool Evaluate(const double* parameters, +// double* cost, +// double* gradient) const override { // const double x = parameters[0]; // const double y = parameters[1]; // @@ -83,9 +83,9 @@ // gradient[1] = 200.0 * (y - x * x); // } // return true; -// }; +// } // -// virtual int NumParameters() const { return 2; }; +// int NumParameters() const override { return 2; } // }; // // ceres::GradientProblem problem(std::make_unique<Rosenbrock>());
diff --git a/include/ceres/gradient_problem_solver.h b/include/ceres/gradient_problem_solver.h index f4c392f..e9ae6f5 100644 --- a/include/ceres/gradient_problem_solver.h +++ b/include/ceres/gradient_problem_solver.h
@@ -66,12 +66,12 @@ NonlinearConjugateGradientType nonlinear_conjugate_gradient_type = FLETCHER_REEVES; - // The LBFGS hessian approximation is a low rank approximation to + // The LBFGS Hessian approximation is a low rank approximation to // the inverse of the Hessian matrix. The rank of the // approximation determines (linearly) the space and time // complexity of using the approximation. Higher the rank, the // better is the quality of the approximation. The increase in - // quality is however is bounded for a number of reasons. + // quality is however bounded for a number of reasons. // // 1. The method only uses secant information and not actual // derivatives. @@ -105,9 +105,9 @@ // by default. In particular it can degrade performance when the // sensitivity of the problem to different parameters varies significantly, // as in this case a single scalar factor fails to capture this variation - // and detrimentally downscales parts of the jacobian approximation which + // and detrimentally downscales parts of the Jacobian approximation which // correspond to low-sensitivity parameters. It can also reduce the - // robustness of the solution to errors in the jacobians. + // robustness of the solution to errors in the Jacobians. // // Oren S.S., Self-scaling variable metric (SSVM) algorithms // Part II: Implementation and experiments, Management Science, @@ -203,20 +203,20 @@ // Minimizer terminates when // - // (new_cost - old_cost) < function_tolerance * old_cost; + // (old_cost - new_cost) < function_tolerance * old_cost; // double function_tolerance = 1e-6; // Minimizer terminates when // - // max_i |x - Project(Plus(x, -g(x))| < gradient_tolerance + // max_i |x - Project(Plus(x, -g(x)))| < gradient_tolerance // // This value should typically be 1e-4 * function_tolerance. double gradient_tolerance = 1e-10; // Minimizer terminates when // - // |step|_2 <= parameter_tolerance * ( |x|_2 + parameter_tolerance) + // |step|_2 <= parameter_tolerance * (|x|_2 + parameter_tolerance) // double parameter_tolerance = 1e-8; @@ -247,8 +247,8 @@ // this vector. By default, parameter blocks are updated only at // the end of the optimization, i.e when the Minimizer // terminates. This behaviour is controlled by - // update_state_every_variable. If the user wishes to have access - // to the update parameter blocks when his/her callbacks are + // update_state_every_iteration. If the user wishes to have access + // to the updated parameter blocks when his/her callbacks are // executed, then set update_state_every_iteration to true. // // The solver does NOT take ownership of these pointers. @@ -264,6 +264,9 @@ // termination. std::string FullReport() const; + // Returns true if the solver terminated for a reason that allows + // the solution to be used. This is true if the termination_type is + // CONVERGENCE or USER_SUCCESS. bool IsSolutionUsable() const; // Minimizer summary ------------------------------------------------- @@ -329,11 +332,10 @@ int max_lbfgs_rank = -1; }; - // Once a least squares problem has been built, this function takes + // Once a gradient problem has been built, this function takes // the problem and optimizes it based on the values of the options // parameters. Upon return, a detailed summary of the work performed - // by the preprocessor, the non-linear minimizer and the linear - // solver are reported in the summary object. + // by the non-linear minimizer is reported in the summary object. virtual void Solve(const GradientProblemSolver::Options& options, const GradientProblem& problem, double* parameters,
diff --git a/include/ceres/internal/autodiff.h b/include/ceres/internal/autodiff.h index f00e537..e83ce16 100644 --- a/include/ceres/internal/autodiff.h +++ b/include/ceres/internal/autodiff.h
@@ -33,7 +33,7 @@ // dual numbers in jet.h. Before reading the rest of this file, it is advisable // to read jet.h's header comment in detail. // -// The helper wrapper AutoDifferentiate() computes the jacobian of +// The helper wrapper AutoDifferentiate() computes the Jacobian of // functors with templated operator() taking this form: // // struct F { @@ -46,7 +46,7 @@ // // All inputs and outputs may be vector-valued. // -// To understand how jets are used to compute the jacobian, a +// To understand how Jets are used to compute the Jacobian, a // picture may help. Consider a vector-valued function, F, returning 3 // dimensions and taking a vector-valued parameter of 4 dimensions: // @@ -57,11 +57,11 @@ // [ * ] // // Similar to the 2-parameter example for f described in jet.h, computing the -// jacobian dy/dx is done by substituting a suitable jet object for x and all -// intermediate steps of the computation of F. Since x is has 4 dimensions, use +// Jacobian dy/dx is done by substituting a suitable Jet object for x and all +// intermediate steps of the computation of F. Since x has 4 dimensions, use // a Jet<double, 4>. // -// Before substituting a jet object for x, the dual components are set +// Before substituting a Jet object for x, the dual components are set // appropriately for each dimension of x: // // y x @@ -80,21 +80,21 @@ // Each column of the 4x4 identity is therefore for a single component of the // independent variable x. // -// Then the jacobian of the mapping, dy/dx, is the 3x4 sub-matrix of the +// Then the Jacobian of the mapping, dy/dx, is the 3x4 sub-matrix of the // extended y vector, indicated in the above diagram. // // Functors with multiple parameters // --------------------------------- // In practice, it is often convenient to use a function f of two or more -// vector-valued parameters, for example, x[3] and z[6]. Unfortunately, the jet +// vector-valued parameters, for example, x[3] and z[6]. Unfortunately, the Jet // framework is designed for a single-parameter vector-valued input. The wrapper // in this file addresses this issue adding support for functions with one or // more parameter vectors. // // To support multiple parameters, all the parameter vectors are concatenated // into one and treated as a single parameter vector, except that since the -// functor expects different inputs, we need to construct the jets as if they -// were part of a single parameter vector. The extended jets are passed +// functor expects different inputs, we need to construct the Jets as if they +// were part of a single parameter vector. The extended Jets are passed // separately for each parameter. // // For example, consider a functor F taking two vector parameters, p[2] and @@ -107,8 +107,8 @@ // } // }; // -// In this case, the necessary jet type is Jet<double, 5>. Here is a -// visualization of the jet objects in this case: +// In this case, the necessary Jet type is Jet<double, 5>. Here is a +// visualization of the Jet objects in this case: // // Dual components for p ----+ // | @@ -127,7 +127,7 @@ // | // Dual components for q --------------+ // -// where the 4x2 submatrix (marked with ".") and 4x3 submatrix (marked with "+" +// where the 4x2 submatrix (marked with ".") and 4x3 submatrix (marked with "+") // of y in the above diagram are the derivatives of y with respect to p and q // respectively. This is how autodiff works for functors taking multiple vector // valued arguments (up to 6).
diff --git a/include/ceres/internal/parameter_dims.h b/include/ceres/internal/parameter_dims.h index 5c806f7..8d4e9e4 100644 --- a/include/ceres/internal/parameter_dims.h +++ b/include/ceres/internal/parameter_dims.h
@@ -43,11 +43,11 @@ // used to pass parameter block dimensions around (e.g. between functions or // classes). // -// As an example if one have three parameter blocks with dimensions (2, 4, 1), +// As an example if one has three parameter blocks with dimensions (2, 4, 1), // one would use 'StaticParameterDims<2, 4, 1>' which is a synonym for // 'ParameterDims<false, 2, 4, 1>'. -// For dynamic parameter dims, one would just use 'DynamicParameterDims', which -// is a synonym for 'ParameterDims<true>'. +// For dynamic parameter dimensions, one would just use 'DynamicParameterDims', +// which is a synonym for 'ParameterDims<true>'. template <bool IsDynamic, int... Ns> class ParameterDims { public: @@ -58,7 +58,7 @@ static constexpr bool kIsValid = ((Ns > 0) && ...); static_assert(kIsValid, "Invalid parameter block dimension detected. Each parameter " - "block dimension must be bigger than zero."); + "block dimension must be greater than zero."); static constexpr bool kIsDynamic = IsDynamic; static constexpr int kNumParameterBlocks = sizeof...(Ns); @@ -69,8 +69,8 @@ static constexpr int GetDim(int dim) { return params_[dim]; } - // If one has all parameters packed into a single array this function unpacks - // the parameters. + // If one has all parameters packed into a single array, this function unpacks + // the parameters into an array of pointers. template <typename T> static inline std::array<T*, kNumParameterBlocks> GetUnpackedParameters( T* ptr) {
diff --git a/include/ceres/internal/variadic_evaluate.h b/include/ceres/internal/variadic_evaluate.h index eaf059b..f6dae6d 100644 --- a/include/ceres/internal/variadic_evaluate.h +++ b/include/ceres/internal/variadic_evaluate.h
@@ -46,17 +46,18 @@ namespace ceres::internal { -// Variadic evaluate is a helper function to evaluate ceres cost function or +// VariadicEvaluate is a helper function to evaluate Ceres cost functions or // functors using an input, output and the parameter dimensions. There are -// several ways different possibilities: -// 1) If the passed functor is a 'ceres::CostFunction' its evaluate method is +// several possibilities: +// 1) If the passed functor is a 'ceres::CostFunction', its Evaluate method is // called. // 2) If the functor is not a 'ceres::CostFunction' and the specified parameter -// dims is dynamic, the functor must have the following signature +// dimensions are dynamic, the functor must have the following signature: // 'bool(T const* const* input, T* output)'. // 3) If the functor is not a 'ceres::CostFunction' and the specified parameter -// dims is not dynamic, the input is expanded by using the number of parameter -// blocks. The signature of the functor must have the following signature +// dimensions are not dynamic, the input is expanded by using the number of +// parameter blocks. The signature of the functor must have the following +// signature: // 'bool()(const T* i_1, const T* i_2, ... const T* i_n, T* output)'. template <typename ParameterDims, typename Functor, typename T> inline bool VariadicEvaluate(const Functor& functor,
diff --git a/include/ceres/iteration_callback.h b/include/ceres/iteration_callback.h index 61dd841..958734e 100644 --- a/include/ceres/iteration_callback.h +++ b/include/ceres/iteration_callback.h
@@ -61,12 +61,12 @@ // Note: step_is_nonmonotonic is always false when iteration = 0; bool step_is_nonmonotonic = false; - // Whether or not the minimizer accepted this step or not. If the + // Whether the minimizer accepted this step. If the // ordinary trust region algorithm is used, this means that the // relative reduction in the objective function value was greater // than Solver::Options::min_relative_decrease. However, if the // non-monotonic trust region algorithm is used - // (Solver::Options:use_nonmonotonic_steps = true), then even if the + // (Solver::Options::use_nonmonotonic_steps = true), then even if the // relative decrease is not sufficient, the algorithm may accept the // step and the step is declared successful. // @@ -106,7 +106,7 @@ // ignore it. double eta = 0.0; - // Step sized computed by the line search algorithm. + // Step size computed by the line search algorithm. double step_size = 0.0; // Number of function value evaluations used by the line search algorithm.
diff --git a/include/ceres/jet.h b/include/ceres/jet.h index bc4d080..fd19f6f 100644 --- a/include/ceres/jet.h +++ b/include/ceres/jet.h
@@ -35,7 +35,7 @@ // beyond the scope of this header (see // http://en.wikipedia.org/wiki/Automatic_differentiation for details), the // basic idea is to extend normal arithmetic with an extra element, "e," often -// denoted with the greek symbol epsilon, such that e != 0 but e^2 = 0. Dual +// denoted with the Greek symbol epsilon, such that e != 0 but e^2 = 0. Dual // numbers are extensions of the real numbers analogous to complex numbers: // whereas complex numbers augment the reals by introducing an imaginary unit i // such that i^2 = -1, dual numbers introduce an "infinitesimal" unit e such @@ -49,7 +49,7 @@ // f(x) = x^2 , // // evaluated at 10. Using normal arithmetic, f(10) = 100, and df/dx(10) = 20. -// Next, argument 10 with an infinitesimal to get: +// Next, augment 10 with an infinitesimal to get: // // f(10 + e) = (10 + e)^2 // = 100 + 2 * 10 * e + e^2 @@ -111,7 +111,7 @@ // << "df/dy = " << z.v[1]; // // Most users should not use Jet objects directly; a wrapper around Jet objects, -// which makes computing the derivative, gradient, or jacobian of templated +// which makes computing the derivative, gradient, or Jacobian of templated // functors simple, is in autodiff.h. Even autodiff.h should not be used // directly; instead autodiff_cost_function.h is typically the file of interest. // @@ -151,7 +151,7 @@ // WARNING: Most Ceres users should not directly include this file or know the // details of how jets work. Instead the suggested method for automatic // derivatives is to use autodiff_cost_function.h, which is a wrapper around -// both jets.h and autodiff.h to make taking derivatives of cost functions for +// both jet.h and autodiff.h to make taking derivatives of cost functions for // use in Ceres easier. #ifndef CERES_PUBLIC_JET_H_ @@ -174,12 +174,12 @@ // Here we provide partial specializations of std::common_type for the Jet class // to allow determining a Jet type with a common underlying arithmetic type. -// Such an arithmetic type can be either a scalar or an another Jet. An example +// Such an arithmetic type can be either a scalar or another Jet. An example // for a common type, say, between a float and a Jet<double, N> is a Jet<double, // N> (i.e., std::common_type_t<float, ceres::Jet<double, N>> and // ceres::Jet<double, N> refer to the same type.) // -// The partial specialization are also used for determining compatible types by +// The partial specializations are also used for determining compatible types by // means of SFINAE and thus allow such types to be expressed as operands of // logical comparison operators. Missing (partial) specialization of // std::common_type for a particular (custom) type will therefore disable the
diff --git a/include/ceres/line_manifold.h b/include/ceres/line_manifold.h index 64b61ba..dae98d8 100644 --- a/include/ceres/line_manifold.h +++ b/include/ceres/line_manifold.h
@@ -62,11 +62,11 @@ // for the case Graff_1(R^n). // // The class works with dynamic and static ambient space dimensions. If the -// ambient space dimensions is known at compile time use +// ambient space dimension is known at compile time use // // LineManifold<3> manifold; // -// If the ambient space dimensions is not known at compile time the template +// If the ambient space dimension is not known at compile time the template // parameter needs to be set to ceres::DYNAMIC and the actual dimension needs // to be provided as a constructor argument: // @@ -142,7 +142,7 @@ bool LineManifold<AmbientSpaceDimension>::Plus(const double* x_ptr, const double* delta_ptr, double* x_plus_delta_ptr) const { - // We seek a box plus operator of the form + // We seek a Plus operator of the form // // [o*, d*] = Plus([o, d], [delta_o, delta_d]) // @@ -154,11 +154,11 @@ // d* = Plus_d(d, delta_d) // o* = Plus_o(o, d, delta_o) // - // The direction update function Plus_d is the same as as the SphereManifold: + // The direction update function Plus_d is the same as for SphereManifold: // // d* = H_{v(d)} [sinc(|delta_d|) delta_d, cos(|delta_d|)]^T // - // where H is the householder matrix + // where H is the Householder matrix // H_{v} = I - (2 / |v|^2) v v^T // and // v(d) = d - sign(d_n) |d| e_n. @@ -188,7 +188,7 @@ } } - // Calculate the householder transformation which is needed for f_d and f_o. + // Calculate the Householder transformation which is needed for f_d and f_o. AmbientVector v(size_); double beta; @@ -206,7 +206,7 @@ // The null space is in the direction of the line, so the tangent space is // perpendicular to the line direction. This is achieved by using the - // householder matrix of the direction and allow only movements + // Householder matrix of the direction and allow only movements // perpendicular to e_n. AmbientVector y(size_); y << delta_o, 0;
diff --git a/include/ceres/loss_function.h b/include/ceres/loss_function.h index 51e372d..7184241 100644 --- a/include/ceres/loss_function.h +++ b/include/ceres/loss_function.h
@@ -53,7 +53,7 @@ // image processing algorithm, which is responsible for producing the // measurements that are input to Ceres, has found and matched all // such tippy-tops in all image frames, except that in one of the -// frame it mistook a car's headlight for a hydrant. If we didn't do +// frames it mistook a car's headlight for a hydrant. If we didn't do // anything special (i.e. if we used a basic quadratic loss), the // residual for the erroneous measurement will result in extreme error // due to the quadratic nature of squared loss. This results in the @@ -65,7 +65,7 @@ // reduced. In the example above, this leads to outlier terms getting // downweighted so they do not overly influence the final solution. // -// What cost function is best? +// What loss function is best? // // In general, there isn't a principled way to select a robust loss // function. The authors suggest starting with a non-robust cost, then @@ -251,7 +251,7 @@ // // where c0 is chosen so that rho(0) == 0 // -// c0 = b log(1 + exp(-a / b) +// c0 = b log(1 + exp(-a / b)) // // This has the following useful properties: // @@ -322,7 +322,7 @@ // s -> a * rho'(s) // s -> a * rho''(s) // -// Since we treat the a nullptr Loss function as the Identity loss +// Since we treat a nullptr Loss function as the Identity loss // function, rho = nullptr is a valid input and will result in the input // being scaled by a. This provides a simple way of implementing a // scaled ResidualBlock. @@ -361,7 +361,7 @@ // whose scale can be mutated after an optimization problem has been // constructed. // -// Since we treat the a nullptr Loss function as the Identity loss +// Since we treat a nullptr Loss function as the Identity loss // function, rho = nullptr is a valid input. // // Example usage @@ -380,13 +380,13 @@ // problem.AddResidualBlock(cost_function, loss_function, parameters); // // Solver::Options options; -// Solger::Summary summary; +// Solver::Summary summary; // -// Solve(options, &problem, &summary) +// Solve(options, &problem, &summary); // // loss_function->Reset(new HuberLoss(1.0), TAKE_OWNERSHIP); // -// Solve(options, &problem, &summary) +// Solve(options, &problem, &summary); // class CERES_EXPORT LossFunctionWrapper final : public LossFunction { public:
diff --git a/include/ceres/manifold.h b/include/ceres/manifold.h index 1d70ddd..b82c3b0 100644 --- a/include/ceres/manifold.h +++ b/include/ceres/manifold.h
@@ -59,16 +59,16 @@ // the two dimensional plane that is tangent to the sphere at that point. There // are two reasons tangent spaces are interesting: // -// 1. They are Eucliean spaces so the usual vector space operations apply there, +// 1. They are Euclidean spaces so the usual vector space operations apply there, // which makes numerical operations easy. -// 2. Movement in the tangent space translate into movements along the manifold. +// 2. Movement in the tangent space translates into movements along the manifold. // Movements perpendicular to the tangent space do not translate into // movements on the manifold. // // Returning to our sphere example, moving in the 2 dimensional plane // tangent to the sphere and projecting back onto the sphere will move you away // from the point you started from but moving along the normal at the same point -// and the projecting back onto the sphere brings you back to the point. +// and then projecting back onto the sphere brings you back to the point. // // The Manifold interface defines two operations (and their derivatives) // involving the tangent space, allowing filtering and optimization to be @@ -100,7 +100,7 @@ // 9 dimensional vectors or 3x3 matrices, and points in its tangent spaces are // represented by 3 dimensional vectors. // -// Defining Plus and Minus are defined in terms of the matrix Exp and Log +// Plus and Minus are defined in terms of the matrix Exp and Log // operations as follows: // // Let Exp(p, q, r) = [cos(theta) + cp^2, -sr + cpq , sq + cpr ] @@ -127,7 +127,7 @@ // 2. For all y, Plus(x, Minus(y, x)) = y. // 3. For all delta, Minus(Plus(x, delta), x) = delta. // 4. For all delta_1, delta_2 -// |Minus(Plus(x, delta_1), Plus(x, delta_2)) <= |delta_1 - delta_2| +// |Minus(Plus(x, delta_1), Plus(x, delta_2))| <= |delta_1 - delta_2| // // Briefly: // (1) Ensures that the tangent space is "centered" at x, and the zero vector is @@ -228,11 +228,11 @@ // Minus(y, x) = y - x. // // The class works with dynamic and static ambient space dimensions. If the -// ambient space dimensions is know at compile time use +// ambient space dimension is known at compile time use // // EuclideanManifold<3> manifold; // -// If the ambient space dimensions is not known at compile time the template +// If the ambient space dimension is not known at compile time the template // parameter needs to be set to ceres::DYNAMIC and the actual dimension needs // to be provided as a constructor argument: //
diff --git a/include/ceres/manifold_test_utils.h b/include/ceres/manifold_test_utils.h index 98f4c69..43fe3e1 100644 --- a/include/ceres/manifold_test_utils.h +++ b/include/ceres/manifold_test_utils.h
@@ -52,7 +52,7 @@ // Testing a Manifold has two parts. // // 1. Checking that Manifold::Plus() and Manifold::Minus() are correctly -// defined. This requires per manifold tests. +// defined. This requires per-manifold tests. // // 2. The other methods of the manifold have mathematical properties that make // them compatible with Plus() and Minus(), as described in [1]. @@ -247,7 +247,7 @@ // https://doi.org/10.1007/s11263-012-0601-0 // // The computation here is closely related to the IsNearQuaternion matcher - // use in rotation_test.cc. The matcher, however, does not compute the + // used in rotation_test.cc. The matcher, however, does not compute the // distance but only compares the coefficients. const Eigen::Vector4d plus = actual + Vector{y}; const Eigen::Vector4d minus = actual - Vector{y};
diff --git a/include/ceres/normal_prior.h b/include/ceres/normal_prior.h index 5a26e01..5b0c786 100644 --- a/include/ceres/normal_prior.h +++ b/include/ceres/normal_prior.h
@@ -59,7 +59,7 @@ class CERES_EXPORT NormalPrior final : public CostFunction { public: - // Check that the number of rows in the vector b are the same as the + // Check that the number of rows in the vector b is the same as the // number of columns in the matrix A, crash otherwise. NormalPrior(const Matrix& A, Vector b); bool Evaluate(double const* const* parameters,
diff --git a/include/ceres/numeric_diff_cost_function.h b/include/ceres/numeric_diff_cost_function.h index 5889b70..9866d36 100644 --- a/include/ceres/numeric_diff_cost_function.h +++ b/include/ceres/numeric_diff_cost_function.h
@@ -29,17 +29,17 @@ // Author: keir@google.com (Keir Mierle) // sameeragarwal@google.com (Sameer Agarwal) // -// Create CostFunctions as needed by the least squares framework with jacobians +// Create CostFunctions as needed by the least squares framework with Jacobians // computed via numeric (a.k.a. finite) differentiation. For more details see // http://en.wikipedia.org/wiki/Numerical_differentiation. // -// To get an numerically differentiated cost function, you must define -// a class with a operator() (a functor) that computes the residuals. +// To get a numerically differentiated cost function, you must define +// a class with an operator() (a functor) that computes the residuals. // // The function must write the computed value in the last argument // (the only non-const one) and return true to indicate success. // Please see cost_function.h for details on how the return value -// maybe used to impose simple constraints on the parameter block. +// may be used to impose simple constraints on the parameter block. // // For example, consider a scalar error e = k - x'y, where both x and y are // two-dimensional column vector parameters, the prime sign indicates @@ -49,19 +49,20 @@ // for a series of measurements, where there is an instance of the cost function // for each measurement k. // -// The actual cost added to the total problem is e^2, or (k - x'k)^2; however, +// The actual cost added to the total problem is e^2, or (k - x'y)^2; however, // the squaring is implicitly done by the optimization framework. // -// To write an numerically-differentiable cost function for the above model, +// To write a numerically-differentiable cost function for the above model, // first define the object // // class MyScalarCostFunctor { +// public: // explicit MyScalarCostFunctor(double k): k_(k) {} // // bool operator()(const double* const x, // const double* const y, // double* residuals) const { -// residuals[0] = k_ - x[0] * y[0] - x[1] * y[1]; +// residuals[0] = k_ - (x[0] * y[0] + x[1] * y[1]); // return true; // } // @@ -116,7 +117,7 @@ // // The central difference method is considerably more accurate at the cost of // twice as many function evaluations than forward difference. Consider using -// central differences begin with, and only after that works, trying forward +// central differences to begin with, and only after that works, trying forward // difference to improve performance. // // WARNING #1: A common beginner's error when first using @@ -138,8 +139,8 @@ // // To get a numerically differentiated cost function, define a // subclass of CostFunction such that the Evaluate() function ignores -// the jacobian parameter. The numeric differentiation wrapper will -// fill in the jacobian parameter if necessary by repeatedly calling +// the jacobians parameter. The numeric differentiation wrapper will +// fill in the jacobians parameter if necessary by repeatedly calling // the Evaluate() function with small changes to the appropriate // parameters, and computing the slope. For performance, the numeric // differentiation wrapper class is templated on the concrete cost @@ -207,7 +208,7 @@ } } - // Constructs the CostFunctor on the heap and takes the ownership. + // Constructs the CostFunctor on the heap and takes ownership. // Invocable only if the number of residuals is known at compile-time. template <class... Args, typename = std::enable_if_t< @@ -246,7 +247,7 @@ constexpr int kNumParameters = ParameterDims::kNumParameters; constexpr int kNumParameterBlocks = ParameterDims::kNumParameterBlocks; - // Get the function value (residuals) at the the point to evaluate. + // Get the function value (residuals) at the point to evaluate. if (!internal::VariadicEvaluate<ParameterDims>( *functor_, parameters, residuals)) { return false;
diff --git a/include/ceres/numeric_diff_first_order_function.h b/include/ceres/numeric_diff_first_order_function.h index b6f8c34..efa93c6 100644 --- a/include/ceres/numeric_diff_first_order_function.h +++ b/include/ceres/numeric_diff_first_order_function.h
@@ -50,10 +50,10 @@ // Creates FirstOrderFunctions as needed by the GradientProblem // framework, with gradients computed via numeric differentiation. For -// more information on numeric differentiation, see the wikipedia +// more information on numeric differentiation, see the Wikipedia // article at https://en.wikipedia.org/wiki/Numerical_differentiation // -// To get an numerically differentiated cost function, you must define +// To get a numerically differentiated cost function, you must define // a class with an operator() (a functor) that computes the cost. // // The function must write the computed value in the last argument @@ -63,7 +63,7 @@ // two-dimensional column vector parameters, the prime sign indicates // transposition, and a is a constant. // -// To write an numerically-differentiable cost function for the above model, +// To write a numerically-differentiable cost function for the above model, // first define the object // // class QuadraticCostFunctor { @@ -92,7 +92,7 @@ // // std::unique_ptr<FirstOrderFunction> function // = std::make_unique< -// NumericDiffFirstOrderFunction<MyScalarCostFunctor, CENTRAL, 4>>( +// NumericDiffFirstOrderFunction<QuadraticCostFunctor, CENTRAL, 4>>( // std::make_unique<QuadraticCostFunctor>(1.0)); ^ ^ // | | // Finite Differencing Scheme -----+ | @@ -108,7 +108,7 @@ // alternate construction syntax can be used: // // std::unique_ptr<FirstOrderFunction> function -// = std::make_unique<NumericDiffFirstOrderFunction<MyScalarCostFunctor, +// = std::make_unique<NumericDiffFirstOrderFunction<QuadraticCostFunctor, // CENTRAL>>( // std::make_unique<QuadraticCostFunctor>(1.0), 4); //
diff --git a/include/ceres/numeric_diff_options.h b/include/ceres/numeric_diff_options.h index eefb7ad..17b61c5 100644 --- a/include/ceres/numeric_diff_options.h +++ b/include/ceres/numeric_diff_options.h
@@ -60,8 +60,7 @@ int max_num_ridders_extrapolations = 10; // Convergence criterion on extrapolation error for Ridders adaptive - // differentiation. The available error estimation methods are defined in - // NumericDiffErrorType and set in the "ridders_error_method" field. + // differentiation. double ridders_epsilon = 1e-12; // The factor in which to shrink the step size with each extrapolation in
diff --git a/include/ceres/ordered_groups.h b/include/ceres/ordered_groups.h index 6ca82af..e6d4590 100644 --- a/include/ceres/ordered_groups.h +++ b/include/ceres/ordered_groups.h
@@ -44,19 +44,19 @@ // A class for storing and manipulating an ordered collection of // groups/sets with the following semantics: // -// Group ids are non-negative integer values. Elements are any type +// Group IDs are non-negative integer values. Elements are any type // that can serve as a key in a map or an element of a set. // // An element can only belong to one group at a time. A group may // contain an arbitrary number of elements. // -// Groups are ordered by their group id. +// Groups are ordered by their group ID. template <typename T> class OrderedGroups { public: - // Add an element to a group. If a group with this id does not + // Add an element to a group. If a group with this ID does not // exist, one is created. This method can be called any number of - // times for the same element. Group ids should be non-negative + // times for the same element. Group IDs should be non-negative // numbers. // // Return value indicates if adding the element was a success. @@ -143,7 +143,7 @@ group_to_elements_.swap(new_group_to_elements); } - // Return the group id for the element. If the element is not a + // Return the group ID for the element. If the element is not a // member of any group, return -1. int GroupId(const T element) const { auto it = element_to_group_.find(element); @@ -171,7 +171,7 @@ int NumGroups() const { return group_to_elements_.size(); } // The first group with one or more elements. Calling this when - // there are no groups with non-zero elements will result in a + // there are no groups with one or more elements will result in a // crash. int MinNonZeroGroup() const { CHECK_NE(NumGroups(), 0);
diff --git a/include/ceres/problem.h b/include/ceres/problem.h index f587594..3d98158 100644 --- a/include/ceres/problem.h +++ b/include/ceres/problem.h
@@ -91,7 +91,7 @@ // // This class is specifically designed to address the important subset of // "sparse" least squares problems, where each component of the residual depends -// only on a small number number of parameters, even though the total number of +// only on a small number of parameters, even though the total number of // residuals and parameters may be very large. This property affords tremendous // gains in scale, allowing efficient solving of large problems that are // otherwise inaccessible. @@ -149,7 +149,7 @@ // the problem. There is a small but measurable performance penalty to these // checks, typically around 5% of construction time. If you are sure your // problem construction is correct, and 5% of the problem construction time - // is truly an overhead you want to avoid, then you can set + // is truly overhead you want to avoid, then you can set // disable_all_safety_checks to true. // // WARNING: Do not set this to true, unless you are absolutely sure of what @@ -164,11 +164,11 @@ Context* context = nullptr; // Using this callback interface, Ceres can notify you when it is about to - // evaluate the residuals or jacobians. With the callback, you can share + // evaluate the residuals or Jacobians. With the callback, you can share // computation between residual blocks by doing the shared computation in // EvaluationCallback::PrepareForEvaluation() before Ceres calls // CostFunction::Evaluate(). It also enables caching results between a pure - // residual evaluation and a residual & jacobian evaluation. + // residual evaluation and a residual & Jacobian evaluation. // // Problem DOES NOT take ownership of the callback. // @@ -182,6 +182,8 @@ // Problem(Problem::Options()). Problem(); explicit Problem(const Options& options); + + // Move constructor and assignment. Problem(Problem&&); Problem& operator=(Problem&&); @@ -226,7 +228,7 @@ // problem.AddResidualBlock(new MyBinaryCostFunction(...), nullptr, x2, x1); // // Add a residual block by listing the parameter block pointers directly - // instead of wapping them in a container. + // instead of wrapping them in a container. template <typename... Ts> ResidualBlockId AddResidualBlock(CostFunction* cost_function, LossFunction* loss_function, @@ -240,6 +242,7 @@ } // Add a residual block by providing a vector of parameter blocks. + // Ownership of cost_function and loss_function is handled as described above. ResidualBlockId AddResidualBlock( CostFunction* cost_function, LossFunction* loss_function, @@ -247,6 +250,7 @@ // Add a residual block by providing a pointer to the parameter block array // and the number of parameter blocks. + // Ownership of cost_function and loss_function is handled as described above. ResidualBlockId AddResidualBlock(CostFunction* cost_function, LossFunction* loss_function, double* const* const parameter_blocks, @@ -261,7 +265,7 @@ // problem. It is okay for manifold to be nullptr. // // Repeated calls with the same arguments are ignored. Repeated calls - // with the same double pointer but a different size results in a crash + // with the same double pointer but a different size result in a crash // (unless Solver::Options::disable_all_safety_checks is set to true). // // Repeated calls with the same double pointer and size but different Manifold @@ -280,8 +284,8 @@ // scan of the entire Problem object. // // WARNING: Removing a residual or parameter block will destroy the implicit - // ordering, rendering the jacobian or residuals returned from the solver - // uninterpretable. If you depend on the evaluated jacobian, do not use + // ordering, rendering the Jacobian or residuals returned from the solver + // uninterpretable. If you depend on the evaluated Jacobian, do not use // remove! This may change in a future release. void RemoveParameterBlock(const double* values); @@ -291,8 +295,8 @@ // problem itself is deleted. // // WARNING: Removing a residual or parameter block will destroy the implicit - // ordering, rendering the jacobian or residuals returned from the solver - // uninterpretable. If you depend on the evaluated jacobian, do not use + // ordering, rendering the Jacobian or residuals returned from the solver + // uninterpretable. If you depend on the evaluated Jacobian, do not use // remove! This may change in a future release. void RemoveResidualBlock(ResidualBlockId residual_block); @@ -405,20 +409,20 @@ struct EvaluateOptions { // The set of parameter blocks for which evaluation should be // performed. This vector determines the order that parameter blocks occur - // in the gradient vector and in the columns of the jacobian matrix. If - // parameter_blocks is empty, then it is assumed to be equal to vector + // in the gradient vector and in the columns of the Jacobian matrix. If + // parameter_blocks is empty, then it is assumed to be equal to the vector // containing ALL the parameter blocks. Generally speaking the parameter // blocks will occur in the order in which they were added to the // problem. But, this may change if the user removes any parameter blocks // from the problem. // // NOTE: This vector should contain the same pointers as the ones used to - // add parameter blocks to the Problem. These parameter block should NOT + // add parameter blocks to the Problem. These parameter blocks should NOT // point to new memory locations. Bad things will happen otherwise. std::vector<double*> parameter_blocks; // The set of residual blocks to evaluate. This vector determines the order - // in which the residuals occur, and how the rows of the jacobian are + // in which the residuals occur, and how the rows of the Jacobian are // ordered. If residual_blocks is empty, then it is assumed to be equal to // the vector containing ALL the residual blocks. Generally speaking the // residual blocks will occur in the order in which they were added to the @@ -462,10 +466,10 @@ // is the way to do so. // // Note 2: If no Manifolds are used, then the size of the gradient vector (and - // the number of columns in the jacobian) is the sum of the sizes of all the + // the number of columns in the Jacobian) is the sum of the sizes of all the // parameter blocks. If a parameter block has a Manifold, then it contributes // "TangentSize" entries to the gradient vector (and the number of columns in - // the jacobian). + // the Jacobian). // // Note 3: This function cannot be called while the problem is being solved, // for example it cannot be called from an IterationCallback at the end of an @@ -481,7 +485,7 @@ CRSMatrix* jacobian); // Evaluates the residual block, storing the scalar cost in *cost, the - // residual components in *residuals, and the jacobians between the parameters + // residual components in *residuals, and the Jacobians between the parameters // and residuals in jacobians[i], in row-major order. // // If residuals is nullptr, the residuals are not computed. @@ -496,8 +500,8 @@ // returns false, the caller should expect the output memory locations to have // been modified. // - // The returned cost and jacobians have had robustification and Manifold - // applied already; for example, the jacobian for a 4-dimensional quaternion + // The returned cost and Jacobians have had robustification and Manifold + // applied already; for example, the Jacobian for a 4-dimensional quaternion // parameter using the "QuaternionParameterization" is num_residuals by 3 // instead of num_residuals by 4. // @@ -524,7 +528,7 @@ // This means, if an EvaluationCallback is associated with the problem then it // is the user's responsibility to call PrepareForEvaluation before calling // this method if necessary, i.e. iff the parameter values have been changed - // since the last call to evaluate / solve.' + // since the last call to evaluate / solve. // // This is because, as the name implies, we assume that the parameter blocks // did not change since the last time PrepareForEvaluation was called (via
diff --git a/include/ceres/rotation.h b/include/ceres/rotation.h index 96a4aac..eede7d2 100644 --- a/include/ceres/rotation.h +++ b/include/ceres/rotation.h
@@ -60,7 +60,7 @@ // Trivial wrapper to index linear arrays as matrices, given a fixed // column and row stride. When an array "T* array" is wrapped by a // -// (const) MatrixAdapter<T, row_stride, col_stride> M" +// (const) MatrixAdapter<T, row_stride, col_stride> M // // the expression M(i, j) is equivalent to // @@ -106,7 +106,7 @@ return {w, x, y, z}; } -// Constructs a quaternion with the Ceres coefficient order (x, y, z, w). +// Constructs a quaternion with the Eigen coefficient order (x, y, z, w). template <typename Order, typename T> constexpr auto MakeQuaternion(T w, T x, T y, T z) -> std::enable_if_t<std::is_same_v<Order, EigenQuaternionOrder>, @@ -238,8 +238,9 @@ // Internally, Euler Axis sequences are classified by Ken Shoemake's scheme from // "Euler angle conversion", Graphics Gems IV, where a choice of axis for the // first rotation and 3 binary choices: -// 1. Oddness of the axis permutation, that defines whether the second axis is -// 'greater-than' the first axis according to the order X>Y>Z>X) +// 1. Parity of the axis permutation. The axis sequence has Even parity if the +// second axis of rotation is 'greater-than' the first axis of rotation +// according to the order X<Y<Z<X, otherwise it has Odd parity. // 2. Proper Euler Angles v.s. Tait-Bryan Angles // 3. Extrinsic Rotations v.s. Intrinsic Rotations // compactly represent all 24 possible Euler Angle Conventions @@ -439,7 +440,7 @@ // result in a normalized angle-axis vector. // // In that case we observe that 2 * theta ~ 2 * theta - 2 * pi, - // which is equivalent saying + // which is equivalent to saying // // theta - pi = atan(sin(theta - pi), cos(theta - pi)) // = atan(-sin(theta), -cos(theta)) @@ -500,9 +501,9 @@ } // The conversion of a rotation matrix to the angle-axis form is -// numerically problematic when then rotation angle is close to zero +// numerically problematic when the rotation angle is close to zero // or to Pi. The following implementation detects when these two cases -// occurs and deals with them by taking code paths that are guaranteed +// occur and deals with them by taking code paths that are guaranteed // to not perform division by a small number. template <typename T> inline void RotationMatrixToAngleAxis(const T* R, T* angle_axis) { @@ -682,7 +683,7 @@ euler[2] = ea[2]; } - // Proper euler angles are defined for angles in + // Proper Euler angles are defined for angles in // [-pi, pi) x [0, pi / 2) x [-pi, pi) // which is enforced here if constexpr (EulerSystem::kIsProperEuler) { @@ -881,7 +882,7 @@ if (internal::AnyExactlyNonZero( angle_axis[0], angle_axis[1], angle_axis[2])) { - // Away from zero, use the rodriguez formula + // Away from zero, use the Rodrigues formula // // result = pt costheta + // (w x pt) * sintheta +
diff --git a/include/ceres/sized_cost_function.h b/include/ceres/sized_cost_function.h index 8928c19..a956ebd 100644 --- a/include/ceres/sized_cost_function.h +++ b/include/ceres/sized_cost_function.h
@@ -41,8 +41,8 @@ #include <initializer_list> #include "ceres/cost_function.h" +#include "ceres/internal/parameter_dims.h" #include "ceres/types.h" -#include "internal/parameter_dims.h" namespace ceres { @@ -50,10 +50,10 @@ class SizedCostFunction : public CostFunction { public: static_assert(kNumResiduals > 0 || kNumResiduals == DYNAMIC, - "Cost functions must have at least one residual block."); + "Cost functions must have at least one residual."); static_assert(internal::StaticParameterDims<Ns...>::kIsValid, "Invalid parameter block dimension detected. Each parameter " - "block dimension must be bigger than zero."); + "block dimension must be greater than zero."); using ParameterDims = internal::StaticParameterDims<Ns...>;
diff --git a/include/ceres/solver.h b/include/ceres/solver.h index b31880f..97ab583 100644 --- a/include/ceres/solver.h +++ b/include/ceres/solver.h
@@ -94,12 +94,12 @@ NonlinearConjugateGradientType nonlinear_conjugate_gradient_type = FLETCHER_REEVES; - // The LBFGS hessian approximation is a low rank approximation to + // The LBFGS Hessian approximation is a low rank approximation to // the inverse of the Hessian matrix. The rank of the // approximation determines (linearly) the space and time // complexity of using the approximation. Higher the rank, the // better is the quality of the approximation. The increase in - // quality is however is bounded for a number of reasons. + // quality is however bounded for a number of reasons. // // 1. The method only uses secant information and not actual // derivatives. @@ -133,9 +133,9 @@ // by default. In particular it can degrade performance when the // sensitivity of the problem to different parameters varies significantly, // as in this case a single scalar factor fails to capture this variation - // and detrimentally downscales parts of the jacobian approximation which + // and detrimentally downscales parts of the Jacobian approximation which // correspond to low-sensitivity parameters. It can also reduce the - // robustness of the solution to errors in the jacobians. + // robustness of the solution to errors in the Jacobians. // // Oren S.S., Self-scaling variable metric (SSVM) algorithms // Part II: Implementation and experiments, Management Science, @@ -269,7 +269,7 @@ double max_solver_time_in_seconds = 1e9; // Number of threads used by Ceres for evaluating the cost and - // jacobians. + // Jacobians. int num_threads = 1; // Trust region minimizer settings. @@ -284,7 +284,7 @@ // accepted. double min_relative_decrease = 1e-3; - // For the Levenberg-Marquadt algorithm, the scaled diagonal of + // For the Levenberg-Marquardt algorithm, the scaled diagonal of // the normal equations J'J is used to control the size of the // trust region. Extremely small and large values along the // diagonal can make this regularization scheme @@ -303,20 +303,20 @@ // Minimizer terminates when // - // (new_cost - old_cost) < function_tolerance * old_cost; + // (old_cost - new_cost) < function_tolerance * old_cost; // double function_tolerance = 1e-6; // Minimizer terminates when // - // max_i |x - Project(Plus(x, -g(x))| < gradient_tolerance + // max_i |x - Project(Plus(x, -g(x)))| < gradient_tolerance // // This value should typically be 1e-4 * function_tolerance. double gradient_tolerance = 1e-10; // Minimizer terminates when // - // |step|_2 <= parameter_tolerance * ( |x|_2 + parameter_tolerance) + // |step|_2 <= parameter_tolerance * (|x|_2 + parameter_tolerance) // double parameter_tolerance = 1e-8; @@ -392,8 +392,8 @@ // can have a significant impact on the efficiency and accuracy of // the method. e.g., when doing sparse Cholesky factorization, // there are matrices for which a good ordering will give a - // Cholesky factor with O(n) storage, where as a bad ordering will - // result in an completely dense factor. + // Cholesky factor with O(n) storage, whereas a bad ordering will + // result in a completely dense factor. // // Sparse direct solvers like SPARSE_NORMAL_CHOLESKY and // SPARSE_SCHUR use a fill reducing ordering of the columns and @@ -462,12 +462,12 @@ // ordering, it must have one important property. The lowest // numbered elimination group must form an independent set in the // graph corresponding to the Hessian, or in other words, no two - // parameter blocks in in the first elimination group should + // parameter blocks in the first elimination group should // co-occur in the same residual block. For the best performance, // this elimination group should be as large as possible. For // standard bundle adjustment problems, this corresponds to the // first elimination group containing all the 3d points, and the - // second containing the all the cameras parameter blocks. + // second containing all the camera parameter blocks. // // If the user leaves the choice to Ceres, then the solver uses an // approximate maximum independent set algorithm to identify the first @@ -479,10 +479,10 @@ // linear_solver_ordering_type = AMD // --------------------------------- // - // A Constrained Approximate Minimum Degree (CAMD) ordering used where the - // parameter blocks in the lowest numbered group are eliminated first, and - // then the parameter blocks in the next lowest numbered group and so - // on. Within each group, CAMD free to order the parameter blocks as it + // A Constrained Approximate Minimum Degree (CAMD) ordering is used where + // the parameter blocks in the lowest numbered group are eliminated first, + // and then the parameter blocks in the next lowest numbered group and so + // on. Within each group, CAMD is free to order the parameter blocks as it // chooses. // // linear_solver_ordering_type = NESDIS @@ -496,7 +496,7 @@ // // b. linear_solver_type = SPARSE_SCHUR/DENSE_SCHUR/ITERATIVE_SCHUR // - // ONLY the lowest group are used to compute the Schur complement, and + // ONLY the lowest group is used to compute the Schur complement, and // Nested Dissection is used to compute a fill reducing ordering for the // Schur Complement (or its preconditioner). // @@ -511,7 +511,7 @@ // // b. linear_solver_type = SPARSE_SCHUR/DENSE_SCHUR/ITERATIVE_SCHUR // - // ONLY the lowest group are used to compute the Schur complement, and AMD + // ONLY the lowest group is used to compute the Schur complement, and AMD // or NESDIS is used to compute a fill reducing ordering for the Schur // Complement (or its preconditioner). std::shared_ptr<ParameterBlockOrdering> linear_solver_ordering; @@ -556,9 +556,9 @@ // Some non-linear least squares problems are symbolically dense but // numerically sparse. i.e. at any given state only a small number - // of jacobian entries are non-zero, but the position and number of + // of Jacobian entries are non-zero, but the position and number of // non-zeros is different depending on the state. For these problems - // it can be useful to factorize the sparse jacobian at each solver + // it can be useful to factorize the sparse Jacobian at each solver // iteration instead of including all of the zero entries in a single // general factorization. // @@ -566,7 +566,7 @@ // then it is probably best to keep this false, otherwise it will // likely lead to worse performance. - // This settings only affects the SPARSE_NORMAL_CHOLESKY solver. + // This setting only affects the SPARSE_NORMAL_CHOLESKY solver. bool dynamic_sparsity = false; // If use_mixed_precision_solves is true, the Gauss-Newton matrix is @@ -580,13 +580,13 @@ // max_num_refinement_iterations = 0, then the Gauss-Newton step is computed // in single precision. // - // This options is available when linear solver uses sparse or dense - // cholesky factorization. + // This option is available when the linear solver uses sparse or dense + // Cholesky factorization. bool use_mixed_precision_solves = false; - // Number steps of the iterative refinement process to run when computing + // Number of steps of the iterative refinement process to run when computing // the Gauss-Newton step. This is most useful when used in conjunction with - // use_mixed_precision = true. + // use_mixed_precision_solves = true. int max_num_refinement_iterations = 0; // Minimum number of iterations for which the linear solver should @@ -601,7 +601,7 @@ // Maximum number of iterations performed by SCHUR_POWER_SERIES_EXPANSION. // Each iteration corresponds to one more term in the power series expansion - // od the inverse of the Schur complement. This value controls the maximum + // of the inverse of the Schur complement. This value controls the maximum // number of iterations whether it is used as a preconditioner or just to // initialize the solution for ITERATIVE_SCHUR. int max_num_spse_iterations = 5; @@ -627,7 +627,7 @@ // (Q_i - Q_{i-1})/Q_i < eta/i double eta = 1e-1; - // Normalize the jacobian using Jacobi scaling before calling + // Normalize the Jacobian using Jacobi scaling before calling // the linear least squares solver. bool jacobi_scaling = true; @@ -645,12 +645,11 @@ // Notice here that the expression on the left is linear in a_1 // and a_2, and given any value for b_1, b_2 and c_1, it is // possible to use linear regression to estimate the optimal - // values of a_1 and a_2. Indeed, its possible to analytically - // eliminate the variables a_1 and a_2 from the problem all - // together. Problems like these are known as separable least - // squares problem and the most famous algorithm for solving them - // is the Variable Projection algorithm invented by Golub & - // Pereyra. + // values of a_1 and a_2. Indeed, it's possible to analytically + // eliminate the variables a_1 and a_2 from the problem altogether. + // Problems like these are known as separable least squares problems + // and the most famous algorithm for solving them is the Variable + // Projection algorithm invented by Golub & Pereyra. // // Similar structure can be found in the matrix factorization with // missing data problem. There the corresponding algorithm is @@ -665,7 +664,7 @@ // Implementing Variable Projection is tedious and expensive, and // they present a simpler algorithm, which they refer to as // Algorithm II, where once the Newton/Trust Region step has been - // computed for the whole problem (a_1, a_2, b_1, b_2, c_1) and + // computed for the whole problem (a_1, a_2, b_1, b_2, c_1), an // additional optimization step is performed to estimate a_1 and // a_2 exactly. // @@ -691,13 +690,13 @@ // highly recommended. bool use_inner_iterations = false; - // If inner_iterations is true, then the user has two choices. + // If use_inner_iterations is true, then the user has two choices. // // 1. Let the solver heuristically decide which parameter blocks // to optimize in each inner iteration. To do this leave // Solver::Options::inner_iteration_ordering untouched. // - // 2. Specify a collection of of ordered independent sets. Where + // 2. Specify a collection of ordered independent sets. Where // the lower numbered groups are optimized before the higher // number groups. Each group must be an independent set. Not // all parameter blocks need to be present in the ordering. @@ -732,11 +731,13 @@ // non-empty and trust_region_problem_dump_format_type is not // CONSOLE. std::string trust_region_problem_dump_directory = "/tmp"; + + // Format in which the trust region problem should be dumped. DumpFormatType trust_region_problem_dump_format_type = TEXTFILE; // Finite differences options ---------------------------------------------- - // Check all jacobians computed by each residual block with finite + // Check all Jacobians computed by each residual block with finite // differences. This is expensive since it involves computing the // derivative by normal means (e.g. user specified, autodiff, // etc), then also computing it using finite differences. The @@ -745,13 +746,13 @@ bool check_gradients = false; // Relative precision to check for in the gradient checker. If the - // relative difference between an element in a jacobian exceeds - // this number, then the jacobian for that cost term is dumped. + // relative difference between an element in a Jacobian exceeds + // this number, then the Jacobian for that cost term is dumped. double gradient_check_relative_precision = 1e-8; - // WARNING: This option only applies to the to the numeric + // WARNING: This option only applies to the numeric // differentiation used for checking the user provided derivatives - // when when Solver::Options::check_gradients is true. If you are + // when Solver::Options::check_gradients is true. If you are // using NumericDiffCostFunction and are interested in changing // the step size for numeric differentiation in your cost // function, please have a look at @@ -824,6 +825,9 @@ // termination. std::string FullReport() const; + // Returns true if the solver terminated for a reason that allows + // the solution to be used. This is true if the termination_type is + // CONVERGENCE or USER_SUCCESS. bool IsSolutionUsable() const; // Minimizer summary ------------------------------------------------- @@ -904,7 +908,7 @@ // Number of residual only evaluations. int num_residual_evaluations = -1; - // Time (in seconds) spent evaluating the jacobian matrix. + // Time (in seconds) spent evaluating the Jacobian matrix. double jacobian_evaluation_time_in_seconds = -1.0; // Number of Jacobian (and residual) evaluations. @@ -1012,7 +1016,7 @@ std::vector<int> linear_solver_ordering_given; // Size of the parameter groups used by the solver when ordering - // the columns of the Jacobian. This maybe different from + // the columns of the Jacobian. This may be different from // linear_solver_ordering_given if the user left // linear_solver_ordering_given blank and asked for an automatic // ordering, or if the problem contains some constant or inactive @@ -1029,7 +1033,7 @@ // schur_structure_given is because the corresponding template // specialization does not exist. // - // Template specializations can be added to ceres by editing + // Template specializations can be added to Ceres by editing // internal/ceres/generate_template_specializations.py std::string schur_structure_used; @@ -1047,8 +1051,8 @@ // inner iterations. std::vector<int> inner_iteration_ordering_given; - // Size of the parameter groups given used by the solver for - // performing inner iterations. This maybe different from + // Size of the parameter groups used by the solver for + // performing inner iterations. This may be different from // inner_iteration_ordering_given if the user left // inner_iteration_ordering_given blank and asked for an automatic // ordering, or if the problem contains some constant or inactive
diff --git a/include/ceres/sphere_manifold.h b/include/ceres/sphere_manifold.h index 06983a0..fa1228f 100644 --- a/include/ceres/sphere_manifold.h +++ b/include/ceres/sphere_manifold.h
@@ -49,7 +49,7 @@ namespace ceres { // This provides a manifold on a sphere meaning that the norm of the vector -// stays the same. Such cases often arises in Structure for Motion +// stays the same. Such cases often arise in Structure from Motion // problems. One example where they are used is in representing points whose // triangulation is ill-conditioned. Here it is advantageous to use an // over-parameterization since homogeneous vectors can represent points at @@ -68,11 +68,11 @@ // than 1. // // The class works with dynamic and static ambient space dimensions. If the -// ambient space dimensions is known at compile time use +// ambient space dimension is known at compile time use // // SphereManifold<3> manifold; // -// If the ambient space dimensions is not known at compile time the template +// If the ambient space dimension is not known at compile time the template // parameter needs to be set to ceres::DYNAMIC and the actual dimension needs // to be provided as a constructor argument: // @@ -203,7 +203,7 @@ Eigen::Map<const AmbientVector> x(x_ptr, size_); Eigen::Map<TangentVector> y_minus_x(y_minus_x_ptr, size_ - 1); - // Apply hoseholder transformation. + // Apply Householder transformation. AmbientVector v(size_); double beta;
diff --git a/include/ceres/tiny_solver.h b/include/ceres/tiny_solver.h index 093bc36..b2b1ba1 100644 --- a/include/ceres/tiny_solver.h +++ b/include/ceres/tiny_solver.h
@@ -42,7 +42,7 @@ // Ceres, so it is possible to take this file alone and put it in another // project without the rest of Ceres. // -// Algorithm based off of: +// Algorithm based on: // // [1] K. Madsen, H. Nielsen, O. Tingleoff. // Methods for Non-linear Least Squares Problems. @@ -60,12 +60,12 @@ namespace ceres { -// To use tiny solver, create a class or struct that allows computing the cost +// To use TinySolver, create a class or struct that allows computing the cost // function (described below). This is similar to a ceres::CostFunction, but is // different to enable statically allocating all memory for the solver // (specifically, enum sizes). Key parts are the Scalar typedef, the enums to // describe problem sizes (needed to remove all heap allocations), and the -// operator() overload to evaluate the cost and (optionally) jacobians. +// operator() overload to evaluate the cost and (optionally) Jacobians. // // struct TinySolverCostFunctionTraits { // typedef double Scalar; @@ -86,7 +86,7 @@ // double* parameters -- NUM_PARAMETERS or NumParameters() // double* residuals -- NUM_RESIDUALS or NumResiduals() // double* jacobian -- NUM_RESIDUALS * NUM_PARAMETERS in column-major format -// (Eigen's default); or nullptr if no jacobian +// (Eigen's default); or nullptr if no Jacobian // requested. // // An example (fully statically sized): @@ -166,6 +166,7 @@ MAX_NUM_PARAMETERS, MAX_NUM_PARAMETERS>; + // Termination status of the solver. enum Status { // max_norm |J'(x) * f(x)| < gradient_tolerance GRADIENT_TOO_SMALL, @@ -175,30 +176,36 @@ COST_TOO_SMALL, // num_iterations >= max_num_iterations HIT_MAX_ITERATIONS, - // (new_cost - old_cost) < function_tolerance * old_cost + // (old_cost - new_cost) < function_tolerance * old_cost COST_CHANGE_TOO_SMALL, // TODO(sameeragarwal): Deal with numerical failures. }; + // Solver options. struct Options { + // Maximum number of iterations to run. int max_num_iterations = 50; - // max_norm |J'(x) * f(x)| < gradient_tolerance + // Minimizer terminates when max_norm |J'(x) * f(x)| < gradient_tolerance. Scalar gradient_tolerance = 1e-10; - // ||dx|| <= parameter_tolerance * (||x|| + parameter_tolerance) + // Minimizer terminates when + // ||dx|| <= parameter_tolerance * (||x|| + parameter_tolerance). Scalar parameter_tolerance = 1e-8; - // (new_cost - old_cost) < function_tolerance * old_cost + // Minimizer terminates when + // (old_cost - new_cost) < function_tolerance * old_cost. Scalar function_tolerance = 1e-6; - // cost_threshold > ||f(x)||^2 / 2 + // Minimizer terminates when cost_threshold > ||f(x)||^2 / 2. Scalar cost_threshold = std::numeric_limits<Scalar>::epsilon(); + // Initial trust region radius. Scalar initial_trust_region_radius = 1e4; }; + // Summary of the optimization. struct Summary { // 1/2 ||f(x_0)||^2 Scalar initial_cost = -1; @@ -206,7 +213,9 @@ Scalar final_cost = -1; // max_norm(J'f(x)) Scalar gradient_max_norm = -1; + // Number of iterations performed. int iterations = -1; + // Termination status. Status status = HIT_MAX_ITERATIONS; }; @@ -351,14 +360,13 @@ return summary; } - ResidualVector Residuals() - const { + ResidualVector Residuals() const { // Residual updates are stored with the opposite sign. return -residuals_; } JacobianMatrix Jacobian() const { - // Undo the scaling applied to the jacobian matrix during Update(). + // Undo the scaling applied to the Jacobian matrix during Update(). return jacobian_ * jacobi_scaling_.cwiseInverse().asDiagonal(); }
diff --git a/include/ceres/tiny_solver_autodiff_function.h b/include/ceres/tiny_solver_autodiff_function.h index 6fe0db8..045ea43 100644 --- a/include/ceres/tiny_solver_autodiff_function.h +++ b/include/ceres/tiny_solver_autodiff_function.h
@@ -132,36 +132,36 @@ // parameter block it is easier to inline to avoid overhead. bool operator()(const T* parameters, T* residuals, T* jacobian) const { if (jacobian == nullptr) { - // No jacobian requested, so just directly call the cost function with - // doubles, skipping jets and derivatives. + // No Jacobian requested, so just directly call the cost function with + // doubles, skipping Jets and derivatives. return cost_functor_(parameters, residuals); } - // Initialize the input jets with passed parameters. + // Initialize the input Jets with passed parameters. for (int i = 0; i < kNumParameters; ++i) { jet_parameters_[i].a = parameters[i]; // Scalar part. jet_parameters_[i].v.setZero(); // Derivative part. jet_parameters_[i].v[i] = T(1.0); } - // Initialize the output jets such that we can detect user errors. + // Initialize the output Jets such that we can detect user errors. for (int i = 0; i < num_residuals_; ++i) { jet_residuals_[i].a = kImpossibleValue; jet_residuals_[i].v.setConstant(kImpossibleValue); } - // Execute the cost function, but with jets to find the derivative. + // Execute the cost function, but with Jets to find the derivative. if (!cost_functor_(jet_parameters_, jet_residuals_.data())) { return false; } - // Copy the jacobian out of the derivative part of the residual jets. + // Copy the Jacobian out of the derivative part of the residual Jets. Eigen::Map<JacobianMatrix> jacobian_matrix( jacobian, num_residuals_, kNumParameters); for (int r = 0; r < num_residuals_; ++r) { residuals[r] = jet_residuals_[r].a; // Note that while this looks like a fast vectorized write, in practice it // unfortunately thrashes the cache since the writes to the column-major - // jacobian are strided (e.g. rows are non-contiguous). + // Jacobian are strided (e.g. rows are non-contiguous). jacobian_matrix.row(r) = jet_residuals_[r].v; } return true; @@ -178,7 +178,7 @@ // This will be overridden if NUM_RESIDUALS == Eigen::Dynamic. int num_residuals_ = kNumResiduals; - // To evaluate the cost function with jets, temporary storage is needed. These + // To evaluate the cost function with Jets, temporary storage is needed. These // are the buffers that are used during evaluation; parameters for the input, // and jet_residuals_ are where the final cost and derivatives end up. //
diff --git a/include/ceres/tiny_solver_cost_function_adapter.h b/include/ceres/tiny_solver_cost_function_adapter.h index 3f7a378..92d78d2 100644 --- a/include/ceres/tiny_solver_cost_function_adapter.h +++ b/include/ceres/tiny_solver_cost_function_adapter.h
@@ -98,7 +98,7 @@ explicit TinySolverCostFunctionAdapter(const CostFunction& cost_function) : cost_function_(cost_function) { CHECK_EQ(cost_function_.parameter_block_sizes().size(), 1) - << "Only CostFunctions with exactly one parameter blocks are allowed."; + << "Only CostFunctions with exactly one parameter block are allowed."; const int parameter_block_size = cost_function_.parameter_block_sizes()[0]; if (NUM_PARAMETERS == Eigen::Dynamic || NUM_RESIDUALS == Eigen::Dynamic) { @@ -114,6 +114,7 @@ } } + // Evaluates the cost function. bool operator()(const double* parameters, double* residuals, double* jacobian) const {
diff --git a/include/ceres/types.h b/include/ceres/types.h index f677d43..dff7c66 100644 --- a/include/ceres/types.h +++ b/include/ceres/types.h
@@ -59,25 +59,25 @@ // normal equations A'A x = A'b. They are direct solvers and do not // assume any special problem structure. - // Solve the normal equations using a dense Cholesky solver; based + // Solve the normal equations using a dense Cholesky solver based // on Eigen. DENSE_NORMAL_CHOLESKY, - // Solve the normal equations using a dense QR solver; based on + // Solve the normal equations using a dense QR solver based on // Eigen. DENSE_QR, - // Solve the normal equations using a sparse cholesky solver; + // Solve the normal equations using a sparse Cholesky solver. SPARSE_NORMAL_CHOLESKY, // Specialized solvers, specific to problems with a generalized - // bi-partitite structure. + // bipartite structure. - // Solves the reduced linear system using a dense Cholesky solver; + // Solves the reduced linear system using a dense Cholesky solver // based on Eigen. DENSE_SCHUR, - // Solves the reduced linear system using a sparse Cholesky solver; + // Solves the reduced linear system using a sparse Cholesky solver // based on CHOLMOD. SPARSE_SCHUR, @@ -105,8 +105,8 @@ // only be used with the ITERATIVE_SCHUR solver. SCHUR_JACOBI, - // Use power series expansion to approximate the inversion of Schur complement - // as a preconditioner. + // Use power series expansion to approximate the inversion of the Schur + // complement as a preconditioner. SCHUR_POWER_SERIES_EXPANSION, // Visibility clustering based preconditioners. @@ -118,7 +118,7 @@ CLUSTER_JACOBI, CLUSTER_TRIDIAGONAL, - // Subset preconditioner is a general purpose preconditioner + // Subset preconditioner is a general purpose preconditioner for // linear least squares problems. Given a set of residual blocks, // it uses the corresponding subset of the rows of the Jacobian to // construct a preconditioner. @@ -185,16 +185,16 @@ }; // The order in which variables are eliminated in a linear solver -// can have a significant of impact on the efficiency and accuracy +// can have a significant impact on the efficiency and accuracy // of the method. e.g., when doing sparse Cholesky factorization, // there are matrices for which a good ordering will give a -// Cholesky factor with O(n) storage, where as a bad ordering will +// Cholesky factor with O(n) storage, whereas a bad ordering will // result in a completely dense factor. // // So sparse direct solvers like SPARSE_NORMAL_CHOLESKY and // SPARSE_SCHUR and preconditioners like SUBSET, CLUSTER_JACOBI & // CLUSTER_TRIDIAGONAL use a fill reducing ordering of the columns and -// rows of the matrix being factorized before actually the numeric +// rows of the matrix being factorized before computing the numeric // factorization. // // This enum controls the class of algorithm used to compute this @@ -208,21 +208,28 @@ NESDIS }; +// Available dense linear algebra libraries. enum DenseLinearAlgebraLibraryType { + // Eigen's dense linear algebra routines. EIGEN, + // System BLAS + LAPACK. LAPACK, + // Nvidia's cuSOLVER + cuBLAS. CUDA, }; -// Logging options +// Logging options. // The options get progressively noisier. enum LoggingType { SILENT, PER_MINIMIZER_ITERATION, }; +// Minimizer types. enum MinimizerType { + // Line search based minimizer. LINE_SEARCH, + // Trust region based minimizer. TRUST_REGION, }; @@ -234,14 +241,14 @@ // functions. The generalization can be performed in a number of // different ways, resulting in a variety of search directions. The // precise choice of the non-linear conjugate gradient algorithm - // used is determined by NonlinerConjuateGradientType. + // used is determined by NonlinearConjugateGradientType. NONLINEAR_CONJUGATE_GRADIENT, - // BFGS, and it's limited memory approximation L-BFGS, are quasi-Newton + // BFGS, and its limited memory approximation L-BFGS, are quasi-Newton // algorithms that approximate the Hessian matrix by iteratively refining // an initial estimate with rank-one updates using the gradient at each - // iteration. They are a generalisation of the Secant method and satisfy - // the Secant equation. The Secant equation has an infinium of solutions + // iteration. They are a generalization of the Secant method and satisfy + // the Secant equation. The Secant equation has an infinitum of solutions // in multiple dimensions, as there are N*(N+1)/2 degrees of freedom in a // symmetric matrix but only N conditions are specified by the Secant // equation. The requirement that the Hessian approximation be positive @@ -306,10 +313,12 @@ HESTENES_STIEFEL, }; +// Line search algorithms. enum LineSearchType { // Backtracking line search with polynomial interpolation or // bisection. ARMIJO, + // Line search satisfying the Wolfe conditions. WOLFE, }; @@ -357,19 +366,19 @@ }; enum TerminationType { - // Minimizer terminated because one of the convergence criterion set + // Minimizer terminated because one of the convergence criteria set // by the user was satisfied. // - // 1. (new_cost - old_cost) < function_tolerance * old_cost; - // 2. max_i |gradient_i| < gradient_tolerance - // 3. |step|_2 <= parameter_tolerance * ( |x|_2 + parameter_tolerance) + // 1. (old_cost - new_cost) < function_tolerance * old_cost; + // 2. max_i |x_i - Project(Plus(x, -g))_i| < gradient_tolerance + // 3. |step|_2 <= parameter_tolerance * (|x|_2 + parameter_tolerance) // // The user's parameter blocks will be updated with the solution. CONVERGENCE, // The solver ran for maximum number of iterations or maximum amount // of time specified by the user, but none of the convergence - // criterion specified by the user were met. The user's parameter + // criteria specified by the user were met. The user's parameter // blocks will be updated with the solution found so far. NO_CONVERGENCE, @@ -387,7 +396,7 @@ // The user's parameter blocks will be updated with the solution. USER_SUCCESS, - // Minimizer terminated because because a user IterationCallback + // Minimizer terminated because a user IterationCallback // returned SOLVER_ABORT. // // The user's parameter blocks will not be updated. @@ -404,7 +413,7 @@ // Terminate solver, and do not update the parameter blocks upon // return. Unless the user has set - // Solver:Options:::update_state_every_iteration, in which case the + // Solver::Options::update_state_every_iteration, in which case the // state would have been updated every iteration // anyways. Solver::Summary::termination_type is set to USER_ABORT. SOLVER_ABORT, @@ -436,7 +445,7 @@ // For SizedCostFunction and AutoDiffCostFunction, DYNAMIC can be // specified for the number of residuals. If specified, then the -// number of residuas for that cost function can vary at runtime. +// number of residuals for that cost function can vary at runtime. enum DimensionType { DYNAMIC = -1, }; @@ -456,12 +465,14 @@ RIDDERS }; +// Type of polynomial used for interpolation during line search. enum LineSearchInterpolationType { BISECTION, QUADRATIC, CUBIC, }; +// Type of algorithm used for computing the covariance matrix. enum CovarianceAlgorithmType { DENSE_SVD, SPARSE_QR,