MayaFlux 0.3.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
SortingHelper.hpp
Go to the documentation of this file.
1#pragma once
2
4
6
8
9namespace MayaFlux::Yantra {
10
13
14/**
15 * @struct SortKey
16 * @brief Multi-dimensional sort key specification for complex sorting
17 */
18struct MAYAFLUX_API SortKey {
19 std::string name;
20 std::function<double(const std::any&)> extractor; ///< Extract sort value from data
21 SortingDirection direction = SortingDirection::ASCENDING;
22 double weight = 1.0; ///< Weight for multi-key sorting
23 bool normalize = false; ///< Normalize values before sorting
24
25 SortKey(std::string n, std::function<double(const std::any&)> e)
26 : name(std::move(n))
27 , extractor(std::move(e))
28 {
29 }
30};
31
32/**
33 * @brief Universal sort function - handles extraction/conversion internally
34 * @tparam T ComputeData type
35 * @param data Data to sort (modified in-place)
36 * @param direction Sort direction
37 * @param algorithm Sort algorithm
38 */
39template <ComputeData T>
41 SortingDirection direction,
42 SortingAlgorithm algorithm)
43{
44 if constexpr (RequiresContainer<T>) {
45 if (!data.has_container()) {
46 error<std::runtime_error>(Journal::Component::Yantra, Journal::Context::ComputeMatrix, std::source_location::current(), "Region-like types require container - use UniversalSorter instead");
47 }
48 auto channels = OperationHelper::extract_numeric_data(data.data, data.container.value());
49 Kinesis::Discrete::sort_channels(channels, direction, algorithm);
50 return;
51 }
52
54 Kinesis::Discrete::sort_channels(channels, direction, algorithm);
55}
56
57/**
58 * @brief Universal sort function - returns sorted copy
59 * @tparam T ComputeData type
60 * @param data Data to sort (not modified)
61 * @param direction Sort direction
62 * @param algorithm Sort algorithm
63 * @return Sorted copy of the data
64 */
65template <ComputeData T>
67 SortingDirection direction,
68 SortingAlgorithm algorithm)
69{
70 if constexpr (RequiresContainer<T>) {
71 static_assert(std::is_same_v<T, void>,
72 "Region-like types require container parameter - use UniversalSorter instead");
73 return T {};
74 }
75
76 std::vector<std::vector<double>> working_buffer;
77 auto [working_spans, structure_info] = OperationHelper::setup_operation_buffer(
78 const_cast<T&>(data), working_buffer);
79
80 Kinesis::Discrete::sort_channels(working_spans, direction, algorithm);
81
82 return OperationHelper::reconstruct_from_double<T>(working_buffer, structure_info);
83}
84
85/**
86 * @brief Universal sort function - returns sorted copy
87 * @tparam T ComputeData type
88 * @param data Data to sort (not modified)
89 * @param direction Sort direction
90 * @param algorithm Sort algorithm
91 * @return Sorted copy of the data
92 */
93template <typename T>
95 SortingDirection direction,
96 SortingAlgorithm algorithm)
97{
98 std::vector<std::vector<double>> working_buffer;
99 auto [working_spans, structure_info] = OperationHelper::setup_operation_buffer(
100 const_cast<Datum<T>&>(data), working_buffer);
101
102 Kinesis::Discrete::sort_channels(working_spans, direction, algorithm);
103
104 return OperationHelper::reconstruct_from_double<T>(working_buffer, structure_info);
105}
106
107/**
108 * @brief Convenience function with default algorithm
109 * @tparam T ComputeData type
110 * @param data Data to sort
111 * @param direction Sort direction
112 * @return Sorted copy of the data
113 */
114template <ComputeData T>
115T sort_compute_data(const T& data, SortingDirection direction = SortingDirection::ASCENDING)
116{
117 return sort_compute_data_extract(data, direction, SortingAlgorithm::STANDARD);
118}
119
120/**
121 * @brief Generate sort indices for any ComputeData type
122 * @tparam T ComputeData type
123 * @param data Data to generate indices for
124 * @param direction Sort direction
125 * @return Vector of index vectors (one per channel)
126 */
127template <ComputeData T>
128std::vector<std::vector<size_t>> generate_compute_data_indices(const Datum<T>& data,
129 SortingDirection direction)
130{
131 if constexpr (RequiresContainer<T>) {
132 auto channels = OperationHelper::extract_numeric_data(data.data, data.container.value());
133 return Kinesis::Discrete::channels_sort_indices(channels, direction);
134 }
135
136 if constexpr (SingleVariant<T>) {
137 auto channel = OperationHelper::extract_numeric_data(data.data);
138 return { Kinesis::Discrete::span_sort_indices({ channel }, direction) };
139 } else {
140 auto channels = OperationHelper::extract_numeric_data(data.data, data.needs_processig());
141 return Kinesis::Discrete::channels_sort_indices(channels, direction);
142 }
143}
144
145/**
146 * @brief Creates a multi-key comparator for complex sorting
147 * @tparam T Data type being sorted
148 * @param keys Vector of sort keys with extractors and weights
149 * @return Lambda comparator that applies all keys in order
150 */
151template <typename T>
152auto create_multi_key_comparator(const std::vector<SortKey>& keys)
153{
154 return [keys](const T& a, const T& b) -> bool {
155 for (const auto& key : keys) {
156 try {
157 double val_a = key.extractor(std::any(a));
158 double val_b = key.extractor(std::any(b));
159
160 if (key.normalize) {
161 val_a = std::tanh(val_a);
162 val_b = std::tanh(val_b);
163 }
164
165 double weighted_diff = key.weight * (val_a - val_b);
166 if (std::abs(weighted_diff) > 1e-9) {
167 return key.direction == SortingDirection::ASCENDING ? weighted_diff < 0 : weighted_diff > 0;
168 }
169 } catch (...) {
170 continue;
171 }
172 }
173 return false;
174 };
175}
176
177/**
178 * @brief Helper function to get temporal position from various types
179 * Used by TemporalSortable concept
180 */
181template <typename T>
182double get_temporal_position(const T& item)
183{
184 if constexpr (requires { item.start_coordinates; }) {
185 return !item.start_coordinates.empty() ? static_cast<double>(item.start_coordinates[0]) : 0.0;
186 } else if constexpr (requires { item.timestamp; }) {
187 return static_cast<double>(item.timestamp);
188 } else if constexpr (requires { item.time; }) {
189 return static_cast<double>(item.time);
190 } else {
191 static_assert(std::is_same_v<T, void>, "Type does not have temporal information");
192 return 0.0;
193 }
194}
195
196/**
197 * @brief Create universal sort key extractor for common data types
198 * @tparam T Data type to extract sort key from
199 * @param name Sort key name
200 * @param direction Sort direction (for the key metadata)
201 * @return SortKey with appropriate extractor
202 */
203template <typename T>
204SortKey create_universal_sort_key(const std::string& name,
205 SortingDirection direction = SortingDirection::ASCENDING)
206{
207 SortKey key(name, [](const std::any& data) -> double {
208 auto cast_result = safe_any_cast<T>(data);
209 if (!cast_result) {
210 return 0.0;
211 }
212
213 const T& value = *cast_result.value;
214
215 if constexpr (ArithmeticData<T>) {
216 return static_cast<double>(value);
217 } else if constexpr (ComplexData<T>) {
218 return std::abs(value);
219 } else if constexpr (requires { get_temporal_position(value); }) {
220 return get_temporal_position(value);
221 } else {
222 return 0.0;
223 }
224 });
225
226 key.direction = direction;
227 return key;
228}
229
230} // namespace MayaFlux::Yantra
size_t a
double weight
size_t b
Discrete sequence sorting primitives for MayaFlux::Kinesis.
static auto setup_operation_buffer(T &input, std::vector< std::vector< double > > &working_buffer)
Setup operation buffer from Datum or ComputeData type.
static std::span< double > extract_numeric_data(const T &compute_data)
extract numeric data from single-variant types
A SingleVariant is either a single DataVariant, an Eigen vector type, or any type constructible from ...
Definition DataSpec.hpp:98
@ ComputeMatrix
Compute operations (Yantra - algorithms, matrices, DSP)
@ Yantra
DSP algorithms, computational units, matrix operations, Grammar.
std::vector< size_t > span_sort_indices(std::span< double > data, SortingDirection direction)
Indices that would sort a span in the given direction.
Definition Sort.cpp:35
void sort_channels(std::vector< std::span< double > > &channels, SortingDirection direction, SortingAlgorithm algorithm)
Sort all channels in-place.
Definition Sort.cpp:19
std::vector< std::vector< size_t > > channels_sort_indices(const std::vector< std::span< double > > &channels, SortingDirection direction)
Per-channel sort indices.
Definition Sort.cpp:46
SortingAlgorithm
Available sorting algorithm backends.
Definition Sort.hpp:41
SortingDirection
Ascending or descending sort order.
Definition Sort.hpp:30
T sort_compute_data(const T &data, SortingDirection direction=SortingDirection::ASCENDING)
Convenience function with default algorithm.
std::vector< std::vector< size_t > > generate_compute_data_indices(const Datum< T > &data, SortingDirection direction)
Generate sort indices for any ComputeData type.
double get_temporal_position(const T &item)
Helper function to get temporal position from various types Used by TemporalSortable concept.
SortKey create_universal_sort_key(const std::string &name, SortingDirection direction=SortingDirection::ASCENDING)
Create universal sort key extractor for common data types.
void sort_compute_data_inplace(Datum< T > &data, SortingDirection direction, SortingAlgorithm algorithm)
Universal sort function - handles extraction/conversion internally.
T sort_compute_data_extract(const T &data, SortingDirection direction, SortingAlgorithm algorithm)
Universal sort function - returns sorted copy.
auto create_multi_key_comparator(const std::vector< SortKey > &keys)
Creates a multi-key comparator for complex sorting.
void normalize(std::vector< double > &data, double target_peak)
Normalize single-channel data to specified peak level (in-place)
Definition Yantra.cpp:560
T data
The actual computation data.
Definition DataIO.hpp:25
bool has_container() const
Check if a container reference is associated.
Definition DataIO.hpp:155
bool needs_processig() const
Check if processing is needed (for container types)
Definition DataIO.hpp:164
std::optional< std::shared_ptr< Kakshya::SignalSourceContainer > > container
Optional reference to container, required for regions.
Definition DataIO.hpp:31
Input/Output container for computation pipeline data flow with structure preservation.
Definition DataIO.hpp:24
std::function< double(const std::any &)> extractor
Extract sort value from data.
SortKey(std::string n, std::function< double(const std::any &)> e)
Multi-dimensional sort key specification for complex sorting.