MayaFlux 0.3.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
ConvolutionTransformer.hpp
Go to the documentation of this file.
1#pragma once
2
5
6namespace MayaFlux::Yantra {
7
9
10/**
11 * @enum ConvolutionOperation
12 * @brief Specific convolution operations supported
13 */
14enum class ConvolutionOperation : uint8_t {
15 DIRECT_CONVOLUTION, ///< Standard convolution
16 CROSS_CORRELATION, ///< Cross-correlation
17 MATCHED_FILTER, ///< Matched filtering
18 DECONVOLUTION, ///< Deconvolution
19 AUTO_CORRELATION ///< Auto-correlation
20};
21
22/**
23 * @class ConvolutionTransformer
24 * @brief Concrete transformer for convolution-based operations
25 *
26 * Handles various convolution operations:
27 * - Direct convolution and cross-correlation
28 * - Impulse response application
29 * - Matched filtering and signal detection
30 * - Deconvolution and restoration
31 */
32template <ComputeData InputType = std::vector<Kakshya::DataVariant>, ComputeData OutputType = InputType>
33class MAYAFLUX_API ConvolutionTransformer final : public UniversalTransformer<InputType, OutputType> {
34public:
37
38 /**
39 * @brief Constructs a ConvolutionTransformer with specified operation
40 * @param op The convolution operation to perform (default: DIRECT_CONVOLUTION)
41 */
42 explicit ConvolutionTransformer(ConvolutionOperation op = ConvolutionOperation::DIRECT_CONVOLUTION)
43 : m_operation(op)
44 {
45 set_default_parameters();
46 }
47
48 /**
49 * @brief Gets the transformation type
50 * @return TransformationType::CONVOLUTION
51 */
52 [[nodiscard]] TransformationType get_transformation_type() const override
53 {
54 return TransformationType::CONVOLUTION;
55 }
56
57 /**
58 * @brief Gets the transformer name including the operation type
59 * @return String representation of the transformer name
60 */
61 [[nodiscard]] std::string get_transformer_name() const override
62 {
63 return std::string("ConvolutionTransformer_").append(Reflect::enum_to_string(m_operation));
64 }
65
66protected:
67 /**
68 * @brief Applies the configured convolution operation
69 * @param input Input data
70 * @return Transformed output
71 *
72 * Extracts per-channel double spans, calls the corresponding
73 * Kinesis::Discrete::Convolution primitive on each channel, then
74 * reconstructs the typed output via OperationHelper.
75 */
77 {
78 switch (m_operation) {
79
80 case ConvolutionOperation::DIRECT_CONVOLUTION: {
81 const auto ir = get_parameter_or<std::vector<double>>(
82 "impulse_response", std::vector<double> { 1.0 });
83 return apply_per_channel(input, [&ir](std::span<const double> ch) {
84 return D::convolve(ch, ir);
85 });
86 }
87
88 case ConvolutionOperation::CROSS_CORRELATION: {
89 const auto tmpl = get_parameter_or<std::vector<double>>(
90 "template_signal", std::vector<double> { 1.0 });
91 const auto norm = get_parameter_or<bool>("normalize", true);
92 return apply_per_channel(input, [&tmpl, norm](std::span<const double> ch) {
93 return D::cross_correlate(ch, tmpl, norm);
94 });
95 }
96
97 case ConvolutionOperation::MATCHED_FILTER: {
98 const auto ref = get_parameter_or<std::vector<double>>(
99 "reference_signal", std::vector<double> { 1.0 });
100 return apply_per_channel(input, [&ref](std::span<const double> ch) {
101 return D::matched_filter(ch, ref);
102 });
103 }
104
105 case ConvolutionOperation::DECONVOLUTION: {
106 const auto ir = get_parameter_or<std::vector<double>>(
107 "impulse_response", std::vector<double> { 1.0 });
108 const auto reg = get_parameter_or<double>("regularization", 1e-6);
109 return apply_per_channel(input, [&ir, reg](std::span<const double> ch) {
110 return D::deconvolve(ch, ir, reg);
111 });
112 }
113
114 case ConvolutionOperation::AUTO_CORRELATION: {
115 const auto norm = get_parameter_or<bool>("normalize", true);
116 return apply_per_channel(input, [norm](std::span<const double> ch) {
117 return D::auto_correlate(ch, norm);
118 });
119 }
120
121 default:
122 return create_output(input);
123 }
124 }
125
126 /**
127 * @brief Sets transformation parameters
128 * @param name Parameter name
129 * @param value Parameter value
130 *
131 * Handles setting of convolution operation type and delegates other parameters to base class.
132 * Supports both enum and string values for the "operation" parameter.
133 *
134 * Common parameters include:
135 * - "impulse_response": Impulse response for convolution/deconvolution operations
136 * - "template_signal": Template signal for cross-correlation
137 * - "reference_signal": Reference signal for matched filtering
138 * - "normalize": Whether to normalize correlation results
139 * - "regularization": Regularization parameter for deconvolution stability
140 */
141 void set_transformation_parameter(const std::string& name, std::any value) override
142 {
143 if (name == "operation") {
144 if (auto r = safe_any_cast<ConvolutionOperation>(value)) {
145 m_operation = *r.value;
146 return;
147 }
148 if (auto r = safe_any_cast<std::string>(value)) {
149 if (auto e = Reflect::string_to_enum_case_insensitive<ConvolutionOperation>(*r.value)) {
150 m_operation = *e;
151 return;
152 }
153 }
154 }
155
157 }
158
159private:
160 ConvolutionOperation m_operation; ///< Current convolution operation
161 mutable std::vector<std::vector<double>> m_working_buffer; ///< Buffer for out-of-place convolution operations
162
163 /**
164 * @brief Extracts per-channel spans, applies func to each, and reconstructs.
165 * @tparam Func Callable matching either void(std::span<double>) or
166 * std::vector<double>(std::span<const double>)
167 *
168 * In-place: results are copied back into the original channel spans of @p input.
169 * Out-of-place: input is not mutated.
170 */
171 template <typename Func>
173 {
174 auto [channels, structure_info] = OperationHelper::extract_structured_double(input);
175 m_working_buffer.resize(channels.size());
176 for (size_t i = 0; i < channels.size(); ++i) {
177 if constexpr (std::is_void_v<std::invoke_result_t<Func, std::span<double>>>) {
178 m_working_buffer[i].assign(channels[i].begin(), channels[i].end());
179 func(std::span<double> { m_working_buffer[i] });
180 } else {
181 m_working_buffer[i] = func(std::span<const double> { channels[i] });
182 }
183 }
184 if (this->is_in_place())
185 for (size_t i = 0; i < channels.size(); ++i)
186 std::ranges::copy(m_working_buffer[i], channels[i].begin());
187 return create_output(
188 OperationHelper::reconstruct_from_double<InputType>(m_working_buffer, structure_info));
189 }
190
191 /**
192 * @brief Sets default parameter values for all convolution operations
193 *
194 * Initializes all possible parameters with sensible defaults to ensure
195 * the transformer works correctly regardless of the selected operation.
196 * Default values are chosen for typical signal processing scenarios.
197 */
199 {
200 this->set_parameter("impulse_response", std::vector<double> { 1.0 });
201 this->set_parameter("template_signal", std::vector<double> { 1.0 });
202 this->set_parameter("reference_signal", std::vector<double> { 1.0 });
203 this->set_parameter("normalize", true);
204 this->set_parameter("regularization", 1e-6);
205 }
206
207 /**
208 * @brief Gets a parameter value with fallback to default
209 * @tparam T Parameter type
210 * @param name Parameter name
211 * @param default_value Default value if parameter not found or wrong type
212 * @return Parameter value or default
213 */
214 template <typename T>
215 T get_parameter_or(const std::string& name, const T& default_value) const
216 {
217 auto param = this->get_transformation_parameter(name);
218 if (!param.has_value())
219 return default_value;
220
221 auto result = safe_any_cast<T>(param);
222 return result.value_or(default_value);
223 }
224
225 /**
226 * @brief Creates output with proper type conversion
227 * @param data Input data to convert
228 * @return Output with converted data type
229 *
230 * Handles type conversion between InputType and OutputType when necessary,
231 * or direct assignment when types match. Ensures convolution processing results
232 * maintain the correct output type and signal characteristics.
233 */
235 {
236 if constexpr (std::is_same_v<InputType, OutputType>) {
237 return input;
238 } else {
239 auto [result_data, metadata] = OperationHelper::extract_structured_double(input);
240 return this->convert_result(result_data, metadata);
241 }
242 }
243};
244
245}
Float Processing Guidelines.
ConvolutionOperation m_operation
Current convolution operation.
ConvolutionTransformer(ConvolutionOperation op=ConvolutionOperation::DIRECT_CONVOLUTION)
Constructs a ConvolutionTransformer with specified operation.
T get_parameter_or(const std::string &name, const T &default_value) const
Gets a parameter value with fallback to default.
std::vector< std::vector< double > > m_working_buffer
Buffer for out-of-place convolution operations.
output_type apply_per_channel(input_type &input, Func &&func)
Extracts per-channel spans, applies func to each, and reconstructs.
void set_default_parameters()
Sets default parameter values for all convolution operations.
output_type transform_implementation(input_type &input) override
Applies the configured convolution operation.
TransformationType get_transformation_type() const override
Gets the transformation type.
output_type create_output(const input_type &input)
Creates output with proper type conversion.
std::string get_transformer_name() const override
Gets the transformer name including the operation type.
void set_transformation_parameter(const std::string &name, std::any value) override
Sets transformation parameters.
Concrete transformer for convolution-based operations.
Template-flexible transformer base with instance-defined I/O types.
ConvolutionOperation
Specific convolution operations supported.
@ DIRECT_CONVOLUTION
Standard convolution.
TransformationType
Categories of transformation operations for discovery and organization.
Input/Output container for computation pipeline data flow with structure preservation.
Definition DataIO.hpp:24