// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 Google Inc. All rights reserved.
// http://ceres-solver.org/
//
// 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)
//
// The LossFunction interface is the way users describe how residuals
// are converted to cost terms for the overall problem cost function.
// For the exact manner in which loss functions are converted to the
// overall cost for a problem, see problem.h.
//
// For least squares problem where there are no outliers and standard
// squared loss is expected, it is not necessary to create a loss
// function; instead passing a NULL to the problem when adding
// residuals implies a standard squared loss.
//
// For least squares problems where the minimization may encounter
// input terms that contain outliers, that is, completely bogus
// measurements, it is important to use a loss function that reduces
// their associated penalty.
//
// Consider a structure from motion problem. The unknowns are 3D
// points and camera parameters, and the measurements are image
// coordinates describing the expected reprojected position for a
// point in a camera. For example, we want to model the geometry of a
// street scene with fire hydrants and cars, observed by a moving
// camera with unknown parameters, and the only 3D points we care
// about are the pointy tippy-tops of the fire hydrants. Our magic
// 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
// 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
// entire solution getting pulled away from the optimimum to reduce
// the large error that would otherwise be attributed to the wrong
// measurement.
//
// Using a robust loss function, the cost for large residuals is
// 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?
//
// In general, there isn't a principled way to select a robust loss
// function. The authors suggest starting with a non-robust cost, then
// only experimenting with robust loss functions if standard squared
// loss doesn't work.

#ifndef CERES_PUBLIC_LOSS_FUNCTION_H_
#define CERES_PUBLIC_LOSS_FUNCTION_H_

#include <memory>
#include "glog/logging.h"
#include "ceres/internal/macros.h"
#include "ceres/types.h"
#include "ceres/internal/disable_warnings.h"

namespace ceres {

class CERES_EXPORT LossFunction {
 public:
  virtual ~LossFunction() {}

  // For a residual vector with squared 2-norm 'sq_norm', this method
  // is required to fill in the value and derivatives of the loss
  // function (rho in this example):
  //
  //   out[0] = rho(sq_norm),
  //   out[1] = rho'(sq_norm),
  //   out[2] = rho''(sq_norm),
  //
  // Here the convention is that the contribution of a term to the
  // cost function is given by 1/2 rho(s),  where
  //
  //   s = ||residuals||^2.
  //
  // Calling the method with a negative value of 's' is an error and
  // the implementations are not required to handle that case.
  //
  // Most sane choices of rho() satisfy:
  //
  //   rho(0) = 0,
  //   rho'(0) = 1,
  //   rho'(s) < 1 in outlier region,
  //   rho''(s) < 0 in outlier region,
  //
  // so that they mimic the least squares cost for small residuals.
  virtual void Evaluate(double sq_norm, double out[3]) const = 0;
};

// Some common implementations follow below.
//
// Note: in the region of interest (i.e. s < 3) we have:
//   TrivialLoss >= HuberLoss >= SoftLOneLoss >= CauchyLoss


// This corresponds to no robustification.
//
//   rho(s) = s
//
// At s = 0: rho = [0, 1, 0].
//
// It is not normally necessary to use this, as passing NULL for the
// loss function when building the problem accomplishes the same
// thing.
class CERES_EXPORT TrivialLoss : public LossFunction {
 public:
  virtual void Evaluate(double, double*) const;
};

// Scaling
// -------
// Given one robustifier
//   s -> rho(s)
// one can change the length scale at which robustification takes
// place, by adding a scale factor 'a' as follows:
//
//   s -> a^2 rho(s / a^2).
//
// The first and second derivatives are:
//
//   s -> rho'(s / a^2),
//   s -> (1 / a^2) rho''(s / a^2),
//
// but the behaviour near s = 0 is the same as the original function,
// i.e.
//
//   rho(s) = s + higher order terms,
//   a^2 rho(s / a^2) = s + higher order terms.
//
// The scalar 'a' should be positive.
//
// The reason for the appearance of squaring is that 'a' is in the
// units of the residual vector norm whereas 's' is a squared
// norm. For applications it is more convenient to specify 'a' than
// its square. The commonly used robustifiers below are described in
// un-scaled format (a = 1) but their implementations work for any
// non-zero value of 'a'.

// Huber.
//
//   rho(s) = s               for s <= 1,
//   rho(s) = 2 sqrt(s) - 1   for s >= 1.
//
// At s = 0: rho = [0, 1, 0].
//
// The scaling parameter 'a' corresponds to 'delta' on this page:
//   http://en.wikipedia.org/wiki/Huber_Loss_Function
class CERES_EXPORT HuberLoss : public LossFunction {
 public:
  explicit HuberLoss(double a) : a_(a), b_(a * a) { }
  virtual void Evaluate(double, double*) const;

 private:
  const double a_;
  // b = a^2.
  const double b_;
};

// Soft L1, similar to Huber but smooth.
//
//   rho(s) = 2 (sqrt(1 + s) - 1).
//
// At s = 0: rho = [0, 1, -1/2].
class CERES_EXPORT SoftLOneLoss : public LossFunction {
 public:
  explicit SoftLOneLoss(double a) : b_(a * a), c_(1 / b_) { }
  virtual void Evaluate(double, double*) const;

 private:
  // b = a^2.
  const double b_;
  // c = 1 / a^2.
  const double c_;
};

// Inspired by the Cauchy distribution
//
//   rho(s) = log(1 + s).
//
// At s = 0: rho = [0, 1, -1].
class CERES_EXPORT CauchyLoss : public LossFunction {
 public:
  explicit CauchyLoss(double a) : b_(a * a), c_(1 / b_) { }
  virtual void Evaluate(double, double*) const;

 private:
  // b = a^2.
  const double b_;
  // c = 1 / a^2.
  const double c_;
};

// Loss that is capped beyond a certain level using the arc-tangent function.
// The scaling parameter 'a' determines the level where falloff occurs.
// For costs much smaller than 'a', the loss function is linear and behaves like
// TrivialLoss, and for values much larger than 'a' the value asymptotically
// approaches the constant value of a * PI / 2.
//
//   rho(s) = a atan(s / a).
//
// At s = 0: rho = [0, 1, 0].
class CERES_EXPORT ArctanLoss : public LossFunction {
 public:
  explicit ArctanLoss(double a) : a_(a), b_(1 / (a * a)) { }
  virtual void Evaluate(double, double*) const;

 private:
  const double a_;
  // b = 1 / a^2.
  const double b_;
};

// Loss function that maps to approximately zero cost in a range around the
// origin, and reverts to linear in error (quadratic in cost) beyond this range.
// The tolerance parameter 'a' sets the nominal point at which the
// transition occurs, and the transition size parameter 'b' sets the nominal
// distance over which most of the transition occurs. Both a and b must be
// greater than zero, and typically b will be set to a fraction of a.
// The slope rho'[s] varies smoothly from about 0 at s <= a - b to
// about 1 at s >= a + b.
//
// The term is computed as:
//
//   rho(s) = b log(1 + exp((s - a) / b)) - c0.
//
// where c0 is chosen so that rho(0) == 0
//
//   c0 = b log(1 + exp(-a / b)
//
// This has the following useful properties:
//
//   rho(s) == 0               for s = 0
//   rho'(s) ~= 0              for s << a - b
//   rho'(s) ~= 1              for s >> a + b
//   rho''(s) > 0              for all s
//
// In addition, all derivatives are continuous, and the curvature is
// concentrated in the range a - b to a + b.
//
// At s = 0: rho = [0, ~0, ~0].
class CERES_EXPORT TolerantLoss : public LossFunction {
 public:
  explicit TolerantLoss(double a, double b);
  virtual void Evaluate(double, double*) const;

 private:
  const double a_, b_, c_;
};

// This is the Tukey biweight loss function which aggressively
// attempts to suppress large errors.
//
// The term is computed as:
//
//   rho(s) = a^2 / 6 * (1 - (1 - s / a^2)^3 )   for s <= a^2,
//   rho(s) = a^2 / 6                            for s >  a^2.
//
// At s = 0: rho = [0, 0.5, -1 / a^2]
class CERES_EXPORT TukeyLoss : public ceres::LossFunction {
 public:
  explicit TukeyLoss(double a) : a_squared_(a * a) { }
  virtual void Evaluate(double, double*) const;

 private:
  const double a_squared_;
};

// Composition of two loss functions.  The error is the result of first
// evaluating g followed by f to yield the composition f(g(s)).
// The loss functions must not be NULL.
class CERES_EXPORT ComposedLoss : public LossFunction {
 public:
  explicit ComposedLoss(const LossFunction* f, Ownership ownership_f,
                        const LossFunction* g, Ownership ownership_g);
  virtual ~ComposedLoss();
  virtual void Evaluate(double, double*) const;

 private:
  std::unique_ptr<const LossFunction> f_, g_;
  const Ownership ownership_f_, ownership_g_;
};

// The discussion above has to do with length scaling: it affects the space
// in which s is measured. Sometimes you want to simply scale the output
// value of the robustifier. For example, you might want to weight
// different error terms differently (e.g., weight pixel reprojection
// errors differently from terrain errors).
//
// If rho is the wrapped robustifier, then this simply outputs
// s -> a * rho(s)
//
// The first and second derivatives are, not surprisingly
// s -> a * rho'(s)
// s -> a * rho''(s)
//
// Since we treat the a NULL Loss function as the Identity loss
// function, rho = NULL is a valid input and will result in the input
// being scaled by a. This provides a simple way of implementing a
// scaled ResidualBlock.
class CERES_EXPORT ScaledLoss : public LossFunction {
 public:
  // Constructs a ScaledLoss wrapping another loss function. Takes
  // ownership of the wrapped loss function or not depending on the
  // ownership parameter.
  ScaledLoss(const LossFunction* rho, double a, Ownership ownership) :
      rho_(rho), a_(a), ownership_(ownership) { }

  virtual ~ScaledLoss() {
    if (ownership_ == DO_NOT_TAKE_OWNERSHIP) {
      rho_.release();
    }
  }
  virtual void Evaluate(double, double*) const;

 private:
  std::unique_ptr<const LossFunction> rho_;
  const double a_;
  const Ownership ownership_;
  CERES_DISALLOW_COPY_AND_ASSIGN(ScaledLoss);
};

// Sometimes after the optimization problem has been constructed, we
// wish to mutate the scale of the loss function. For example, when
// performing estimation from data which has substantial outliers,
// convergence can be improved by starting out with a large scale,
// optimizing the problem and then reducing the scale. This can have
// better convergence behaviour than just using a loss function with a
// small scale.
//
// This templated class allows the user to implement a loss function
// whose scale can be mutated after an optimization problem has been
// constructed.
//
// Since we treat the a NULL Loss function as the Identity loss
// function, rho = NULL is a valid input.
//
// Example usage
//
//  Problem problem;
//
//  // Add parameter blocks
//
//  CostFunction* cost_function =
//    new AutoDiffCostFunction < UW_Camera_Mapper, 2, 9, 3>(
//      new UW_Camera_Mapper(feature_x, feature_y));
//
//  LossFunctionWrapper* loss_function(new HuberLoss(1.0), TAKE_OWNERSHIP);
//
//  problem.AddResidualBlock(cost_function, loss_function, parameters);
//
//  Solver::Options options;
//  Solger::Summary summary;
//
//  Solve(options, &problem, &summary)
//
//  loss_function->Reset(new HuberLoss(1.0), TAKE_OWNERSHIP);
//
//  Solve(options, &problem, &summary)
//
class CERES_EXPORT LossFunctionWrapper : public LossFunction {
 public:
  LossFunctionWrapper(LossFunction* rho, Ownership ownership)
      : rho_(rho), ownership_(ownership) {
  }

  virtual ~LossFunctionWrapper() {
    if (ownership_ == DO_NOT_TAKE_OWNERSHIP) {
      rho_.release();
    }
  }

  virtual void Evaluate(double sq_norm, double out[3]) const {
    if (rho_.get() == NULL) {
      out[0] = sq_norm;
      out[1] = 1.0;
      out[2] = 0.0;
    }
    else {
      rho_->Evaluate(sq_norm, out);
    }
  }

  void Reset(LossFunction* rho, Ownership ownership) {
    if (ownership_ == DO_NOT_TAKE_OWNERSHIP) {
      rho_.release();
    }
    rho_.reset(rho);
    ownership_ = ownership;
  }

 private:
  std::unique_ptr<const LossFunction> rho_;
  Ownership ownership_;
  CERES_DISALLOW_COPY_AND_ASSIGN(LossFunctionWrapper);
};

}  // namespace ceres

#include "ceres/internal/reenable_warnings.h"

#endif  // CERES_PUBLIC_LOSS_FUNCTION_H_
