// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// 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/.
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0

#define TEST_ENABLE_TEMPORARY_TRACKING

#include "main.h"
#include <Eigen/Core>
#include "NonCommutativeScalar.h"

// The scaled permutation P * D of a permutation and a diagonal matrix. Every closed-form operation below moves
// or multiplies single coefficients, so the comparisons with the dense references are exact.
template <typename Scalar, int Size>
void scaled_permutation(Index size) {
  using PermutationType = PermutationMatrix<Size>;
  using DiagonalType = DiagonalMatrix<Scalar, Size>;
  using ScaledType = ScaledPermutationMatrix<Scalar, Size>;
  using MatrixType = Matrix<Scalar, Size, Size>;
  using VectorType = Matrix<Scalar, Size, 1>;
  using RealScalar = typename NumTraits<Scalar>::Real;

  Matrix<int, Size, 1> indices, indices2;
  randomPermutationVector(indices, size);
  randomPermutationVector(indices2, size);
  const PermutationType perm(indices), perm2(indices2);
  const DiagonalType diag(VectorType::Random(size)), diag2(VectorType::Random(size));
  const MatrixType permDense = perm.toDenseMatrix().template cast<Scalar>();
  const MatrixType perm2Dense = perm2.toDenseMatrix().template cast<Scalar>();
  const MatrixType inverseDense = perm.inverse().toDenseMatrix().template cast<Scalar>();
  const MatrixType diagDense = diag.toDenseMatrix();
  const MatrixType diag2Dense = diag2.toDenseMatrix();
  const Scalar alpha = internal::random<Scalar>();

  // P * D and the three sibling products are scaled permutations, not dense expressions.
  STATIC_CHECK((internal::is_same<decltype(perm * diag), ScaledType>::value));
  STATIC_CHECK((internal::is_same<decltype(diag * perm.inverse()), ScaledType>::value));
  const ScaledType scaled = perm * diag;
  const MatrixType scaledDense = permDense * diagDense;
  VERIFY_IS_EQUAL(scaled.toDenseMatrix(), scaledDense);
  VERIFY_IS_EQUAL(MatrixType(diag * perm), MatrixType(diagDense * permDense));
  VERIFY_IS_EQUAL(MatrixType(perm.inverse() * diag), MatrixType(inverseDense * diagDense));
  VERIFY_IS_EQUAL(MatrixType(perm.transpose() * diag), MatrixType(inverseDense * diagDense));
  VERIFY_IS_EQUAL(MatrixType(diag * perm.inverse()), MatrixType(diagDense * inverseDense));
  VERIFY_IS_EQUAL(MatrixType(indices.asPermutation() * diag.diagonal().asDiagonal()), scaledDense);
  VERIFY_IS_EQUAL(MatrixType(diag * Map<PermutationType>(indices.data(), size)), MatrixType(diagDense * permDense));
  VERIFY_IS_EQUAL(MatrixType(ScaledType(perm)), permDense);
  VERIFY_IS_EQUAL(MatrixType(ScaledType(diag)), diagDense);
  for (Index i = 0; i < size; ++i)
    for (Index j = 0; j < size; ++j) VERIFY_IS_EQUAL(scaled.coeff(i, j), scaledDense(i, j));

  // Assignment to dense.
  MatrixType result = MatrixType::Random(size, size), expected = result;
  result = scaled;
  VERIFY_IS_EQUAL(result, scaledDense);
  result = expected;
  result += scaled;
  expected += scaledDense;
  VERIFY_IS_EQUAL(result, expected);
  result -= scaled;
  expected -= scaledDense;
  VERIFY_IS_EQUAL(result, expected);

  // Products of scales are complex multiplications, whose rounding depends on the kernel: compare approximately.
  // Closed-form algebra: every result is a scaled permutation and costs O(n).
  VERIFY_IS_APPROX(MatrixType(scaled * diag2), MatrixType(scaledDense * diag2Dense));
  VERIFY_IS_APPROX(MatrixType(diag2 * scaled), MatrixType(diag2Dense * scaledDense));
  VERIFY_IS_EQUAL(MatrixType(scaled * perm2), MatrixType(scaledDense * perm2Dense));
  VERIFY_IS_EQUAL(MatrixType(perm2 * scaled), MatrixType(perm2Dense * scaledDense));
  VERIFY_IS_EQUAL(MatrixType(scaled * perm2.inverse()), MatrixType(scaledDense * perm2Dense.transpose()));
  VERIFY_IS_EQUAL(MatrixType(perm2.inverse() * scaled), MatrixType(perm2Dense.transpose() * scaledDense));
  const ScaledType scaled2 = diag2 * perm2;
  VERIFY_IS_APPROX(MatrixType(scaled * scaled2), MatrixType(scaledDense * scaled2.toDenseMatrix()));
  VERIFY_IS_APPROX(MatrixType(alpha * scaled), MatrixType(alpha * scaledDense));
  VERIFY_IS_APPROX(MatrixType(scaled * alpha), MatrixType(scaledDense * alpha));
  VERIFY_IS_EQUAL(MatrixType(-scaled), MatrixType(-scaledDense));
  VERIFY_IS_EQUAL(MatrixType(scaled.transpose()), MatrixType(scaledDense.transpose()));
  VERIFY_IS_EQUAL(MatrixType(scaled.adjoint()), MatrixType(scaledDense.adjoint()));
  STATIC_CHECK((internal::is_same<decltype(perm * diag * perm.inverse()), ScaledType>::value));
  VERIFY_IS_EQUAL(MatrixType(perm * diag * perm.inverse()), MatrixType(permDense * diagDense * inverseDense));
  VERIFY_IS_APPROX(MatrixType(scaled.inverse() * scaled), MatrixType::Identity(size, size));
  VERIFY_IS_APPROX(MatrixType(scaled.inverse()), scaledDense.inverse());
  // The dense determinant underflows for large sizes; the sign of a unit-scale permutation is exact at any size.
  if (size <= 8) VERIFY_IS_APPROX(scaled.determinant(), scaledDense.determinant());
  VERIFY_IS_EQUAL(ScaledType(perm).determinant(), Scalar(RealScalar(perm.determinant())));

  // Products with dense operands scale and permute rows or columns; no n x n intermediate. Complex products round
  // differently in the dense kernels, so those comparisons are approximate.
  const MatrixType a = MatrixType::Random(size, size);
  const VectorType x = VectorType::Random(size);
  VectorType y(size);
  VERIFY_EVALUATION_COUNT(y.noalias() = scaled * x, 0);
  VERIFY_IS_APPROX(y, VectorType(scaledDense * x));
  VERIFY_EVALUATION_COUNT(result.noalias() = scaled * a, 0);
  VERIFY_IS_APPROX(result, MatrixType(scaledDense * a));
  VERIFY_EVALUATION_COUNT(result.noalias() = a * scaled, 0);
  VERIFY_IS_APPROX(result, MatrixType(a * scaledDense));
  VERIFY_IS_APPROX(VectorType(perm * diag * x), VectorType(scaledDense * x));
  VERIFY_IS_APPROX(VectorType(x.transpose() * (diag * perm)).eval(),
                   VectorType((x.transpose() * diagDense * permDense).eval()));
  result = a;
  expected = a;
  result.noalias() += scaled * a;
  expected += scaledDense * a;
  VERIFY_IS_APPROX(result, expected);
  result.noalias() -= a * scaled.inverse();
  expected -= a * scaledDense.inverse();
  VERIFY_IS_APPROX(result, expected);
  result = alpha * (scaled * a);
  VERIFY_IS_APPROX(result, alpha * scaledDense * a);
  result = a * (scaled * a);
  VERIFY_IS_APPROX(result, a * scaledDense * a);
  result = scaled * (a * a);
  VERIFY_IS_APPROX(result, scaledDense * a * a);
  // In-place: the dense permutation kernel detects the aliasing.
  result = a;
  result.noalias() = scaled * result;
  VERIFY_IS_APPROX(result, MatrixType(scaledDense * a));
  result = a;
  result = result * scaled;
  VERIFY_IS_APPROX(result, MatrixType(a * scaledDense));

  // Triangular and self-adjoint operands are densified, as toDenseMatrix() does.
  const MatrixType lower = a.template triangularView<Lower>();
  const MatrixType upperSelfadjoint = a.template selfadjointView<Upper>();
  VERIFY_IS_APPROX(MatrixType(scaled * a.template triangularView<Lower>()), MatrixType(scaledDense * lower));
  VERIFY_IS_APPROX(MatrixType(a.template triangularView<Lower>() * scaled), MatrixType(lower * scaledDense));
  VERIFY_IS_APPROX(MatrixType(scaled * a.template selfadjointView<Upper>()),
                   MatrixType(scaledDense * upperSelfadjoint));
  VERIFY_IS_APPROX(MatrixType(a.template selfadjointView<Upper>() * scaled),
                   MatrixType(upperSelfadjoint * scaledDense));

  // Lazy sums with a dense matrix.
  STATIC_CHECK(
      (internal::is_same<decltype(a + scaled), const CwiseBinaryOp<internal::scalar_sum_op<Scalar, Scalar>,
                                                                   const MatrixType, const ScaledType>>::value));
  VERIFY_IS_EQUAL(MatrixType(a + scaled), MatrixType(a + scaledDense));
  VERIFY_IS_EQUAL(MatrixType(scaled + a), MatrixType(scaledDense + a));
  VERIFY_IS_EQUAL(MatrixType(a - scaled), MatrixType(a - scaledDense));
  VERIFY_IS_EQUAL(MatrixType(scaled - a), MatrixType(scaledDense - a));
  VERIFY_IS_APPROX((a + scaled) * x, (a + scaledDense) * x);
  // The lazy sum reduces in scalar order and the dense one in packets, so the results differ by rounding of order
  // eps * sum|t|, not of order eps * |result|, which cancellation can make arbitrarily small. Measured below 2 eps.
  const RealScalar sumMagnitude = (a + scaledDense).cwiseAbs().sum();
  VERIFY(numext::abs((a + scaled).sum() - (a + scaledDense).sum()) <=
         8 * NumTraits<RealScalar>::epsilon() * sumMagnitude);

  // Storage and setters.
  ScaledType identity(size);
  identity.setIdentity();
  VERIFY_IS_EQUAL(MatrixType(identity), MatrixType::Identity(size, size));
  VERIFY_IS_EQUAL(MatrixType(identity * scaled), scaledDense);
  ScaledType copy = scaled;
  copy.scales() *= alpha;
  VERIFY_IS_APPROX(MatrixType(copy), MatrixType(alpha * scaledDense));
  copy = scaled2;
  VERIFY_IS_EQUAL(MatrixType(copy), scaled2.toDenseMatrix());
}

template <typename Real>
void scaled_permutation_mixed_scalars() {
  using Complex = std::complex<Real>;
  using Dense = Matrix<Complex, 3, 3>;
  ScaledPermutationMatrix<Real, 3> real;
  ScaledPermutationMatrix<Complex, Dynamic> complex(3);
  real.indices() << 1, 2, 0;
  real.scales() << 2, 3, 5;
  complex.indices() << 2, 0, 1;
  complex.scales() << Complex(1, 2), Complex(3, -1), Complex(-2, 4);
  const DiagonalMatrix<Real, 3> realDiagonal(real.scales());
  const DiagonalMatrix<Complex, 3> complexDiagonal(complex.scales());
  const Dense realDense = real.toDenseMatrix().template cast<Complex>();
  const Dense complexDense = complex.toDenseMatrix();
  const Dense realDiagonalDense = realDiagonal.toDenseMatrix().template cast<Complex>();
  const Dense complexDiagonalDense = complexDiagonal.toDenseMatrix();
  const auto product = real * complex;
  STATIC_CHECK((internal::is_same<typename decltype(product)::Scalar, Complex>::value));
  STATIC_CHECK(decltype(product)::RowsAtCompileTime == 3);
  VERIFY_IS_EQUAL(Dense(product), Dense(realDense * complexDense));
  VERIFY_IS_EQUAL(Dense(complex * real), Dense(complexDense * realDense));
  VERIFY_IS_EQUAL(Dense(real * complexDiagonal), Dense(realDense * complexDiagonalDense));
  VERIFY_IS_EQUAL(Dense(complexDiagonal * real), Dense(complexDiagonalDense * realDense));
  VERIFY_IS_EQUAL(Dense(complex * realDiagonal), Dense(complexDense * realDiagonalDense));
  VERIFY_IS_EQUAL(Dense(realDiagonal * complex), Dense(realDiagonalDense * complexDense));
  VERIFY_IS_EQUAL(Dense(real * complexDense), Dense(realDense * complexDense));
  VERIFY_IS_EQUAL(Dense(complexDense * real), Dense(complexDense * realDense));
  Dense accumulated = Dense::Zero();
  accumulated.noalias() += real * complexDense;
  VERIFY_IS_EQUAL(accumulated, Dense(realDense * complexDense));
  accumulated.setZero();
  accumulated.noalias() += complexDense * real;
  VERIFY_IS_EQUAL(accumulated, Dense(complexDense * realDense));
}

template <int Order>
void scaled_permutation_noncommutative() {
  using Scalar = noncommutative_scalar::Quaternion;
  using Dense = Matrix<Scalar, 3, 3, Order>;
  ScaledPermutationMatrix<Scalar, 3> scaled;
  scaled.indices() << 1, 2, 0;
  scaled.scales() << Scalar(1, 2, 0, -1), Scalar(2, -1, 3, 0), Scalar(-1, 0, 2, 1);
  Dense matrix, left, right;
  for (Index i = 0; i < 3; ++i)
    for (Index j = 0; j < 3; ++j) matrix(i, j) = Scalar(i + 1, j + 1, i - j, i + j);
  for (Index k = 0; k < 3; ++k) {
    for (Index j = 0; j < 3; ++j) left(scaled.indices()(k), j) = scaled.scales()(k) * matrix(k, j);
    for (Index i = 0; i < 3; ++i) right(i, k) = matrix(i, scaled.indices()(k)) * scaled.scales()(k);
  }
  Dense result = scaled * matrix;
  VERIFY((result.array() == left.array()).all());
  result = matrix * scaled;
  VERIFY((result.array() == right.array()).all());
  result = matrix;
  result = scaled * result;
  VERIFY((result.array() == left.array()).all());
  result = matrix;
  result = result * scaled;
  VERIFY((result.array() == right.array()).all());
  result.setZero();
  result.noalias() += scaled * matrix;
  VERIFY((result.array() == left.array()).all());
  result.setZero();
  result.noalias() += matrix * scaled;
  VERIFY((result.array() == right.array()).all());
  const Scalar alpha(1, -2, 3, 1);
  result.setZero();
  result.noalias() += alpha * (scaled * matrix);
  for (Index i = 0; i < 3; ++i)
    for (Index j = 0; j < 3; ++j) VERIFY(result(i, j) == alpha * left(i, j));
  result.setZero();
  result.noalias() -= alpha * (matrix * scaled);
  for (Index i = 0; i < 3; ++i)
    for (Index j = 0; j < 3; ++j) VERIFY(result(i, j) == -(alpha * right(i, j)));
}

EIGEN_DECLARE_TEST(scaled_permutation) {
  CALL_SUBTEST_1((scaled_permutation<float, 1>(1)));
  CALL_SUBTEST_1((scaled_permutation<double, 3>(3)));
  CALL_SUBTEST_1((scaled_permutation<std::complex<double>, 4>(4)));
  CALL_SUBTEST_4(scaled_permutation_mixed_scalars<float>());
  CALL_SUBTEST_4(scaled_permutation_mixed_scalars<double>());
  CALL_SUBTEST_5(scaled_permutation_noncommutative<ColMajor>());
  CALL_SUBTEST_5(scaled_permutation_noncommutative<RowMajor>());
  for (int i = 0; i < g_repeat; i++) {
    CALL_SUBTEST_2((scaled_permutation<float, Dynamic>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_2((scaled_permutation<double, Dynamic>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
    CALL_SUBTEST_3((scaled_permutation<std::complex<double>, Dynamic>(internal::random<int>(1, EIGEN_TEST_MAX_SIZE))));
  }
}
