7 if (dimensions.empty())
10 return std::transform_reduce(dimensions.begin(), dimensions.end(),
11 uint64_t(1), std::multiplies<>(),
17 if (dimensions.empty())
20 return std::transform_reduce(
21 dimensions.begin() + 1, dimensions.end(),
22 uint64_t(1), std::multiplies<>(),
28 return std::visit([](
const auto& vec) -> std::type_index {
29 return std::type_index(
typeid(
decltype(vec)));
36 std::visit([&](
const auto& input_vec,
auto& output_vec) {
37 using InputType =
typename std::decay_t<
decltype(input_vec)>::value_type;
38 using OutputType =
typename std::decay_t<
decltype(output_vec)>::value_type;
40 if constexpr (ProcessableData<InputType> && ProcessableData<OutputType>) {
41 std::vector<OutputType> temp_storage;
42 auto input_span = extract_from_variant<OutputType>(input, temp_storage);
44 output_vec.resize(input_span.size());
45 std::copy(input_span.begin(), input_span.end(), output_vec.begin());
47 error<std::invalid_argument>(
50 std::source_location::current(),
51 "Unsupported type conversion from {} to {}",
52 typeid(InputType).name(),
53 typeid(OutputType).name());
59void set_metadata_value(std::unordered_map<std::string, std::any>& metadata,
const std::string& key, std::any value)
61 metadata[key] = std::move(value);
66 auto it = std::ranges::find_if(dimensions,
69 return (it != dimensions.end()) ?
static_cast<int>(std::distance(dimensions.begin(), it)) : -1;
74 if (dimensions.empty()) {
78 size_t time_dims = 0, spatial_dims = 0, channel_dims = 0, frequency_dims = 0, custom_dims = 0;
79 size_t total_spatial_elements = 1;
80 size_t total_channels = 0;
82 for (
const auto& dim : dimensions) {
95 if (dim.grouping->count == 3)
97 if (dim.grouping->count == 4)
101 if (dim.grouping->count == 16)
108 for (
const auto& dim : dimensions) {
117 total_spatial_elements *= dim.size;
121 total_channels += dim.size;
133 if (time_dims == 1 && spatial_dims == 0 && frequency_dims == 0) {
134 if (channel_dims == 0) {
136 }
else if (channel_dims == 1) {
143 if (time_dims >= 1 && frequency_dims >= 1) {
144 if (spatial_dims == 0 && channel_dims <= 1) {
150 if (spatial_dims >= 2 && time_dims == 0) {
151 if (spatial_dims == 2) {
152 if (channel_dims == 0) {
154 }
else if (channel_dims == 1 && total_channels >= 3) {
159 }
else if (spatial_dims == 3) {
164 if (time_dims >= 1 && spatial_dims >= 2) {
165 if (spatial_dims == 2) {
166 if (channel_dims == 0 || (channel_dims == 1 && total_channels <= 1)) {
175 if (spatial_dims == 2 && time_dims == 0 && channel_dims >= 1) {
176 if (total_spatial_elements >= 64 && total_channels >= 1) {
186 std::cerr <<
"Inferring structure from single DataVariant...\n"
187 <<
"This is not advisable as the method makes naive assumptions that can lead to massive computational errors\n"
188 <<
"If the variant is part of a container, region, or segment, please use the appropriate method instead.\n"
189 <<
"If the variant is part of a vector, please use infer_from_data_variant_vector instead.\n"
190 <<
"If you are sure you want to proceed, please ignore this warning.\n";
192 return std::visit([](
const auto& vec) -> std::vector<DataDimension> {
193 using ValueType =
typename std::decay_t<
decltype(vec)>::value_type;
195 std::vector<DataDimension> dims;
197 if constexpr (DecimalData<ValueType>) {
200 }
else if constexpr (ComplexData<ValueType>) {
203 }
else if constexpr (IntegerData<ValueType>) {
206 uint64_t total_size = vec.size();
208 if (total_size == 0) {
212 auto sqrt_size =
static_cast<uint64_t
>(std::sqrt(total_size));
213 if (sqrt_size * sqrt_size == total_size) {
217 uint64_t width = sqrt_size;
218 uint64_t height = total_size / width;
219 while (width * height != total_size && width > 1) {
221 height = total_size / width;
227 }
else if constexpr (GlmData<ValueType>) {
228 constexpr size_t components = glm_component_count<ValueType>();
231 if constexpr (GlmVec2Type<ValueType>) {
233 }
else if constexpr (GlmVec3Type<ValueType>) {
235 }
else if constexpr (GlmVec4Type<ValueType>) {
237 }
else if constexpr (GlmMatrixType<ValueType>) {
242 "glm_structured_data",
243 static_cast<uint64_t
>(vec.size()),
244 static_cast<uint8_t
>(components),
256 const std::vector<DataVariant>& variants)
258 std::cerr <<
"Inferring structure from DataVariant vector...\n"
259 <<
"This is not advisable as the method makes naive assumptions that can lead to massive computational errors\n"
260 <<
"If the variant is part of a container, region, or segment, please use the appropriate method instead.\n"
261 <<
"If you are sure you want to proceed, please ignore this warning.\n";
263 if (variants.empty()) {
264 std::vector<DataDimension> dims;
269 std::vector<DataDimension> dimensions;
270 size_t variant_count = variants.size();
272 size_t first_variant_size = std::visit([](
const auto& vec) ->
size_t {
277 bool consistent_glm = std::ranges::all_of(variants, [](
const auto& variant) {
278 return std::visit([](
const auto& vec) ->
bool {
279 using ValueType =
typename std::decay_t<
decltype(vec)>::value_type;
280 return GlmData<ValueType>;
285 bool consistent_decimal = std::ranges::all_of(variants, [](
const auto& variant) {
286 return std::visit([](
const auto& vec) ->
bool {
287 using ValueType =
typename std::decay_t<
decltype(vec)>::value_type;
288 return MayaFlux::DecimalData<ValueType>;
293 bool consistent_complex = std::ranges::all_of(variants, [](
const auto& variant) {
294 return std::visit([](
const auto& vec) ->
bool {
295 using ValueType =
typename std::decay_t<
decltype(vec)>::value_type;
296 return MayaFlux::ComplexData<ValueType>;
301 bool consistent_integer = std::ranges::all_of(variants, [](
const auto& variant) {
302 return std::visit([](
const auto& vec) ->
bool {
303 using ValueType =
typename std::decay_t<
decltype(vec)>::value_type;
304 return MayaFlux::IntegerData<ValueType>;
309 if (consistent_glm) {
312 std::visit([&](
const auto& first_vec) {
313 using ValueType =
typename std::decay_t<
decltype(first_vec)>::value_type;
314 constexpr size_t components = glm_component_count<ValueType>();
317 if constexpr (GlmVec2Type<ValueType>) {
319 }
else if constexpr (GlmVec3Type<ValueType>) {
321 }
else if constexpr (GlmVec4Type<ValueType>) {
328 static_cast<uint8_t
>(components),
336 if (variant_count == 1) {
337 if (consistent_decimal) {
339 }
else if (consistent_complex) {
341 }
else if (consistent_integer) {
344 dimensions.emplace_back(
"unknown_data", first_variant_size, 1,
348 }
else if (variant_count == 2 && (consistent_decimal || consistent_complex || consistent_integer)) {
350 if (consistent_decimal) {
352 }
else if (consistent_complex) {
358 }
else if (variant_count <= 16 && (consistent_decimal || consistent_complex || consistent_integer)) {
360 if (consistent_decimal) {
362 }
else if (consistent_complex) {
368 }
else if (consistent_decimal || consistent_complex || consistent_integer) {
369 if (consistent_decimal) {
371 dimensions.emplace_back(
"block_samples", first_variant_size, 1,
373 }
else if (consistent_complex) {
382 dimensions.emplace_back(
"mixed_variants", variant_count, 1,
384 dimensions.emplace_back(
"variant_data", first_variant_size, 1,
@ Runtime
General runtime operations (default fallback)
@ Kakshya
Containers[Signalsource, Stream, File], Regions, DataProcessors.
std::vector< DataDimension > detect_data_dimensions(const DataVariant &data)
Detect data dimensions from a DataVariant.
uint64_t calculate_frame_size(const std::vector< DataDimension > &dimensions)
Calculate the frame size (number of elements per frame) for a set of dimensions.
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.
DataModality
Data modality types for cross-modal analysis.
@ AUDIO_MULTICHANNEL
Multi-channel audio.
@ SPECTRAL_2D
2D spectral data (time + frequency)
@ AUDIO_1D
1D audio signal
@ UNKNOWN
Unknown or undefined modality.
@ VOLUMETRIC_3D
3D volumetric data
@ VIDEO_GRAYSCALE
3D video (time + 2D grayscale)
@ VIDEO_COLOR
4D video (time + 2D + color)
@ TENSOR_ND
N-dimensional tensor.
@ TEXTURE_2D
2D texture data
@ IMAGE_COLOR
2D RGB/RGBA image
@ IMAGE_2D
2D image (grayscale or single channel)
std::type_index get_variant_type_index(const DataVariant &data)
Get type index from DataVariant.
int find_dimension_by_role(const std::vector< DataDimension > &dimensions, DataDimension::Role role)
Find the index of a dimension by its semantic role.
void set_metadata_value(std::unordered_map< std::string, std::any > &metadata, const std::string &key, std::any value)
Set a value in a metadata map (key-value).
DataModality detect_data_modality(const std::vector< DataDimension > &dimensions)
Detects data modality from dimension information.
void safe_copy_data_variant(const DataVariant &input, DataVariant &output)
Safely copy data from a DataVariant to another DataVariant, handling type conversion.
uint64_t calculate_total_elements(const std::vector< DataDimension > &dimensions)
Calculate the total number of elements in an N-dimensional container.
Role
Semantic role of the dimension.
@ COLOR
Color data (RGB/RGBA)
@ FREQUENCY
Spectral/frequency axis.
@ SPATIAL_Y
Spatial Y axis.
@ TIME
Temporal progression (samples, frames, steps)
@ BITANGENT
Bitangent vectors.
@ TANGENT
Tangent vectors.
@ CUSTOM
User-defined or application-specific.
@ SPATIAL_Z
Spatial Z axis.
@ POSITION
Vertex positions (3D space)
@ CHANNEL
Parallel streams (audio channels, color channels)
@ SPATIAL_X
Spatial X axis (images, tensors)
uint64_t size
Number of elements in this dimension.
Role role
Semantic hint for common operations.
static DataDimension spatial(uint64_t size, char axis, uint64_t stride=1, std::string name="spatial")
Convenience constructor for a spatial dimension.
static DataDimension grouped(std::string name, uint64_t element_count, uint8_t components_per_element, Role role=Role::CUSTOM)
Create dimension with component grouping.
static DataDimension frequency(uint64_t bins, std::string name="frequency")
Convenience constructor for a frequency dimension.
static DataDimension time(uint64_t samples, std::string name="time")
Convenience constructor for a temporal (time) dimension.
static DataDimension channel(uint64_t count, uint64_t stride=1)
Convenience constructor for a channel dimension.
Minimal dimension descriptor focusing on structure only.