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 : /// @}
|