// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors may be
//   used to endorse or promote products derived from this software without
//   specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// 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.
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
//         keir@google.com (Keir Mierle)

#ifndef CERES_INTERNAL_EVALUATOR_H_
#define CERES_INTERNAL_EVALUATOR_H_

#include <string>
#include <vector>
#include "ceres/internal/port.h"
#include "ceres/types.h"

namespace ceres {

struct CRSMatrix;

namespace internal {

class Program;
class SparseMatrix;

// The Evaluator interface offers a way to interact with a least squares cost
// function that is useful for an optimizer that wants to minimize the least
// squares objective. This insulates the optimizer from issues like Jacobian
// storage, parameterization, etc.
class Evaluator {
 public:
  virtual ~Evaluator();

  struct Options {
    Options()
        : num_threads(1),
          num_eliminate_blocks(-1),
          linear_solver_type(DENSE_QR) {}

    int num_threads;
    int num_eliminate_blocks;
    LinearSolverType linear_solver_type;
  };

  static Evaluator* Create(const Options& options,
                           Program* program,
                           string* error);


  // This is used for computing the cost, residual and Jacobian for
  // returning to the user. For actually solving the optimization
  // problem, the optimization algorithm uses the ProgramEvaluator
  // objects directly.
  //
  // The residual, gradients and jacobian pointers can be NULL, in
  // which case they will not be evaluated. cost cannot be NULL.
  //
  // The parallelism of the evaluator is controlled by num_threads; it
  // should be at least 1.
  //
  // Note: That this function does not take a parameter vector as
  // input. The parameter blocks are evaluated on the values contained
  // in the arrays pointed to by their user_state pointers.
  //
  // Also worth noting is that this function mutates program by
  // calling Program::SetParameterOffsetsAndIndex() on it so that an
  // evaluator object can be constructed.
  static bool Evaluate(Program* program,
                       int num_threads,
                       double* cost,
                       vector<double>* residuals,
                       vector<double>* gradient,
                       CRSMatrix* jacobian);

  // Build and return a sparse matrix for storing and working with the Jacobian
  // of the objective function. The jacobian has dimensions
  // NumEffectiveParameters() by NumParameters(), and is typically extremely
  // sparse. Since the sparsity pattern of the Jacobian remains constant over
  // the lifetime of the optimization problem, this method is used to
  // instantiate a SparseMatrix object with the appropriate sparsity structure
  // (which can be an expensive operation) and then reused by the optimization
  // algorithm and the various linear solvers.
  //
  // It is expected that the classes implementing this interface will be aware
  // of their client's requirements for the kind of sparse matrix storage and
  // layout that is needed for an efficient implementation. For example
  // CompressedRowOptimizationProblem creates a compressed row representation of
  // the jacobian for use with CHOLMOD, where as BlockOptimizationProblem
  // creates a BlockSparseMatrix representation of the jacobian for use in the
  // Schur complement based methods.
  virtual SparseMatrix* CreateJacobian() const = 0;

  // Evaluate the cost function for the given state. Returns the cost,
  // residuals, and jacobian in the corresponding arguments. Both residuals and
  // jacobian are optional; to avoid computing them, pass NULL.
  //
  // If non-NULL, the Jacobian must have a suitable sparsity pattern; only the
  // values array of the jacobian is modified.
  //
  // state is an array of size NumParameters(), cost is a pointer to a single
  // double, and residuals is an array of doubles of size NumResiduals().
  virtual bool Evaluate(const double* state,
                        double* cost,
                        double* residuals,
                        double* gradient,
                        SparseMatrix* jacobian) = 0;

  // Make a change delta (of size NumEffectiveParameters()) to state (of size
  // NumParameters()) and store the result in state_plus_delta.
  //
  // In the case that there are no parameterizations used, this is equivalent to
  //
  //   state_plus_delta[i] = state[i] + delta[i] ;
  //
  // however, the mapping is more complicated in the case of parameterizations
  // like quaternions. This is the same as the "Plus()" operation in
  // local_parameterization.h, but operating over the entire state vector for a
  // problem.
  virtual bool Plus(const double* state,
                    const double* delta,
                    double* state_plus_delta) const = 0;

  // The number of parameters in the optimization problem.
  virtual int NumParameters() const = 0;

  // This is the effective number of parameters that the optimizer may adjust.
  // This applies when there are parameterizations on some of the parameters.
  virtual int NumEffectiveParameters()  const = 0;

  // The number of residuals in the optimization problem.
  virtual int NumResiduals() const = 0;
};

}  // namespace internal
}  // namespace ceres

#endif  // CERES_INTERNAL_EVALUATOR_H_
