// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 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: moll.markus@arcor.de (Markus Moll)

#include <limits>
#include "ceres/internal/eigen.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/dense_qr_solver.h"
#include "ceres/dogleg_strategy.h"
#include "ceres/linear_solver.h"
#include "ceres/trust_region_strategy.h"
#include "glog/logging.h"
#include "gtest/gtest.h"

namespace ceres {
namespace internal {
namespace {

class Fixture : public testing::Test {
 protected:
  scoped_ptr<DenseSparseMatrix> jacobian_;
  Vector residual_;
  Vector x_;
  TrustRegionStrategy::Options options_;
};

// A test problem where
//
//   J^T J = Q diag([1 2 4 8 16 32]) Q^T
//
// where Q is a randomly chosen orthonormal basis of R^6.
// The residual is chosen so that the minimum of the quadratic function is
// at (1, 1, 1, 1, 1, 1). It is therefore at a distance of sqrt(6) ~ 2.45
// from the origin.
class DoglegStrategyFixtureEllipse : public Fixture {
 protected:
  virtual void SetUp() {
    Matrix basis(6, 6);
    // The following lines exceed 80 characters for better readability.
    basis << -0.1046920933796121, -0.7449367449921986, -0.4190744502875876, -0.4480450716142566,  0.2375351607929440, -0.0363053418882862,
              0.4064975684355914,  0.2681113508511354, -0.7463625494601520, -0.0803264850508117, -0.4463149623021321,  0.0130224954867195,
             -0.5514387729089798,  0.1026621026168657, -0.5008316122125011,  0.5738122212666414,  0.2974664724007106,  0.1296020877535158,
              0.5037835370947156,  0.2668479925183712, -0.1051754618492798, -0.0272739396578799,  0.7947481647088278, -0.1776623363955670,
             -0.4005458426625444,  0.2939330589634109, -0.0682629380550051, -0.2895448882503687, -0.0457239396341685, -0.8139899477847840,
             -0.3247764582762654,  0.4528151365941945, -0.0276683863102816, -0.6155994592510784,  0.1489240599972848,  0.5362574892189350;

    Vector Ddiag(6);
    Ddiag << 1.0, 2.0, 4.0, 8.0, 16.0, 32.0;

    Matrix sqrtD = Ddiag.array().sqrt().matrix().asDiagonal();
    Matrix jacobian = sqrtD * basis;
    jacobian_.reset(new DenseSparseMatrix(jacobian));

    Vector minimum(6);
    minimum << 1.0, 1.0, 1.0, 1.0, 1.0, 1.0;
    residual_ = -jacobian * minimum;

    x_.resize(6);
    x_.setZero();

    options_.lm_min_diagonal = 1.0;
    options_.lm_max_diagonal = 1.0;
  }
};

// A test problem where
//
//   J^T J = diag([1 2 4 8 16 32]) .
//
// The residual is chosen so that the minimum of the quadratic function is
// at (0, 0, 1, 0, 0, 0). It is therefore at a distance of 1 from the origin.
// The gradient at the origin points towards the global minimum.
class DoglegStrategyFixtureValley : public Fixture {
 protected:
  virtual void SetUp() {
    Vector Ddiag(6);
    Ddiag << 1.0, 2.0, 4.0, 8.0, 16.0, 32.0;

    Matrix jacobian = Ddiag.asDiagonal();
    jacobian_.reset(new DenseSparseMatrix(jacobian));

    Vector minimum(6);
    minimum << 0.0, 0.0, 1.0, 0.0, 0.0, 0.0;
    residual_ = -jacobian * minimum;

    x_.resize(6);
    x_.setZero();

    options_.lm_min_diagonal = 1.0;
    options_.lm_max_diagonal = 1.0;
  }
};

const double kTolerance = 1e-14;
const double kToleranceLoose = 1e-5;
const double kEpsilon = std::numeric_limits<double>::epsilon();

}  // namespace

// The DoglegStrategy must never return a step that is longer than the current
// trust region radius.
TEST_F(DoglegStrategyFixtureEllipse, TrustRegionObeyedTraditional) {
  scoped_ptr<LinearSolver> linear_solver(
      new DenseQRSolver(LinearSolver::Options()));
  options_.linear_solver = linear_solver.get();
  // The global minimum is at (1, 1, ..., 1), so the distance to it is sqrt(6.0).
  // By restricting the trust region to a radius of 2.0, we test if the trust
  // region is actually obeyed.
  options_.dogleg_type = TRADITIONAL_DOGLEG;
  options_.initial_radius = 2.0;
  options_.max_radius = 2.0;

  DoglegStrategy strategy(options_);
  TrustRegionStrategy::PerSolveOptions pso;

  TrustRegionStrategy::Summary summary = strategy.ComputeStep(pso,
                                                              jacobian_.get(),
                                                              residual_.data(),
                                                              x_.data());

  EXPECT_NE(summary.termination_type, FAILURE);
  EXPECT_LE(x_.norm(), options_.initial_radius * (1.0 + 4.0 * kEpsilon));
}

TEST_F(DoglegStrategyFixtureEllipse, TrustRegionObeyedSubspace) {
  scoped_ptr<LinearSolver> linear_solver(
      new DenseQRSolver(LinearSolver::Options()));
  options_.linear_solver = linear_solver.get();
  options_.dogleg_type = SUBSPACE_DOGLEG;
  options_.initial_radius = 2.0;
  options_.max_radius = 2.0;

  DoglegStrategy strategy(options_);
  TrustRegionStrategy::PerSolveOptions pso;

  TrustRegionStrategy::Summary summary = strategy.ComputeStep(pso,
                                                              jacobian_.get(),
                                                              residual_.data(),
                                                              x_.data());

  EXPECT_NE(summary.termination_type, FAILURE);
  EXPECT_LE(x_.norm(), options_.initial_radius * (1.0 + 4.0 * kEpsilon));
}

TEST_F(DoglegStrategyFixtureEllipse, CorrectGaussNewtonStep) {
  scoped_ptr<LinearSolver> linear_solver(
      new DenseQRSolver(LinearSolver::Options()));
  options_.linear_solver = linear_solver.get();
  options_.dogleg_type = SUBSPACE_DOGLEG;
  options_.initial_radius = 10.0;
  options_.max_radius = 10.0;

  DoglegStrategy strategy(options_);
  TrustRegionStrategy::PerSolveOptions pso;

  TrustRegionStrategy::Summary summary = strategy.ComputeStep(pso,
                                                              jacobian_.get(),
                                                              residual_.data(),
                                                              x_.data());

  EXPECT_NE(summary.termination_type, FAILURE);
  EXPECT_NEAR(x_(0), 1.0, kToleranceLoose);
  EXPECT_NEAR(x_(1), 1.0, kToleranceLoose);
  EXPECT_NEAR(x_(2), 1.0, kToleranceLoose);
  EXPECT_NEAR(x_(3), 1.0, kToleranceLoose);
  EXPECT_NEAR(x_(4), 1.0, kToleranceLoose);
  EXPECT_NEAR(x_(5), 1.0, kToleranceLoose);
}

// Test if the subspace basis is a valid orthonormal basis of the space spanned
// by the gradient and the Gauss-Newton point.
TEST_F(DoglegStrategyFixtureEllipse, ValidSubspaceBasis) {
  scoped_ptr<LinearSolver> linear_solver(
      new DenseQRSolver(LinearSolver::Options()));
  options_.linear_solver = linear_solver.get();
  options_.dogleg_type = SUBSPACE_DOGLEG;
  options_.initial_radius = 2.0;
  options_.max_radius = 2.0;

  DoglegStrategy strategy(options_);
  TrustRegionStrategy::PerSolveOptions pso;

  TrustRegionStrategy::Summary summary = strategy.ComputeStep(pso,
                                                              jacobian_.get(),
                                                              residual_.data(),
                                                              x_.data());

  // Check if the basis is orthonormal.
  const Matrix basis = strategy.subspace_basis();
  EXPECT_NEAR(basis.col(0).norm(), 1.0, kTolerance);
  EXPECT_NEAR(basis.col(1).norm(), 1.0, kTolerance);
  EXPECT_NEAR(basis.col(0).dot(basis.col(1)), 0.0, kTolerance);

  // Check if the gradient projects onto itself.
  const Vector gradient = strategy.gradient();
  EXPECT_NEAR((gradient - basis*(basis.transpose()*gradient)).norm(),
              0.0,
              kTolerance);

  // Check if the Gauss-Newton point projects onto itself.
  const Vector gn = strategy.gauss_newton_step();
  EXPECT_NEAR((gn - basis*(basis.transpose()*gn)).norm(),
              0.0,
              kTolerance);
}

// Test if the step is correct if the gradient and the Gauss-Newton step point
// in the same direction and the Gauss-Newton step is outside the trust region,
// i.e. the trust region is active.
TEST_F(DoglegStrategyFixtureValley, CorrectStepLocalOptimumAlongGradient) {
  scoped_ptr<LinearSolver> linear_solver(
      new DenseQRSolver(LinearSolver::Options()));
  options_.linear_solver = linear_solver.get();
  options_.dogleg_type = SUBSPACE_DOGLEG;
  options_.initial_radius = 0.25;
  options_.max_radius = 0.25;

  DoglegStrategy strategy(options_);
  TrustRegionStrategy::PerSolveOptions pso;

  TrustRegionStrategy::Summary summary = strategy.ComputeStep(pso,
                                                              jacobian_.get(),
                                                              residual_.data(),
                                                              x_.data());

  EXPECT_NE(summary.termination_type, FAILURE);
  EXPECT_NEAR(x_(0), 0.0, kToleranceLoose);
  EXPECT_NEAR(x_(1), 0.0, kToleranceLoose);
  EXPECT_NEAR(x_(2), options_.initial_radius, kToleranceLoose);
  EXPECT_NEAR(x_(3), 0.0, kToleranceLoose);
  EXPECT_NEAR(x_(4), 0.0, kToleranceLoose);
  EXPECT_NEAR(x_(5), 0.0, kToleranceLoose);
}

// Test if the step is correct if the gradient and the Gauss-Newton step point
// in the same direction and the Gauss-Newton step is inside the trust region,
// i.e. the trust region is inactive.
TEST_F(DoglegStrategyFixtureValley, CorrectStepGlobalOptimumAlongGradient) {
  scoped_ptr<LinearSolver> linear_solver(
      new DenseQRSolver(LinearSolver::Options()));
  options_.linear_solver = linear_solver.get();
  options_.dogleg_type = SUBSPACE_DOGLEG;
  options_.initial_radius = 2.0;
  options_.max_radius = 2.0;

  DoglegStrategy strategy(options_);
  TrustRegionStrategy::PerSolveOptions pso;

  TrustRegionStrategy::Summary summary = strategy.ComputeStep(pso,
                                                              jacobian_.get(),
                                                              residual_.data(),
                                                              x_.data());

  EXPECT_NE(summary.termination_type, FAILURE);
  EXPECT_NEAR(x_(0), 0.0, kToleranceLoose);
  EXPECT_NEAR(x_(1), 0.0, kToleranceLoose);
  EXPECT_NEAR(x_(2), 1.0, kToleranceLoose);
  EXPECT_NEAR(x_(3), 0.0, kToleranceLoose);
  EXPECT_NEAR(x_(4), 0.0, kToleranceLoose);
  EXPECT_NEAR(x_(5), 0.0, kToleranceLoose);
}

}  // namespace internal
}  // namespace ceres

