// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2009 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>
void array_for_matrix(const MatrixType& m) {
  typedef typename MatrixType::Scalar Scalar;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;
  typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;

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

  MatrixType m1 = MatrixType::Random(rows, cols), m2 = MatrixType::Random(rows, cols), m3(rows, cols);
  ColVectorType cv1 = ColVectorType::Random(rows);
  RowVectorType rv1 = RowVectorType::Random(cols);

  Scalar s1 = internal::random<Scalar>(), s2 = internal::random<Scalar>();

  // Prevent overflows for integer types.
  if (Eigen::NumTraits<Scalar>::IsInteger) {
    Scalar kMaxVal = Scalar(10000);
    m1.array() = m1.array() - kMaxVal * (m1.array() / kMaxVal);
    m2.array() = m2.array() - kMaxVal * (m2.array() / kMaxVal);
  }

  // scalar addition
  VERIFY_IS_APPROX(m1.array() + s1, s1 + m1.array());
  VERIFY_IS_APPROX((m1.array() + s1).matrix(), MatrixType::Constant(rows, cols, s1) + m1);
  VERIFY_IS_APPROX(((m1 * Scalar(2)).array() - s2).matrix(), (m1 + m1) - MatrixType::Constant(rows, cols, s2));
  m3 = m1;
  m3.array() += s2;
  VERIFY_IS_APPROX(m3, (m1.array() + s2).matrix());
  m3 = m1;
  m3.array() -= s1;
  VERIFY_IS_APPROX(m3, (m1.array() - s1).matrix());

  // reductions
  VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum().sum() - m1.sum(), m1.squaredNorm());
  VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum().sum() - m1.sum(), m1.squaredNorm());
  VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum() + m2.colwise().sum() - (m1 + m2).colwise().sum(),
                              (m1 + m2).squaredNorm());
  VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum() - m2.rowwise().sum() - (m1 - m2).rowwise().sum(),
                              (m1 - m2).squaredNorm());
  VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(internal::scalar_sum_op<Scalar, Scalar>()));

  // vector-wise ops
  m3 = m1;
  VERIFY_IS_APPROX(m3.colwise() += cv1, m1.colwise() + cv1);
  m3 = m1;
  VERIFY_IS_APPROX(m3.colwise() -= cv1, m1.colwise() - cv1);
  m3 = m1;
  VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1);
  m3 = m1;
  VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1);

  // empty objects
  VERIFY_IS_EQUAL((m1.template block<0, Dynamic>(0, 0, 0, cols).colwise().sum()), RowVectorType::Zero(cols));
  VERIFY_IS_EQUAL((m1.template block<Dynamic, 0>(0, 0, rows, 0).rowwise().sum()), ColVectorType::Zero(rows));
  VERIFY_IS_EQUAL((m1.template block<0, Dynamic>(0, 0, 0, cols).colwise().prod()), RowVectorType::Ones(cols));
  VERIFY_IS_EQUAL((m1.template block<Dynamic, 0>(0, 0, rows, 0).rowwise().prod()), ColVectorType::Ones(rows));

  VERIFY_IS_EQUAL(m1.block(0, 0, 0, cols).colwise().sum(), RowVectorType::Zero(cols));
  VERIFY_IS_EQUAL(m1.block(0, 0, rows, 0).rowwise().sum(), ColVectorType::Zero(rows));
  VERIFY_IS_EQUAL(m1.block(0, 0, 0, cols).colwise().prod(), RowVectorType::Ones(cols));
  VERIFY_IS_EQUAL(m1.block(0, 0, rows, 0).rowwise().prod(), ColVectorType::Ones(rows));

  // verify the const accessors exist
  const Scalar& ref_m1 = m.matrix().array().coeffRef(0);
  const Scalar& ref_m2 = m.matrix().array().coeffRef(0, 0);
  const Scalar& ref_a1 = m.array().matrix().coeffRef(0);
  const Scalar& ref_a2 = m.array().matrix().coeffRef(0, 0);
  VERIFY(&ref_a1 == &ref_m1);
  VERIFY(&ref_a2 == &ref_m2);

  // Check write accessors:
  m1.array().coeffRef(0, 0) = 1;
  VERIFY_IS_APPROX(m1(0, 0), Scalar(1));
  m1.array()(0, 0) = 2;
  VERIFY_IS_APPROX(m1(0, 0), Scalar(2));
  m1.array().matrix().coeffRef(0, 0) = 3;
  VERIFY_IS_APPROX(m1(0, 0), Scalar(3));
  m1.array().matrix()(0, 0) = 4;
  VERIFY_IS_APPROX(m1(0, 0), Scalar(4));
}

template <typename MatrixType>
void comparisons(const MatrixType& m) {
  using std::abs;
  typedef typename MatrixType::Scalar Scalar;
  typedef typename NumTraits<Scalar>::Real RealScalar;

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

  Index r = internal::random<Index>(0, rows - 1), c = internal::random<Index>(0, cols - 1);

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

  VERIFY(((m1.array() + Scalar(1)) > m1.array()).all());
  VERIFY(((m1.array() - Scalar(1)) < m1.array()).all());
  if (rows * cols > 1) {
    m3 = m1;
    m3(r, c) += 1;
    VERIFY(!(m1.array() < m3.array()).all());
    VERIFY(!(m1.array() > m3.array()).all());
  }

  // comparisons to scalar
  VERIFY((m1.array() != (m1(r, c) + 1)).any());
  VERIFY((m1.array() > (m1(r, c) - 1)).any());
  VERIFY((m1.array() < (m1(r, c) + 1)).any());
  VERIFY((m1.array() == m1(r, c)).any());
  VERIFY(m1.cwiseEqual(m1(r, c)).any());

  // test Select
  VERIFY_IS_APPROX((m1.array() < m2.array()).select(m1, m2), m1.cwiseMin(m2));
  VERIFY_IS_APPROX((m1.array() > m2.array()).select(m1, m2), m1.cwiseMax(m2));
  Scalar mid = (m1.cwiseAbs().minCoeff() + m1.cwiseAbs().maxCoeff()) / Scalar(2);
  for (int j = 0; j < cols; ++j)
    for (int i = 0; i < rows; ++i) m3(i, j) = abs(m1(i, j)) < mid ? 0 : m1(i, j);
  VERIFY_IS_APPROX(
      (m1.array().abs() < MatrixType::Constant(rows, cols, mid).array()).select(MatrixType::Zero(rows, cols), m1), m3);
  // shorter versions:
  VERIFY_IS_APPROX((m1.array().abs() < MatrixType::Constant(rows, cols, mid).array()).select(0, m1), m3);
  VERIFY_IS_APPROX((m1.array().abs() >= MatrixType::Constant(rows, cols, mid).array()).select(m1, 0), m3);
  // even shorter version:
  VERIFY_IS_APPROX((m1.array().abs() < mid).select(0, m1), m3);

  // count
  VERIFY(((m1.array().abs() + 1) > RealScalar(0.1)).count() == rows * cols);

  // and/or
  VERIFY(((m1.array() < RealScalar(0)).matrix() && (m1.array() > RealScalar(0)).matrix()).count() == 0);
  VERIFY(((m1.array() < RealScalar(0)).matrix() || (m1.array() >= RealScalar(0)).matrix()).count() == rows * cols);
  RealScalar a = m1.cwiseAbs().mean();
  VERIFY(((m1.array() < -a).matrix() || (m1.array() > a).matrix()).count() == (m1.cwiseAbs().array() > a).count());

  typedef Matrix<Index, Dynamic, 1> VectorOfIndices;

  // TODO allows colwise/rowwise for array
  VERIFY_IS_APPROX(((m1.array().abs() + 1) > RealScalar(0.1)).matrix().colwise().count(),
                   VectorOfIndices::Constant(cols, rows).transpose());
  VERIFY_IS_APPROX(((m1.array().abs() + 1) > RealScalar(0.1)).matrix().rowwise().count(),
                   VectorOfIndices::Constant(rows, cols));
}

template <typename VectorType>
void lpNorm(const VectorType& v) {
  using std::sqrt;
  typedef typename VectorType::RealScalar RealScalar;
  VectorType u = VectorType::Random(v.size());

  if (v.size() == 0) {
    VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), RealScalar(0));
    VERIFY_IS_APPROX(u.template lpNorm<1>(), RealScalar(0));
    VERIFY_IS_APPROX(u.template lpNorm<2>(), RealScalar(0));
    VERIFY_IS_APPROX(u.template lpNorm<5>(), RealScalar(0));
  } else {
    VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), u.cwiseAbs().maxCoeff());
  }

  VERIFY_IS_APPROX(u.template lpNorm<1>(), u.cwiseAbs().sum());
  VERIFY_IS_APPROX(u.template lpNorm<2>(), sqrt(u.array().abs().square().sum()));
  VERIFY_IS_APPROX(numext::pow(u.template lpNorm<5>(), typename VectorType::RealScalar(5)),
                   u.array().abs().pow(5).sum());
}

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

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

  MatrixType m1 = MatrixType::Random(rows, cols);

  // min/max with array
  Scalar maxM1 = m1.maxCoeff();
  Scalar minM1 = m1.minCoeff();

  VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, minM1), m1.cwiseMin(MatrixType::Constant(rows, cols, minM1)));
  VERIFY_IS_APPROX(m1, m1.cwiseMin(MatrixType::Constant(rows, cols, maxM1)));

  VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, maxM1), m1.cwiseMax(MatrixType::Constant(rows, cols, maxM1)));
  VERIFY_IS_APPROX(m1, m1.cwiseMax(MatrixType::Constant(rows, cols, minM1)));

  // min/max with scalar input
  VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, minM1), m1.cwiseMin(minM1));
  VERIFY_IS_APPROX(m1, m1.cwiseMin(maxM1));
  VERIFY_IS_APPROX(-m1, (-m1).cwiseMin(-minM1));
  VERIFY_IS_APPROX(-m1.array(), ((-m1).array().min)(-minM1));

  VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, maxM1), m1.cwiseMax(maxM1));
  VERIFY_IS_APPROX(m1, m1.cwiseMax(minM1));
  VERIFY_IS_APPROX(-m1, (-m1).cwiseMax(-maxM1));
  VERIFY_IS_APPROX(-m1.array(), ((-m1).array().max)(-maxM1));

  VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, minM1).array(), (m1.array().min)(minM1));
  VERIFY_IS_APPROX(m1.array(), (m1.array().min)(maxM1));

  VERIFY_IS_APPROX(MatrixType::Constant(rows, cols, maxM1).array(), (m1.array().max)(maxM1));
  VERIFY_IS_APPROX(m1.array(), (m1.array().max)(minM1));

  // Test NaN propagation for min/max.
  if (!NumTraits<Scalar>::IsInteger) {
    m1(0, 0) = NumTraits<Scalar>::quiet_NaN();
    // Elementwise.
    VERIFY((numext::isnan)(m1.template cwiseMax<PropagateNaN>(MatrixType::Constant(rows, cols, Scalar(1)))(0, 0)));
    VERIFY((numext::isnan)(m1.template cwiseMin<PropagateNaN>(MatrixType::Constant(rows, cols, Scalar(1)))(0, 0)));
    VERIFY(!(numext::isnan)(m1.template cwiseMax<PropagateNumbers>(MatrixType::Constant(rows, cols, Scalar(1)))(0, 0)));
    VERIFY(!(numext::isnan)(m1.template cwiseMin<PropagateNumbers>(MatrixType::Constant(rows, cols, Scalar(1)))(0, 0)));
    VERIFY((numext::isnan)(m1.template cwiseMax<PropagateNaN>(Scalar(1))(0, 0)));
    VERIFY((numext::isnan)(m1.template cwiseMin<PropagateNaN>(Scalar(1))(0, 0)));
    VERIFY(!(numext::isnan)(m1.template cwiseMax<PropagateNumbers>(Scalar(1))(0, 0)));
    VERIFY(!(numext::isnan)(m1.template cwiseMin<PropagateNumbers>(Scalar(1))(0, 0)));

    VERIFY((numext::isnan)(
        m1.array().template max<PropagateNaN>(MatrixType::Constant(rows, cols, Scalar(1)).array())(0, 0)));
    VERIFY((numext::isnan)(
        m1.array().template min<PropagateNaN>(MatrixType::Constant(rows, cols, Scalar(1)).array())(0, 0)));
    VERIFY(!(numext::isnan)(
        m1.array().template max<PropagateNumbers>(MatrixType::Constant(rows, cols, Scalar(1)).array())(0, 0)));
    VERIFY(!(numext::isnan)(
        m1.array().template min<PropagateNumbers>(MatrixType::Constant(rows, cols, Scalar(1)).array())(0, 0)));
    VERIFY((numext::isnan)(m1.array().template max<PropagateNaN>(Scalar(1))(0, 0)));
    VERIFY((numext::isnan)(m1.array().template min<PropagateNaN>(Scalar(1))(0, 0)));
    VERIFY(!(numext::isnan)(m1.array().template max<PropagateNumbers>(Scalar(1))(0, 0)));
    VERIFY(!(numext::isnan)(m1.array().template min<PropagateNumbers>(Scalar(1))(0, 0)));

    // Reductions.
    VERIFY((numext::isnan)(m1.template maxCoeff<PropagateNaN>()));
    VERIFY((numext::isnan)(m1.template minCoeff<PropagateNaN>()));
    if (m1.size() > 1) {
      VERIFY(!(numext::isnan)(m1.template maxCoeff<PropagateNumbers>()));
      VERIFY(!(numext::isnan)(m1.template minCoeff<PropagateNumbers>()));
    } else {
      VERIFY((numext::isnan)(m1.template maxCoeff<PropagateNumbers>()));
      VERIFY((numext::isnan)(m1.template minCoeff<PropagateNumbers>()));
    }
  }
}

template <typename MatrixTraits>
void resize(const MatrixTraits& t) {
  typedef typename MatrixTraits::Scalar Scalar;
  typedef Matrix<Scalar, Dynamic, Dynamic> MatrixType;
  typedef Array<Scalar, Dynamic, Dynamic> Array2DType;
  typedef Matrix<Scalar, Dynamic, 1> VectorType;
  typedef Array<Scalar, Dynamic, 1> Array1DType;

  Index rows = t.rows(), cols = t.cols();

  MatrixType m(rows, cols);
  VectorType v(rows);
  Array2DType a2(rows, cols);
  Array1DType a1(rows);

  m.array().resize(rows + 1, cols + 1);
  VERIFY(m.rows() == rows + 1 && m.cols() == cols + 1);
  a2.matrix().resize(rows + 1, cols + 1);
  VERIFY(a2.rows() == rows + 1 && a2.cols() == cols + 1);
  v.array().resize(cols);
  VERIFY(v.size() == cols);
  a1.matrix().resize(cols);
  VERIFY(a1.size() == cols);
}

template <int>
void regression_bug_654() {
  ArrayXf a = RowVectorXf(3);
  VectorXf v = Array<float, 1, Dynamic>(3);
}

// Check propagation of LvalueBit through Array/Matrix-Wrapper
template <int>
void regrrssion_bug_1410() {
  const Matrix4i M;
  const Array4i A;
  ArrayWrapper<const Matrix4i> MA = M.array();
  MA.row(0);
  MatrixWrapper<const Array4i> AM = A.matrix();
  AM.row(0);

  VERIFY((internal::traits<ArrayWrapper<const Matrix4i> >::Flags & LvalueBit) == 0);
  VERIFY((internal::traits<MatrixWrapper<const Array4i> >::Flags & LvalueBit) == 0);

  VERIFY((internal::traits<ArrayWrapper<Matrix4i> >::Flags & LvalueBit) == LvalueBit);
  VERIFY((internal::traits<MatrixWrapper<Array4i> >::Flags & LvalueBit) == LvalueBit);
}

EIGEN_DECLARE_TEST(array_for_matrix) {
  for (int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1(array_for_matrix(Matrix<float, 1, 1>()));
    CALL_SUBTEST_2(array_for_matrix(Matrix2f()));
    CALL_SUBTEST_3(array_for_matrix(Matrix4d()));
    CALL_SUBTEST_4(array_for_matrix(
        MatrixXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_5(array_for_matrix(
        MatrixXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_6(array_for_matrix(
        MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
  }
  for (int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1(comparisons(Matrix<float, 1, 1>()));
    CALL_SUBTEST_2(comparisons(Matrix2f()));
    CALL_SUBTEST_3(comparisons(Matrix4d()));
    CALL_SUBTEST_5(comparisons(
        MatrixXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_6(comparisons(
        MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
  }
  for (int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1(cwise_min_max(Matrix<float, 1, 1>()));
    CALL_SUBTEST_2(cwise_min_max(Matrix2f()));
    CALL_SUBTEST_3(cwise_min_max(Matrix4d()));
    CALL_SUBTEST_5(cwise_min_max(
        MatrixXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_6(cwise_min_max(
        MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
  }
  for (int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1(lpNorm(Matrix<float, 1, 1>()));
    CALL_SUBTEST_2(lpNorm(Vector2f()));
    CALL_SUBTEST_7(lpNorm(Vector3d()));
    CALL_SUBTEST_8(lpNorm(Vector4f()));
    CALL_SUBTEST_5(lpNorm(VectorXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_4(lpNorm(VectorXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
  }
  CALL_SUBTEST_5(lpNorm(VectorXf(0)));
  CALL_SUBTEST_4(lpNorm(VectorXcf(0)));
  for (int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_4(resize(
        MatrixXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_5(
        resize(MatrixXf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_6(
        resize(MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
  }
  CALL_SUBTEST_6(regression_bug_654<0>());
  CALL_SUBTEST_6(regrrssion_bug_1410<0>());
}
