// 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: sameeragarwal@google.com (Sameer Agarwal)

#include "ceres/compressed_row_sparse_matrix.h"

#include <algorithm>
#include <numeric>
#include <vector>
#include "ceres/crs_matrix.h"
#include "ceres/internal/port.h"
#include "ceres/triplet_sparse_matrix.h"
#include "glog/logging.h"

namespace ceres {
namespace internal {

using std::vector;

namespace {

// Helper functor used by the constructor for reordering the contents
// of a TripletSparseMatrix. This comparator assumes thay there are no
// duplicates in the pair of arrays rows and cols, i.e., there is no
// indices i and j (not equal to each other) s.t.
//
//  rows[i] == rows[j] && cols[i] == cols[j]
//
// If this is the case, this functor will not be a StrictWeakOrdering.
struct RowColLessThan {
  RowColLessThan(const int* rows, const int* cols)
      : rows(rows), cols(cols) {
  }

  bool operator()(const int x, const int y) const {
    if (rows[x] == rows[y]) {
      return (cols[x] < cols[y]);
    }
    return (rows[x] < rows[y]);
  }

  const int* rows;
  const int* cols;
};

void TransposeForCompressedRowSparseStructure(const int num_rows,
                                              const int num_cols,
                                              const int num_nonzeros,
                                              const int *rows,
                                              const int *cols,
                                              const double *values,
                                              int* transpose_rows,
                                              int *transpose_cols,
                                              double *transpose_values) {
  for (int idx = 0; idx < num_nonzeros; ++idx) {
    ++transpose_rows[cols[idx] + 1];
  }

  for (int i = 1; i < num_cols + 1; ++i) {
    transpose_rows[i] += transpose_rows[i - 1];
  }

  for (int r = 0; r < num_rows; ++r) {
    for (int idx = rows[r]; idx < rows[r + 1]; ++idx) {
      const int c = cols[idx];
      const int transpose_idx = transpose_rows[c]++;
      transpose_cols[transpose_idx] = r;
      if (values) {
         transpose_values[transpose_idx] = values[idx];
      }
    }
  }

  for (int i = num_cols - 1; i > 0 ; --i) {
    transpose_rows[i] = transpose_rows[i - 1];
  }
  transpose_rows[0] = 0;
}
}  // namespace

// This constructor gives you a semi-initialized CompressedRowSparseMatrix.
CompressedRowSparseMatrix::CompressedRowSparseMatrix(int num_rows,
                                                     int num_cols,
                                                     int max_num_nonzeros) {
  num_rows_ = num_rows;
  num_cols_ = num_cols;
  rows_.resize(num_rows + 1, 0);
  cols_.resize(max_num_nonzeros, 0);
  values_.resize(max_num_nonzeros, 0.0);


  VLOG(1) << "# of rows: " << num_rows_
          << " # of columns: " << num_cols_
          << " max_num_nonzeros: " << cols_.size()
          << ". Allocating " << (num_rows_ + 1) * sizeof(int) +  // NOLINT
      cols_.size() * sizeof(int) +  // NOLINT
      cols_.size() * sizeof(double);  // NOLINT
}

CompressedRowSparseMatrix::CompressedRowSparseMatrix(
    const TripletSparseMatrix& m) {
  num_rows_ = m.num_rows();
  num_cols_ = m.num_cols();

  rows_.resize(num_rows_ + 1, 0);
  cols_.resize(m.num_nonzeros(), 0);
  values_.resize(m.max_num_nonzeros(), 0.0);

  // index is the list of indices into the TripletSparseMatrix m.
  vector<int> index(m.num_nonzeros(), 0);
  for (int i = 0; i < m.num_nonzeros(); ++i) {
    index[i] = i;
  }

  // Sort index such that the entries of m are ordered by row and ties
  // are broken by column.
  sort(index.begin(), index.end(), RowColLessThan(m.rows(), m.cols()));

  VLOG(1) << "# of rows: " << num_rows_
          << " # of columns: " << num_cols_
          << " max_num_nonzeros: " << cols_.size()
          << ". Allocating "
          << ((num_rows_ + 1) * sizeof(int) +  // NOLINT
              cols_.size() * sizeof(int) +     // NOLINT
              cols_.size() * sizeof(double));  // NOLINT

  // Copy the contents of the cols and values array in the order given
  // by index and count the number of entries in each row.
  for (int i = 0; i < m.num_nonzeros(); ++i) {
    const int idx = index[i];
    ++rows_[m.rows()[idx] + 1];
    cols_[i] = m.cols()[idx];
    values_[i] = m.values()[idx];
  }

  // Find the cumulative sum of the row counts.
  for (int i = 1; i < num_rows_ + 1; ++i) {
    rows_[i] += rows_[i - 1];
  }

  CHECK_EQ(num_nonzeros(), m.num_nonzeros());
}

CompressedRowSparseMatrix::CompressedRowSparseMatrix(const double* diagonal,
                                                     int num_rows) {
  CHECK_NOTNULL(diagonal);

  num_rows_ = num_rows;
  num_cols_ = num_rows;
  rows_.resize(num_rows + 1);
  cols_.resize(num_rows);
  values_.resize(num_rows);

  rows_[0] = 0;
  for (int i = 0; i < num_rows_; ++i) {
    cols_[i] = i;
    values_[i] = diagonal[i];
    rows_[i + 1] = i + 1;
  }

  CHECK_EQ(num_nonzeros(), num_rows);
}

CompressedRowSparseMatrix::~CompressedRowSparseMatrix() {
}

void CompressedRowSparseMatrix::SetZero() {
  std::fill(values_.begin(), values_.end(), 0);
}

void CompressedRowSparseMatrix::RightMultiply(const double* x,
                                              double* y) const {
  CHECK_NOTNULL(x);
  CHECK_NOTNULL(y);

  for (int r = 0; r < num_rows_; ++r) {
    for (int idx = rows_[r]; idx < rows_[r + 1]; ++idx) {
      y[r] += values_[idx] * x[cols_[idx]];
    }
  }
}

void CompressedRowSparseMatrix::LeftMultiply(const double* x, double* y) const {
  CHECK_NOTNULL(x);
  CHECK_NOTNULL(y);

  for (int r = 0; r < num_rows_; ++r) {
    for (int idx = rows_[r]; idx < rows_[r + 1]; ++idx) {
      y[cols_[idx]] += values_[idx] * x[r];
    }
  }
}

void CompressedRowSparseMatrix::SquaredColumnNorm(double* x) const {
  CHECK_NOTNULL(x);

  std::fill(x, x + num_cols_, 0.0);
  for (int idx = 0; idx < rows_[num_rows_]; ++idx) {
    x[cols_[idx]] += values_[idx] * values_[idx];
  }
}

void CompressedRowSparseMatrix::ScaleColumns(const double* scale) {
  CHECK_NOTNULL(scale);

  for (int idx = 0; idx < rows_[num_rows_]; ++idx) {
    values_[idx] *= scale[cols_[idx]];
  }
}

void CompressedRowSparseMatrix::ToDenseMatrix(Matrix* dense_matrix) const {
  CHECK_NOTNULL(dense_matrix);
  dense_matrix->resize(num_rows_, num_cols_);
  dense_matrix->setZero();

  for (int r = 0; r < num_rows_; ++r) {
    for (int idx = rows_[r]; idx < rows_[r + 1]; ++idx) {
      (*dense_matrix)(r, cols_[idx]) = values_[idx];
    }
  }
}

void CompressedRowSparseMatrix::DeleteRows(int delta_rows) {
  CHECK_GE(delta_rows, 0);
  CHECK_LE(delta_rows, num_rows_);

  num_rows_ -= delta_rows;
  rows_.resize(num_rows_ + 1);

  // The rest of the code update block information.
  // Immediately return in case of no block information.
  if (row_blocks_.empty()) {
    return;
  }

  // Sanity check for compressed row sparse block information
  CHECK_EQ(crsb_rows_.size(), row_blocks_.size() + 1);
  CHECK_EQ(crsb_rows_.back(), crsb_cols_.size());

  // Walk the list of row blocks until we reach the new number of rows
  // and the drop the rest of the row blocks.
  int num_row_blocks = 0;
  int num_rows = 0;
  while (num_row_blocks < row_blocks_.size() && num_rows < num_rows_) {
    num_rows += row_blocks_[num_row_blocks];
    ++num_row_blocks;
  }

  row_blocks_.resize(num_row_blocks);

  // Update compressed row sparse block (crsb) information.
  CHECK_EQ(num_rows, num_rows_);
  crsb_rows_.resize(num_row_blocks + 1);
  crsb_cols_.resize(crsb_rows_[num_row_blocks]);
}

void CompressedRowSparseMatrix::AppendRows(const CompressedRowSparseMatrix& m) {
  CHECK_EQ(m.num_cols(), num_cols_);

  CHECK((row_blocks_.size() == 0 && m.row_blocks().size() == 0) ||
        (row_blocks_.size() != 0 && m.row_blocks().size() != 0))
      << "Cannot append a matrix with row blocks to one without and vice versa."
      << "This matrix has : " << row_blocks_.size() << " row blocks."
      << "The matrix being appended has: " << m.row_blocks().size()
      << " row blocks.";

  if (m.num_rows() == 0) {
    return;
  }

  if (cols_.size() < num_nonzeros() + m.num_nonzeros()) {
    cols_.resize(num_nonzeros() + m.num_nonzeros());
    values_.resize(num_nonzeros() + m.num_nonzeros());
  }

  // Copy the contents of m into this matrix.
  DCHECK_LT(num_nonzeros(), cols_.size());
  if (m.num_nonzeros() > 0) {
    std::copy(m.cols(), m.cols() + m.num_nonzeros(), &cols_[num_nonzeros()]);
    std::copy(m.values(),
              m.values() + m.num_nonzeros(),
              &values_[num_nonzeros()]);
  }

  rows_.resize(num_rows_ + m.num_rows() + 1);
  // new_rows = [rows_, m.row() + rows_[num_rows_]]
  std::fill(rows_.begin() + num_rows_,
            rows_.begin() + num_rows_ + m.num_rows() + 1,
            rows_[num_rows_]);

  for (int r = 0; r < m.num_rows() + 1; ++r) {
    rows_[num_rows_ + r] += m.rows()[r];
  }

  num_rows_ += m.num_rows();

  // The rest of the code update block information.
  // Immediately return in case of no block information.
  if (row_blocks_.empty()) {
    return;
  }

  // Sanity check for compressed row sparse block information
  CHECK_EQ(crsb_rows_.size(), row_blocks_.size() + 1);
  CHECK_EQ(crsb_rows_.back(), crsb_cols_.size());

  row_blocks_.insert(row_blocks_.end(),
                     m.row_blocks().begin(),
                     m.row_blocks().end());

  // The rest of the code update compressed row sparse block (crsb) information.
  const int num_crsb_nonzeros = crsb_cols_.size();
  const int m_num_crsb_nonzeros = m.crsb_cols_.size();
  crsb_cols_.resize(num_crsb_nonzeros + m_num_crsb_nonzeros);
  std::copy(&m.crsb_cols()[0], &m.crsb_cols()[0] + m_num_crsb_nonzeros,
            &crsb_cols_[num_crsb_nonzeros]);

  const int num_crsb_rows = crsb_rows_.size() - 1;
  const int m_num_crsb_rows = m.crsb_rows_.size() - 1;
  crsb_rows_.resize(num_crsb_rows + m_num_crsb_rows + 1);
  std::fill(crsb_rows_.begin() + num_crsb_rows,
            crsb_rows_.begin() + num_crsb_rows + m_num_crsb_rows + 1,
            crsb_rows_[num_crsb_rows]);

  for (int r = 0; r < m_num_crsb_rows + 1; ++r) {
    crsb_rows_[num_crsb_rows + r] += m.crsb_rows()[r];
  }
}

void CompressedRowSparseMatrix::ToTextFile(FILE* file) const {
  CHECK_NOTNULL(file);
  for (int r = 0; r < num_rows_; ++r) {
    for (int idx = rows_[r]; idx < rows_[r + 1]; ++idx) {
      fprintf(file,
              "% 10d % 10d %17f\n",
              r,
              cols_[idx],
              values_[idx]);
    }
  }
}

void CompressedRowSparseMatrix::ToCRSMatrix(CRSMatrix* matrix) const {
  matrix->num_rows = num_rows_;
  matrix->num_cols = num_cols_;
  matrix->rows = rows_;
  matrix->cols = cols_;
  matrix->values = values_;

  // Trim.
  matrix->rows.resize(matrix->num_rows + 1);
  matrix->cols.resize(matrix->rows[matrix->num_rows]);
  matrix->values.resize(matrix->rows[matrix->num_rows]);
}

void CompressedRowSparseMatrix::SetMaxNumNonZeros(int num_nonzeros) {
  CHECK_GE(num_nonzeros, 0);

  cols_.resize(num_nonzeros);
  values_.resize(num_nonzeros);
}

void CompressedRowSparseMatrix::SolveLowerTriangularInPlace(
    double* solution) const {
  for (int r = 0; r < num_rows_; ++r) {
    for (int idx = rows_[r]; idx < rows_[r + 1] - 1; ++idx) {
      solution[r] -= values_[idx] * solution[cols_[idx]];
    }
    solution[r] /=  values_[rows_[r + 1] - 1];
  }
}

void CompressedRowSparseMatrix::SolveLowerTriangularTransposeInPlace(
    double* solution) const {
  for (int r = num_rows_ - 1; r >= 0; --r) {
    solution[r] /= values_[rows_[r + 1] - 1];
    for (int idx = rows_[r + 1] - 2; idx >= rows_[r]; --idx) {
      solution[cols_[idx]] -= values_[idx] * solution[r];
    }
  }
}

CompressedRowSparseMatrix* CompressedRowSparseMatrix::CreateBlockDiagonalMatrix(
    const double* diagonal,
    const vector<int>& blocks) {
  int num_rows = 0;
  int num_nonzeros = 0;
  for (int i = 0; i < blocks.size(); ++i) {
    num_rows += blocks[i];
    num_nonzeros += blocks[i] * blocks[i];
  }

  CompressedRowSparseMatrix* matrix =
      new CompressedRowSparseMatrix(num_rows, num_rows, num_nonzeros);

  int* rows = matrix->mutable_rows();
  int* cols = matrix->mutable_cols();
  double* values = matrix->mutable_values();
  std::fill(values, values + num_nonzeros, 0.0);

  int idx_cursor = 0;
  int col_cursor = 0;
  for (int i = 0; i < blocks.size(); ++i) {
    const int block_size = blocks[i];
    for (int r = 0; r < block_size; ++r) {
      *(rows++) = idx_cursor;
      values[idx_cursor + r] = diagonal[col_cursor + r];
      for (int c = 0; c < block_size; ++c, ++idx_cursor) {
        *(cols++) = col_cursor + c;
      }
    }
    col_cursor += block_size;
  }
  *rows = idx_cursor;

  *matrix->mutable_row_blocks() = blocks;
  *matrix->mutable_col_blocks() = blocks;

  // Fill compressed row sparse block (crsb) information.
  vector<int>& crsb_rows = *matrix->mutable_crsb_rows();
  vector<int>& crsb_cols = *matrix->mutable_crsb_cols();
  for (int i = 0; i < blocks.size(); ++i) {
    crsb_rows.push_back(i);
    crsb_cols.push_back(i);
  }
  crsb_rows.push_back(blocks.size());

  CHECK_EQ(idx_cursor, num_nonzeros);
  CHECK_EQ(col_cursor, num_rows);
  return matrix;
}

CompressedRowSparseMatrix* CompressedRowSparseMatrix::Transpose() const {
  CompressedRowSparseMatrix* transpose =
      new CompressedRowSparseMatrix(num_cols_, num_rows_, num_nonzeros());

  TransposeForCompressedRowSparseStructure(
      num_rows(), num_cols(), num_nonzeros(),
      rows(), cols(), values(),
      transpose->mutable_rows(),
      transpose->mutable_cols(),
      transpose->mutable_values());

  // The rest of the code update block information.
  // Immediately return in case of no block information.
  if (row_blocks_.empty()) {
    return transpose;
  }

  // Sanity check for compressed row sparse block information
  CHECK_EQ(crsb_rows_.size(), row_blocks_.size() + 1);
  CHECK_EQ(crsb_rows_.back(), crsb_cols_.size());

  *(transpose->mutable_row_blocks()) = col_blocks_;
  *(transpose->mutable_col_blocks()) = row_blocks_;

  // The rest of the code update compressed row sparse block (crsb) information.
  vector<int>& transpose_crsb_rows = *transpose->mutable_crsb_rows();
  vector<int>& transpose_crsb_cols = *transpose->mutable_crsb_cols();

  transpose_crsb_rows.resize(col_blocks_.size() + 1);
  std::fill(transpose_crsb_rows.begin(), transpose_crsb_rows.end(), 0);
  transpose_crsb_cols.resize(crsb_cols_.size());

  TransposeForCompressedRowSparseStructure(
      row_blocks().size(), col_blocks().size(), crsb_cols().size(),
      crsb_rows().data(), crsb_cols().data(), NULL,
      transpose_crsb_rows.data(), transpose_crsb_cols.data(), NULL);

  return transpose;
}

namespace {
// A ProductTerm is a term in the block outer product of a matrix with
// itself.
struct ProductTerm {
  ProductTerm(const int row, const int col, const int index)
      : row(row), col(col), index(index) {
  }

  bool operator<(const ProductTerm& right) const {
    if (row == right.row) {
      if (col == right.col) {
        return index < right.index;
      }
      return col < right.col;
    }
    return row < right.row;
  }

  int row;
  int col;
  int index;
};

// Create outerproduct matrix based on the block product information.
// The input block product is already sorted.  This function does not
// set the sparse rows/cols information.  Instead, it only collects the
// nonzeros for each compressed row and puts in row_nnz.
// The caller of this function will traverse the block product in a second
// round to generate the sparse rows/cols information.
// This function also computes the block offset information for
// the outerproduct matrix, which is used in outer product computation.
CompressedRowSparseMatrix*
CreateOuterProductMatrix(const int num_cols,
                         const vector<int>& blocks,
                         const vector<ProductTerm>& product,
                         vector<int>* row_nnz) {

  // Count the number of unique product term, which in turn is the
  // number of non-zeros in the outer product.
  // Also count the number of non-zeros in each row.
  row_nnz->resize(blocks.size());
  std::fill(row_nnz->begin(), row_nnz->end(), 0);
  (*row_nnz)[product[0].row] = blocks[product[0].col];
  int num_nonzeros = blocks[product[0].row] * blocks[product[0].col];
  for (int i = 1; i < product.size(); ++i) {
    // Each (row, col) block counts only once.
    // This check depends on product sorted on (row, col).
    if (product[i].row != product[i - 1].row ||
        product[i].col != product[i - 1].col) {
      (*row_nnz)[product[i].row] += blocks[product[i].col];
      num_nonzeros += blocks[product[i].row] * blocks[product[i].col];
    }
  }

  CompressedRowSparseMatrix* matrix =
      new CompressedRowSparseMatrix(num_cols, num_cols, num_nonzeros);

  // Compute block offsets for outer product matrix, which is used
  // in ComputeOuterProduct.
  vector<int>* block_offsets = matrix->mutable_block_offsets();
  block_offsets->resize(blocks.size() + 1);
  (*block_offsets)[0] = 0;
  for (int i = 0; i < blocks.size(); ++i) {
    (*block_offsets)[i + 1] = (*block_offsets)[i] + blocks[i];
  }

  return matrix;
}

CompressedRowSparseMatrix*
CompressAndFillProgram(const int num_cols,
                       const vector<int>& blocks,
                       const vector<ProductTerm>& product,
                       vector<int>* program) {
  CHECK_GT(product.size(), 0);

  vector<int> row_nnz;
  CompressedRowSparseMatrix* matrix =
      CreateOuterProductMatrix(num_cols, blocks, product, &row_nnz);

  const vector<int>& block_offsets = matrix->block_offsets();

  int* crsm_rows = matrix->mutable_rows();
  std::fill(crsm_rows, crsm_rows + num_cols + 1, 0);
  int* crsm_cols = matrix->mutable_cols();
  std::fill(crsm_cols, crsm_cols + matrix->num_nonzeros(), 0);

  CHECK_NOTNULL(program)->clear();
  program->resize(product.size());

  // Non zero elements are not stored consecutively across rows in a block.
  // We seperate nonzero into three categories:
  //   nonzeros in all previous row blocks counted in nnz
  //   nonzeros in current row counted in row_nnz
  //   nonzeros in previous col blocks of current row counted in col_nnz
  //
  // Give an element (j, k) within a block such that j and k
  // represent the relative position to the starting row and starting col of
  // the block, the row and col for the element is
  //   block_offsets[current.row] + j
  //   block_offsets[current.col] + k
  // The total number of nonzero to the element is
  //   nnz + row_nnz[current.row] * j + col_nnz + k
  //
  // program keeps col_nnz for block product, which is used later for
  // outerproduct computation.
  //
  // There is no special handling for diagonal blocks as we generate
  // BLOCK triangular matrix (diagonal block is full block) instead of
  // standard triangular matrix.
  int nnz = 0;
  int col_nnz = 0;

  // Process first product term.
  for (int j = 0; j < blocks[product[0].row]; ++j) {
    crsm_rows[block_offsets[product[0].row] + j + 1] =
        row_nnz[product[0].row];
    for (int k = 0; k < blocks[product[0].col]; ++k) {
      crsm_cols[row_nnz[product[0].row] * j + k]
          = block_offsets[product[0].col] + k;
    }
  }

  (*program)[product[0].index] = 0;

  // Process rest product terms.
  for (int i = 1; i < product.size(); ++i) {
    const ProductTerm& previous = product[i - 1];
    const ProductTerm& current = product[i];

    // Sparsity structure is updated only if the term is not a repeat.
    if (previous.row != current.row || previous.col != current.col) {
      col_nnz += blocks[previous.col];
      if (previous.row != current.row) {
        nnz += col_nnz * blocks[previous.row];
        col_nnz = 0;

        for (int j = 0; j < blocks[current.row]; ++j) {
          crsm_rows[block_offsets[current.row] + j + 1] =
              row_nnz[current.row];
        }
      }

      for (int j = 0; j < blocks[current.row]; ++j) {
        for (int k = 0; k < blocks[current.col]; ++k) {
          crsm_cols[nnz + row_nnz[current.row] * j + col_nnz + k]
              = block_offsets[current.col] + k;
        }
      }
    }

    (*program)[current.index] = col_nnz;
  }

  for (int i = 1; i < num_cols + 1; ++i) {
    crsm_rows[i] += crsm_rows[i - 1];
  }

  return matrix;
}

// input is a matrix of dimesion <row_block_size, input_cols>
// output is a matrix of dimension <col_block1_size, output_cols>
//
// Implement block multiplication O = I1' * I2.
// I1 is block(0, col_block1_begin, row_block_size, col_block1_size) of input
// I2 is block(0, col_block2_begin, row_block_size, col_block2_size) of input
// O is block(0, 0, col_block1_size, col_block2_size) of output
void ComputeBlockMultiplication(const int row_block_size,
                                const int col_block1_size,
                                const int col_block2_size,
                                const int col_block1_begin,
                                const int col_block2_begin,
                                const int input_cols,
                                const double *input,
                                const int output_cols,
                                double *output) {
  for (int r = 0; r < row_block_size; ++r) {
    for (int idx1 = 0; idx1 < col_block1_size; ++idx1) {
      for (int idx2 = 0; idx2 < col_block2_size; ++idx2) {
        output[output_cols * idx1 + idx2] +=
            input[input_cols * r + col_block1_begin + idx1] *
            input[input_cols * r + col_block2_begin + idx2];
      }
    }
  }
}
}  // namespace

CompressedRowSparseMatrix*
CompressedRowSparseMatrix::CreateOuterProductMatrixAndProgram(
      const CompressedRowSparseMatrix& m,
      const int stype,
      vector<int>* program) {
  CHECK_NOTNULL(program)->clear();
  CHECK_GT(m.num_nonzeros(), 0)
                << "Congratulations, "
                << "you found a bug in Ceres. Please report it.";

  vector<ProductTerm> product;
  const vector<int>& col_blocks = m.col_blocks();
  const vector<int>& crsb_rows = m.crsb_rows();
  const vector<int>& crsb_cols = m.crsb_cols();

  // Give input matrix m in Compressed Row Sparse Block format
  //     (row_block, col_block)
  // represent each block multiplication
  //     (row_block, col_block1)' X (row_block, col_block2)
  // by its product term index and sort the product terms
  //     (col_block1, col_block2, index)
  //
  // Due to the compression on rows, col_block is accessed through idx to
  // crsb_cols.  So col_block is accessed as crsb_cols[idx] in the code.
  for (int row_block = 1; row_block < crsb_rows.size(); ++row_block) {
    for (int idx1 = crsb_rows[row_block - 1]; idx1 < crsb_rows[row_block];
         ++idx1) {
      if (stype > 0) { // Lower triangular matrix.
        for (int idx2 = crsb_rows[row_block - 1]; idx2 <= idx1; ++idx2) {
          product.push_back(ProductTerm(crsb_cols[idx1], crsb_cols[idx2],
                                        product.size()));
        }
      }
      else { // Upper triangular matrix.
        for (int idx2 = idx1; idx2 < crsb_rows[row_block]; ++idx2) {
          product.push_back(ProductTerm(crsb_cols[idx1], crsb_cols[idx2],
                                        product.size()));
        }
      }
    }
  }

  sort(product.begin(), product.end());
  return CompressAndFillProgram(m.num_cols(), col_blocks, product, program);
}

// Give input matrix m in Compressed Row Sparse Block format
//     (row_block, col_block)
// compute outerproduct m' * m as sum of block multiplications
//     (row_block, col_block1)' X (row_block, col_block2)
//
// Given row_block of the input matrix m, we use m_row_begin to represent
// the starting row of the row block and m_row_nnz to represent number of
// nonzero in each row of the row block, then the rows belonging to
// the row block can be represented as a dense matrix starting at
//     m.values() + m.rows()[m_row_begin]
// with dimension
//     <m.row_blocks()[row_block], m_row_nnz>
//
// Then each input matrix block (row_block, col_block) can be represented as
// a block of above dense matrix starting at position
//     (0, m_col_nnz)
// with size
//     <m.row_blocks()[row_block], m.col_blocks()[col_block]>
// where m_col_nnz is the number of nonzero before col_block in each row.
//
// The outerproduct block is represented similarly with m_row_begin,
// m_row_nnz, m_col_nnz, etc. replaced by row_begin, row_nnz, col_nnz, etc.
// The difference is, m_row_begin and m_col_nnz is counted during the
// traverse of block multiplication, while row_begin and col_nnz are got
// from pre-computed block_offsets and program.
//
// Due to the compression on rows, col_block is accessed through
// idx to crsb_col vector. So col_block is accessed as crsb_col[idx]
// in the code.
//
// Note this function produces a triangular matrix in block unit (i.e.
// diagonal block is a normal block) instead of standard triangular matrix.
// So there is no special handling for diagonal blocks.
void CompressedRowSparseMatrix::ComputeOuterProduct(
    const CompressedRowSparseMatrix& m,
    const int stype,
    const vector<int>& program,
    CompressedRowSparseMatrix* result) {
  result->SetZero();
  double* values = result->mutable_values();
  const int* rows = result->rows();
  const vector<int>& block_offsets = result->block_offsets();

  int cursor = 0;
  const double* m_values = m.values();
  const int* m_rows = m.rows();
  const vector<int>& row_blocks = m.row_blocks();
  const vector<int>& col_blocks = m.col_blocks();
  const vector<int>& crsb_rows = m.crsb_rows();
  const vector<int>& crsb_cols = m.crsb_cols();

#define COL_BLOCK1 (crsb_cols[idx1])
#define COL_BLOCK2 (crsb_cols[idx2])

  // Iterate row blocks.
  for (int row_block = 0, m_row_begin = 0; row_block < row_blocks.size();
       m_row_begin += row_blocks[row_block++]) {
    // Non zeros are not stored consecutively across rows in a block.
    // The gaps between rows is the number of nonzeros of the
    // input matrix compressed row.
    const int m_row_nnz =
        m_rows[m_row_begin + 1] - m_rows[m_row_begin];

    // Iterate (col_block1 x col_block2).
    for (int idx1 = crsb_rows[row_block], m_col_nnz1 = 0;
         idx1 < crsb_rows[row_block + 1];
         m_col_nnz1 += col_blocks[COL_BLOCK1], ++idx1) {
      // Non zeros are not stored consecutively across rows in a block.
      // The gaps between rows is the number of nonzeros of the
      // outerproduct matrix compressed row.
      const int row_begin = block_offsets[COL_BLOCK1];
      const int row_nnz = rows[row_begin + 1] - rows[row_begin];

      if (stype > 0) {  // Lower triangular matrix.
        for (int idx2 = crsb_rows[row_block], m_col_nnz2 = 0;
             idx2 <= idx1;
             m_col_nnz2 += col_blocks[COL_BLOCK2], ++idx2, ++cursor) {
          int col_nnz = program[cursor];
          ComputeBlockMultiplication(row_blocks[row_block],
                                     col_blocks[COL_BLOCK1],
                                     col_blocks[COL_BLOCK2],
                                     m_col_nnz1,
                                     m_col_nnz2,
                                     m_row_nnz,
                                     m_values + m_rows[m_row_begin],
                                     row_nnz,
                                     values + rows[row_begin] + col_nnz);
        }
      }
      else { // Upper triangular matrix.
        for (int idx2 = idx1, m_col_nnz2 = m_col_nnz1;
             idx2 < crsb_rows[row_block + 1];
             m_col_nnz2 += col_blocks[COL_BLOCK2], ++idx2, ++cursor) {
          int col_nnz = program[cursor];
          ComputeBlockMultiplication(row_blocks[row_block],
                                     col_blocks[COL_BLOCK1],
                                     col_blocks[COL_BLOCK2],
                                     m_col_nnz1,
                                     m_col_nnz2,
                                     m_row_nnz,
                                     m_values + m_rows[m_row_begin],
                                     row_nnz,
                                     values + rows[row_begin] + col_nnz);
        }
      }
    }
  }

#undef COL_BLOCK1
#undef COL_BLOCK2

  CHECK_EQ(cursor, program.size());
}

}  // namespace internal
}  // namespace ceres
