MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Polynomial.hpp
Go to the documentation of this file.
1#pragma once
2
4
6
7/**
8 * @enum PolynomialMode
9 * @brief Defines how the polynomial function processes input values
10 */
11enum class PolynomialMode : uint8_t {
12 DIRECT, ///< Evaluates f(x) where x is the current phase/input
13 RECURSIVE, ///< Evaluates using current and previous outputs: y[n] = f(y[n-1], y[n-2], ...)
14 FEEDFORWARD ///< Evaluates using current and previous inputs: y[n] = f(x[n], x[n-1], ...)
15};
16
17class MAYAFLUX_API PolynomialContext : public NodeContext {
18public:
19 /**
20 * @brief Constructs a PolynomialContext
21 * @param value Current output value
22 * @param mode Current polynomial mode
23 * @param buffer_size Size of the input/output buffers
24 * @param input_buffer Current input buffer contents
25 * @param output_buffer Current output buffer contents
26 * @param coefficients Current polynomial coefficients
27 */
28 PolynomialContext(double value,
29 PolynomialMode mode,
30 size_t buffer_size,
31 const std::deque<double>& input_buffer,
32 const std::deque<double>& output_buffer,
33 const std::vector<double>& coefficients)
34 : NodeContext(value, typeid(PolynomialContext).name())
35 , m_mode(mode)
36 , m_buffer_size(buffer_size)
37 , m_input_buffer(input_buffer)
38 , m_output_buffer(output_buffer)
39 , m_coefficients(coefficients)
40 {
41 }
42
43 /**
44 * @brief Gets the current polynomial mode
45 * @return Current polynomial mode
46 */
47 PolynomialMode get_mode() const { return m_mode; }
48
49 /**
50 * @brief Gets the buffer size
51 * @return Current buffer size
52 */
53 size_t get_buffer_size() const { return m_buffer_size; }
54
55 /**
56 * @brief Gets the input buffer
57 * @return Reference to the input buffer
58 */
59 const std::deque<double>& get_input_buffer() const { return m_input_buffer; }
60
61 /**
62 * @brief Gets the output buffer
63 * @return Reference to the output buffer
64 */
65 const std::deque<double>& get_output_buffer() const { return m_output_buffer; }
66
67 /**
68 * @brief Gets the polynomial coefficients
69 * @return Reference to the coefficient vector
70 */
71 const std::vector<double>& get_coefficients() const { return m_coefficients; }
72
73private:
74 PolynomialMode m_mode; ///< Current processing mode
75 size_t m_buffer_size; ///< Size of the buffers
76 std::deque<double> m_input_buffer; ///< Copy of input buffer
77 std::deque<double> m_output_buffer; ///< Copy of output buffer
78 std::vector<double> m_coefficients; ///< Copy of polynomial coefficients
79 std::unordered_map<std::string, std::any> m_attributes; ///< Named attributes for callbacks
80};
81
82class MAYAFLUX_API PolynomialContextGpu
83 : public PolynomialContext,
84 public GpuVectorData {
85public:
87 double value,
88 PolynomialMode mode,
89 size_t buffer_size,
90 const std::deque<double>& input_buffer,
91 const std::deque<double>& output_buffer,
92 const std::vector<double>& coefficients,
93 std::span<const float> gpu_data)
94 : PolynomialContext(value, mode, buffer_size, input_buffer, output_buffer, coefficients)
95 , GpuVectorData(gpu_data)
96 {
97 type_id = typeid(PolynomialContextGpu).name();
98 }
99};
100
101/**
102 * @class Polynomial
103 * @brief Generator that produces values based on polynomial functions
104 *
105 * The Polynomial generator creates a signal based on mathematical functions
106 * that can operate in different modes:
107 * - Direct mode: evaluates f(x) where x is the current phase or input
108 * - Recursive mode: evaluates using current and previous outputs
109 * - Feedforward mode: evaluates using current and previous inputs
110 *
111 * This flexible approach allows implementing various types of polynomial
112 * equations, difference equations, and recurrence relations.
113 */
114class MAYAFLUX_API Polynomial : public Generator {
115public:
116 /**
117 * @brief Function type for direct polynomial evaluation
118 *
119 * Takes a single input value and returns the computed output.
120 */
121 using DirectFunction = std::function<double(double)>;
122
123 /**
124 * @brief Function type for recursive/feedforward polynomial evaluation
125 *
126 * Takes a reference to a buffer of values and returns the computed output.
127 * For recursive mode, the buffer contains previous outputs.
128 * For feedforward mode, the buffer contains current and previous inputs.
129 */
130 using BufferFunction = std::function<double(const std::deque<double>&)>;
131
132 /**
133 * @class PolynomialContext
134 * @brief Context object for polynomial node callbacks
135 *
136 * Extends the base NodeContext with polynomial-specific information
137 * such as mode, buffer contents, and coefficients.
138 */
139 ;
140
141 /**
142 * @brief Constructs a Polynomial generator in direct mode with coefficient-based definition
143 * @param coefficients Vector of polynomial coefficients (highest power first)
144 *
145 * Creates a polynomial generator that evaluates a standard polynomial function
146 * defined by the provided coefficients. The coefficients are ordered from
147 * highest power to lowest (e.g., [2, 3, 1] represents 2x² + 3x + 1).
148 */
149 explicit Polynomial(const std::vector<double>& coefficients);
150
151 /**
152 * @brief Constructs a Polynomial generator in direct mode with a custom function
153 * @param function Custom function that maps input to output value
154 *
155 * Creates a polynomial generator that evaluates a custom mathematical function
156 * provided by the user.
157 */
158 explicit Polynomial(DirectFunction function);
159
160 /**
161 * @brief Constructs a Polynomial generator in recursive or feedforward mode
162 * @param function Function that processes a buffer of values
163 * @param mode Processing mode (RECURSIVE or FEEDFORWARD)
164 * @param buffer_size Number of previous values to maintain
165 *
166 * Creates a polynomial generator that evaluates using current and previous values.
167 * In recursive mode, the buffer contains previous outputs.
168 * In feedforward mode, the buffer contains current and previous inputs.
169 */
170 Polynomial(BufferFunction function, PolynomialMode mode, size_t buffer_size);
171
172 ~Polynomial() override = default;
173
174 /**
175 * @brief Processes a single sample
176 * @param input Input value
177 * @return The next sample value from the polynomial function
178 *
179 * Computes the next output value based on the polynomial function and current mode.
180 */
181 double process_sample(double input = 0.) override;
182
183 /**
184 * @brief Processes multiple samples at once
185 * @param num_samples Number of samples to generate
186 * @return Vector of generated samples
187 *
188 * This method is more efficient than calling process_sample() repeatedly
189 * when generating multiple samples at once.
190 */
191 std::vector<double> process_batch(unsigned int num_samples) override;
192
193 /**
194 * @brief Resets the generator to its initial state
195 *
196 * Clears the internal buffers and resets to initial conditions.
197 */
198 void reset();
199
200 /**
201 * @brief Sets the polynomial coefficients (for direct mode)
202 * @param coefficients Vector of polynomial coefficients (highest power first)
203 *
204 * Updates the polynomial function to use the specified coefficients.
205 * This allows dynamically changing the polynomial during operation.
206 */
207 void set_coefficients(const std::vector<double>& coefficients);
208
209 /**
210 * @brief Sets a custom direct function
211 * @param function Custom function that maps input to output value
212 *
213 * Updates the generator to use the specified custom function.
214 */
215 void set_direct_function(DirectFunction function);
216
217 /**
218 * @brief Sets a custom buffer function
219 * @param function Function that processes a buffer of values
220 * @param mode Processing mode (RECURSIVE or FEEDFORWARD)
221 * @param buffer_size Number of previous values to maintain
222 *
223 * Updates the generator to use the specified buffer function and mode.
224 */
225 void set_buffer_function(BufferFunction function, PolynomialMode mode, size_t buffer_size);
226
227 /**
228 * @brief Sets initial conditions for recursive mode
229 * @param initial_values Vector of initial output values
230 *
231 * Sets the initial values for the output buffer in recursive mode.
232 * The values are ordered from newest to oldest.
233 */
234 void set_initial_conditions(const std::vector<double>& initial_values);
235
236 /**
237 * @brief Creates a polynomial function from coefficients
238 * @param coefficients Vector of polynomial coefficients (highest power first)
239 * @return Function that evaluates the polynomial
240 *
241 * Generates a function that evaluates the polynomial defined by the
242 * specified coefficients.
243 * The cofficients are ordered from highest power to lowest.
244 */
245 DirectFunction create_polynomial_function(const std::vector<double>& coefficients);
246
247 /**
248 * @brief Sets the input node to generate polynomial values from
249 * @param input_node Node providing the input values
250 *
251 * Configures the node to receive input from another node
252 */
253 inline void set_input_node(const std::shared_ptr<Node>& input_node) { m_input_node = input_node; }
254
255 /**
256 * @brief Gets the current polynomial mode
257 * @return Current polynomial mode
258 */
259 [[nodiscard]] PolynomialMode get_mode() const { return m_mode; }
260
261 /**
262 * @brief Gets the buffer size
263 * @return Current buffer size
264 */
265 [[nodiscard]] size_t get_buffer_size() const { return m_buffer_size; }
266
267 /**
268 * @brief Gets the polynomial coefficients
269 * @return Reference to the coefficient vector
270 */
271 [[nodiscard]] const std::vector<double>& get_coefficients() const { return m_coefficients; }
272
273 /**
274 * @brief Gets the input buffer
275 * @return Reference to the input buffer
276 */
277 [[nodiscard]] const std::deque<double>& get_input_buffer() const { return m_input_buffer; }
278
279 /**
280 * @brief Gets the output buffer
281 * @return Reference to the output buffer
282 */
283 [[nodiscard]] const std::deque<double>& get_output_buffer() const { return m_output_buffer; }
284
285 /**
286 * @brief Prints a visual representation of the polynomial function
287 *
288 * Outputs a text-based graph of the polynomial function over a range of inputs.
289 */
290 inline void printGraph() override { }
291
292 /**
293 * @brief Prints the current state and parameters
294 *
295 * Outputs the current mode, buffer contents, and other relevant information.
296 */
297 inline void printCurrent() override { }
298
299 /**
300 * @brief Sets the scaling factor for the output values
301 */
302 inline void set_amplitude(double amplitude) override { m_scale_factor = amplitude; }
303
304 /**
305 * @brief Gets the current amplitude scaling factor
306 * @return Current amplitude scaling factor
307 *
308 * This method retrieves the scaling factor applied to the output values,
309 * which controls the overall amplitude of the generated signal.
310 */
311 [[nodiscard]] inline double get_amplitude() const override { return m_scale_factor; }
312
313 void save_state() override;
314 void restore_state() override;
315
316 /**
317 * @brief Uses an external buffer context for processing
318 * @param buffer_view Span representing the external buffer
319 *
320 * Configures the generator to use an external buffer context
321 * for its internal processing, allowing integration with
322 * external data sources.
323 */
324 void set_buffer_context(std::span<double> buffer_view)
325 {
326 m_external_buffer_context = buffer_view;
327 m_use_external_context = true;
328 }
329
330 /**
331 * @brief Clear external buffer context, resume internal accumulation
332 */
334 {
335 m_use_external_context = false;
336 m_external_buffer_context = {};
337 }
338
339 [[nodiscard]] inline bool using_external_context() const
340 {
341 return m_use_external_context;
342 }
343
344protected:
345 /**
346 * @brief Creates a context object for callbacks
347 * @param value The current generated sample
348 * @return A unique pointer to a GeneratorContext object
349 *
350 * This method creates a specialized context object containing
351 * the current sample value and all oscillator parameters, providing
352 * callbacks with rich information about the oscillator's state.
353 */
354 std::unique_ptr<NodeContext> create_context(double value) override;
355
356 /**
357 * @brief Notifies all registered callbacks about a new sample
358 * @param value The newly generated sample
359 *
360 * This method is called internally whenever a new sample is generated,
361 * creating the appropriate context and invoking all registered callbacks
362 * that should receive notification about this sample.
363 */
364 void notify_tick(double value) override;
365
366private:
367 /**
368 * @brief Converts coefficient vector to a polynomial function
369 * @param coefficients Vector of polynomial coefficients (highest power first)
370 * @return Function that evaluates the polynomial
371 *
372 * Creates a function that evaluates the polynomial defined by the
373 * specified coefficients.
374 */
375 // DirectFunction create_polynomial_function(const std::vector<double>& coefficients);
376
377 PolynomialMode m_mode; ///< Current processing mode
378 DirectFunction m_direct_function; ///< Function for direct mode
379 BufferFunction m_buffer_function; ///< Function for recursive/feedforward mode
380 std::vector<double> m_coefficients; ///< Polynomial coefficients (if using coefficient-based definition)
381 std::deque<double> m_input_buffer; ///< Buffer of input values for feedforward mode
382 std::deque<double> m_output_buffer; ///< Buffer of output values for recursive mode
383 std::span<double> m_external_buffer_context; // View into external buffer
384 size_t m_buffer_size; ///< Maximum size of the buffers
385 double m_scale_factor; ///< Scaling factor for output
386 std::shared_ptr<Node> m_input_node; ///< Input node for processing
387 size_t m_current_buffer_position {}; // Where we are in the external buffer
388
389 std::deque<double> m_saved_input_buffer; ///< Buffer of input values for feedforward mode
390 std::deque<double> m_saved_output_buffer; ///< Buffer of output values for recursive mode
391 double m_saved_last_output {};
392 bool m_state_saved {};
393 bool m_use_external_context {}; // Whether to use it
394
395 /**
396 * @brief Builds buffer from external context or internal accumulation
397 * @param input Current input sample
398 * @param use_output_buffer If true, uses m_output_buffer; else m_input_buffer
399 * @return Buffer ready for m_buffer_function
400 */
401 std::deque<double> build_processing_buffer(double input, bool use_output_buffer);
402};
403
404} // namespace MayaFlux::Nodes::Generator
Base class for all signal and pattern generators in Maya Flux.
PolynomialContextGpu(double value, PolynomialMode mode, size_t buffer_size, const std::deque< double > &input_buffer, const std::deque< double > &output_buffer, const std::vector< double > &coefficients, std::span< const float > gpu_data)
std::deque< double > m_input_buffer
Copy of input buffer.
std::deque< double > m_output_buffer
Copy of output buffer.
const std::vector< double > & get_coefficients() const
Gets the polynomial coefficients.
PolynomialMode m_mode
Current processing mode.
const std::deque< double > & get_output_buffer() const
Gets the output buffer.
std::vector< double > m_coefficients
Copy of polynomial coefficients.
std::unordered_map< std::string, std::any > m_attributes
Named attributes for callbacks.
size_t get_buffer_size() const
Gets the buffer size.
PolynomialContext(double value, PolynomialMode mode, size_t buffer_size, const std::deque< double > &input_buffer, const std::deque< double > &output_buffer, const std::vector< double > &coefficients)
Constructs a PolynomialContext.
PolynomialMode get_mode() const
Gets the current polynomial mode.
const std::deque< double > & get_input_buffer() const
Gets the input buffer.
PolynomialMode m_mode
Converts coefficient vector to a polynomial function.
const std::deque< double > & get_output_buffer() const
Gets the output buffer.
std::deque< double > m_saved_output_buffer
Buffer of output values for recursive mode.
void set_amplitude(double amplitude) override
Sets the scaling factor for the output values.
PolynomialMode get_mode() const
Gets the current polynomial mode.
void set_input_node(const std::shared_ptr< Node > &input_node)
Sets the input node to generate polynomial values from.
std::deque< double > m_output_buffer
Buffer of output values for recursive mode.
void set_buffer_context(std::span< double > buffer_view)
Uses an external buffer context for processing.
void printCurrent() override
Prints the current state and parameters.
std::deque< double > m_input_buffer
Buffer of input values for feedforward mode.
const std::vector< double > & get_coefficients() const
Gets the polynomial coefficients.
double get_amplitude() const override
Gets the current amplitude scaling factor.
double m_scale_factor
Scaling factor for output.
std::span< double > m_external_buffer_context
size_t m_buffer_size
Maximum size of the buffers.
const std::deque< double > & get_input_buffer() const
Gets the input buffer.
size_t get_buffer_size() const
Gets the buffer size.
std::function< double(const std::deque< double > &)> BufferFunction
Function type for recursive/feedforward polynomial evaluation.
void clear_buffer_context()
Clear external buffer context, resume internal accumulation.
BufferFunction m_buffer_function
Function for recursive/feedforward mode.
std::shared_ptr< Node > m_input_node
Input node for processing.
std::function< double(double)> DirectFunction
Function type for direct polynomial evaluation.
DirectFunction m_direct_function
Function for direct mode.
void printGraph() override
Prints a visual representation of the polynomial function.
std::deque< double > m_saved_input_buffer
Buffer of input values for feedforward mode.
std::vector< double > m_coefficients
Polynomial coefficients (if using coefficient-based definition)
Generator that produces values based on polynomial functions.
GPU-uploadable 1D array data interface.
Base context class for node callbacks.
Definition Node.hpp:30
@ DIRECT
Stateless evaluation of current input only (combinational logic)
PolynomialMode
Defines how the polynomial function processes input values.
@ RECURSIVE
Evaluates using current and previous outputs: y[n] = f(y[n-1], y[n-2], ...)
@ FEEDFORWARD
Evaluates using current and previous inputs: y[n] = f(x[n], x[n-1], ...)