1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com> 5 // 6 // This Source Code Form is subject to the terms of the Mozilla 7 // Public License v. 2.0. If a copy of the MPL was not distributed 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10 #include "main.h" 11 12 #include <Eigen/CXX11/Tensor> 13 14 using Eigen::Tensor; 15 using Eigen::TensorMap; 16 17 18 19 static void test_additions() 20 { 21 Tensor<std::complex<float>, 1> data1(3); 22 Tensor<std::complex<float>, 1> data2(3); 23 for (int i = 0; i < 3; ++i) { 24 data1(i) = std::complex<float>(i, -i); 25 data2(i) = std::complex<float>(i, 7 * i); 26 } 27 28 Tensor<std::complex<float>, 1> sum = data1 + data2; 29 for (int i = 0; i < 3; ++i) { 30 VERIFY_IS_EQUAL(sum(i), std::complex<float>(2*i, 6*i)); 31 } 32 } 33 34 35 static void test_abs() 36 { 37 Tensor<std::complex<float>, 1> data1(3); 38 Tensor<std::complex<double>, 1> data2(3); 39 data1.setRandom(); 40 data2.setRandom(); 41 42 Tensor<float, 1> abs1 = data1.abs(); 43 Tensor<double, 1> abs2 = data2.abs(); 44 for (int i = 0; i < 3; ++i) { 45 VERIFY_IS_APPROX(abs1(i), std::abs(data1(i))); 46 VERIFY_IS_APPROX(abs2(i), std::abs(data2(i))); 47 } 48 } 49 50 51 static void test_conjugate() 52 { 53 Tensor<std::complex<float>, 1> data1(3); 54 Tensor<std::complex<double>, 1> data2(3); 55 Tensor<int, 1> data3(3); 56 data1.setRandom(); 57 data2.setRandom(); 58 data3.setRandom(); 59 60 Tensor<std::complex<float>, 1> conj1 = data1.conjugate(); 61 Tensor<std::complex<double>, 1> conj2 = data2.conjugate(); 62 Tensor<int, 1> conj3 = data3.conjugate(); 63 for (int i = 0; i < 3; ++i) { 64 VERIFY_IS_APPROX(conj1(i), std::conj(data1(i))); 65 VERIFY_IS_APPROX(conj2(i), std::conj(data2(i))); 66 VERIFY_IS_APPROX(conj3(i), data3(i)); 67 } 68 } 69 70 static void test_contractions() 71 { 72 Tensor<std::complex<float>, 4> t_left(30, 50, 8, 31); 73 Tensor<std::complex<float>, 5> t_right(8, 31, 7, 20, 10); 74 Tensor<std::complex<float>, 5> t_result(30, 50, 7, 20, 10); 75 76 t_left.setRandom(); 77 t_right.setRandom(); 78 79 typedef Map<Matrix<std::complex<float>, Dynamic, Dynamic>> MapXcf; 80 MapXcf m_left(t_left.data(), 1500, 248); 81 MapXcf m_right(t_right.data(), 248, 1400); 82 Matrix<std::complex<float>, Dynamic, Dynamic> m_result(1500, 1400); 83 84 // This contraction should be equivalent to a regular matrix multiplication 85 typedef Tensor<float, 1>::DimensionPair DimPair; 86 Eigen::array<DimPair, 2> dims; 87 dims[0] = DimPair(2, 0); 88 dims[1] = DimPair(3, 1); 89 t_result = t_left.contract(t_right, dims); 90 m_result = m_left * m_right; 91 for (int i = 0; i < t_result.dimensions().TotalSize(); i++) { 92 VERIFY_IS_APPROX(t_result.data()[i], m_result.data()[i]); 93 } 94 } 95 96 97 void test_cxx11_tensor_of_complex() 98 { 99 CALL_SUBTEST(test_additions()); 100 CALL_SUBTEST(test_abs()); 101 CALL_SUBTEST(test_conjugate()); 102 CALL_SUBTEST(test_contractions()); 103 } 104