// 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 <limits>
#include <memory>
#include <vector>

#include "ceres/block_random_access_sparse_matrix.h"
#include "ceres/internal/eigen.h"
#include "glog/logging.h"
#include "gtest/gtest.h"

namespace ceres {
namespace internal {

using std::make_pair;
using std::pair;
using std::set;
using std::vector;

TEST(BlockRandomAccessSparseMatrix, GetCell) {
  vector<int> blocks;
  blocks.push_back(3);
  blocks.push_back(4);
  blocks.push_back(5);
  const int num_rows = 3 + 4 + 5;

  set<pair<int, int>> block_pairs;
  int num_nonzeros = 0;
  block_pairs.insert(make_pair(0, 0));
  num_nonzeros += blocks[0] * blocks[0];

  block_pairs.insert(make_pair(1, 1));
  num_nonzeros += blocks[1] * blocks[1];

  block_pairs.insert(make_pair(1, 2));
  num_nonzeros += blocks[1] * blocks[2];

  block_pairs.insert(make_pair(0, 2));
  num_nonzeros += blocks[2] * blocks[0];

  BlockRandomAccessSparseMatrix m(blocks, block_pairs);
  EXPECT_EQ(m.num_rows(), num_rows);
  EXPECT_EQ(m.num_cols(), num_rows);

  for (const auto& block_pair : block_pairs) {
    const int row_block_id = block_pair.first;
    const int col_block_id = block_pair.second;
    int row;
    int col;
    int row_stride;
    int col_stride;
    CellInfo* cell =  m.GetCell(row_block_id, col_block_id,
                                &row, &col,
                                &row_stride, &col_stride);
    EXPECT_TRUE(cell != NULL);
    EXPECT_EQ(row, 0);
    EXPECT_EQ(col, 0);
    EXPECT_EQ(row_stride, blocks[row_block_id]);
    EXPECT_EQ(col_stride, blocks[col_block_id]);

    // Write into the block
    MatrixRef(cell->values, row_stride, col_stride).block(
        row, col, blocks[row_block_id], blocks[col_block_id]) =
        (row_block_id + 1) * (col_block_id +1) *
        Matrix::Ones(blocks[row_block_id], blocks[col_block_id]);
  }

  const TripletSparseMatrix* tsm = m.matrix();
  EXPECT_EQ(tsm->num_nonzeros(), num_nonzeros);
  EXPECT_EQ(tsm->max_num_nonzeros(), num_nonzeros);

  Matrix dense;
  tsm->ToDenseMatrix(&dense);

  double kTolerance = 1e-14;

  // (0, 0)
  EXPECT_NEAR((dense.block(0, 0, 3, 3) - Matrix::Ones(3, 3)).norm(),
              0.0,
              kTolerance);
  // (1, 1)
  EXPECT_NEAR((dense.block(3, 3, 4, 4) - 2 * 2 * Matrix::Ones(4, 4)).norm(),
              0.0,
              kTolerance);
  // (1, 2)
  EXPECT_NEAR((dense.block(3, 3 + 4, 4, 5) - 2 * 3 * Matrix::Ones(4, 5)).norm(),
              0.0,
              kTolerance);
  // (0, 2)
  EXPECT_NEAR((dense.block(0, 3 + 4, 3, 5) - 3 * 1 * Matrix::Ones(3, 5)).norm(),
              0.0,
              kTolerance);

  // There is nothing else in the matrix besides these four blocks.
  EXPECT_NEAR(dense.norm(), sqrt(9. + 16. * 16. + 36. * 20. + 9. * 15.),
              kTolerance);

  Vector x = Vector::Ones(dense.rows());
  Vector actual_y = Vector::Zero(dense.rows());
  Vector expected_y = Vector::Zero(dense.rows());

  expected_y += dense.selfadjointView<Eigen::Upper>() * x;
  m.SymmetricRightMultiply(x.data(), actual_y.data());
  EXPECT_NEAR((expected_y - actual_y).norm(), 0.0, kTolerance)
      << "actual: " << actual_y.transpose() << "\n"
      << "expected: " << expected_y.transpose()
      << "matrix: \n " << dense;
}

// IntPairToLong is private, thus this fixture is needed to access and
// test it.
class BlockRandomAccessSparseMatrixTest : public ::testing::Test {
 public:
  virtual void SetUp() {
    vector<int> blocks;
    blocks.push_back(1);
    set<pair<int, int>> block_pairs;
    block_pairs.insert(make_pair(0, 0));
    m_.reset(new BlockRandomAccessSparseMatrix(blocks, block_pairs));
  }

  void CheckIntPairToLong(int a, int b) {
    int64_t value = m_->IntPairToLong(a, b);
    EXPECT_GT(value, 0) << "Overflow a = " << a << " b = " << b;
    EXPECT_GT(value, a) << "Overflow a = " << a << " b = " << b;
    EXPECT_GT(value, b) << "Overflow a = " << a << " b = " << b;
  }

  void CheckLongToIntPair() {
    uint64_t max_rows =  m_->kMaxRowBlocks;
    for (int row = max_rows - 10; row < max_rows; ++row) {
      for (int col = 0; col < 10; ++col) {
        int row_computed;
        int col_computed;
        m_->LongToIntPair(m_->IntPairToLong(row, col),
                          &row_computed,
                          &col_computed);
        EXPECT_EQ(row, row_computed);
        EXPECT_EQ(col, col_computed);
      }
    }
  }

 private:
  std::unique_ptr<BlockRandomAccessSparseMatrix> m_;
};

TEST_F(BlockRandomAccessSparseMatrixTest, IntPairToLongOverflow) {
  CheckIntPairToLong(std::numeric_limits<int>::max(),
                     std::numeric_limits<int>::max());
}

TEST_F(BlockRandomAccessSparseMatrixTest, LongToIntPair) {
  CheckLongToIntPair();
}

}  // namespace internal
}  // namespace ceres
