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

#include <glog/logging.h>
#include "gtest/gtest.h"
#include "ceres/block_sparse_matrix.h"
#include "ceres/block_structure.h"
#include "ceres/casts.h"
#include "ceres/linear_least_squares_problems.h"
#include "ceres/linear_solver.h"
#include "ceres/schur_complement_solver.h"
#include "ceres/triplet_sparse_matrix.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/types.h"

namespace ceres {
namespace internal {

class SchurComplementSolverTest : public ::testing::Test {
 protected:
  void SetUpFromProblemId(int problem_id) {
    scoped_ptr<LinearLeastSquaresProblem> problem(
        CreateLinearLeastSquaresProblemFromId(problem_id));

    CHECK_NOTNULL(problem.get());
    A.reset(down_cast<BlockSparseMatrix*>(problem->A.release()));
    b.reset(problem->b.release());
    D.reset(problem->D.release());

    num_cols = A->num_cols();
    num_rows = A->num_rows();
    num_eliminate_blocks = problem->num_eliminate_blocks;

    x.reset(new double[num_cols]);
    sol.reset(new double[num_cols]);
    sol_d.reset(new double[num_cols]);

    LinearSolver::Options options;
    options.type = DENSE_QR;

    scoped_ptr<LinearSolver> qr(LinearSolver::Create(options));

    TripletSparseMatrix triplet_A(A->num_rows(),
                                  A->num_cols(),
                                  A->num_nonzeros());
    A->ToTripletSparseMatrix(&triplet_A);

    // Gold standard solutions using dense QR factorization.
    DenseSparseMatrix dense_A(triplet_A);
    LinearSolver::Summary summary1 =
        qr->Solve(&dense_A,
                  b.get(),
                  LinearSolver::PerSolveOptions(),
                  sol.get());

    // Gold standard solution with appended diagonal.
    LinearSolver::PerSolveOptions per_solve_options;
    per_solve_options.D = D.get();
    LinearSolver::Summary summary2 =
        qr->Solve(&dense_A,
                  b.get(),
                  per_solve_options,
                  sol_d.get());
  }

  void ComputeAndCompareSolutions(int problem_id,
                                  bool regularization,
                                  ceres::LinearSolverType linear_solver_type) {
    SetUpFromProblemId(problem_id);
    LinearSolver::Options options;
    options.num_eliminate_blocks = num_eliminate_blocks;
    options.type = linear_solver_type;
    scoped_ptr<LinearSolver> solver(LinearSolver::Create(options));

    LinearSolver::PerSolveOptions per_solve_options;
    LinearSolver::Summary summary;
    if (regularization) {
      per_solve_options.D = D.get();
    }

    summary = solver->Solve(A.get(), b.get(), per_solve_options, x.get());

    if (regularization) {
      for (int i = 0; i < num_cols; ++i) {
        ASSERT_NEAR(sol_d.get()[i], x[i], 1e-10);
      }
    } else {
      for (int i = 0; i < num_cols; ++i) {
        ASSERT_NEAR(sol.get()[i], x[i], 1e-10);
      }
    }
  }

  int num_rows;
  int num_cols;
  int num_eliminate_blocks;

  scoped_ptr<BlockSparseMatrix> A;
  scoped_array<double> b;
  scoped_array<double> x;
  scoped_array<double> D;
  scoped_array<double> sol;
  scoped_array<double> sol_d;
};

#ifndef CERES_NO_SUITESPARSE

TEST_F(SchurComplementSolverTest, SparseSchur) {
  ComputeAndCompareSolutions(2, false, SPARSE_SCHUR);
  ComputeAndCompareSolutions(3, false, SPARSE_SCHUR);
  ComputeAndCompareSolutions(2, true, SPARSE_SCHUR);
  ComputeAndCompareSolutions(3, true, SPARSE_SCHUR);
}

#endif  // CERES_NO_SUITESPARSE

TEST_F(SchurComplementSolverTest, DenseSchur) {
  ComputeAndCompareSolutions(2, false, DENSE_SCHUR);
  ComputeAndCompareSolutions(3, false, DENSE_SCHUR);
  ComputeAndCompareSolutions(2, true, DENSE_SCHUR);
  ComputeAndCompareSolutions(3, true, DENSE_SCHUR);
}

}  // namespace internal
}  // namespace ceres
