cart-elc

Source code for CART-ELC
git clone git://git.laack.co/cart-elc.git
Log | Files | Refs | README | LICENSE

cxx11_tensor_of_complex.cpp (2893B)


      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 EIGEN_DECLARE_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 }