// 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)

#include "ceres/loss_function.h"

#include <cstddef>

#include <glog/logging.h>
#include "gtest/gtest.h"

namespace ceres {
namespace internal {
namespace {

// Helper function for testing a LossFunction callback.
//
// Compares the values of rho'(s) and rho''(s) computed by the
// callback with estimates obtained by symmetric finite differencing
// of rho(s).
void AssertLossFunctionIsValid(const LossFunction& loss, double s) {
  CHECK_GT(s, 0);

  // Evaluate rho(s), rho'(s) and rho''(s).
  double rho[3];
  loss.Evaluate(s, rho);

  // Use symmetric finite differencing to estimate rho'(s) and
  // rho''(s).
  const double kH = 1e-4;
  // Values at s + kH.
  double fwd[3];
  // Values at s - kH.
  double bwd[3];
  loss.Evaluate(s + kH, fwd);
  loss.Evaluate(s - kH, bwd);

  // First derivative.
  const double fd_1 = (fwd[0] - bwd[0]) / (2 * kH);
  ASSERT_NEAR(fd_1, rho[1], 1e-6);

  // Second derivative.
  const double fd_2 = (fwd[0] - 2*rho[0] + bwd[0]) / (kH * kH);
  ASSERT_NEAR(fd_2, rho[2], 1e-6);
}
}  // namespace

// Try two values of the scaling a = 0.7 and 1.3
// (where scaling makes sense) and of the squared norm
// s = 0.357 and 1.792
//
// Note that for the Huber loss the test exercises both code paths
//  (i.e. both small and large values of s).

TEST(LossFunction, TrivialLoss) {
  AssertLossFunctionIsValid(TrivialLoss(), 0.357);
  AssertLossFunctionIsValid(TrivialLoss(), 1.792);
}

TEST(LossFunction, HuberLoss) {
  AssertLossFunctionIsValid(HuberLoss(0.7), 0.357);
  AssertLossFunctionIsValid(HuberLoss(0.7), 1.792);
  AssertLossFunctionIsValid(HuberLoss(1.3), 0.357);
  AssertLossFunctionIsValid(HuberLoss(1.3), 1.792);
}

TEST(LossFunction, SoftLOneLoss) {
  AssertLossFunctionIsValid(SoftLOneLoss(0.7), 0.357);
  AssertLossFunctionIsValid(SoftLOneLoss(0.7), 1.792);
  AssertLossFunctionIsValid(SoftLOneLoss(1.3), 0.357);
  AssertLossFunctionIsValid(SoftLOneLoss(1.3), 1.792);
}

TEST(LossFunction, CauchyLoss) {
  AssertLossFunctionIsValid(CauchyLoss(0.7), 0.357);
  AssertLossFunctionIsValid(CauchyLoss(0.7), 1.792);
  AssertLossFunctionIsValid(CauchyLoss(1.3), 0.357);
  AssertLossFunctionIsValid(CauchyLoss(1.3), 1.792);
}

TEST(LossFunction, ScaledLoss) {
  // Wrap a few loss functions, and a few scale factors. This can't combine
  // construction with the call to AssertLossFunctionIsValid() because Apple's
  // GCC is unable to eliminate the copy of ScaledLoss, which is not copyable.
  {
    ScaledLoss scaled_loss(NULL, 6, TAKE_OWNERSHIP);
    AssertLossFunctionIsValid(scaled_loss, 0.323);
  }
  {
    ScaledLoss scaled_loss(new TrivialLoss(), 10, TAKE_OWNERSHIP);
    AssertLossFunctionIsValid(scaled_loss, 0.357);
  }
  {
    ScaledLoss scaled_loss(new HuberLoss(0.7), 0.1, TAKE_OWNERSHIP);
    AssertLossFunctionIsValid(scaled_loss, 1.792);
  }
  {
    ScaledLoss scaled_loss(new SoftLOneLoss(1.3), 0.1, TAKE_OWNERSHIP);
    AssertLossFunctionIsValid(scaled_loss, 1.792);
  }
  {
    ScaledLoss scaled_loss(new CauchyLoss(1.3), 10, TAKE_OWNERSHIP);
    AssertLossFunctionIsValid(scaled_loss, 1.792);
  }
}

TEST(LossFunction, LossFunctionWrapper) {
  // Initialization
  HuberLoss loss_function1(1.0);
  LossFunctionWrapper loss_function_wrapper(new HuberLoss(1.0),
                                            TAKE_OWNERSHIP);

  double s = 0.862;
  double rho_gold[3];
  double rho[3];
  loss_function1.Evaluate(s, rho_gold);
  loss_function_wrapper.Evaluate(s, rho);
  for (int i = 0; i < 3; ++i) {
    EXPECT_NEAR(rho[i], rho_gold[i], 1e-12);
  }

  // Resetting
  HuberLoss loss_function2(0.5);
  loss_function_wrapper.Reset(new HuberLoss(0.5), TAKE_OWNERSHIP);
  loss_function_wrapper.Evaluate(s, rho);
  loss_function2.Evaluate(s, rho_gold);
  for (int i = 0; i < 3; ++i) {
    EXPECT_NEAR(rho[i], rho_gold[i], 1e-12);
  }

  // Not taking ownership.
  HuberLoss loss_function3(0.3);
  loss_function_wrapper.Reset(&loss_function3, DO_NOT_TAKE_OWNERSHIP);
  loss_function_wrapper.Evaluate(s, rho);
  loss_function3.Evaluate(s, rho_gold);
  for (int i = 0; i < 3; ++i) {
    EXPECT_NEAR(rho[i], rho_gold[i], 1e-12);
  }
}

}  // namespace internal
}  // namespace ceres
