// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.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 <Eigen/CXX11/Tensor>

using Eigen::Tensor;
using Eigen::TensorMap;



static void test_additions()
{
  Tensor<std::complex<float>, 1> data1(3);
  Tensor<std::complex<float>, 1> data2(3);
  for (int i = 0; i < 3; ++i) {
    data1(i) = std::complex<float>(i, -i);
    data2(i) = std::complex<float>(i, 7 * i);
  }

  Tensor<std::complex<float>, 1> sum = data1 + data2;
  for (int i = 0; i < 3; ++i) {
    VERIFY_IS_EQUAL(sum(i),  std::complex<float>(2*i, 6*i));
  }
}


static void test_abs()
{
  Tensor<std::complex<float>, 1> data1(3);
  Tensor<std::complex<double>, 1> data2(3);
  data1.setRandom();
  data2.setRandom();

  Tensor<float, 1> abs1 = data1.abs();
  Tensor<double, 1> abs2 = data2.abs();
  for (int i = 0; i < 3; ++i) {
    VERIFY_IS_APPROX(abs1(i), std::abs(data1(i)));
    VERIFY_IS_APPROX(abs2(i), std::abs(data2(i)));
  }
}


static void test_conjugate()
{
  Tensor<std::complex<float>, 1> data1(3);
  Tensor<std::complex<double>, 1> data2(3);
  Tensor<int, 1> data3(3);
  data1.setRandom();
  data2.setRandom();
  data3.setRandom();

  Tensor<std::complex<float>, 1> conj1 = data1.conjugate();
  Tensor<std::complex<double>, 1> conj2 = data2.conjugate();
  Tensor<int, 1> conj3 = data3.conjugate();
  for (int i = 0; i < 3; ++i) {
    VERIFY_IS_APPROX(conj1(i), std::conj(data1(i)));
    VERIFY_IS_APPROX(conj2(i), std::conj(data2(i)));
    VERIFY_IS_APPROX(conj3(i), data3(i));
  }
}

static void test_contractions()
{
  Tensor<std::complex<float>, 4> t_left(30, 50, 8, 31);
  Tensor<std::complex<float>, 5> t_right(8, 31, 7, 20, 10);
  Tensor<std::complex<float>, 5> t_result(30, 50, 7, 20, 10);

  t_left.setRandom();
  t_right.setRandom();

  typedef Map<Matrix<std::complex<float>, Dynamic, Dynamic>> MapXcf;
  MapXcf m_left(t_left.data(), 1500, 248);
  MapXcf m_right(t_right.data(), 248, 1400);
  Matrix<std::complex<float>, Dynamic, Dynamic> m_result(1500, 1400);

  // This contraction should be equivalent to a regular matrix multiplication
  typedef Tensor<float, 1>::DimensionPair DimPair;
  Eigen::array<DimPair, 2> dims;
  dims[0] = DimPair(2, 0);
  dims[1] = DimPair(3, 1);
  t_result = t_left.contract(t_right, dims);
  m_result = m_left * m_right;
  for (int i = 0; i < t_result.dimensions().TotalSize(); i++) {
    VERIFY_IS_APPROX(t_result.data()[i], m_result.data()[i]);
  }
}


EIGEN_DECLARE_TEST(cxx11_tensor_of_complex)
{
  CALL_SUBTEST(test_additions());
  CALL_SUBTEST(test_abs());
  CALL_SUBTEST(test_conjugate());
  CALL_SUBTEST(test_contractions());
}
