MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Boolean.hpp
Go to the documentation of this file.
1#pragma once
2
3/**
4 * @file Boolean.hpp
5 * @brief Pure decision functions of bits and an array of numbers.
6 *
7 * The boolean counterpart of Kernels.hpp. Every kernel returns a bit and
8 * keeps whatever it remembers in the array it is given, so the behaviour is
9 * the numbers: the array can be retuned live, saved and restored with the
10 * node, and cloned. A signal is a bit when it exceeds the kernel's threshold,
11 * and a kernel driven by an edge counts a signal that starts high as a rise.
12 *
13 * Four shapes, each the function type of the matching Logic constructor:
14 * - history kernels: `bool(span<const bool> history, span<const double>)`,
15 * history[0] the newest bit
16 * - input kernels: `bool(double input, span<double>)`
17 * - time kernels: `bool(double input, double time, span<double>)`
18 * - parallel kernels: `bool(const vector<double>& inputs, span<double>)`, one
19 * value per input slot as documented by each kernel
20 *
21 * `Logic(Kinesis::Discrete::truth_table, 3, truth_table_state(3, rule))` is a
22 * complete node. Every kernel returns false for an array too short to hold
23 * its layout.
24 */
25
27
28/**
29 * @brief One step of the 32-bit xorshift generator.
30 * @param state Nonzero state; zero stays zero
31 *
32 * Small enough to be held exactly in an element of the array, which is what
33 * the random kernels do.
34 */
35[[nodiscard]] inline uint32_t xorshift32(uint32_t state) noexcept
36{
37 state ^= state << 13U;
38 state ^= state >> 17U;
39 state ^= state << 5U;
40 return state;
41}
42
43// ---------------------------------------------------------------------------
44// History kernels
45// ---------------------------------------------------------------------------
46
47/**
48 * @brief Builds the array truth_table reads.
49 * @param arity Number of history bits, at most 6
50 * @param rule Output for each input pattern; bit i is the output when the
51 * pattern, with history[0] as the lowest bit, equals i
52 *
53 * Layout: [arity, outputs...], 2^arity outputs of 0 or 1. For larger arities
54 * write the array directly.
55 */
56[[nodiscard]] MAYAFLUX_API std::vector<double> truth_table_state(size_t arity, uint64_t rule);
57
58/**
59 * @brief Any boolean function of the last bits, as a table.
60 *
61 * coefs: [arity, outputs...]. Reads the arity newest bits, missing ones as
62 * zero, and returns the output at that pattern. A table is a universal gate,
63 * so this covers AND, XOR, majority and every other combinational rule,
64 * and with a rule number over three bits it is an elementary automaton run
65 * through time.
66 */
67[[nodiscard]] MAYAFLUX_API bool truth_table(
68 std::span<const bool> history, std::span<const double> coefs) noexcept;
69
70/**
71 * @brief True when at least k of the last n bits are set.
72 *
73 * coefs: [n, k]. Majority, burst detection and k-of-n voting.
74 */
75[[nodiscard]] MAYAFLUX_API bool count_at_least(
76 std::span<const bool> history, std::span<const double> coefs) noexcept;
77
78// ---------------------------------------------------------------------------
79// Input kernels
80// ---------------------------------------------------------------------------
81
82/**
83 * @brief Builds the array hysteresis_gate reads and writes.
84 * @param low Level the input must fall below to release
85 * @param high Level the input must rise above to engage
86 *
87 * Layout: [low, high, state].
88 */
89[[nodiscard]] MAYAFLUX_API std::vector<double> hysteresis_gate_state(double low, double high);
90
91/**
92 * @brief Schmitt trigger: engages above high, releases below low, holds between.
93 *
94 * coefs: [low, high, state].
95 */
96[[nodiscard]] MAYAFLUX_API bool hysteresis_gate(double input, std::span<double> coefs) noexcept;
97
98/**
99 * @brief Builds the array rising_toggle reads and writes.
100 * @param threshold Level the input must rise through
101 *
102 * Layout: [threshold, latched, state].
103 */
104[[nodiscard]] MAYAFLUX_API std::vector<double> rising_toggle_state(double threshold = 0.5);
105
106/**
107 * @brief Flip-flop: the output inverts on every rise of the input.
108 *
109 * coefs: [threshold, latched, state]. Divide by two with a half-rate square
110 * wave out.
111 */
112[[nodiscard]] MAYAFLUX_API bool rising_toggle(double input, std::span<double> coefs) noexcept;
113
114/**
115 * @brief Builds the array edge_divider reads and writes.
116 * @param n Pass every n-th rise
117 * @param offset Which of each n rises passes, counted from zero
118 * @param threshold Level the input must rise through
119 *
120 * Layout: [threshold, latched, edges, n, offset, pass].
121 */
122[[nodiscard]] MAYAFLUX_API std::vector<double> edge_divider_state(
123 size_t n, size_t offset = 0, double threshold = 0.5);
124
125/**
126 * @brief Gate divider: the input passes only during every n-th pulse.
127 *
128 * coefs: [threshold, latched, edges, n, offset, pass]. The pulse keeps its
129 * own length; the pulses in between are dropped.
130 */
131[[nodiscard]] MAYAFLUX_API bool edge_divider(double input, std::span<double> coefs) noexcept;
132
133/**
134 * @brief Builds the array bernoulli_gate reads and writes.
135 * @param probability Chance each pulse passes, 0 to 1
136 * @param seed Generator state; zero selects a fixed seed
137 * @param threshold Level the input must rise through
138 *
139 * Layout: [threshold, latched, probability, state, pass].
140 */
141[[nodiscard]] MAYAFLUX_API std::vector<double> bernoulli_gate_state(
142 double probability, uint32_t seed = 0, double threshold = 0.5);
143
144/**
145 * @brief Probabilistic gate: each pulse passes with the given probability.
146 *
147 * coefs: [threshold, latched, probability, state, pass]. The draw happens
148 * once per rise with xorshift32, so a clone with the same array repeats the
149 * same decisions.
150 */
151[[nodiscard]] MAYAFLUX_API bool bernoulli_gate(double input, std::span<double> coefs) noexcept;
152
153/**
154 * @brief Builds the array galois_lfsr reads and writes.
155 * @param taps Feedback mask; 0xB400 gives 16 bits and 0x80200003 gives 32 of maximal length
156 * @param seed Starting register; zero selects 1
157 * @param threshold Level the input must rise through
158 *
159 * Layout: [threshold, latched, taps, register].
160 */
161[[nodiscard]] MAYAFLUX_API std::vector<double> galois_lfsr_state(
162 uint32_t taps, uint32_t seed = 1, double threshold = 0.5);
163
164/**
165 * @brief Linear feedback shift register clocked by the rises of the input.
166 *
167 * coefs: [threshold, latched, taps, register]. Each rise shifts the register
168 * right and, when a bit fell out, folds the taps in. The output is the low
169 * bit, a pseudo-random bit stream with a period set by the taps.
170 */
171[[nodiscard]] MAYAFLUX_API bool galois_lfsr(double input, std::span<double> coefs) noexcept;
172
173/**
174 * @brief Builds the array state_machine reads and writes.
175 * @param table Per state, four entries: next state and output when the input
176 * bit is 0, then next state and output when it is 1
177 * @param threshold Level that makes the input bit 1
178 * @param initial Starting state
179 *
180 * Layout: [threshold, states, state, table...]. The state count is the table
181 * length over four.
182 */
183[[nodiscard]] MAYAFLUX_API std::vector<double> state_machine_state(
184 std::span<const double> table, double threshold = 0.5, size_t initial = 0);
185
186/**
187 * @brief Mealy machine: the state and the input bit pick the next state and the output.
188 *
189 * coefs: [threshold, states, state, table...]. Counters, debouncers, pulse
190 * sequencers and every other finite controller are tables. An out of range
191 * state falls back to state zero.
192 */
193[[nodiscard]] MAYAFLUX_API bool state_machine(double input, std::span<double> coefs) noexcept;
194
195/**
196 * @brief The maximally even placement of pulses among steps, as a 0 or 1 table.
197 * @param pulses Number of ones
198 * @param steps Length of the table
199 * @param rotation Steps to rotate the start by
200 *
201 * Spreads the pulses as evenly as the grid allows, the Euclidean rhythm:
202 * (3, 8) gives 1 0 0 1 0 0 1 0. Feed it to step_sequence_state or
203 * step_pattern.
204 */
205[[nodiscard]] MAYAFLUX_API std::vector<double> maximally_even_sequence(
206 size_t pulses, size_t steps, size_t rotation = 0);
207
208/**
209 * @brief A table of bits advanced by the rises of the input.
210 *
211 * The array is step_sequence_state's, read as bits: an entry above 0.5 is a
212 * one. Each rise moves to the next entry and wraps.
213 */
214[[nodiscard]] MAYAFLUX_API bool step_pattern(double input, std::span<double> coefs) noexcept;
215
216// ---------------------------------------------------------------------------
217// Time kernels
218// ---------------------------------------------------------------------------
219
220/**
221 * @brief Builds the array refractory_gate reads and writes.
222 * @param period Seconds to stay shut after firing
223 * @param threshold Level the input must exceed
224 *
225 * Layout: [last fire time, period, threshold].
226 */
227[[nodiscard]] MAYAFLUX_API std::vector<double> refractory_gate_state(double period, double threshold = 0.5);
228
229/**
230 * @brief Fires while the input is high, then ignores it for a period.
231 *
232 * coefs: [last fire time, period, threshold]. A held input fires again
233 * once per period.
234 */
235[[nodiscard]] MAYAFLUX_API bool refractory_gate(
236 double input, double time, std::span<double> coefs) noexcept;
237
238/**
239 * @brief Builds the array one_shot reads and writes.
240 * @param duration Seconds the output stays high after a rise
241 * @param threshold Level the input must rise through
242 *
243 * Layout: [threshold, latched, release time, duration].
244 */
245[[nodiscard]] MAYAFLUX_API std::vector<double> one_shot_state(double duration, double threshold = 0.5);
246
247/**
248 * @brief Monostable: every rise of the input opens the output for a fixed time.
249 *
250 * coefs: [threshold, latched, release time, duration]. A rise during the pulse
251 * restarts it; the input's own length does not matter.
252 */
253[[nodiscard]] MAYAFLUX_API bool one_shot(
254 double input, double time, std::span<double> coefs) noexcept;
255
256// ---------------------------------------------------------------------------
257// Parallel kernels: one value per input slot
258// ---------------------------------------------------------------------------
259
260/**
261 * @brief Builds the array set_reset_latch reads and writes.
262 * @param threshold Level that makes a slot a one
263 *
264 * Layout: [threshold, state].
265 */
266[[nodiscard]] MAYAFLUX_API std::vector<double> set_reset_latch_state(double threshold = 0.5);
267
268/**
269 * @brief Memory cell: slot 0 sets it, slot 1 resets it, reset wins.
270 *
271 * coefs: [threshold, state]. Holds while neither is high.
272 */
273[[nodiscard]] MAYAFLUX_API bool set_reset_latch(
274 const std::vector<double>& inputs, std::span<double> coefs) noexcept;
275
276/**
277 * @brief Builds the array comparator reads and writes.
278 * @param margin Half width of the dead band around equality
279 *
280 * Layout: [margin, state].
281 */
282[[nodiscard]] MAYAFLUX_API std::vector<double> comparator_state(double margin = 0.0);
283
284/**
285 * @brief Signal against signal: true once slot 0 exceeds slot 1 by the margin.
286 *
287 * coefs: [margin, state]. It releases when slot 0 falls below slot 1 by the
288 * margin and holds in between, so two signals that cross slowly do not chatter.
289 */
290[[nodiscard]] MAYAFLUX_API bool comparator(
291 const std::vector<double>& inputs, std::span<double> coefs) noexcept;
292
293/**
294 * @brief True while slot 0 lies strictly between slot 1 and slot 2.
295 *
296 * Needs no array; the bounds are signals and can move.
297 */
298[[nodiscard]] MAYAFLUX_API bool window_comparator(
299 const std::vector<double>& inputs, std::span<const double> coefs) noexcept;
300
301/**
302 * @brief Builds the array signals_at_least reads.
303 * @param k How many slots must be high
304 * @param threshold Level that makes a slot a one
305 *
306 * Layout: [threshold, k].
307 */
308[[nodiscard]] MAYAFLUX_API std::vector<double> signals_at_least_state(size_t k, double threshold = 0.5);
309
310/**
311 * @brief True when at least k of the input slots are high.
312 *
313 * coefs: [threshold, k]. Coincidence at k equal to the slot count, any at 1,
314 * majority in between.
315 */
316[[nodiscard]] MAYAFLUX_API bool signals_at_least(
317 const std::vector<double>& inputs, std::span<const double> coefs) noexcept;
318
319/**
320 * @brief Builds the array input_truth_table reads.
321 * @param arity Number of input slots, at most 6
322 * @param rule Output for each pattern; bit i is the output when the pattern,
323 * slot 0 as the lowest bit, equals i
324 * @param threshold Level that makes a slot a one
325 *
326 * Layout: [threshold, arity, outputs...].
327 */
328[[nodiscard]] MAYAFLUX_API std::vector<double> input_truth_table_state(
329 size_t arity, uint64_t rule, double threshold = 0.5);
330
331/**
332 * @brief Any boolean function of the input slots, as a table.
333 *
334 * coefs: [threshold, arity, outputs...]. The signal counterpart of
335 * truth_table: AND, XOR, majority or any other gate of the slots, missing
336 * slots read as zero.
337 */
338[[nodiscard]] MAYAFLUX_API bool input_truth_table(
339 const std::vector<double>& inputs, std::span<const double> coefs) noexcept;
340
341/**
342 * @brief Builds the array clocked_register reads and writes.
343 * @param length Number of stages
344 * @param tap Which stage is read out, 0 the newest
345 * @param threshold Level that makes a slot a one
346 *
347 * Layout: [threshold, latched, length, tap, stages...].
348 */
349[[nodiscard]] MAYAFLUX_API std::vector<double> clocked_register_state(
350 size_t length, size_t tap, double threshold = 0.5);
351
352/**
353 * @brief Shift register: slot 1 is sampled into it on every rise of slot 0.
354 *
355 * coefs: [threshold, latched, length, tap, stages...]. The output is the
356 * chosen stage, so the data a while ago comes back out on the clock: a
357 * clocked delay line of bits, and with a random or feedback data signal a
358 * sequence generator.
359 */
360[[nodiscard]] MAYAFLUX_API bool clocked_register(
361 const std::vector<double>& inputs, std::span<double> coefs) noexcept;
362
363} // namespace MayaFlux::Kinesis::Discrete
uint64_t offset
Definition Composite.cpp:10
Core::GlobalInputConfig input
Definition Config.cpp:42
float threshold
bool one_shot(double input, double time, std::span< double > coefs) noexcept
Monostable: every rise of the input opens the output for a fixed time.
Definition Boolean.cpp:242
bool bernoulli_gate(double input, std::span< double > coefs) noexcept
Probabilistic gate: each pulse passes with the given probability.
Definition Boolean.cpp:129
bool truth_table(std::span< const bool > history, std::span< const double > coefs) noexcept
Any boolean function of the last bits, as a table.
Definition Boolean.cpp:45
std::vector< double > state_machine_state(std::span< const double > table, double threshold, size_t initial)
Builds the array state_machine reads and writes.
Definition Boolean.cpp:169
std::vector< double > truth_table_state(size_t arity, uint64_t rule)
Builds the array truth_table reads.
Definition Boolean.cpp:33
uint32_t xorshift32(uint32_t state) noexcept
One step of the 32-bit xorshift generator.
Definition Boolean.hpp:35
bool comparator(const std::vector< double > &inputs, std::span< double > coefs) noexcept
Signal against signal: true once slot 0 exceeds slot 1 by the margin.
Definition Boolean.cpp:274
std::vector< double > signals_at_least_state(size_t k, double threshold)
Builds the array signals_at_least reads.
Definition Boolean.cpp:294
std::vector< double > bernoulli_gate_state(double probability, uint32_t seed, double threshold)
Builds the array bernoulli_gate reads and writes.
Definition Boolean.cpp:124
std::vector< double > edge_divider_state(size_t n, size_t offset, double threshold)
Builds the array edge_divider reads and writes.
Definition Boolean.cpp:104
bool window_comparator(const std::vector< double > &inputs, std::span< const double >) noexcept
True while slot 0 lies strictly between slot 1 and slot 2.
Definition Boolean.cpp:287
bool step_pattern(double input, std::span< double > coefs) noexcept
A table of bits advanced by the rises of the input.
Definition Boolean.cpp:215
bool count_at_least(std::span< const bool > history, std::span< const double > coefs) noexcept
True when at least k of the last n bits are set.
Definition Boolean.cpp:62
std::vector< double > hysteresis_gate_state(double low, double high)
Builds the array hysteresis_gate reads and writes.
Definition Boolean.cpp:72
std::vector< double > comparator_state(double margin)
Builds the array comparator reads and writes.
Definition Boolean.cpp:269
std::vector< double > galois_lfsr_state(uint32_t taps, uint32_t seed, double threshold)
Builds the array galois_lfsr reads and writes.
Definition Boolean.cpp:146
bool refractory_gate(double input, double time, std::span< double > coefs) noexcept
Fires while the input is high, then ignores it for a period.
Definition Boolean.cpp:225
std::vector< double > maximally_even_sequence(size_t pulses, size_t steps, size_t rotation)
The maximally even placement of pulses among steps, as a 0 or 1 table.
Definition Boolean.cpp:201
bool rising_toggle(double input, std::span< double > coefs) noexcept
Flip-flop: the output inverts on every rise of the input.
Definition Boolean.cpp:94
bool clocked_register(const std::vector< double > &inputs, std::span< double > coefs) noexcept
Shift register: slot 1 is sampled into it on every rise of slot 0.
Definition Boolean.cpp:349
std::vector< double > refractory_gate_state(double period, double threshold)
Builds the array refractory_gate reads and writes.
Definition Boolean.cpp:220
bool state_machine(double input, std::span< double > coefs) noexcept
Mealy machine: the state and the input bit pick the next state and the output.
Definition Boolean.cpp:182
bool input_truth_table(const std::vector< double > &inputs, std::span< const double > coefs) noexcept
Any boolean function of the input slots, as a table.
Definition Boolean.cpp:323
bool signals_at_least(const std::vector< double > &inputs, std::span< const double > coefs) noexcept
True when at least k of the input slots are high.
Definition Boolean.cpp:299
std::vector< double > input_truth_table_state(size_t arity, uint64_t rule, double threshold)
Builds the array input_truth_table reads.
Definition Boolean.cpp:310
std::vector< double > clocked_register_state(size_t length, size_t tap, double threshold)
Builds the array clocked_register reads and writes.
Definition Boolean.cpp:340
std::vector< double > set_reset_latch_state(double threshold)
Builds the array set_reset_latch reads and writes.
Definition Boolean.cpp:252
std::vector< double > one_shot_state(double duration, double threshold)
Builds the array one_shot reads and writes.
Definition Boolean.cpp:237
bool galois_lfsr(double input, std::span< double > coefs) noexcept
Linear feedback shift register clocked by the rises of the input.
Definition Boolean.cpp:151
bool set_reset_latch(const std::vector< double > &inputs, std::span< double > coefs) noexcept
Memory cell: slot 0 sets it, slot 1 resets it, reset wins.
Definition Boolean.cpp:257
bool edge_divider(double input, std::span< double > coefs) noexcept
Gate divider: the input passes only during every n-th pulse.
Definition Boolean.cpp:109
bool hysteresis_gate(double input, std::span< double > coefs) noexcept
Schmitt trigger: engages above high, releases below low, holds between.
Definition Boolean.cpp:77
std::vector< double > rising_toggle_state(double threshold)
Builds the array rising_toggle reads and writes.
Definition Boolean.cpp:89