MayaFlux 0.2.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 std::span<double> input_buffer,
32 std::span<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 [[nodiscard]] PolynomialMode get_mode() const { return m_mode; }
48
49 /**
50 * @brief Gets the buffer size
51 * @return Current buffer size
52 */
53 [[nodiscard]] 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 [[nodiscard]] std::span<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 [[nodiscard]] std::span<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 [[nodiscard]] 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::span<double> m_input_buffer; ///< Copy of input buffer
77 std::span<double> m_output_buffer; ///< Copy of output buffer
78 const std::vector<double>& m_coefficients; ///< Copy of polynomial coefficients
79
80 friend class Polynomial;
81};
82
83class MAYAFLUX_API PolynomialContextGpu
84 : public PolynomialContext,
85 public GpuVectorData {
86public:
88 double value,
89 PolynomialMode mode,
90 size_t buffer_size,
91 std::span<double> input_buffer,
92 std::span<double> output_buffer,
93 const std::vector<double>& coefficients,
94 std::span<const float> gpu_data)
95 : PolynomialContext(value, mode, buffer_size, input_buffer, output_buffer, coefficients)
96 , GpuVectorData(gpu_data)
97 {
98 type_id = typeid(PolynomialContextGpu).name();
99 }
100};
101
102/**
103 * @class Polynomial
104 * @brief Generator that produces values based on polynomial functions
105 *
106 * The Polynomial generator creates a signal based on mathematical functions
107 * that can operate in different modes:
108 * - Direct mode: evaluates f(x) where x is the current phase or input
109 * - Recursive mode: evaluates using current and previous outputs
110 * - Feedforward mode: evaluates using current and previous inputs
111 *
112 * This flexible approach allows implementing various types of polynomial
113 * equations, difference equations, and recurrence relations.
114 */
115class MAYAFLUX_API Polynomial : public Generator {
116public:
117 /**
118 * @brief Function type for direct polynomial evaluation
119 *
120 * Takes a single input value and returns the computed output.
121 */
122 using DirectFunction = std::function<double(double)>;
123
124 /**
125 * @brief Function type for recursive/feedforward polynomial evaluation
126 *
127 * Takes a reference to a buffer of values and returns the computed output.
128 * For recursive mode, the buffer contains previous outputs.
129 * For feedforward mode, the buffer contains current and previous inputs.
130 */
131 using BufferFunction = std::function<double(std::span<double>)>;
132
133 /**
134 * @class PolynomialContext
135 * @brief Context object for polynomial node callbacks
136 *
137 * Extends the base NodeContext with polynomial-specific information
138 * such as mode, buffer contents, and coefficients.
139 */
140 ;
141
142 /**
143 * @brief Constructs a Polynomial generator in direct mode with coefficient-based definition
144 * @param coefficients Vector of polynomial coefficients (highest power first)
145 *
146 * Creates a polynomial generator that evaluates a standard polynomial function
147 * defined by the provided coefficients. The coefficients are ordered from
148 * highest power to lowest (e.g., [2, 3, 1] represents 2x² + 3x + 1).
149 */
150 explicit Polynomial(const std::vector<double>& coefficients);
151
152 /**
153 * @brief Constructs a Polynomial generator in direct mode with a custom function
154 * @param function Custom function that maps input to output value
155 *
156 * Creates a polynomial generator that evaluates a custom mathematical function
157 * provided by the user.
158 */
159 explicit Polynomial(DirectFunction function);
160
161 /**
162 * @brief Constructs a Polynomial generator in recursive or feedforward mode
163 * @param function Function that processes a buffer of values
164 * @param mode Processing mode (RECURSIVE or FEEDFORWARD)
165 * @param buffer_size Number of previous values to maintain
166 *
167 * Creates a polynomial generator that evaluates using current and previous values.
168 * In recursive mode, the buffer contains previous outputs.
169 * In feedforward mode, the buffer contains current and previous inputs.
170 */
171 Polynomial(BufferFunction function, PolynomialMode mode, size_t buffer_size);
172
173 ~Polynomial() override = default;
174
175 /**
176 * @brief Processes a single sample
177 * @param input Input value
178 * @return The next sample value from the polynomial function
179 *
180 * Computes the next output value based on the polynomial function and current mode.
181 */
182 double process_sample(double input = 0.) override;
183
184 /**
185 * @brief Processes multiple samples at once
186 * @param num_samples Number of samples to generate
187 * @return Vector of generated samples
188 *
189 * This method is more efficient than calling process_sample() repeatedly
190 * when generating multiple samples at once.
191 */
192 std::vector<double> process_batch(unsigned int num_samples) override;
193
194 /**
195 * @brief Resets the generator to its initial state
196 *
197 * Clears the internal buffers and resets to initial conditions.
198 */
199 void reset();
200
201 /**
202 * @brief Sets the polynomial coefficients (for direct mode)
203 * @param coefficients Vector of polynomial coefficients (highest power first)
204 *
205 * Updates the polynomial function to use the specified coefficients.
206 * This allows dynamically changing the polynomial during operation.
207 */
208 void set_coefficients(const std::vector<double>& coefficients);
209
210 /**
211 * @brief Sets a custom direct function
212 * @param function Custom function that maps input to output value
213 *
214 * Updates the generator to use the specified custom function.
215 */
216 void set_direct_function(DirectFunction function);
217
218 /**
219 * @brief Sets a custom buffer function
220 * @param function Function that processes a buffer of values
221 * @param mode Processing mode (RECURSIVE or FEEDFORWARD)
222 * @param buffer_size Number of previous values to maintain
223 *
224 * Updates the generator to use the specified buffer function and mode.
225 */
226 void set_buffer_function(BufferFunction function, PolynomialMode mode, size_t buffer_size);
227
228 /**
229 * @brief Sets initial conditions for recursive mode
230 * @param initial_values Vector of initial output values
231 *
232 * Sets the initial values for the output buffer in recursive mode.
233 * The values are ordered from newest to oldest.
234 */
235 void set_initial_conditions(const std::vector<double>& initial_values);
236
237 /**
238 * @brief Creates a polynomial function from coefficients
239 * @param coefficients Vector of polynomial coefficients (highest power first)
240 * @return Function that evaluates the polynomial
241 *
242 * Generates a function that evaluates the polynomial defined by the
243 * specified coefficients.
244 * The cofficients are ordered from highest power to lowest.
245 */
246 DirectFunction create_polynomial_function(const std::vector<double>& coefficients);
247
248 /**
249 * @brief Sets the input node to generate polynomial values from
250 * @param input_node Node providing the input values
251 *
252 * Configures the node to receive input from another node
253 */
254 inline void set_input_node(const std::shared_ptr<Node>& input_node) { m_input_node = input_node; }
255
256 /**
257 * @brief Gets the current polynomial mode
258 * @return Current polynomial mode
259 */
260 [[nodiscard]] PolynomialMode get_mode() const { return m_mode; }
261
262 /**
263 * @brief Gets the buffer size
264 * @return Current buffer size
265 */
266 [[nodiscard]] size_t get_buffer_size() const { return m_buffer_size; }
267
268 /**
269 * @brief Gets the polynomial coefficients
270 * @return Reference to the coefficient vector
271 */
272 [[nodiscard]] const std::vector<double>& get_coefficients() const { return m_coefficients; }
273
274 /**
275 * @brief Gets the input buffer
276 * @return Reference to the input buffer
277 */
278 [[nodiscard]] std::span<double> get_input_buffer() { return { m_linear_view.data(), m_ring_count }; }
279
280 /**
281 * @brief Gets the output buffer
282 * @return Reference to the output buffer
283 */
284 [[nodiscard]] std::span<double> get_output_buffer() { return { m_linear_view.data(), m_ring_count }; }
285
286 /**
287 * @brief Prints a visual representation of the polynomial function
288 *
289 * Outputs a text-based graph of the polynomial function over a range of inputs.
290 */
291 inline void printGraph() override { }
292
293 /**
294 * @brief Prints the current state and parameters
295 *
296 * Outputs the current mode, buffer contents, and other relevant information.
297 */
298 inline void printCurrent() override { }
299
300 /**
301 * @brief Sets the scaling factor for the output values
302 */
303 inline void set_amplitude(double amplitude) override { m_scale_factor = amplitude; }
304
305 /**
306 * @brief Gets the current amplitude scaling factor
307 * @return Current amplitude scaling factor
308 *
309 * This method retrieves the scaling factor applied to the output values,
310 * which controls the overall amplitude of the generated signal.
311 */
312 [[nodiscard]] inline double get_amplitude() const override { return m_scale_factor; }
313
314 void save_state() override;
315 void restore_state() override;
316
317 /**
318 * @brief Uses an external buffer context for processing
319 * @param buffer_view Span representing the external buffer
320 *
321 * Configures the generator to use an external buffer context
322 * for its internal processing, allowing integration with
323 * external data sources.
324 */
325 void set_buffer_context(std::span<double> buffer_view)
326 {
327 m_external_buffer_context = buffer_view;
328 m_use_external_context = true;
329 }
330
331 /**
332 * @brief Clear external buffer context, resume internal accumulation
333 */
335 {
336 m_use_external_context = false;
337 m_external_buffer_context = {};
338 }
339
340 [[nodiscard]] inline bool using_external_context() const
341 {
342 return m_use_external_context;
343 }
344
345 /**
346 * @brief Retrieves the last created context object
347 * @return Reference to the last PolynomialContext object
348 *
349 * This method provides access to the most recent PolynomialContext object
350 * created by the polynomial generator. This context contains information
351 * about the generator's state at the time of the last output generation.
352 */
353 NodeContext& get_last_context() override;
354
355protected:
356 /**
357 * @brief Updates the context object with the current node state
358 * @param value The current sample value
359 */
360 void update_context(double value) override;
361
362 /**
363 * @brief Notifies all registered callbacks about a new sample
364 * @param value The newly generated sample
365 *
366 * This method is called internally whenever a new sample is generated,
367 * creating the appropriate context and invoking all registered callbacks
368 * that should receive notification about this sample.
369 */
370 void notify_tick(double value) override;
371
372private:
373 /**
374 * @brief Converts coefficient vector to a polynomial function
375 * @param coefficients Vector of polynomial coefficients (highest power first)
376 * @return Function that evaluates the polynomial
377 *
378 * Creates a function that evaluates the polynomial defined by the
379 * specified coefficients.
380 */
381 // DirectFunction create_polynomial_function(const std::vector<double>& coefficients);
382
383 PolynomialMode m_mode; ///< Current processing mode
384 DirectFunction m_direct_function; ///< Function for direct mode
385 BufferFunction m_buffer_function; ///< Function for recursive/feedforward mode
386 std::vector<double> m_coefficients; ///< Polynomial coefficients (if using coefficient-based definition)
387 std::span<double> m_external_buffer_context; // View into external buffer
388
389 std::vector<double> m_ring_data;
390 std::vector<double> m_linear_view;
391 size_t m_ring_head {};
392 size_t m_ring_count {};
393
394 std::vector<double> m_saved_ring_data;
395 size_t m_saved_ring_head {};
396 size_t m_saved_ring_count {};
397 size_t m_buffer_size {}; ///< Maximum size of the buffers
398 double m_scale_factor; ///< Scaling factor for output
399 std::shared_ptr<Node> m_input_node; ///< Input node for processing
400 size_t m_current_buffer_position {}; // Where we are in the external buffer
401
402 double m_saved_last_output {};
403 bool m_use_external_context {}; // Whether to use it
404
407
408 void ring_push(double val);
409
410 double ring_at(size_t i);
411
412 std::span<double> linearized_view();
413
414 std::span<double> external_context_view(double input);
415};
416
417} // namespace MayaFlux::Nodes::Generator
Base class for all signal and pattern generators in Maya Flux.
PolynomialContextGpu(double value, PolynomialMode mode, size_t buffer_size, std::span< double > input_buffer, std::span< double > output_buffer, const std::vector< double > &coefficients, std::span< const float > gpu_data)
std::span< double > get_output_buffer() const
Gets the output buffer.
const std::vector< double > & m_coefficients
Copy of polynomial coefficients.
const std::vector< double > & get_coefficients() const
Gets the polynomial coefficients.
std::span< double > m_output_buffer
Copy of output buffer.
PolynomialMode m_mode
Current processing mode.
PolynomialContext(double value, PolynomialMode mode, size_t buffer_size, std::span< double > input_buffer, std::span< double > output_buffer, const std::vector< double > &coefficients)
Constructs a PolynomialContext.
std::span< double > m_input_buffer
Copy of input buffer.
std::span< double > get_input_buffer() const
Gets the input buffer.
size_t get_buffer_size() const
Gets the buffer size.
PolynomialMode get_mode() const
Gets the current polynomial mode.
std::function< double(std::span< double >)> BufferFunction
Function type for recursive/feedforward polynomial evaluation.
PolynomialMode m_mode
Converts coefficient vector to a polynomial function.
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.
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.
const std::vector< double > & get_coefficients() const
Gets the polynomial coefficients.
std::vector< double > m_saved_ring_data
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 get_buffer_size() const
Gets the buffer size.
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::span< double > get_output_buffer()
Gets the output buffer.
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::span< double > get_input_buffer()
Gets the input buffer.
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], ...)