// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>
// Copyright (C) 2015 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/.

#define TEST_ENABLE_TEMPORARY_TRACKING

#include "main.h"

template <int N, typename XprType>
void use_n_times(const XprType& xpr) {
  typename internal::nested_eval<XprType, N>::type mat(xpr);
  typename XprType::PlainObject res(mat.rows(), mat.cols());
  nb_temporaries--;  // remove res
  res.setZero();
  for (int i = 0; i < N; ++i) res += mat;
}

template <int N, typename ReferenceType, typename XprType>
bool verify_eval_type(const XprType&, const ReferenceType&) {
  typedef typename internal::nested_eval<XprType, N>::type EvalType;
  return internal::is_same<internal::remove_all_t<EvalType>, internal::remove_all_t<ReferenceType>>::value;
}

template <typename MatrixType>
void run_nesting_ops_1(const MatrixType& _m) {
  typename internal::nested_eval<MatrixType, 2>::type m(_m);

  // Make really sure that we are in debug mode!
  VERIFY_RAISES_ASSERT(eigen_assert(false));

  // The only intention of these tests is to ensure that this code does
  // not trigger any asserts or segmentation faults... more to come.
  VERIFY_IS_APPROX((m.transpose() * m).diagonal().sum(), (m.transpose() * m).diagonal().sum());
  VERIFY_IS_APPROX((m.transpose() * m).diagonal().array().abs().sum(),
                   (m.transpose() * m).diagonal().array().abs().sum());

  VERIFY_IS_APPROX((m.transpose() * m).array().abs().sum(), (m.transpose() * m).array().abs().sum());
}

template <typename MatrixType>
void run_nesting_ops_2(const MatrixType& _m) {
  typedef typename MatrixType::Scalar Scalar;
  Index rows = _m.rows();
  Index cols = _m.cols();
  MatrixType m1 = MatrixType::Random(rows, cols);
  Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime, ColMajor> m2;

  if ((MatrixType::SizeAtCompileTime == Dynamic)) {
    VERIFY_EVALUATION_COUNT(use_n_times<1>(m1 + m1 * m1), 1);
    VERIFY_EVALUATION_COUNT(use_n_times<10>(m1 + m1 * m1), 1);

    VERIFY_EVALUATION_COUNT(use_n_times<1>(m1.template triangularView<Lower>().solve(m1.col(0))), 1);
    VERIFY_EVALUATION_COUNT(use_n_times<10>(m1.template triangularView<Lower>().solve(m1.col(0))), 1);

    VERIFY_EVALUATION_COUNT(use_n_times<1>(Scalar(2) * m1.template triangularView<Lower>().solve(m1.col(0))),
                            2);  // FIXME could be one by applying the scaling in-place on the solve result
    VERIFY_EVALUATION_COUNT(use_n_times<1>(m1.col(0) + m1.template triangularView<Lower>().solve(m1.col(0))),
                            2);  // FIXME could be one by adding m1.col() inplace
    VERIFY_EVALUATION_COUNT(use_n_times<10>(m1.col(0) + m1.template triangularView<Lower>().solve(m1.col(0))), 2);
  }

  {
    VERIFY(verify_eval_type<10>(m1, m1));
    if (!NumTraits<Scalar>::IsComplex) {
      VERIFY(verify_eval_type<3>(2 * m1, 2 * m1));
      VERIFY(verify_eval_type<4>(2 * m1, m1));
    } else {
      VERIFY(verify_eval_type<2>(2 * m1, 2 * m1));
      VERIFY(verify_eval_type<3>(2 * m1, m1));
    }
    VERIFY(verify_eval_type<2>(m1 + m1, m1 + m1));
    VERIFY(verify_eval_type<3>(m1 + m1, m1));
    VERIFY(verify_eval_type<1>(m1 * m1.transpose(), m2));
    VERIFY(verify_eval_type<1>(m1 * (m1 + m1).transpose(), m2));
    VERIFY(verify_eval_type<2>(m1 * m1.transpose(), m2));
    VERIFY(verify_eval_type<1>(m1 + m1 * m1, m1));

    VERIFY(verify_eval_type<1>(m1.template triangularView<Lower>().solve(m1), m1));
    VERIFY(verify_eval_type<1>(m1 + m1.template triangularView<Lower>().solve(m1), m1));
  }
}

EIGEN_DECLARE_TEST(nesting_ops) {
  CALL_SUBTEST_1(run_nesting_ops_1(MatrixXf::Random(25, 25)));
  CALL_SUBTEST_2(run_nesting_ops_1(MatrixXcd::Random(25, 25)));
  CALL_SUBTEST_3(run_nesting_ops_1(Matrix4f::Random()));
  CALL_SUBTEST_4(run_nesting_ops_1(Matrix2d::Random()));

  Index s = internal::random<int>(1, EIGEN_TEST_MAX_SIZE);
  CALL_SUBTEST_1(run_nesting_ops_2(MatrixXf(s, s)));
  CALL_SUBTEST_2(run_nesting_ops_2(MatrixXcd(s, s)));
  CALL_SUBTEST_3(run_nesting_ops_2(Matrix4f()));
  CALL_SUBTEST_4(run_nesting_ops_2(Matrix2d()));
  TEST_SET_BUT_UNUSED_VARIABLE(s)
}
