// 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)
//
// Purpose: See .h file.

#include "ceres/loss_function.h"

#include <cmath>
#include <cstddef>

namespace ceres {

void TrivialLoss::Evaluate(double s, double rho[3]) const {
  rho[0] = s;
  rho[1] = 1;
  rho[2] = 0;
}

void HuberLoss::Evaluate(double s, double rho[3]) const {
  if (s > b_) {
    // Outlier region.
    // 'r' is always positive.
    const double r = sqrt(s);
    rho[0] = 2 * a_ * r - b_;
    rho[1] = a_ / r;
    rho[2] = - rho[1] / (2 * s);
  } else {
    // Inlier region.
    rho[0] = s;
    rho[1] = 1;
    rho[2] = 0;
  }
}

void SoftLOneLoss::Evaluate(double s, double rho[3]) const {
  const double sum = 1 + s * c_;
  const double tmp = sqrt(sum);
  // 'sum' and 'tmp' are always positive, assuming that 's' is.
  rho[0] = 2 * b_ * (tmp - 1);
  rho[1] = 1 / tmp;
  rho[2] = - (c_ * rho[1]) / (2 * sum);
}

void CauchyLoss::Evaluate(double s, double rho[3]) const {
  const double sum = 1 + s * c_;
  const double inv = 1 / sum;
  // 'sum' and 'inv' are always positive, assuming that 's' is.
  rho[0] = b_ * log(sum);
  rho[1] = inv;
  rho[2] = - c_ * (inv * inv);
}

void ArctanLoss::Evaluate(double s, double rho[3]) const {
  const double sum = 1 + s * s * b_;
  const double inv = 1 / sum;
  // 'sum' and 'inv' are always positive.
  rho[0] = a_ * atan2(s, a_);
  rho[1] = inv;
  rho[2] = -2 * s * b_ * (inv * inv);
}

TolerantLoss::TolerantLoss(double a, double b)
    : a_(a),
      b_(b),
      c_(b * log(1.0 + exp(-a / b))) {
  CHECK_GE(a, 0.0);
  CHECK_GT(b, 0.0);
}

void TolerantLoss::Evaluate(double s, double rho[3]) const {
  const double x = (s - a_) / b_;
  // The basic equation is rho[0] = b ln(1 + e^x).  However, if e^x is too
  // large, it will overflow.  Since numerically 1 + e^x == e^x when the
  // x is greater than about ln(2^53) for doubles, beyond this threshold
  // we substitute x for ln(1 + e^x) as a numerically equivalent approximation.
  static const double kLog2Pow53 = 36.7;  // ln(MathLimits<double>::kEpsilon).
  if (x > kLog2Pow53) {
    rho[0] = s - a_ - c_;
    rho[1] = 1.0;
    rho[2] = 0.0;
  } else {
    const double e_x = exp(x);
    rho[0] = b_ * log(1.0 + e_x) - c_;
    rho[1] = e_x / (1.0 + e_x);
    rho[2] = 0.5 / (b_ * (1.0 + cosh(x)));
  }
}

ComposedLoss::ComposedLoss(const LossFunction* f, Ownership ownership_f,
                           const LossFunction* g, Ownership ownership_g)
    : f_(CHECK_NOTNULL(f)),
      g_(CHECK_NOTNULL(g)),
      ownership_f_(ownership_f),
      ownership_g_(ownership_g) {
}

ComposedLoss::~ComposedLoss() {
  if (ownership_f_ == DO_NOT_TAKE_OWNERSHIP) {
    f_.release();
  }
  if (ownership_g_ == DO_NOT_TAKE_OWNERSHIP) {
    g_.release();
  }
}

void ComposedLoss::Evaluate(double s, double rho[3]) const {
  double rho_f[3], rho_g[3];
  g_->Evaluate(s, rho_g);
  f_->Evaluate(rho_g[0], rho_f);
  rho[0] = rho_f[0];
  // f'(g(s)) * g'(s).
  rho[1] = rho_f[1] * rho_g[1];
  // f''(g(s)) * g'(s) * g'(s) + f'(g(s)) * g''(s).
  rho[2] = rho_f[2] * rho_g[1] * rho_g[1] + rho_f[1] * rho_g[2];
}

void ScaledLoss::Evaluate(double s, double rho[3]) const {
  if (rho_.get() == NULL) {
    rho[0] = a_ * s;
    rho[1] = a_;
    rho[2] = 0.0;
  } else {
    rho_->Evaluate(s, rho);
    rho[0] *= a_;
    rho[1] *= a_;
    rho[2] *= a_;
  }
}

}  // namespace ceres
