// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

#undef VERIFY_IS_APPROX
#define VERIFY_IS_APPROX(a, b) VERIFY((a) == (b));
#undef VERIFY_IS_NOT_APPROX
#define VERIFY_IS_NOT_APPROX(a, b) VERIFY((a) != (b));

template <typename MatrixType>
void signed_integer_type_tests(const MatrixType& m) {
  typedef typename MatrixType::Scalar Scalar;

  enum { is_signed = (Scalar(-1) > Scalar(0)) ? 0 : 1 };
  VERIFY(is_signed == 1);

  Index rows = m.rows();
  Index cols = m.cols();

  MatrixType m1(rows, cols), m2 = MatrixType::Random(rows, cols), mzero = MatrixType::Zero(rows, cols);

  do {
    m1 = MatrixType::Random(rows, cols);
  } while (m1 == mzero || m1 == m2);

  // check linear structure

  Scalar s1;
  do {
    s1 = internal::random<Scalar>();
  } while (s1 == 0);

  VERIFY_IS_EQUAL(-(-m1), m1);
  VERIFY_IS_EQUAL(-m2 + m1 + m2, m1);
  VERIFY_IS_EQUAL((-m1 + m2) * s1, -s1 * m1 + s1 * m2);
}

template <typename MatrixType>
void integer_type_tests(const MatrixType& m) {
  typedef typename MatrixType::Scalar Scalar;

  VERIFY(NumTraits<Scalar>::IsInteger);
  enum { is_signed = (Scalar(-1) > Scalar(0)) ? 0 : 1 };
  VERIFY(int(NumTraits<Scalar>::IsSigned) == is_signed);

  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;

  Index rows = m.rows();
  Index cols = m.cols();

  // this test relies a lot on Random.h, and there's not much more that we can do
  // to test it, hence I consider that we will have tested Random.h
  MatrixType m1(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols), mzero = MatrixType::Zero(rows, cols);

  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;
  SquareMatrixType identity = SquareMatrixType::Identity(rows, rows), square = SquareMatrixType::Random(rows, rows);
  VectorType v1(rows), v2 = VectorType::Random(rows), vzero = VectorType::Zero(rows);

  do {
    m1 = MatrixType::Random(rows, cols);
  } while (m1 == mzero || m1 == m2);

  do {
    v1 = VectorType::Random(rows);
  } while (v1 == vzero || v1 == v2);

  VERIFY_IS_APPROX(v1, v1);
  VERIFY_IS_NOT_APPROX(v1, 2 * v1);
  VERIFY_IS_APPROX(vzero, v1 - v1);
  VERIFY_IS_APPROX(m1, m1);
  VERIFY_IS_NOT_APPROX(m1, 2 * m1);
  VERIFY_IS_APPROX(mzero, m1 - m1);

  VERIFY_IS_APPROX(m3 = m1, m1);
  MatrixType m4;
  VERIFY_IS_APPROX(m4 = m1, m1);

  m3.real() = m1.real();
  VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), static_cast<const MatrixType&>(m1).real());
  VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), m1.real());

  // check == / != operators
  VERIFY(m1 == m1);
  VERIFY(m1 != m2);
  VERIFY(!(m1 == m2));
  VERIFY(!(m1 != m1));
  m1 = m2;
  VERIFY(m1 == m2);
  VERIFY(!(m1 != m2));

  // check linear structure

  Scalar s1;
  do {
    s1 = internal::random<Scalar>();
  } while (s1 == 0);

  VERIFY_IS_EQUAL(m1 + m1, 2 * m1);
  VERIFY_IS_EQUAL(m1 + m2 - m1, m2);
  VERIFY_IS_EQUAL(m1 * s1, s1 * m1);
  VERIFY_IS_EQUAL((m1 + m2) * s1, s1 * m1 + s1 * m2);
  m3 = m2;
  m3 += m1;
  VERIFY_IS_EQUAL(m3, m1 + m2);
  m3 = m2;
  m3 -= m1;
  VERIFY_IS_EQUAL(m3, m2 - m1);
  m3 = m2;
  m3 *= s1;
  VERIFY_IS_EQUAL(m3, s1 * m2);

  // check matrix product.

  VERIFY_IS_APPROX(identity * m1, m1);
  VERIFY_IS_APPROX(square * (m1 + m2), square * m1 + square * m2);
  VERIFY_IS_APPROX((m1 + m2).transpose() * square, m1.transpose() * square + m2.transpose() * square);
  VERIFY_IS_APPROX((m1 * m2.transpose()) * m1, m1 * (m2.transpose() * m1));
}

template <int>
void integer_types_extra() {
  VERIFY_IS_EQUAL(int(internal::scalar_div_cost<int>::value), 8);
  VERIFY_IS_EQUAL(int(internal::scalar_div_cost<unsigned int>::value), 8);
  if (sizeof(long) > sizeof(int)) {
    VERIFY(int(internal::scalar_div_cost<long>::value) > int(internal::scalar_div_cost<int>::value));
    VERIFY(int(internal::scalar_div_cost<unsigned long>::value) > int(internal::scalar_div_cost<int>::value));
  }
}

EIGEN_DECLARE_TEST(integer_types) {
  for (int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1(integer_type_tests(Matrix<unsigned int, 1, 1>()));
    CALL_SUBTEST_1(integer_type_tests(Matrix<unsigned long, 3, 4>()));

    CALL_SUBTEST_2(integer_type_tests(Matrix<long, 2, 2>()));
    CALL_SUBTEST_2(signed_integer_type_tests(Matrix<long, 2, 2>()));

    CALL_SUBTEST_3(integer_type_tests(Matrix<char, 2, Dynamic>(2, 10)));
    CALL_SUBTEST_3(signed_integer_type_tests(Matrix<signed char, 2, Dynamic>(2, 10)));

    CALL_SUBTEST_4(integer_type_tests(Matrix<unsigned char, 3, 3>()));
    CALL_SUBTEST_4(integer_type_tests(Matrix<unsigned char, Dynamic, Dynamic>(20, 20)));

    CALL_SUBTEST_5(integer_type_tests(Matrix<short, Dynamic, 4>(7, 4)));
    CALL_SUBTEST_5(signed_integer_type_tests(Matrix<short, Dynamic, 4>(7, 4)));

    CALL_SUBTEST_6(integer_type_tests(Matrix<unsigned short, 4, 4>()));

    CALL_SUBTEST_7(integer_type_tests(Matrix<long long, 11, 13>()));
    CALL_SUBTEST_7(signed_integer_type_tests(Matrix<long long, 11, 13>()));

    CALL_SUBTEST_8(integer_type_tests(Matrix<unsigned long long, Dynamic, 5>(1, 5)));
  }
  CALL_SUBTEST_9(integer_types_extra<0>());
}
