// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2015 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: strandmark@google.com (Petter Strandmark)

// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/config.h"

#ifndef CERES_NO_CXSPARSE

#include <memory>
#include <string>
#include <vector>

#include "ceres/compressed_col_sparse_matrix_utils.h"
#include "ceres/compressed_row_sparse_matrix.h"
#include "ceres/cxsparse.h"
#include "ceres/triplet_sparse_matrix.h"
#include "glog/logging.h"

namespace ceres {
namespace internal {

using std::vector;

CXSparse::CXSparse() : scratch_(nullptr), scratch_size_(0) {}

CXSparse::~CXSparse() {
  if (scratch_size_ > 0) {
    cs_di_free(scratch_);
  }
}

csn* CXSparse::Cholesky(cs_di* A, cs_dis* symbolic_factor) {
  return cs_di_chol(A, symbolic_factor);
}

void CXSparse::Solve(cs_dis* symbolic_factor, csn* numeric_factor, double* b) {
  // Make sure we have enough scratch space available.
  const int num_cols = numeric_factor->L->n;
  if (scratch_size_ < num_cols) {
    if (scratch_size_ > 0) {
      cs_di_free(scratch_);
    }
    scratch_ =
        reinterpret_cast<CS_ENTRY*>(cs_di_malloc(num_cols, sizeof(CS_ENTRY)));
    scratch_size_ = num_cols;
  }

  // When the Cholesky factor succeeded, these methods are
  // guaranteed to succeeded as well. In the comments below, "x"
  // refers to the scratch space.
  //
  // Set x = P * b.
  CHECK(cs_di_ipvec(symbolic_factor->pinv, b, scratch_, num_cols));
  // Set x = L \ x.
  CHECK(cs_di_lsolve(numeric_factor->L, scratch_));
  // Set x = L' \ x.
  CHECK(cs_di_ltsolve(numeric_factor->L, scratch_));
  // Set b = P' * x.
  CHECK(cs_di_pvec(symbolic_factor->pinv, scratch_, b, num_cols));
}

bool CXSparse::SolveCholesky(cs_di* lhs, double* rhs_and_solution) {
  return cs_cholsol(1, lhs, rhs_and_solution);
}

cs_dis* CXSparse::AnalyzeCholesky(cs_di* A) {
  // order = 1 for Cholesky factor.
  return cs_schol(1, A);
}

cs_dis* CXSparse::AnalyzeCholeskyWithNaturalOrdering(cs_di* A) {
  // order = 0 for Natural ordering.
  return cs_schol(0, A);
}

cs_dis* CXSparse::BlockAnalyzeCholesky(cs_di* A,
                                       const vector<int>& row_blocks,
                                       const vector<int>& col_blocks) {
  const int num_row_blocks = row_blocks.size();
  const int num_col_blocks = col_blocks.size();

  vector<int> block_rows;
  vector<int> block_cols;
  CompressedColumnScalarMatrixToBlockMatrix(
      A->i, A->p, row_blocks, col_blocks, &block_rows, &block_cols);
  cs_di block_matrix;
  block_matrix.m = num_row_blocks;
  block_matrix.n = num_col_blocks;
  block_matrix.nz = -1;
  block_matrix.nzmax = block_rows.size();
  block_matrix.p = &block_cols[0];
  block_matrix.i = &block_rows[0];
  block_matrix.x = nullptr;

  int* ordering = cs_amd(1, &block_matrix);
  vector<int> block_ordering(num_row_blocks, -1);
  std::copy(ordering, ordering + num_row_blocks, &block_ordering[0]);
  cs_free(ordering);

  vector<int> scalar_ordering;
  BlockOrderingToScalarOrdering(row_blocks, block_ordering, &scalar_ordering);

  cs_dis* symbolic_factor =
      reinterpret_cast<cs_dis*>(cs_calloc(1, sizeof(cs_dis)));
  symbolic_factor->pinv = cs_pinv(&scalar_ordering[0], A->n);
  cs* permuted_A = cs_symperm(A, symbolic_factor->pinv, 0);

  symbolic_factor->parent = cs_etree(permuted_A, 0);
  int* postordering = cs_post(symbolic_factor->parent, A->n);
  int* column_counts =
      cs_counts(permuted_A, symbolic_factor->parent, postordering, 0);
  cs_free(postordering);
  cs_spfree(permuted_A);

  symbolic_factor->cp = (int*)cs_malloc(A->n + 1, sizeof(int));
  symbolic_factor->lnz = cs_cumsum(symbolic_factor->cp, column_counts, A->n);
  symbolic_factor->unz = symbolic_factor->lnz;

  cs_free(column_counts);

  if (symbolic_factor->lnz < 0) {
    cs_sfree(symbolic_factor);
    symbolic_factor = nullptr;
  }

  return symbolic_factor;
}

cs_di CXSparse::CreateSparseMatrixTransposeView(CompressedRowSparseMatrix* A) {
  cs_di At;
  At.m = A->num_cols();
  At.n = A->num_rows();
  At.nz = -1;
  At.nzmax = A->num_nonzeros();
  At.p = A->mutable_rows();
  At.i = A->mutable_cols();
  At.x = A->mutable_values();
  return At;
}

cs_di* CXSparse::CreateSparseMatrix(TripletSparseMatrix* tsm) {
  cs_di_sparse tsm_wrapper;
  tsm_wrapper.nzmax = tsm->num_nonzeros();
  tsm_wrapper.nz = tsm->num_nonzeros();
  tsm_wrapper.m = tsm->num_rows();
  tsm_wrapper.n = tsm->num_cols();
  tsm_wrapper.p = tsm->mutable_cols();
  tsm_wrapper.i = tsm->mutable_rows();
  tsm_wrapper.x = tsm->mutable_values();

  return cs_compress(&tsm_wrapper);
}

void CXSparse::ApproximateMinimumDegreeOrdering(cs_di* A, int* ordering) {
  int* cs_ordering = cs_amd(1, A);
  std::copy(cs_ordering, cs_ordering + A->m, ordering);
  cs_free(cs_ordering);
}

cs_di* CXSparse::TransposeMatrix(cs_di* A) { return cs_di_transpose(A, 1); }

cs_di* CXSparse::MatrixMatrixMultiply(cs_di* A, cs_di* B) {
  return cs_di_multiply(A, B);
}

void CXSparse::Free(cs_di* sparse_matrix) { cs_di_spfree(sparse_matrix); }

void CXSparse::Free(cs_dis* symbolic_factor) { cs_di_sfree(symbolic_factor); }

void CXSparse::Free(csn* numeric_factor) { cs_di_nfree(numeric_factor); }

std::unique_ptr<SparseCholesky> CXSparseCholesky::Create(
    const OrderingType ordering_type) {
  return std::unique_ptr<SparseCholesky>(new CXSparseCholesky(ordering_type));
}

CompressedRowSparseMatrix::StorageType CXSparseCholesky::StorageType() const {
  return CompressedRowSparseMatrix::LOWER_TRIANGULAR;
}

CXSparseCholesky::CXSparseCholesky(const OrderingType ordering_type)
    : ordering_type_(ordering_type),
      symbolic_factor_(nullptr),
      numeric_factor_(nullptr) {}

CXSparseCholesky::~CXSparseCholesky() {
  FreeSymbolicFactorization();
  FreeNumericFactorization();
}

LinearSolverTerminationType CXSparseCholesky::Factorize(
    CompressedRowSparseMatrix* lhs, std::string* message) {
  CHECK_EQ(lhs->storage_type(), StorageType());
  if (lhs == nullptr) {
    *message = "Failure: Input lhs is nullptr.";
    return LINEAR_SOLVER_FATAL_ERROR;
  }

  cs_di cs_lhs = cs_.CreateSparseMatrixTransposeView(lhs);

  if (symbolic_factor_ == nullptr) {
    if (ordering_type_ == NATURAL) {
      symbolic_factor_ = cs_.AnalyzeCholeskyWithNaturalOrdering(&cs_lhs);
    } else {
      if (!lhs->col_blocks().empty() && !(lhs->row_blocks().empty())) {
        symbolic_factor_ = cs_.BlockAnalyzeCholesky(
            &cs_lhs, lhs->col_blocks(), lhs->row_blocks());
      } else {
        symbolic_factor_ = cs_.AnalyzeCholesky(&cs_lhs);
      }
    }

    if (symbolic_factor_ == nullptr) {
      *message = "CXSparse Failure : Symbolic factorization failed.";
      return LINEAR_SOLVER_FATAL_ERROR;
    }
  }

  FreeNumericFactorization();
  numeric_factor_ = cs_.Cholesky(&cs_lhs, symbolic_factor_);
  if (numeric_factor_ == nullptr) {
    *message = "CXSparse Failure : Numeric factorization failed.";
    return LINEAR_SOLVER_FAILURE;
  }

  return LINEAR_SOLVER_SUCCESS;
}

LinearSolverTerminationType CXSparseCholesky::Solve(const double* rhs,
                                                    double* solution,
                                                    std::string* message) {
  CHECK(numeric_factor_ != nullptr)
      << "Solve called without a call to Factorize first.";
  const int num_cols = numeric_factor_->L->n;
  memcpy(solution, rhs, num_cols * sizeof(*solution));
  cs_.Solve(symbolic_factor_, numeric_factor_, solution);
  return LINEAR_SOLVER_SUCCESS;
}

void CXSparseCholesky::FreeSymbolicFactorization() {
  if (symbolic_factor_ != nullptr) {
    cs_.Free(symbolic_factor_);
    symbolic_factor_ = nullptr;
  }
}

void CXSparseCholesky::FreeNumericFactorization() {
  if (numeric_factor_ != nullptr) {
    cs_.Free(numeric_factor_);
    numeric_factor_ = nullptr;
  }
}

}  // namespace internal
}  // namespace ceres

#endif  // CERES_NO_CXSPARSE
