// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2022 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)

#include "ceres/levenberg_marquardt_strategy.h"

#include <memory>

#include "ceres/internal/eigen.h"
#include "ceres/linear_solver.h"
#include "ceres/trust_region_strategy.h"
#include "glog/logging.h"
#include "gmock/gmock.h"
#include "gmock/mock-log.h"
#include "gtest/gtest.h"

using testing::_;
using testing::AllOf;
using testing::AnyNumber;
using testing::HasSubstr;
using testing::ScopedMockLog;

namespace ceres {
namespace internal {

const double kTolerance = 1e-16;

// Linear solver that takes as input a vector and checks that the
// caller passes the same vector as LinearSolver::PerSolveOptions.D.
class RegularizationCheckingLinearSolver : public DenseSparseMatrixSolver {
 public:
  RegularizationCheckingLinearSolver(const int num_cols, const double* diagonal)
      : num_cols_(num_cols), diagonal_(diagonal) {}


 private:
  LinearSolver::Summary SolveImpl(
      DenseSparseMatrix* A,
      const double* b,
      const LinearSolver::PerSolveOptions& per_solve_options,
      double* x) final {
    CHECK(per_solve_options.D != nullptr);
    for (int i = 0; i < num_cols_; ++i) {
      EXPECT_NEAR(per_solve_options.D[i], diagonal_[i], kTolerance)
          << i << " " << per_solve_options.D[i] << " " << diagonal_[i];
    }
    return {};
  }

  const int num_cols_;
  const double* diagonal_;
};

TEST(LevenbergMarquardtStrategy, AcceptRejectStepRadiusScaling) {
  TrustRegionStrategy::Options options;
  options.initial_radius = 2.0;
  options.max_radius = 20.0;
  options.min_lm_diagonal = 1e-8;
  options.max_lm_diagonal = 1e8;

  // We need a non-null pointer here, so anything should do.
  std::unique_ptr<LinearSolver> linear_solver(
      new RegularizationCheckingLinearSolver(0, nullptr));
  options.linear_solver = linear_solver.get();

  LevenbergMarquardtStrategy lms(options);
  EXPECT_EQ(lms.Radius(), options.initial_radius);
  lms.StepRejected(0.0);
  EXPECT_EQ(lms.Radius(), 1.0);
  lms.StepRejected(-1.0);
  EXPECT_EQ(lms.Radius(), 0.25);
  lms.StepAccepted(1.0);
  EXPECT_EQ(lms.Radius(), 0.25 * 3.0);
  lms.StepAccepted(1.0);
  EXPECT_EQ(lms.Radius(), 0.25 * 3.0 * 3.0);
  lms.StepAccepted(0.25);
  EXPECT_EQ(lms.Radius(), 0.25 * 3.0 * 3.0 / 1.125);
  lms.StepAccepted(1.0);
  EXPECT_EQ(lms.Radius(), 0.25 * 3.0 * 3.0 / 1.125 * 3.0);
  lms.StepAccepted(1.0);
  EXPECT_EQ(lms.Radius(), 0.25 * 3.0 * 3.0 / 1.125 * 3.0 * 3.0);
  lms.StepAccepted(1.0);
  EXPECT_EQ(lms.Radius(), options.max_radius);
}

TEST(LevenbergMarquardtStrategy, CorrectDiagonalToLinearSolver) {
  Matrix jacobian(2, 3);
  jacobian.setZero();
  jacobian(0, 0) = 0.0;
  jacobian(0, 1) = 1.0;
  jacobian(1, 1) = 1.0;
  jacobian(0, 2) = 100.0;

  double residual = 1.0;
  double x[3];
  DenseSparseMatrix dsm(jacobian);

  TrustRegionStrategy::Options options;
  options.initial_radius = 2.0;
  options.max_radius = 20.0;
  options.min_lm_diagonal = 1e-2;
  options.max_lm_diagonal = 1e2;

  double diagonal[3];
  diagonal[0] = options.min_lm_diagonal;
  diagonal[1] = 2.0;
  diagonal[2] = options.max_lm_diagonal;
  for (double& diagonal_entry : diagonal) {
    diagonal_entry = sqrt(diagonal_entry / options.initial_radius);
  }

  RegularizationCheckingLinearSolver linear_solver(3, diagonal);
  options.linear_solver = &linear_solver;

  LevenbergMarquardtStrategy lms(options);
  TrustRegionStrategy::PerSolveOptions pso;

  {
    ScopedMockLog log;
    EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
    // This using directive is needed get around the fact that there
    // are versions of glog which are not in the google namespace.
    using namespace google;

#if defined(GLOG_NO_ABBREVIATED_SEVERITIES)
    // Use GLOG_WARNING to support MSVC if GLOG_NO_ABBREVIATED_SEVERITIES
    // is defined.
    EXPECT_CALL(log,
                Log(GLOG_WARNING, _, HasSubstr("Failed to compute a step")));
#else
    EXPECT_CALL(log,
                Log(google::WARNING, _, HasSubstr("Failed to compute a step")));
#endif

    TrustRegionStrategy::Summary summary =
        lms.ComputeStep(pso, &dsm, &residual, x);
    EXPECT_EQ(summary.termination_type, LINEAR_SOLVER_FAILURE);
  }
}

}  // namespace internal
}  // namespace ceres
