// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2010-2011 Jitse Niesen <jitse@maths.leeds.ac.uk>
// Copyright (C) 2016 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// 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"

template <typename MatrixType>
bool equalsIdentity(const MatrixType& A) {
  bool offDiagOK = true;
  for (Index i = 0; i < A.rows(); ++i) {
    for (Index j = i + 1; j < A.cols(); ++j) {
      offDiagOK = offDiagOK && numext::is_exactly_zero(A(i, j));
    }
  }
  for (Index i = 0; i < A.rows(); ++i) {
    for (Index j = 0; j < (std::min)(i, A.cols()); ++j) {
      offDiagOK = offDiagOK && numext::is_exactly_zero(A(i, j));
    }
  }

  bool diagOK = (A.diagonal().array() == 1).all();
  return offDiagOK && diagOK;
}

template <typename VectorType>
void check_extremity_accuracy(const VectorType& v, const typename VectorType::Scalar& low,
                              const typename VectorType::Scalar& high) {
  typedef typename VectorType::Scalar Scalar;
  typedef typename VectorType::RealScalar RealScalar;

  RealScalar prec = internal::is_same<RealScalar, float>::value ? NumTraits<RealScalar>::dummy_precision() * 10
                                                                : NumTraits<RealScalar>::dummy_precision() / 10;
  Index size = v.size();

  if (size < 20) return;

  for (int i = 0; i < size; ++i) {
    if (i < 5 || i > size - 6) {
      Scalar ref =
          (low * RealScalar(size - i - 1)) / RealScalar(size - 1) + (high * RealScalar(i)) / RealScalar(size - 1);
      if (std::abs(ref) > 1) {
        if (!internal::isApprox(v(i), ref, prec))
          std::cout << v(i) << " != " << ref << "  ; relative error: " << std::abs((v(i) - ref) / ref)
                    << "  ; required precision: " << prec << "  ; range: " << low << "," << high << "  ; i: " << i
                    << "\n";
        VERIFY(internal::isApprox(
            v(i),
            (low * RealScalar(size - i - 1)) / RealScalar(size - 1) + (high * RealScalar(i)) / RealScalar(size - 1),
            prec));
      }
    }
  }
}

template <typename VectorType>
void testVectorType(const VectorType& base) {
  typedef typename VectorType::Scalar Scalar;
  typedef typename VectorType::RealScalar RealScalar;

  const Index size = base.size();

  Scalar high = internal::random<Scalar>(-500, 500);
  Scalar low = (size == 1 ? high : internal::random<Scalar>(-500, 500));
  if (numext::real(low) > numext::real(high)) std::swap(low, high);

  // check low==high
  if (internal::random<float>(0.f, 1.f) < 0.05f) low = high;
  // check abs(low) >> abs(high)
  else if (size > 2 && std::numeric_limits<RealScalar>::max_exponent10 > 0 && internal::random<float>(0.f, 1.f) < 0.1f)
    low = -internal::random<Scalar>(1, 2) *
          RealScalar(std::pow(RealScalar(10), std::numeric_limits<RealScalar>::max_exponent10 / 2));

  const Scalar step = ((size == 1) ? 1 : (high - low) / RealScalar(size - 1));

  // check whether the result yields what we expect it to do
  VectorType m(base), o(base);
  m.setLinSpaced(size, low, high);
  o.setEqualSpaced(size, low, step);

  if (!NumTraits<Scalar>::IsInteger) {
    VectorType n(size);
    for (int i = 0; i < size; ++i) n(i) = low + RealScalar(i) * step;
    VERIFY_IS_APPROX(m, n);
    VERIFY_IS_APPROX(n, o);

    CALL_SUBTEST(check_extremity_accuracy(m, low, high));
  }

  RealScalar range_length = numext::real(high - low);
  if ((!NumTraits<Scalar>::IsInteger) || (range_length >= size && (Index(range_length) % (size - 1)) == 0) ||
      (Index(range_length + 1) < size && (size % Index(range_length + 1)) == 0)) {
    VectorType n(size);
    if ((!NumTraits<Scalar>::IsInteger) || (range_length >= size))
      for (int i = 0; i < size; ++i) n(i) = size == 1 ? low : (low + ((high - low) * Scalar(i)) / RealScalar(size - 1));
    else
      for (int i = 0; i < size; ++i)
        n(i) = size == 1 ? low : low + Scalar((double(range_length + 1) * double(i)) / double(size));
    VERIFY_IS_APPROX(m, n);

    // random access version
    m = VectorType::LinSpaced(size, low, high);
    VERIFY_IS_APPROX(m, n);
    VERIFY(internal::isApprox(m(m.size() - 1), high));
    VERIFY(size == 1 || internal::isApprox(m(0), low));
    VERIFY_IS_EQUAL(m(m.size() - 1), high);
    if (!NumTraits<Scalar>::IsInteger) CALL_SUBTEST(check_extremity_accuracy(m, low, high));
  }

  VERIFY(numext::real(m(m.size() - 1)) <= numext::real(high));
  VERIFY((m.array().real() <= numext::real(high)).all());
  VERIFY((m.array().real() >= numext::real(low)).all());

  VERIFY(numext::real(m(m.size() - 1)) >= numext::real(low));
  if (size >= 1) {
    VERIFY(internal::isApprox(m(0), low));
    VERIFY_IS_EQUAL(m(0), low);
  }

  // check whether everything works with row and col major vectors
  Matrix<Scalar, Dynamic, 1> row_vector(size);
  Matrix<Scalar, 1, Dynamic> col_vector(size);
  row_vector.setLinSpaced(size, low, high);
  col_vector.setLinSpaced(size, low, high);
  // when using the extended precision (e.g., FPU) the relative error might exceed 1 bit
  // when computing the squared sum in isApprox, thus the 2x factor.
  VERIFY(row_vector.isApprox(col_vector.transpose(), RealScalar(2) * NumTraits<Scalar>::epsilon()));

  Matrix<Scalar, Dynamic, 1> size_changer(size + 50);
  size_changer.setLinSpaced(size, low, high);
  VERIFY(size_changer.size() == size);

  typedef Matrix<Scalar, 1, 1> ScalarMatrix;
  ScalarMatrix scalar;
  scalar.setLinSpaced(1, low, high);
  VERIFY_IS_APPROX(scalar, ScalarMatrix::Constant(high));
  VERIFY_IS_APPROX(ScalarMatrix::LinSpaced(1, low, high), ScalarMatrix::Constant(high));

  // regression test for bug 526 (linear vectorized transversal)
  if (size > 1 && (!NumTraits<Scalar>::IsInteger)) {
    m.tail(size - 1).setLinSpaced(low, high);
    VERIFY_IS_APPROX(m(size - 1), high);
  }

  // regression test for bug 1383 (LinSpaced with empty size/range)
  {
    Index n0 = VectorType::SizeAtCompileTime == Dynamic ? 0 : VectorType::SizeAtCompileTime;
    low = internal::random<Scalar>();
    m = VectorType::LinSpaced(n0, low, low - RealScalar(1));
    VERIFY(m.size() == n0);

    if (VectorType::SizeAtCompileTime == Dynamic) {
      VERIFY_IS_EQUAL(VectorType::LinSpaced(n0, 0, Scalar(n0 - 1)).sum(), Scalar(0));
      VERIFY_IS_EQUAL(VectorType::LinSpaced(n0, low, low - RealScalar(1)).sum(), Scalar(0));
    }

    m.setLinSpaced(n0, 0, Scalar(n0 - 1));
    VERIFY(m.size() == n0);
    m.setLinSpaced(n0, low, low - RealScalar(1));
    VERIFY(m.size() == n0);

    // empty range only:
    VERIFY_IS_APPROX(VectorType::LinSpaced(size, low, low), VectorType::Constant(size, low));
    m.setLinSpaced(size, low, low);
    VERIFY_IS_APPROX(m, VectorType::Constant(size, low));

    if (NumTraits<Scalar>::IsInteger) {
      VERIFY_IS_APPROX(VectorType::LinSpaced(size, low, low + Scalar(size - 1)),
                       VectorType::LinSpaced(size, low + Scalar(size - 1), low).reverse());

      if (VectorType::SizeAtCompileTime == Dynamic) {
        // Check negative multiplicator path:
        for (Index k = 1; k < 5; ++k)
          VERIFY_IS_APPROX(VectorType::LinSpaced(size, low, low + Scalar((size - 1) * k)),
                           VectorType::LinSpaced(size, low + Scalar((size - 1) * k), low).reverse());
        // Check negative divisor path:
        for (Index k = 1; k < 5; ++k)
          VERIFY_IS_APPROX(VectorType::LinSpaced(size * k, low, low + Scalar(size - 1)),
                           VectorType::LinSpaced(size * k, low + Scalar(size - 1), low).reverse());
      }
    }
  }

  // test setUnit()
  if (m.size() > 0) {
    for (Index k = 0; k < 10; ++k) {
      Index i = internal::random<Index>(0, m.size() - 1);
      m.setUnit(i);
      VERIFY_IS_APPROX(m, VectorType::Unit(m.size(), i));
    }
    if (VectorType::SizeAtCompileTime == Dynamic) {
      Index i = internal::random<Index>(0, 2 * m.size() - 1);
      m.setUnit(2 * m.size(), i);
      VERIFY_IS_APPROX(m, VectorType::Unit(m.size(), i));
    }
  }
}

template <typename MatrixType>
void testMatrixType(const MatrixType& m) {
  using std::abs;
  const Index rows = m.rows();
  const Index cols = m.cols();
  typedef typename MatrixType::Scalar Scalar;
  typedef typename MatrixType::RealScalar RealScalar;

  Scalar s1;
  do {
    s1 = internal::random<Scalar>();
  } while (abs(s1) < RealScalar(1e-5) && (!NumTraits<Scalar>::IsInteger));

  MatrixType A;
  A.setIdentity(rows, cols);
  VERIFY(equalsIdentity(A));
  VERIFY(equalsIdentity(MatrixType::Identity(rows, cols)));

  A = MatrixType::Constant(rows, cols, s1);
  Index i = internal::random<Index>(0, rows - 1);
  Index j = internal::random<Index>(0, cols - 1);
  VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, s1)(i, j), s1);
  VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, s1).coeff(i, j), s1);
  VERIFY_IS_APPROX(A(i, j), s1);
}

template <int>
void bug79() {
  // Assignment of a RowVectorXd to a MatrixXd (regression test for bug #79).
  VERIFY((MatrixXd(RowVectorXd::LinSpaced(3, 0, 1)) - RowVector3d(0, 0.5, 1)).norm() <
         std::numeric_limits<double>::epsilon());
}

template <int>
void bug1630() {
  Array4d x4 = Array4d::LinSpaced(0.0, 1.0);
  Array3d x3(Array4d::LinSpaced(0.0, 1.0).head(3));
  VERIFY_IS_APPROX(x4.head(3), x3);
}

template <int>
void nullary_overflow() {
  // Check possible overflow issue
  int n = 60000;
  ArrayXi a1(n), a2(n), a_ref(n);
  a1.setLinSpaced(n, 0, n - 1);
  a2.setEqualSpaced(n, 0, 1);
  for (int i = 0; i < n; ++i) a_ref(i) = i;
  VERIFY_IS_APPROX(a1, a_ref);
  VERIFY_IS_APPROX(a2, a_ref);
}

template <int>
void nullary_internal_logic() {
  // check some internal logic
  VERIFY((internal::has_nullary_operator<internal::scalar_constant_op<double> >::value));
  VERIFY((!internal::has_unary_operator<internal::scalar_constant_op<double> >::value));
  VERIFY((!internal::has_binary_operator<internal::scalar_constant_op<double> >::value));
  VERIFY((internal::functor_has_linear_access<internal::scalar_constant_op<double> >::ret));

  VERIFY((!internal::has_nullary_operator<internal::scalar_identity_op<double> >::value));
  VERIFY((!internal::has_unary_operator<internal::scalar_identity_op<double> >::value));
  VERIFY((internal::has_binary_operator<internal::scalar_identity_op<double> >::value));
  VERIFY((!internal::functor_has_linear_access<internal::scalar_identity_op<double> >::ret));

  VERIFY((!internal::has_nullary_operator<internal::linspaced_op<float> >::value));
  VERIFY((internal::has_unary_operator<internal::linspaced_op<float> >::value));
  VERIFY((!internal::has_binary_operator<internal::linspaced_op<float> >::value));
  VERIFY((internal::functor_has_linear_access<internal::linspaced_op<float> >::ret));

  // Regression unit test for a weird MSVC bug.
  // Search "nullary_wrapper_workaround_msvc" in CoreEvaluators.h for the details.
  // See also traits<Ref>::match.
  {
    MatrixXf A = MatrixXf::Random(3, 3);
    Ref<const MatrixXf> R = 2.0 * A;
    VERIFY_IS_APPROX(R, A + A);

    Ref<const MatrixXf> R1 = MatrixXf::Random(3, 3) + A;

    VectorXi V = VectorXi::Random(3);
    Ref<const VectorXi> R2 = VectorXi::LinSpaced(3, 1, 3) + V;
    VERIFY_IS_APPROX(R2, V + Vector3i(1, 2, 3));

    VERIFY((internal::has_nullary_operator<internal::scalar_constant_op<float> >::value));
    VERIFY((!internal::has_unary_operator<internal::scalar_constant_op<float> >::value));
    VERIFY((!internal::has_binary_operator<internal::scalar_constant_op<float> >::value));
    VERIFY((internal::functor_has_linear_access<internal::scalar_constant_op<float> >::ret));

    VERIFY((!internal::has_nullary_operator<internal::linspaced_op<int> >::value));
    VERIFY((internal::has_unary_operator<internal::linspaced_op<int> >::value));
    VERIFY((!internal::has_binary_operator<internal::linspaced_op<int> >::value));
    VERIFY((internal::functor_has_linear_access<internal::linspaced_op<int> >::ret));
  }
}

EIGEN_DECLARE_TEST(nullary) {
  CALL_SUBTEST_1(testMatrixType(Matrix2d()));
  CALL_SUBTEST_2(testMatrixType(MatrixXcf(internal::random<int>(1, 300), internal::random<int>(1, 300))));
  CALL_SUBTEST_3(testMatrixType(MatrixXf(internal::random<int>(1, 300), internal::random<int>(1, 300))));

  for (int i = 0; i < g_repeat * 10; i++) {
    CALL_SUBTEST_3(testVectorType(VectorXcd(internal::random<int>(1, 30000))));
    CALL_SUBTEST_4(testVectorType(VectorXd(internal::random<int>(1, 30000))));
    CALL_SUBTEST_5(testVectorType(Vector4d()));  // regression test for bug 232
    CALL_SUBTEST_6(testVectorType(Vector3d()));
    CALL_SUBTEST_7(testVectorType(VectorXf(internal::random<int>(1, 30000))));
    CALL_SUBTEST_8(testVectorType(Vector3f()));
    CALL_SUBTEST_8(testVectorType(Vector4f()));
    CALL_SUBTEST_8(testVectorType(Matrix<float, 8, 1>()));
    CALL_SUBTEST_8(testVectorType(Matrix<float, 1, 1>()));

    CALL_SUBTEST_9(testVectorType(VectorXi(internal::random<int>(1, 10))));
    CALL_SUBTEST_9(testVectorType(VectorXi(internal::random<int>(9, 300))));
    CALL_SUBTEST_9(testVectorType(Matrix<int, 1, 1>()));
  }

  CALL_SUBTEST_6(bug79<0>());
  CALL_SUBTEST_6(bug1630<0>());
  CALL_SUBTEST_9(nullary_overflow<0>());
  CALL_SUBTEST_10(nullary_internal_logic<0>());
}
