cxx11_tensor_random.cpp (2513B)
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 template<typename Scalar> 15 static void test_default() 16 { 17 Tensor<Scalar, 1> vec(6); 18 vec.setRandom(); 19 20 // Fixme: we should check that the generated numbers follow a uniform 21 // distribution instead. 22 for (int i = 1; i < 6; ++i) { 23 VERIFY_IS_NOT_EQUAL(vec(i), vec(i-1)); 24 } 25 } 26 27 template<typename Scalar> 28 static void test_normal() 29 { 30 Tensor<Scalar, 1> vec(6); 31 vec.template setRandom<Eigen::internal::NormalRandomGenerator<Scalar>>(); 32 33 // Fixme: we should check that the generated numbers follow a gaussian 34 // distribution instead. 35 for (int i = 1; i < 6; ++i) { 36 VERIFY_IS_NOT_EQUAL(vec(i), vec(i-1)); 37 } 38 } 39 40 41 struct MyGenerator { 42 MyGenerator() { } 43 MyGenerator(const MyGenerator&) { } 44 45 // Return a random value to be used. "element_location" is the 46 // location of the entry to set in the tensor, it can typically 47 // be ignored. 48 int operator()(Eigen::DenseIndex element_location, Eigen::DenseIndex /*unused*/ = 0) const { 49 return static_cast<int>(3 * element_location); 50 } 51 52 // Same as above but generates several numbers at a time. 53 internal::packet_traits<int>::type packetOp( 54 Eigen::DenseIndex packet_location, Eigen::DenseIndex /*unused*/ = 0) const { 55 const int packetSize = internal::packet_traits<int>::size; 56 EIGEN_ALIGN_MAX int values[packetSize]; 57 for (int i = 0; i < packetSize; ++i) { 58 values[i] = static_cast<int>(3 * (packet_location + i)); 59 } 60 return internal::pload<typename internal::packet_traits<int>::type>(values); 61 } 62 }; 63 64 65 static void test_custom() 66 { 67 Tensor<int, 1> vec(6); 68 vec.setRandom<MyGenerator>(); 69 70 for (int i = 0; i < 6; ++i) { 71 VERIFY_IS_EQUAL(vec(i), 3*i); 72 } 73 } 74 75 EIGEN_DECLARE_TEST(cxx11_tensor_random) 76 { 77 CALL_SUBTEST((test_default<float>())); 78 CALL_SUBTEST((test_normal<float>())); 79 CALL_SUBTEST((test_default<double>())); 80 CALL_SUBTEST((test_normal<double>())); 81 CALL_SUBTEST((test_default<Eigen::half>())); 82 CALL_SUBTEST((test_normal<Eigen::half>())); 83 CALL_SUBTEST((test_default<Eigen::bfloat16>())); 84 CALL_SUBTEST((test_normal<Eigen::bfloat16>())); 85 CALL_SUBTEST(test_custom()); 86 }