Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <blaze/math/traits/MultTrait.h> 7 : 8 : #include "Utilities/Gsl.hpp" 9 : 10 : /// @{ 11 : /// \ingroup UtilitiesGroup 12 : /// \brief Computes the outer product between two vectors. 13 : /// \details For vectors \f$A\f$ and \f$B\f$, the resulting outer product is 14 : /// \f$\{A_1 B_1,\, A_2 B_1\, \dots\, A_N B_1,\, A_1 B_2\, \dots\, A_N B_M\}\f$. 15 : /// This is useful for generating separable volume data from its constituent 16 : /// inputs. 17 : template <typename LhsVectorType, typename RhsVectorType, 18 : typename ResultVectorType = 19 : typename blaze::MultTrait<LhsVectorType, RhsVectorType>::Type> 20 1 : void outer_product(const gsl::not_null<ResultVectorType*> result, 21 : const LhsVectorType& lhs, const RhsVectorType& rhs) { 22 : result->destructive_resize(lhs.size() * rhs.size()); 23 : for (size_t i = 0; i < rhs.size(); ++i) { 24 : ResultVectorType view{result->data() + i * lhs.size(), lhs.size()}; 25 : view = rhs[i] * lhs; 26 : } 27 : } 28 : 29 : template <typename LhsVectorType, typename RhsVectorType, 30 : typename ResultVectorType = 31 : typename blaze::MultTrait<LhsVectorType, RhsVectorType>::Type> 32 1 : ResultVectorType outer_product(const LhsVectorType& lhs, 33 : const RhsVectorType& rhs) { 34 : auto result = ResultVectorType{lhs.size() * rhs.size()}; 35 : outer_product(make_not_null(&result), lhs, rhs); 36 : return result; 37 : } 38 : /// @} 39 : 40 : /// @{ 41 : /// \ingroup UtilitiesGroup 42 : /// \brief Creates or fills a vector with data from `to_repeat` copied 43 : /// `times_to_repeat` times in sequence. 44 : /// 45 : /// \details This can be useful for generating data that consists of the same 46 : /// block of values duplicated a number of times. For instance, this can be used 47 : /// to create a vector representing three-dimensional volume data from a 48 : /// corresponding two-dimensional vector data, if the two-dimensional data 49 : /// corresponds to the two fastest-varying directions of the desired 50 : /// three-dimensional representation. The result would then be uniform in the 51 : /// slowest-varying direction of the three dimensional grid. 52 : template <typename VectorType> 53 1 : void fill_with_n_copies( 54 : // NOLINTNEXTLINE(readability-avoid-const-params-in-decls) 55 : const gsl::not_null<VectorType*> result, const VectorType& to_copy, 56 : // NOLINTNEXTLINE(readability-avoid-const-params-in-decls) 57 : const size_t times_to_copy) { 58 : result->destructive_resize(to_copy.size() * times_to_copy); 59 : for (size_t i = 0; i < times_to_copy; ++i) { 60 : VectorType view{result->data() + i * to_copy.size(), to_copy.size()}; 61 : view = to_copy; 62 : } 63 : } 64 : 65 : // clang-tidy incorrectly believes this to be a forward-declaration 66 : template <typename VectorType> 67 1 : VectorType create_vector_of_n_copies(const VectorType& to_copy, 68 : const size_t times_to_copy) { // NOLINT 69 : auto result = VectorType{to_copy.size() * times_to_copy}; 70 : fill_with_n_copies(make_not_null(&result), to_copy, times_to_copy); 71 : return result; 72 : } 73 : /// @}