8#include <glm/gtc/type_ptr.hpp>
36 [[nodiscard]] Eigen::VectorXd to_vector()
const;
49 [[nodiscard]] Eigen::MatrixXd to_matrix()
const;
56 [[nodiscard]] Eigen::VectorXd to_magnitude_vector()
const;
63 [[nodiscard]] Eigen::VectorXcd to_complex_vector()
const;
70 [[nodiscard]] Eigen::VectorXd to_phase_vector()
const;
76 [[nodiscard]]
size_t element_count() const noexcept;
82 [[nodiscard]]
size_t component_count() const;
88 [[nodiscard]]
std::pair<
size_t,
size_t> matrix_dimensions() const;
94 [[nodiscard]]
bool validate_dimensions() const;
100 [[nodiscard]]
bool is_complex() const;
106 [[nodiscard]]
bool is_structured() const;
112 [[nodiscard]]
std::
string type_name() const;
129 template <typename EigenType>
130 auto view() const ->
std::optional<Eigen::Map<const EigenType>>;
145 template <typename Scalar =
double>
146 auto view_as_matrix(Eigen::Index rows) const
147 ->
std::optional<Eigen::Map<const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>>;
156 template <typename GlmVecType>
157 requires GlmType<GlmVecType>
158 auto view_as_glm() const ->
std::optional<
std::span<const GlmVecType>>;
163 template <typename T>
164 Eigen::VectorXd scalar_to_vector(const
std::vector<T>& vec)
const
167 return Eigen::VectorXd(0);
169 if (vec.size() >
static_cast<size_t>(std::numeric_limits<Eigen::Index>::max())) {
170 error<std::overflow_error>(
171 Journal::Component::Kakshya,
172 Journal::Context::Runtime,
173 std::source_location::current(),
174 "Vector size {} exceeds Eigen::Index maximum {}",
176 std::numeric_limits<Eigen::Index>::max());
179 Eigen::VectorXd result(vec.size());
180 for (Eigen::Index i = 0; i < vec.size(); ++i) {
181 result(i) =
static_cast<double>(vec[i]);
186 template <
typename T>
189 Eigen::MatrixXd result(1, vec.size());
190 for (Eigen::Index i = 0; i < vec.size(); ++i) {
191 result(0, i) =
static_cast<double>(vec[i]);
196 template <
typename T>
199 Eigen::MatrixXd result(2, vec.size());
200 for (Eigen::Index i = 0; i < vec.size(); ++i) {
201 result(0, i) =
static_cast<double>(vec[i].real());
202 result(1, i) =
static_cast<double>(vec[i].imag());
207 template <
typename T>
210 if constexpr (GlmVec2Type<T>) {
211 Eigen::MatrixXd result(2, vec.size());
212 for (Eigen::Index i = 0; i < vec.size(); ++i) {
213 result(0, i) =
static_cast<double>(vec[i].x);
214 result(1, i) =
static_cast<double>(vec[i].y);
217 }
else if constexpr (GlmVec3Type<T>) {
218 Eigen::MatrixXd result(3, vec.size());
219 for (Eigen::Index i = 0; i < vec.size(); ++i) {
220 result(0, i) =
static_cast<double>(vec[i].x);
221 result(1, i) =
static_cast<double>(vec[i].y);
222 result(2, i) =
static_cast<double>(vec[i].z);
225 }
else if constexpr (GlmVec4Type<T>) {
226 Eigen::MatrixXd result(4, vec.size());
227 for (Eigen::Index i = 0; i < vec.size(); ++i) {
228 result(0, i) =
static_cast<double>(vec[i].x);
229 result(1, i) =
static_cast<double>(vec[i].y);
230 result(2, i) =
static_cast<double>(vec[i].z);
231 result(3, i) =
static_cast<double>(vec[i].w);
234 }
else if constexpr (GlmMatrixType<T>) {
235 Eigen::MatrixXd result(16, vec.size());
236 for (Eigen::Index i = 0; i < vec.size(); ++i) {
237 const float* ptr = glm::value_ptr(vec[i]);
238 for (
int j = 0; j < 16; ++j) {
239 result(j, i) =
static_cast<double>(ptr[j]);
244 error<std::invalid_argument>(
245 Journal::Component::Kakshya,
246 Journal::Context::Runtime,
247 std::source_location::current(),
248 "Unknown GLM type: {}",
274template <
typename EigenType>
277 return std::visit([](
const auto& vec) -> std::optional<Eigen::Map<const EigenType>> {
278 using T =
typename std::decay_t<
decltype(vec)>::value_type;
284 if constexpr (std::is_same_v<EigenType, Eigen::VectorXd>) {
285 if constexpr (std::is_same_v<T, double>) {
286 return Eigen::Map<const Eigen::VectorXd>(vec.data(), vec.size());
288 }
else if constexpr (std::is_same_v<EigenType, Eigen::VectorXf>) {
289 if constexpr (std::is_same_v<T, float>) {
290 return Eigen::Map<const Eigen::VectorXf>(vec.data(), vec.size());
292 }
else if constexpr (std::is_same_v<EigenType, Eigen::VectorXcd>) {
293 if constexpr (std::is_same_v<T, std::complex<double>>) {
294 return Eigen::Map<const Eigen::VectorXcd>(
295 reinterpret_cast<const std::complex<double>*
>(vec.data()),
298 }
else if constexpr (std::is_same_v<EigenType, Eigen::VectorXcf>) {
299 if constexpr (std::is_same_v<T, std::complex<float>>) {
300 return Eigen::Map<const Eigen::VectorXcf>(
301 reinterpret_cast<const std::complex<float>*
>(vec.data()),
311template <
typename Scalar>
313 -> std::optional<Eigen::Map<const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>>
315 return std::visit([rows](
const auto& vec)
316 -> std::optional<Eigen::Map<
const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>> {
317 using T =
typename std::decay_t<
decltype(vec)>::value_type;
323 if constexpr (std::is_same_v<T, Scalar>) {
324 if (vec.size() % rows != 0) {
328 Eigen::Index cols = vec.size() / rows;
329 return Eigen::Map<const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>>(
330 vec.data(), rows, cols);
338template <
typename GlmVecType>
339 requires GlmType<GlmVecType>
342 return std::visit([](
const auto& vec) -> std::optional<std::span<const GlmVecType>> {
343 using T =
typename std::decay_t<
decltype(vec)>::value_type;
345 if constexpr (std::is_same_v<T, GlmVecType>) {
346 return std::span<const GlmVecType>(vec.data(), vec.size());
Eigen::VectorXd to_vector() const
Convert DataVariant to Eigen column vector.
auto view_as_glm() const -> std::optional< std::span< const GlmVecType > >
Get zero-copy span view of GLM vector data.
auto view_as_matrix(Eigen::Index rows) const -> std::optional< Eigen::Map< const Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > > >
Get zero-copy matrix view with explicit row count.
Eigen::MatrixXd to_matrix() const
Convert DataVariant to Eigen matrix.
EigenAccess(const Kakshya::DataVariant &variant)
auto view() const -> std::optional< Eigen::Map< const EigenType > >
Get zero-copy Eigen::Map view of data.
Eigen::MatrixXd scalar_to_matrix(const std::vector< T > &vec) const
Eigen::MatrixXd glm_to_matrix(const std::vector< T > &vec) const
const Kakshya::DataVariant & m_variant
Eigen::MatrixXd complex_to_matrix(const std::vector< std::complex< T > > &vec) const
Type-erased accessor for converting DataVariant to Eigen types.
Eigen::MatrixXd to_eigen_matrix(const Kakshya::DataVariant &variant)
Convenience function for direct conversion.
std::variant< std::vector< double >, std::vector< float >, std::vector< uint8_t >, std::vector< uint16_t >, std::vector< uint32_t >, std::vector< std::complex< float > >, std::vector< std::complex< double > >, std::vector< glm::vec2 >, std::vector< glm::vec3 >, std::vector< glm::vec4 >, std::vector< glm::mat4 > > DataVariant
Multi-type data storage for different precision needs.
Eigen::VectorXd to_eigen_vector(const Kakshya::DataVariant &variant)
Convenience function for vector conversion.