// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2009 Ricard Marxer <email@ricardmarxer.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"
#include <iostream>

using namespace std;

template <typename MatrixType>
void reverse(const MatrixType& m) {
  typedef typename MatrixType::Scalar Scalar;
  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 = MatrixType::Random(rows, cols), m2;
  VectorType v1 = VectorType::Random(rows);

  MatrixType m1_r = m1.reverse();
  // Verify that MatrixBase::reverse() works
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
      VERIFY_IS_APPROX(m1_r(i, j), m1(rows - 1 - i, cols - 1 - j));
    }
  }

  Reverse<MatrixType> m1_rd(m1);
  // Verify that a Reverse default (in both directions) of an expression works
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
      VERIFY_IS_APPROX(m1_rd(i, j), m1(rows - 1 - i, cols - 1 - j));
    }
  }

  Reverse<MatrixType, BothDirections> m1_rb(m1);
  // Verify that a Reverse in both directions of an expression works
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
      VERIFY_IS_APPROX(m1_rb(i, j), m1(rows - 1 - i, cols - 1 - j));
    }
  }

  Reverse<MatrixType, Vertical> m1_rv(m1);
  // Verify that a Reverse in the vertical directions of an expression works
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
      VERIFY_IS_APPROX(m1_rv(i, j), m1(rows - 1 - i, j));
    }
  }

  Reverse<MatrixType, Horizontal> m1_rh(m1);
  // Verify that a Reverse in the horizontal directions of an expression works
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
      VERIFY_IS_APPROX(m1_rh(i, j), m1(i, cols - 1 - j));
    }
  }

  VectorType v1_r = v1.reverse();
  // Verify that a VectorType::reverse() of an expression works
  for (int i = 0; i < rows; i++) {
    VERIFY_IS_APPROX(v1_r(i), v1(rows - 1 - i));
  }

  MatrixType m1_cr = m1.colwise().reverse();
  // Verify that PartialRedux::reverse() works (for colwise())
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
      VERIFY_IS_APPROX(m1_cr(i, j), m1(rows - 1 - i, j));
    }
  }

  MatrixType m1_rr = m1.rowwise().reverse();
  // Verify that PartialRedux::reverse() works (for rowwise())
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
      VERIFY_IS_APPROX(m1_rr(i, j), m1(i, cols - 1 - j));
    }
  }

  Scalar x = internal::random<Scalar>();

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

  m1.reverse()(r, c) = x;
  VERIFY_IS_APPROX(x, m1(rows - 1 - r, cols - 1 - c));

  m2 = m1;
  m2.reverseInPlace();
  VERIFY_IS_APPROX(m2, m1.reverse().eval());

  m2 = m1;
  m2.col(0).reverseInPlace();
  VERIFY_IS_APPROX(m2.col(0), m1.col(0).reverse().eval());

  m2 = m1;
  m2.row(0).reverseInPlace();
  VERIFY_IS_APPROX(m2.row(0), m1.row(0).reverse().eval());

  m2 = m1;
  m2.rowwise().reverseInPlace();
  VERIFY_IS_APPROX(m2, m1.rowwise().reverse().eval());

  m2 = m1;
  m2.colwise().reverseInPlace();
  VERIFY_IS_APPROX(m2, m1.colwise().reverse().eval());

  m1.colwise().reverse()(r, c) = x;
  VERIFY_IS_APPROX(x, m1(rows - 1 - r, c));

  m1.rowwise().reverse()(r, c) = x;
  VERIFY_IS_APPROX(x, m1(r, cols - 1 - c));
}

template <int>
void array_reverse_extra() {
  Vector4f x;
  x << 1, 2, 3, 4;
  Vector4f y;
  y << 4, 3, 2, 1;
  VERIFY(x.reverse()[1] == 3);
  VERIFY(x.reverse() == y);
}

// Simpler version of reverseInPlace leveraging a bug
// in clang 6/7 with -O2 and AVX or AVX512 enabled.
// This simpler version ensure that the clang bug is not simply hidden
// through mis-inlining of reverseInPlace or other minor changes.
template <typename MatrixType>
EIGEN_DONT_INLINE void bug1684_job1(MatrixType& m1, MatrixType& m2) {
  m2 = m1;
  m2.col(0).swap(m2.col(3));
  m2.col(1).swap(m2.col(2));
}

template <typename MatrixType>
EIGEN_DONT_INLINE void bug1684_job2(MatrixType& m1, MatrixType& m2) {
  m2 = m1;                // load m1/m2 in AVX registers
  m1.col(0) = m2.col(3);  // perform 128 bits moves
  m1.col(1) = m2.col(2);
  m1.col(2) = m2.col(1);
  m1.col(3) = m2.col(0);
}

template <typename MatrixType>
EIGEN_DONT_INLINE void bug1684_job3(MatrixType& m1, MatrixType& m2) {
  m2 = m1;
  Vector4f tmp;
  tmp = m2.col(0);
  m2.col(0) = m2.col(3);
  m2.col(3) = tmp;
  tmp = m2.col(1);
  m2.col(1) = m2.col(2);
  m2.col(2) = tmp;
}

template <int>
void bug1684() {
  Matrix4f m1 = Matrix4f::Random();
  Matrix4f m2 = Matrix4f::Random();
  bug1684_job1(m1, m2);
  VERIFY_IS_APPROX(m2, m1.rowwise().reverse().eval());
  bug1684_job2(m1, m2);
  VERIFY_IS_APPROX(m2, m1.rowwise().reverse().eval());
  // This one still fail after our swap's workaround,
  // but I expect users not to implement their own swap.
  // bug1684_job3(m1,m2);
  // VERIFY_IS_APPROX(m2, m1.rowwise().reverse().eval());
}

// Test reverseInPlace at vectorization boundary sizes.
// Vectorized swap used by reverseInPlace has remainder handling
// that could fail at packet boundaries.
template <typename Scalar>
void reverseInPlace_boundary() {
  const Index PS = internal::packet_traits<Scalar>::size;
  const Index sizes[] = {1,      2,          3,      PS - 1,     PS,     PS + 1,    2 * PS - 1,
                         2 * PS, 2 * PS + 1, 4 * PS, 4 * PS + 1, 8 * PS, 8 * PS + 1};
  for (int si = 0; si < 13; ++si) {
    Index n = sizes[si];
    if (n <= 0) continue;
    typedef Matrix<Scalar, Dynamic, 1> Vec;
    typedef Matrix<Scalar, Dynamic, Dynamic> Mat;

    // Vector reverseInPlace
    Vec v1 = Vec::Random(n);
    Vec v2 = v1;
    v2.reverseInPlace();
    for (Index k = 0; k < n; ++k) VERIFY_IS_APPROX(v2(k), v1(n - 1 - k));

    // Matrix reverseInPlace (full)
    Mat m1 = Mat::Random(n, n);
    Mat m2 = m1;
    m2.reverseInPlace();
    for (Index j = 0; j < n; ++j)
      for (Index i = 0; i < n; ++i) VERIFY_IS_APPROX(m2(i, j), m1(n - 1 - i, n - 1 - j));

    // colwise reverseInPlace
    m2 = m1;
    m2.colwise().reverseInPlace();
    for (Index j = 0; j < n; ++j)
      for (Index i = 0; i < n; ++i) VERIFY_IS_APPROX(m2(i, j), m1(n - 1 - i, j));

    // rowwise reverseInPlace
    m2 = m1;
    m2.rowwise().reverseInPlace();
    for (Index j = 0; j < n; ++j)
      for (Index i = 0; i < n; ++i) VERIFY_IS_APPROX(m2(i, j), m1(i, n - 1 - j));
  }
}

EIGEN_DECLARE_TEST(array_reverse) {
  for (int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_1(reverse(Matrix<float, 1, 1>()));
    CALL_SUBTEST_2(reverse(Matrix2f()));
    CALL_SUBTEST_3(reverse(Matrix4f()));
    CALL_SUBTEST_4(reverse(Matrix4d()));
    CALL_SUBTEST_5(reverse(
        MatrixXcf(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_6(reverse(
        MatrixXi(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_7(reverse(
        MatrixXcd(internal::random<int>(1, EIGEN_TEST_MAX_SIZE), internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_8(reverse(Matrix<float, 100, 100>()));
    CALL_SUBTEST_9(reverse(Matrix<float, Dynamic, Dynamic, RowMajor>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE),
                                                                     internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_3(bug1684<0>());
  }
  CALL_SUBTEST_3(array_reverse_extra<0>());

  // reverseInPlace at vectorization boundaries (deterministic, outside g_repeat).
  CALL_SUBTEST_10(reverseInPlace_boundary<float>());
  CALL_SUBTEST_10(reverseInPlace_boundary<double>());
  CALL_SUBTEST_10(reverseInPlace_boundary<int>());
}
