// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2023 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 "gtest/gtest.h"

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

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);
}

// TODO(sameeragarwal): Re-enable this once we move to absl, as absl provides
// absl/log/scoped_mock_log.h
/*
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, LinearSolverTerminationType::FAILURE);
  }
}
*/

}  // namespace internal
}  // namespace ceres
