MayaFlux 0.2.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
EigenAccess.cpp
Go to the documentation of this file.
1#include "EigenAccess.hpp"
2
3namespace MayaFlux::Kakshya {
4
5Eigen::VectorXd EigenAccess::to_vector() const
6{
7 return std::visit([this](const auto& vec) -> Eigen::VectorXd {
8 using T = typename std::decay_t<decltype(vec)>::value_type;
9
10 if constexpr (std::is_arithmetic_v<T>) {
11 return scalar_to_vector(vec);
12 } else if constexpr (std::is_same_v<T, std::complex<float>> || std::is_same_v<T, std::complex<double>>) {
13 Eigen::VectorXd result(vec.size());
14 for (Eigen::Index i = 0; i < vec.size(); ++i) {
15 result(i) = static_cast<double>(std::abs(vec[i]));
16 }
17 return result;
18 } else if constexpr (GlmType<T>) {
19 error<std::invalid_argument>(
22 std::source_location::current(),
23 "Cannot convert structured GLM type {} to vector. Use to_matrix() instead.",
24 typeid(T).name());
25 } else {
26 error<std::invalid_argument>(
29 std::source_location::current(),
30 "Unsupported type for Eigen conversion: {}",
31 typeid(T).name());
32 }
33 },
34 m_variant);
35}
36
37Eigen::MatrixXd EigenAccess::to_matrix() const
38{
39 return std::visit([this](const auto& vec) -> Eigen::MatrixXd {
40 using T = typename std::decay_t<decltype(vec)>::value_type;
41
42 if constexpr (std::is_arithmetic_v<T>) {
43 return scalar_to_matrix(vec);
44 } else if constexpr (std::is_same_v<T, std::complex<float>> || std::is_same_v<T, std::complex<double>>) {
45 return complex_to_matrix(vec);
46 } else if constexpr (GlmType<T>) {
47 return glm_to_matrix(vec);
48 } else {
49 error<std::invalid_argument>(
52 std::source_location::current(),
53 "Unsupported type for Eigen conversion: {}",
54 typeid(T).name());
55 }
56 },
57 m_variant);
58}
59
60Eigen::VectorXd EigenAccess::to_magnitude_vector() const
61{
62 if (!is_complex()) {
63 error<std::invalid_argument>(
66 std::source_location::current(),
67 "to_magnitude_vector() requires complex data, but variant contains {}",
68 type_name());
69 }
70
71 return std::visit([](const auto& vec) -> Eigen::VectorXd {
72 using T = typename std::decay_t<decltype(vec)>::value_type;
73
74 if constexpr (std::is_same_v<T, std::complex<float>> || std::is_same_v<T, std::complex<double>>) {
75 Eigen::VectorXd result(vec.size());
76 for (Eigen::Index i = 0; i < vec.size(); ++i) {
77 result(i) = std::abs(vec[i]);
78 }
79 return result;
80 } else {
81 return Eigen::VectorXd(0);
82 }
83 },
84 m_variant);
85}
86
87Eigen::VectorXcd EigenAccess::to_complex_vector() const
88{
89 if (!is_complex()) {
90 error<std::invalid_argument>(
93 std::source_location::current(),
94 "to_complex_vector() requires complex data, but variant contains {}",
95 type_name());
96 }
97
98 return std::visit([](const auto& vec) -> Eigen::VectorXcd {
99 using T = typename std::decay_t<decltype(vec)>::value_type;
100
101 if constexpr (std::is_same_v<T, std::complex<float>>) {
102 Eigen::VectorXcd result(vec.size());
103 for (Eigen::Index i = 0; i < vec.size(); ++i) {
104 result(i) = std::complex<double>(
105 static_cast<double>(vec[i].real()),
106 static_cast<double>(vec[i].imag()));
107 }
108 return result;
109 } else if constexpr (std::is_same_v<T, std::complex<double>>) {
110 Eigen::VectorXcd result(vec.size());
111 for (Eigen::Index i = 0; i < vec.size(); ++i) {
112 result(i) = vec[i];
113 }
114 return result;
115 } else {
116 return Eigen::VectorXcd(0);
117 }
118 },
119 m_variant);
120}
121
122Eigen::VectorXd EigenAccess::to_phase_vector() const
123{
124 if (!is_complex()) {
125 error<std::invalid_argument>(
128 std::source_location::current(),
129 "to_phase_vector() requires complex data, but variant contains {}",
130 type_name());
131 }
132
133 return std::visit([](const auto& vec) -> Eigen::VectorXd {
134 using T = typename std::decay_t<decltype(vec)>::value_type;
135
136 if constexpr (std::is_same_v<T, std::complex<float>> || std::is_same_v<T, std::complex<double>>) {
137 Eigen::VectorXd result(vec.size());
138 for (Eigen::Index i = 0; i < vec.size(); ++i) {
139 result(i) = std::arg(vec[i]); // atan2(imag, real)
140 }
141 return result;
142 } else {
143 return Eigen::VectorXd(0);
144 }
145 },
146 m_variant);
147}
148
149size_t EigenAccess::element_count() const noexcept
150{
151 return std::visit([](const auto& vec) { return vec.size(); }, m_variant);
152}
153
155{
156 return std::visit([](const auto& vec) -> size_t {
157 using T = typename std::decay_t<decltype(vec)>::value_type;
158
159 if constexpr (std::is_arithmetic_v<T>) {
160 return 1;
161 } else if constexpr (std::is_same_v<T, std::complex<float>> || std::is_same_v<T, std::complex<double>>) {
162 return 2;
163 } else if constexpr (GlmVec2Type<T>) {
164 return 2;
165 } else if constexpr (GlmVec3Type<T>) {
166 return 3;
167 } else if constexpr (GlmVec4Type<T>) {
168 return 4;
169 } else if constexpr (GlmMatrixType<T>) {
170 return 16;
171 } else {
172 return 1;
173 }
174 },
175 m_variant);
176}
177
178std::pair<size_t, size_t> EigenAccess::matrix_dimensions() const
179{
180 return { component_count(), element_count() };
181}
182
184{
185 return std::visit([](const auto& vec) -> bool {
186 return vec.size() <= std::numeric_limits<Eigen::Index>::max();
187 },
188 m_variant);
189}
190
192{
193 return std::visit([](const auto& vec) -> bool {
194 using T = typename std::decay_t<decltype(vec)>::value_type;
195 return std::is_same_v<T, std::complex<float>> || std::is_same_v<T, std::complex<double>>;
196 },
197 m_variant);
198}
199
201{
202 return std::visit([](const auto& vec) -> bool {
203 using T = typename std::decay_t<decltype(vec)>::value_type;
204 return GlmType<T>;
205 },
206 m_variant);
207}
208
209std::string EigenAccess::type_name() const
210{
211 return std::visit([](const auto& vec) -> std::string {
212 using T = typename std::decay_t<decltype(vec)>::value_type;
213 return typeid(T).name();
214 },
215 m_variant);
216}
217
218} // namespace MayaFlux::Kakshya
Eigen::VectorXd to_vector() const
Convert DataVariant to Eigen column vector.
bool is_complex() const
Check if data contains complex numbers.
bool validate_dimensions() const
Validate that data dimensions fit within Eigen limits.
Eigen::VectorXcd to_complex_vector() const
Convert complex data to Eigen complex vector.
size_t element_count() const noexcept
Get number of elements (columns in matrix representation)
std::string type_name() const
Get underlying data type name.
Eigen::MatrixXd to_matrix() const
Convert DataVariant to Eigen matrix.
std::pair< size_t, size_t > matrix_dimensions() const
Get matrix dimensions as (rows, cols)
Eigen::MatrixXd scalar_to_matrix(const std::vector< T > &vec) const
Eigen::VectorXd to_magnitude_vector() const
Convert complex data to magnitude vector.
Eigen::VectorXd scalar_to_vector(const std::vector< T > &vec) const
bool is_structured() const
Check if data contains GLM types.
Eigen::MatrixXd glm_to_matrix(const std::vector< T > &vec) const
Eigen::VectorXd to_phase_vector() const
Convert complex data to phase vector (angle in radians)
size_t component_count() const
Get number of components per element (rows in matrix representation)
const Kakshya::DataVariant & m_variant
Eigen::MatrixXd complex_to_matrix(const std::vector< std::complex< T > > &vec) const
@ Runtime
General runtime operations (default fallback)
@ Kakshya
Containers[Signalsource, Stream, File], Regions, DataProcessors.