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

#ifndef CERES_INTERNAL_TRIPLET_SPARSE_MATRIX_H_
#define CERES_INTERNAL_TRIPLET_SPARSE_MATRIX_H_

#include <memory>
#include <random>
#include <vector>

#include "ceres/crs_matrix.h"
#include "ceres/internal/disable_warnings.h"
#include "ceres/internal/eigen.h"
#include "ceres/internal/export.h"
#include "ceres/sparse_matrix.h"
#include "ceres/types.h"

namespace ceres::internal {

// An implementation of the SparseMatrix interface to store and
// manipulate sparse matrices in triplet (i,j,s) form.  This object is
// inspired by the design of the cholmod_triplet struct used in the
// SuiteSparse package and is memory layout compatible with it.
class CERES_NO_EXPORT TripletSparseMatrix final : public SparseMatrix {
 public:
  TripletSparseMatrix();
  TripletSparseMatrix(int num_rows, int num_cols, int max_num_nonzeros);
  TripletSparseMatrix(int num_rows,
                      int num_cols,
                      const std::vector<int>& rows,
                      const std::vector<int>& cols,
                      const std::vector<double>& values);

  TripletSparseMatrix(const TripletSparseMatrix& orig);

  TripletSparseMatrix& operator=(const TripletSparseMatrix& rhs);

  ~TripletSparseMatrix() override;

  // Implementation of the SparseMatrix interface.
  void SetZero() final;
  void RightMultiplyAndAccumulate(const double* x, double* y) const final;
  void LeftMultiplyAndAccumulate(const double* x, double* y) const final;
  void SquaredColumnNorm(double* x) const final;
  void ScaleColumns(const double* scale) final;
  void ToCRSMatrix(CRSMatrix* matrix) const;
  void ToDenseMatrix(Matrix* dense_matrix) const final;
  void ToTextFile(FILE* file) const final;
  // clang-format off
  int num_rows()        const final   { return num_rows_;     }
  int num_cols()        const final   { return num_cols_;     }
  int num_nonzeros()    const final   { return num_nonzeros_; }
  const double* values()  const final { return values_.get(); }
  double* mutable_values() final      { return values_.get(); }
  // clang-format on
  void set_num_nonzeros(int num_nonzeros);

  // Increase max_num_nonzeros and correspondingly increase the size
  // of rows_, cols_ and values_. If new_max_num_nonzeros is smaller
  // than max_num_nonzeros_, then num_non_zeros should be less than or
  // equal to new_max_num_nonzeros, otherwise data loss is possible
  // and the method crashes.
  void Reserve(int new_max_num_nonzeros);

  // Append the matrix B at the bottom of this matrix. B should have
  // the same number of columns as num_cols_.
  void AppendRows(const TripletSparseMatrix& B);

  // Append the matrix B at the right of this matrix. B should have
  // the same number of rows as num_rows_;
  void AppendCols(const TripletSparseMatrix& B);

  // Resize the matrix. Entries which fall outside the new matrix
  // bounds are dropped and the num_non_zeros changed accordingly.
  void Resize(int new_num_rows, int new_num_cols);

  // clang-format off
  int max_num_nonzeros() const { return max_num_nonzeros_; }
  const int* rows()      const { return rows_.get();       }
  const int* cols()      const { return cols_.get();       }
  int* mutable_rows()          { return rows_.get();       }
  int* mutable_cols()          { return cols_.get();       }
  // clang-format on

  // Returns true if the entries of the matrix obey the row, column,
  // and column size bounds and false otherwise.
  bool AllTripletsWithinBounds() const;

  bool IsValid() const { return AllTripletsWithinBounds(); }

  // Build a sparse diagonal matrix of size num_rows x num_rows from
  // the array values. Entries of the values array are copied into the
  // sparse matrix.
  static std::unique_ptr<TripletSparseMatrix> CreateSparseDiagonalMatrix(
      const double* values, int num_rows);

  // Options struct to control the generation of random
  // TripletSparseMatrix objects.
  struct RandomMatrixOptions {
    int num_rows;
    int num_cols;
    // 0 < density <= 1 is the probability of an entry being
    // structurally non-zero. A given random matrix will not have
    // precisely this density.
    double density;
  };

  // Create a random CompressedRowSparseMatrix whose entries are
  // normally distributed and whose structure is determined by
  // RandomMatrixOptions.
  static std::unique_ptr<TripletSparseMatrix> CreateRandomMatrix(
      const TripletSparseMatrix::RandomMatrixOptions& options,
      std::mt19937& prng);

  // Load a triplet sparse matrix from a text file.
  static std::unique_ptr<TripletSparseMatrix> CreateFromTextFile(FILE* file);

 private:
  void AllocateMemory();
  void CopyData(const TripletSparseMatrix& orig);

  int num_rows_;
  int num_cols_;
  int max_num_nonzeros_;
  int num_nonzeros_;

  // The data is stored as three arrays. For each i, values_[i] is
  // stored at the location (rows_[i], cols_[i]). If the there are
  // multiple entries with the same (rows_[i], cols_[i]), the values_
  // entries corresponding to them are summed up.
  std::unique_ptr<int[]> rows_;
  std::unique_ptr<int[]> cols_;
  std::unique_ptr<double[]> values_;
};

}  // namespace ceres::internal

#include "ceres/internal/reenable_warnings.h"

#endif  // CERES_INTERNAL_TRIPLET_SPARSE_MATRIX_H__
