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/GroupTag.h>
7 :
8 : #include "DataStructures/VectorImpl.hpp"
9 : #include "Utilities/TMPL.hpp"
10 :
11 : /// \cond
12 : class ModalVector;
13 : class ComplexModalVector;
14 : /// \endcond
15 :
16 : namespace blaze {
17 0 : DECLARE_GENERAL_VECTOR_BLAZE_TRAITS(ComplexModalVector);
18 : } // namespace blaze
19 :
20 : /*!
21 : * \ingroup DataStructuresGroup
22 : * \brief A class for storing complex spectral coefficients on a spectral grid.
23 : *
24 : * \details A ComplexModalVector holds an array of spectral coefficients
25 : * represented as `std::complex<double>`s, and can be either owning (the array
26 : * is deleted when the ComplexModalVector goes out of scope) or non-owning,
27 : * meaning it just has a pointer to an array.
28 : *
29 : * Only basic mathematical operations are supported with
30 : * `ComplexModalVector`s. `ComplexModalVector`s may be added or subtracted and
31 : * may be added or subtracted with `ModalVector`s, and the following unary
32 : * operations are supported:
33 : * - conj
34 : * - imag (which returns a `ModalVector`)
35 : * - real (which returns a `ModalVector`)
36 : *
37 : * Also multiplication is supported with `std::complex<double>`s or doubles and
38 : * `ComplexModalVector`s, and `ComplexModalVector`s can be divided by
39 : * `std::complex<double>`s or `double`s. Multiplication is supported with
40 : * `ComplexDiagonalModalOperator`s and `ComplexModalVector`s.
41 : */
42 1 : class ComplexModalVector
43 : : public VectorImpl<std::complex<double>, ComplexModalVector> {
44 : public:
45 0 : ComplexModalVector() = default;
46 0 : ComplexModalVector(const ComplexModalVector&) = default;
47 0 : ComplexModalVector(ComplexModalVector&&) = default;
48 0 : ComplexModalVector& operator=(const ComplexModalVector&) = default;
49 0 : ComplexModalVector& operator=(ComplexModalVector&&) = default;
50 0 : ~ComplexModalVector() = default;
51 :
52 0 : using BaseType = VectorImpl<std::complex<double>, ComplexModalVector>;
53 :
54 : using BaseType::operator=;
55 : using BaseType::VectorImpl;
56 : };
57 :
58 : namespace blaze {
59 : template <>
60 0 : struct TransposeFlag<ComplexModalVector>
61 : : BoolConstant<ComplexModalVector::transpose_flag> {};
62 : template <>
63 0 : struct AddTrait<ComplexModalVector, ComplexModalVector> {
64 0 : using Type = ComplexModalVector;
65 : };
66 0 : BLAZE_TRAIT_SPECIALIZE_COMPATIBLE_BINARY_TRAIT(ComplexModalVector, ModalVector,
67 : AddTrait, ComplexModalVector);
68 : template <>
69 0 : struct SubTrait<ComplexModalVector, ComplexModalVector> {
70 0 : using Type = ComplexModalVector;
71 : };
72 0 : BLAZE_TRAIT_SPECIALIZE_COMPATIBLE_BINARY_TRAIT(ComplexModalVector, ModalVector,
73 : SubTrait, ComplexModalVector);
74 0 : BLAZE_TRAIT_SPECIALIZE_COMPATIBLE_BINARY_TRAIT(ComplexModalVector,
75 : std::complex<double>, MultTrait,
76 : ComplexModalVector);
77 0 : BLAZE_TRAIT_SPECIALIZE_COMPATIBLE_BINARY_TRAIT(ModalVector,
78 : std::complex<double>, MultTrait,
79 : ComplexModalVector);
80 0 : BLAZE_TRAIT_SPECIALIZE_COMPATIBLE_BINARY_TRAIT(ComplexModalVector, double,
81 : MultTrait, ComplexModalVector);
82 : template <>
83 : struct DivTrait<ComplexModalVector, std::complex<double>> {
84 : using Type = ComplexModalVector;
85 : };
86 : template <>
87 0 : struct DivTrait<ComplexModalVector, double> {
88 0 : using Type = ComplexModalVector;
89 : };
90 :
91 : template <typename Operator>
92 0 : struct MapTrait<ComplexModalVector, Operator> {
93 : // Selectively allow unary operations for spectral coefficients
94 : static_assert(tmpl::list_contains_v<
95 : tmpl::list<blaze::Conj,
96 : // Following 3 reqd. by operator(+,+=), (-,-=),
97 : // (-) w/doubles
98 : blaze::Bind1st<blaze::Add, std::complex<double>>,
99 : blaze::Bind2nd<blaze::Add, std::complex<double>>,
100 : blaze::Bind1st<blaze::Sub, std::complex<double>>,
101 : blaze::Bind2nd<blaze::Sub, std::complex<double>>,
102 : blaze::Bind1st<blaze::Add, double>,
103 : blaze::Bind2nd<blaze::Add, double>,
104 : blaze::Bind1st<blaze::Sub, double>,
105 : blaze::Bind2nd<blaze::Sub, double>>,
106 : Operator>,
107 : "Only unary operations permitted on a ComplexModalVector are:"
108 : " conj, imag, and real");
109 0 : using Type = ComplexModalVector;
110 : };
111 : template <>
112 0 : struct MapTrait<ComplexModalVector, blaze::Imag> {
113 0 : using Type = ModalVector;
114 : };
115 : template <>
116 0 : struct MapTrait<ComplexModalVector, blaze::Real> {
117 0 : using Type = ModalVector;
118 : };
119 : template <>
120 0 : struct MapTrait<ModalVector, blaze::Imag> {
121 0 : using Type = ModalVector;
122 : };
123 : template <>
124 0 : struct MapTrait<ModalVector, blaze::Real> {
125 0 : using Type = ModalVector;
126 : };
127 :
128 : template <typename Operator>
129 0 : struct MapTrait<ComplexModalVector, ComplexModalVector, Operator> {
130 : // Forbid math operations in this specialization of BinaryMap traits for
131 : // ComplexModalVector that are unlikely to be used on spectral coefficients.
132 : // Currently no non-arithmetic binary operations are supported.
133 : static_assert(
134 : tmpl::list_contains_v<tmpl::list<>, Operator>,
135 : "This binary operation is not permitted on a ComplexModalVector.");
136 0 : using Type = ComplexModalVector;
137 : };
138 : } // namespace blaze
139 :
140 : /// \cond
141 : DEFINE_STD_ARRAY_BINOP(ComplexModalVector, ComplexModalVector,
142 : ComplexModalVector, operator+, std::plus<>())
143 : DEFINE_STD_ARRAY_BINOP(ComplexModalVector, ComplexModalVector,
144 : ComplexModalVector, operator-, std::minus<>())
145 : DEFINE_STD_ARRAY_INPLACE_BINOP(ComplexModalVector,
146 : ComplexModalVector, operator+=, std::plus<>())
147 : DEFINE_STD_ARRAY_INPLACE_BINOP(ComplexModalVector,
148 : ComplexModalVector, operator-=, std::minus<>())
149 :
150 : namespace blaze {
151 : // Partial specialization to disable being able to take the l?Norm of a
152 : // ComplexModalVector. This does *not* prevent taking the norm of the square (or
153 : // some other math expression) of a ComplexModalVector.
154 : template <typename Abs, typename Power>
155 : struct DVecNormHelper<
156 : blaze::CustomVector<std::complex<double>, blaze::AlignmentFlag::unaligned,
157 : blaze::PaddingFlag::unpadded,
158 : blaze::defaultTransposeFlag, blaze::GroupTag<0>,
159 : ComplexModalVector>,
160 : Abs, Power> {};
161 : } // namespace blaze
162 : /// \endcond
163 : MAKE_WITH_VALUE_IMPL_DEFINITION_FOR(ComplexModalVector)
|