Operator Calculus, Co.
Browse Studio documentation
On this page

Stochastic Noise 🎲

add_stochastic_noise_operator(ctx, field, opts)

Add coloured stochastic noise with configurable spectral characteristics and stochastic calculus law. Useful for broadband forcing, thermal fluctuations, and correlated random drives without explicitly tracking a separate mean-reverting state operator.

Method Signature

add_stochastic_noise_operator(ctx, field, [options]) -> operator

Returns: Operator handle (userdata)

Mathematical Formulation

Ornstein-Uhlenbeck Process:

dΞΎ=βˆ’ΞΎΟ„dt+Οƒβ‹…dWtd\xi = -\frac{\xi}{\tau} dt + \sigma \cdot dW_t

where:

  • ΞΎ\xi is the noise state
  • Ο„\tau is the autocorrelation time
  • Οƒ\sigma is the noise intensity
  • dWtdW_t is a Wiener increment

Spectral Characteristics:

The noise has power spectral density:

S(f)∝11+(2Ο€fΟ„)2β‹…βˆ£fβˆ£βˆ’Ξ±S(f) \propto \frac{1}{1 + (2\pi f \tau)^2} \cdot |f|^{-\alpha}

where Ξ±\alpha controls the spectral color:

  • Ξ±=0\alpha = 0: White noise (flat spectrum)
  • Ξ±=1\alpha = 1: Pink/flicker noise (1/f1/f)
  • Ξ±=2\alpha = 2: Brownian/red noise (1/f21/f^2)

Stochastic Calculus Laws:

  • ItΓ΄: Standard interpretation; dWdW independent of current state
  • Stratonovich: Midpoint rule; preserves chain rule; often preferred for physical systems

Parameters

Parameter Type Default Range Description
sigma double β‰₯0 Noise intensity (standard deviation) (required)
tau double 0.0 β‰₯0 Autocorrelation decay time (0 = white noise)
alpha double 0.0 [0, 2.5] Spectral exponent controlling color
seed integer 0 β‰₯0 RNG seed (0 = auto from system)
law enum "ito" ito, stratonovich Stochastic calculus convention

Boundary & Initial Conditions

  • Operates elementwise; no boundary handling required
  • Internal state initialized to zero; transient period β‰ˆ 3Ο„3\tau
  • For reproducible results, set explicit seed

Stability & Convergence

  • White noise (Ο„=0\tau = 0): Uncorrelated samples; scales with Ξ”t\sqrt{\Delta t}
  • Colored noise (Ο„>0\tau > 0): Requires Ξ”tβ‰ͺΟ„\Delta t \ll \tau for accurate dynamics
  • Large Ξ±\alpha values produce slowly-varying (low-frequency dominated) noise
  • Stratonovich interpretation avoids spurious drift in multiplicative noise contexts

Performance Notes

  • One random number generation per element per timestep
  • Colored noise maintains per-element state (O(N) memory)
  • Seed affects entire field; use different operators for independent noise sources

Examples

-- Simple white noise
ooc.add_stochastic_noise_operator(ctx, field, {
    sigma = 0.1
})

-- Colored noise with Stratonovich interpretation
ooc.add_stochastic_noise_operator(ctx, field, {
    sigma = 0.15,
    law = "stratonovich"
})

-- Ornstein-Uhlenbeck process
ooc.add_stochastic_noise_operator(ctx, field, {
    sigma = 0.05,
    tau = 0.1
})

-- Pink noise (1/f spectrum)
ooc.add_stochastic_noise_operator(ctx, field, {
    sigma = 0.05,
    tau = 0.1,
    alpha = 1.0,
    seed = 42
})

-- Brownian noise (1/fΒ² spectrum)
ooc.add_stochastic_noise_operator(ctx, field, {
    sigma = 0.02,
    tau = 0.5,
    alpha = 2.0
})

-- Reproducible noise for testing
ooc.add_stochastic_noise_operator(ctx, field, {
    sigma = 0.1,
    seed = 12345
})

Ornstein-Uhlenbeck 🌫️

add_ornstein_uhlenbeck_operator(ctx, field, opts)

Evolve a field as an exact discrete-time Ornstein-Uhlenbeck process. This is the dedicated mean-reverting stochastic operator for direct state evolution, separate from additive Stochastic Noise.

Method Signature

add_ornstein_uhlenbeck_operator(ctx, field, [options]) -> operator

Returns: Operator handle (userdata)

Mathematical Formulation

For each evolved scalar coordinate:

xt+Ξ”t=ΞΌ+eβˆ’Ξ”t/Ο„(xtβˆ’ΞΌ)+Οƒ1βˆ’eβˆ’2Ξ”t/τ ξx_{t + \Delta t} = \mu + e^{-\Delta t / \tau}(x_t - \mu) + \sigma\sqrt{1 - e^{-2\Delta t / \tau}}\,\xi

where:

  • ΞΌ\mu is the mean
  • Ο„\tau is the relaxation time
  • Οƒ\sigma is the stationary standard deviation
  • ξ∼N(0,1)\xi \sim \mathcal{N}(0, 1)

For complex fields:

  • component: evolve real and imaginary parts independently
  • polar: evolve magnitude and phase coordinates independently, then reconstruct the complex sample

Parameters

Parameter Type Default Range Description
mean double 0.0 unbounded Mean reversion target
sigma double 1.0 β‰₯0 Stationary standard deviation
tau double 1.0 >0 Relaxation time constant
complex_mode enum "component" component, polar Complex-field evolution mode
seed integer 0 β‰₯0 RNG seed (0 = derive from context/system)

Boundary & Initial Conditions

  • Operates elementwise; no boundary handling required
  • Maintains per-element stochastic state through the field itself
  • polar mode is ignored for real fields

Stability & Convergence

  • Uses the exact discrete-time OU transition, so it remains well behaved for any positive tau
  • Smaller tau values produce faster relaxation toward mean
  • sigma controls the long-run spread, not a per-step increment scale

Performance Notes

  • One Gaussian draw per evolved scalar coordinate each step
  • Complex polar mode requires extra magnitude/phase conversions
  • Useful when the field itself should relax stochastically rather than receive additive forcing

Examples

-- Real-valued OU relaxation
ooc.add_ornstein_uhlenbeck_operator(ctx, field, {
    mean = 0.25,
    sigma = 0.12,
    tau = 0.35
})

-- Complex OU in polar coordinates
ooc.add_ornstein_uhlenbeck_operator(ctx, complex_field, {
    mean = 0.0,
    sigma = 0.1,
    tau = 0.5,
    complex_mode = "polar"
})

-- Seeded playback for reproducible stochastic trajectories
ooc.add_ornstein_uhlenbeck_operator(ctx, state, {
    sigma = 0.08,
    tau = 1.2,
    seed = 4242
})

Random Fourier 🎡

add_stimulus_operator(ctx, field, opts)

Generate spatially-correlated random fields using random Fourier features. Creates band-limited noise patterns with controllable spectral content, useful for initial conditions, driving forces, and procedural textures.

Method Signature

add_stimulus_operator(ctx, field, [options]) -> operator

Returns: Operator handle (userdata)

Note: Requires type = "stimulus_random_fourier".

Mathematical Formulation

The field is constructed as a superposition of random sinusoids:

u(x,t)=Aβˆ‘n=1Nwncos⁑(knβ‹…x+Ο•n+Ο‰t)u(\mathbf{x}, t) = A \sum_{n=1}^{N} w_n \cos(\mathbf{k}_n \cdot \mathbf{x} + \phi_n + \omega t)

where:

  • AA is the amplitude
  • NN is feature_count
  • kn\mathbf{k}_n are random wavenumbers in [kmin⁑,kmax⁑][k_{\min}, k_{\max}]
  • Ο•n\phi_n are random phases in [0,2Ο€][0, 2\pi]
  • wnw_n are weights from the spectral slope: wn∝∣knβˆ£βˆ’Ξ²/2w_n \propto |k_n|^{-\beta/2}
  • Ο‰\omega is the temporal frequency (optional)

Spectral Slope:

When spectral_slope (Ξ²\beta) is specified, the power spectral density follows:

S(k)∝∣kβˆ£βˆ’Ξ²S(k) \propto |k|^{-\beta}

Parameters

Core Parameters:

Parameter Type Default Range Description
type string β€” β€” Must be "stimulus_random_fourier"
amplitude double unbounded Overall scale of features (required)
feature_count integer 16 β‰₯1 Number of random basis functions
seed integer 1 β‰₯1 RNG seed for reproducibility

Spectral Parameters:

Parameter Type Default Range Description
k_min double 0.1 β‰₯0 Minimum wavenumber (rad/unit)
k_max double 1.0 >k_min Maximum wavenumber (rad/unit)
spectral_slope double 0.0 unbounded Spectral decay exponent Ξ²\beta

Temporal Parameters:

Parameter Type Default Range Description
omega double 0.0 unbounded Temporal angular frequency (rad/s)
time_offset double 0.0 unbounded Additional time shift
nominal_dt double 0.0 β‰₯0 Lock time to fixed timestep
fixed_clock boolean false β€” Use nominal_dt for time evolution

Coordinate Mapping:

Parameter Type Default Description
coord_mode enum "axis" Coordinate mode: axis, angle, radial, separable
coord_axis enum "x" Axis for 1D mapping
coord_combine enum "multiply" Combine rule for separable: multiply, add
coord_angle double 0.0 Angle for angle-mode (radians)
origin_x, origin_y double 0.0 Coordinate origin
spacing_x, spacing_y double 1.0 Grid spacing
coord_center_x, coord_center_y double 0.0 Center for radial mode
coord_velocity_x, coord_velocity_y double 0.0 Moving center velocity

Output Parameters:

Parameter Type Default Description
scale_by_dt boolean true Scale writes by dt

Boundary & Initial Conditions

  • Generates field values based on coordinates; no explicit boundaries
  • Periodic by nature due to sinusoidal basis
  • Same seed produces identical patterns

Stability & Convergence

  • Output is bounded by Aβ‹…NA \cdot N (sum of all features)
  • spectral_slope > 0 produces smoother fields (low-frequency dominated)
  • spectral_slope < 0 produces rougher fields (high-frequency dominated)
  • More features improve statistical convergence at cost of computation

Performance Notes

  • Computational cost: O(N Γ— feature_count) per timestep
  • Features are precomputed once at creation; only phases advance
  • Use fixed_clock for deterministic, frame-rate-independent animation

Examples

-- Basic random Fourier field
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_random_fourier",
    amplitude = 0.5,
    k_min = 0.1,
    k_max = 2.0,
    feature_count = 32,
    seed = 99
})

-- Red noise spectrum (smooth variations)
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_random_fourier",
    amplitude = 0.2,
    spectral_slope = 2.0,  -- 1/kΒ² falloff
    feature_count = 64
})

-- Pink noise spectrum (1/f)
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_random_fourier",
    amplitude = 0.3,
    spectral_slope = 1.0,
    k_min = 0.05,
    k_max = 5.0,
    feature_count = 48
})

-- Time-varying random field
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_random_fourier",
    amplitude = 0.4,
    omega = 0.5,  -- slow temporal variation
    feature_count = 24
})

-- Narrow-band noise (limited wavenumber range)
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_random_fourier",
    amplitude = 0.3,
    k_min = 0.8,
    k_max = 1.2,  -- centered around k=1
    feature_count = 16
})

-- Radial coordinate mapping
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_random_fourier",
    amplitude = 0.5,
    coord_mode = "radial",
    coord_center_x = 128,
    coord_center_y = 128,
    k_min = 0.1,
    k_max = 1.0
})

White Noise ❄️

add_stimulus_operator(ctx, field, opts)

Generate Gaussian white noise with configurable mean and variance. Fundamental building block for stochastic simulations, Monte Carlo methods, and noise injection.

Method Signature

add_stimulus_operator(ctx, field, [options]) -> operator

Returns: Operator handle (userdata)

Note: Requires type = "stimulus_white_noise".

Mathematical Formulation

Each sample is drawn independently from a Gaussian distribution:

ΞΎi∼N(ΞΌ,Οƒ2)\xi_i \sim \mathcal{N}(\mu, \sigma^2)

When scale_by_dt = true, the noise is scaled for proper stochastic integration:

ΞΎi∼N(ΞΌ,Οƒ2Ξ”t)β‹…Ξ”t=N(ΞΌβ‹…Ξ”t,Οƒ2β‹…Ξ”t)\xi_i \sim \mathcal{N}\left(\mu, \frac{\sigma^2}{\Delta t}\right) \cdot \Delta t = \mathcal{N}(\mu \cdot \Delta t, \sigma^2 \cdot \Delta t)

This ensures that the integrated noise has variance proportional to time (Wiener process behavior).

Parameters

Parameter Type Default Range Description
type string β€” β€” Must be "stimulus_white_noise"
sigma double β‰₯0 Standard deviation (required)
mean double 0.0 unbounded Mean offset
seed integer 1 β‰₯1 RNG seed for reproducibility
scale_by_dt boolean true β€” Scale by sqrt(dt) for stochastic integration
nominal_dt double 0.0 β‰₯0 Lock scaling to fixed timestep
fixed_clock boolean false β€” Use nominal_dt for scaling

Boundary & Initial Conditions

  • Operates elementwise; no boundary handling required
  • Each call generates fresh noise; no temporal correlation
  • Same seed produces identical noise sequence

Stability & Convergence

  • Uncorrelated in space and time (delta-correlated)
  • Proper scaling (scale_by_dt = true) essential for SDE integration
  • Mean shifts the distribution; does not affect variance
  • For non-Gaussian noise, consider combining with nonlinear transformations

Performance Notes

  • Uses Box-Muller or similar transform for Gaussian generation
  • One random number per element per timestep
  • Very fast; typically memory-bandwidth limited

Examples

-- Basic white noise
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_white_noise",
    sigma = 0.05,
    seed = 12345
})

-- White noise with nonzero mean
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_white_noise",
    sigma = 0.2,
    mean = 0.1
})

-- Unscaled noise (for non-SDE applications)
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_white_noise",
    sigma = 0.1,
    scale_by_dt = false
})

-- Fixed timestep scaling (for variable dt simulations)
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_white_noise",
    sigma = 0.1,
    nominal_dt = 0.01,
    fixed_clock = true
})

-- High-intensity noise for testing
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_white_noise",
    sigma = 1.0,
    seed = 42
})

Spectral Shells 🐚

add_stimulus_operator(ctx, field, opts)

Generate a spatially-correlated random field by sampling random Fourier modes from concentric annular shells in k-space. Each shell spans a radial band; modes within a shell are randomly oriented, creating isotropic noise with controllable spectral distribution.

Method Signature

add_stimulus_operator(ctx, field, [options]) -> operator

Returns: Operator handle (userdata)

Note: Requires type = "stimulus_spectral_shells".

Mathematical Formulation

The field is constructed as a superposition of modes sampled uniformly from SS concentric shells in 2D k-space:

u(x,t)=Aβˆ‘s=1Sβˆ‘m=1Mwscos⁑(ks,mβ‹…x+Ο•s,m+Ξ©t)u(\mathbf{x}, t) = A \sum_{s=1}^{S} \sum_{m=1}^{M} w_s \cos(\mathbf{k}_{s,m} \cdot \mathbf{x} + \phi_{s,m} + \Omega t)

where:

  • SS is shell_count
  • MM is modes_per_shell
  • ks,m\mathbf{k}_{s,m} are random wavevectors with ∣ks,m∣∈[ks,ks+Ξ”k]|\mathbf{k}_{s,m}| \in [k_s, k_s + \Delta k]
  • Ο•s,m\phi_{s,m} are random phases in [0,2Ο€][0, 2\pi]
  • Ξ©\Omega is omega

Per-shell amplitude weighting with spectral slope Ξ²\beta:

ws∝∣kΛ‰sβˆ£βˆ’Ξ²/2,kΛ‰s=ks+ks+12w_s \propto |\bar{k}_s|^{-\beta/2}, \quad \bar{k}_s = \frac{k_s + k_{s+1}}{2}

Shell boundaries are linearly spaced between k_min and k_max.

Parameters

Parameter Type Default Range Description
type string β€” β€” Must be "stimulus_spectral_shells"
amplitude double β€” unbounded Overall amplitude scale (required)
k_min double β€” β‰₯0 Minimum shell radius in k-space (rad/unit, required)
k_max double β€” β‰₯0 Maximum shell radius in k-space (rad/unit, required)
shell_count integer 4 β‰₯1 Number of concentric spectral shells
modes_per_shell integer 8 β‰₯1 Random Fourier modes sampled per shell
shell_width double 0.0 β‰₯0 Annulus thickness per shell (0 = auto)
spectral_slope double 0.0 unbounded Spectral slope Ξ²\beta, PSD ∝∣kβˆ£βˆ’Ξ²\propto |k|^{-\beta}
seed integer 1 β‰₯1 Seed for reproducible shell realization
omega double 0.0 unbounded Temporal angular frequency (rad/s)
time_offset double 0.0 unbounded Additional time shift
scale_by_dt boolean false β€” Scale writes by dt
nominal_dt double 0.0 β‰₯0 Fixed timestep (requires fixed_clock = true)
fixed_clock boolean false β€” Lock evolution to nominal_dt
origin_x, origin_y double 0.0 β€” Coordinate origin
spacing_x, spacing_y double 1.0 >0 Grid spacing

Examples

-- Basic 2D spectral shells
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_spectral_shells",
    amplitude = 0.5,
    k_min = 0.2,
    k_max = 2.5,
    shell_count = 6,
    modes_per_shell = 12,
    seed = 42
})

-- Pink-noise (1/f) spectral weighting
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_spectral_shells",
    amplitude = 0.4,
    k_min = 0.1,
    k_max = 3.0,
    shell_count = 8,
    spectral_slope = 2.0,
    seed = 7
})

-- Dense fine-scale shells with temporal oscillation
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_spectral_shells",
    amplitude = 0.3,
    k_min = 1.0,
    k_max = 4.0,
    shell_count = 4,
    modes_per_shell = 24,
    omega = 0.5,
    seed = 99
})

-- Fixed-clock for frame-rate independent animation
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_spectral_shells",
    amplitude = 0.6,
    k_min = 0.3,
    k_max = 2.0,
    shell_count = 5,
    omega = 1.0,
    fixed_clock = true,
    nominal_dt = 0.0167
})

Fractional Brownian Motion 🌫️

add_stimulus_operator(ctx, field, opts)

Generate fractional Brownian motion (fBm) noise with configurable roughness and multi-octave structure. Creates natural-looking textures and spatially-correlated noise with long-range dependence.

Method Signature

add_stimulus_operator(ctx, field, [options]) -> operator

Returns: Operator handle (userdata)

Note: Requires type = "stimulus_fbm".

Mathematical Formulation

Fractional Brownian motion is constructed by summing multiple octaves of noise:

fBm(x)=βˆ‘i=0Oβˆ’1Aβ‹…Ξ»βˆ’iHβ‹…noise(Ξ»ix)\text{fBm}(\mathbf{x}) = \sum_{i=0}^{O-1} A \cdot \lambda^{-iH} \cdot \text{noise}(\lambda^i \mathbf{x})

where:

  • OO is the number of octaves
  • AA is the base amplitude
  • Ξ»\lambda is the lacunarity (frequency multiplier)
  • HH is the Hurst exponent

Hurst Exponent:

The Hurst exponent H∈(0,1)H \in (0, 1) controls the roughness:

  • H=0.5H = 0.5: Standard Brownian motion (random walk)
  • H>0.5H > 0.5: Persistent (smoother, trending)
  • H<0.5H < 0.5: Anti-persistent (rougher, mean-reverting)

Spectral Properties:

The power spectral density follows:

S(f)∝fβˆ’(2H+1)S(f) \propto f^{-(2H+1)}

Parameters

Parameter Type Default Range Description
type string β€” β€” Must be "stimulus_fbm"
amplitude double unbounded Scale of coarsest octave (required)
hurst double 0.5 (0, 1) Hurst exponent controlling roughness
lacunarity double 2.0 >1 Octave frequency multiplier
octaves integer 4 [1, 16] Number of octaves
seed integer 1 β‰₯1 RNG seed for reproducibility
scale_by_dt boolean true β€” Scale writes by dt

Boundary & Initial Conditions

  • Generates based on coordinates; no explicit boundaries
  • Underlying noise is typically periodic or uses value noise
  • Same seed produces identical patterns

Stability & Convergence

  • Output bounded approximately by Aβ‹…βˆ‘i=0Oβˆ’1Ξ»βˆ’iHA \cdot \sum_{i=0}^{O-1} \lambda^{-iH}
  • Higher octaves adds fine detail but increases computation
  • lacunarity = 2 is standard; other values change frequency spacing
  • hurst > 0.5 produces visually smoother terrain; hurst < 0.5 produces rougher textures

Performance Notes

  • Cost: O(N Γ— octaves) per timestep
  • Each octave requires noise evaluation at different frequency
  • Higher octaves contribute diminishing detail; often 4-8 octaves sufficient
  • Consider caching for static fBm fields

Examples

-- Standard fBm (Hurst = 0.5)
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_fbm",
    amplitude = 0.5,
    octaves = 6,
    seed = 123
})

-- Smooth terrain (persistent fBm)
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_fbm",
    amplitude = 0.5,
    hurst = 0.7,  -- smoother
    octaves = 6,
    lacunarity = 2.0,
    seed = 123
})

-- Rough texture (anti-persistent)
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_fbm",
    amplitude = 0.25,
    hurst = 0.3,  -- rougher
    octaves = 8
})

-- Low-octave (broad features only)
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_fbm",
    amplitude = 1.0,
    hurst = 0.5,
    octaves = 2
})

-- High-octave detail
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_fbm",
    amplitude = 0.3,
    hurst = 0.5,
    octaves = 12,
    lacunarity = 2.0
})

-- Custom lacunarity (non-power-of-2 spacing)
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_fbm",
    amplitude = 0.4,
    hurst = 0.6,
    octaves = 5,
    lacunarity = 1.87  -- golden ratio-ish
})

-- Low amplitude for subtle texture
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_fbm",
    amplitude = 0.1,
    hurst = 0.5,
    octaves = 4
})

Worley Noise 🧱

add_stimulus_operator(ctx, field, opts)

Generate cellular Worley noise from distances to the nearest feature points in a jittered lattice. Useful for crack patterns, foam cells, Voronoi textures, and edge-distance masks.

Method Signature

add_stimulus_operator(ctx, field, [options]) -> operator

Returns: Operator handle (userdata)

Note: Requires type = "stimulus_worley_noise".

Mathematical Formulation

Let F1(x)F_1(\mathbf{x}) and F2(x)F_2(\mathbf{x}) be the distances from sample x\mathbf{x} to the nearest and second-nearest feature points under the selected metric. The operator emits one of:

u(x)={Aβ‹…F1(x)β€˜output_modeΒ =Β "f1"β€˜Aβ‹…F2(x)β€˜output_modeΒ =Β "f2"β€˜Aβ‹…(F2(x)βˆ’F1(x))β€˜output_modeΒ =Β "f2_minus_f1"β€˜u(\mathbf{x}) = \begin{cases} A \cdot F_1(\mathbf{x}) & \text{`output\_mode = "f1"`} \\ A \cdot F_2(\mathbf{x}) & \text{`output\_mode = "f2"`} \\ A \cdot \left(F_2(\mathbf{x}) - F_1(\mathbf{x})\right) & \text{`output\_mode = "f2\_minus\_f1"`} \end{cases}

Feature points are deterministically jittered inside each unit cell using seed.

Parameters

Parameter Type Default Description
type string β€” Must be "stimulus_worley_noise"
amplitude double 1.0 Output amplitude scale
feature_frequency double 4.0 Lattice cell frequency in local coordinates
jitter double 1.0 Feature-point jitter within each cell
distance_metric enum "euclidean" euclidean, manhattan, chebyshev, minkowski
distance_exponent double 2.0 Exponent used when distance_metric = "minkowski"
output_mode enum "f2_minus_f1" f1, f2, f2_minus_f1
seed integer 0 Seed for reproducible cellular layouts
scale_by_dt boolean false Scale writes by dt

Plus coordinate mapping parameters (coord_mode, coord_axis, coord_combine, coord_angle, origin_x/y, spacing_x/y, coord_center_x/y, coord_velocity_x/y, coord_ellipse_u/v, spiral params).

Boundary & Initial Conditions

  • Generated from coordinates; no explicit boundary state
  • Same seed and coordinate transform reproduce the same cell layout
  • Complex fields synthesize an independent lattice for the imaginary channel

Stability & Convergence

  • Output is bounded by the chosen distance statistic and amplitude
  • jitter = 0 produces a regular lattice; larger jitter produces less uniform cells
  • f2_minus_f1 highlights cell borders and ridge structures

Performance Notes

  • Computes local nearest-neighbor distances rather than global Voronoi construction
  • Cheaper than wide spectral synthesis for many cellular patterns
  • Metric choice affects branch count and arithmetic intensity

Examples

-- Classic cellular edge pattern
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_worley_noise",
    amplitude = 0.45,
    feature_frequency = 7.0,
    output_mode = "f2_minus_f1"
})

-- Manhattan-cell blocks
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_worley_noise",
    distance_metric = "manhattan",
    output_mode = "f1",
    jitter = 0.75
})

-- Polar cellular shells around a moving center
ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_worley_noise",
    coord_mode = "polar",
    coord_center_x = 128,
    coord_center_y = 128,
    feature_frequency = 5.0
})

Turbulence πŸŒͺ️

add_stimulus_operator(ctx, field, opts)

Generate a centered billowy turbulence field by summing absolute-value octave bands. This produces soft cloud-like structures with strong large-scale coherence.

Method Signature

add_stimulus_operator(ctx, field, [options]) -> operator

Returns: Operator handle (userdata)

Note: Requires type = "stimulus_turbulence".

Mathematical Formulation

u(x)=βˆ‘o=0Oβˆ’1AΞ»βˆ’oH(∣cos⁑ ⁣(2πλok ⁣⋅ ⁣x+Ο•o)βˆ£βˆ’2Ο€)u(\mathbf{x}) = \sum_{o=0}^{O-1} A \lambda^{-oH} \left(\left|\cos\!\left(2\pi \lambda^o \mathbf{k}\!\cdot\!\mathbf{x} + \phi_o\right)\right| - \frac{2}{\pi}\right)

where HH is hurst, Ξ»\lambda is lacunarity, and the seeded phases Ο•o\phi_o decorrelate octaves.

Parameters

Parameter Type Default Description
type string β€” Must be "stimulus_turbulence"
amplitude double 1.0 Base amplitude of the coarsest octave
hurst double 0.5 Hurst exponent controlling roughness
lacunarity double 2.0 Frequency multiplier per octave
octaves integer 4 Number of octaves to sum
seed integer 0 Seed for reproducible octave phases
scale_by_dt boolean false Scale writes by dt

Plus coordinate mapping parameters (coord_mode, coord_axis, coord_combine, coord_angle, origin_x/y, spacing_x/y, coord_center_x/y, coord_velocity_x/y, coord_ellipse_u/v, spiral params).

Boundary & Initial Conditions

  • Coordinate-driven synthesis; no explicit boundary state
  • Same seed, transform, and parameters reproduce the same billowy field
  • Complex fields use a corresponding centered sine-basis turbulence field for the imaginary part

Stability & Convergence

  • Higher octaves add finer billow detail but increase cost
  • Larger hurst values suppress fine-scale roughness
  • lacunarity < 2 packs octave bands more tightly; larger values spread them apart

Performance Notes

  • Cost scales linearly with octaves
  • Absolute-value shaping is cheap and tends to produce visually smooth macro-structure
  • Good default when you want cloud-like forcing without hard ridges

Examples

ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_turbulence",
    amplitude = 0.4,
    hurst = 0.6,
    octaves = 5
})

ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_turbulence",
    amplitude = 0.25,
    lacunarity = 1.8,
    seed = 17
})

Multifractal πŸͺ’

add_stimulus_operator(ctx, field, opts)

Generate multiplicative multifractal noise where each octave modulates the next. This produces clustered, strongly coupled detail compared with additive fBm.

Method Signature

add_stimulus_operator(ctx, field, [options]) -> operator

Returns: Operator handle (userdata)

Note: Requires type = "stimulus_multifractal".

Mathematical Formulation

u(x)=A(∏o=0Oβˆ’1[1+12Ξ»βˆ’oHcos⁑ ⁣(2πλok ⁣⋅ ⁣x+Ο•o)]βˆ’1)u(\mathbf{x}) = A\left( \prod_{o=0}^{O-1} \left[ 1 + \frac{1}{2}\lambda^{-oH} \cos\!\left(2\pi \lambda^o \mathbf{k}\!\cdot\!\mathbf{x} + \phi_o\right) \right] - 1 \right)

The multiplicative cascade creates stronger octave-to-octave coupling than additive fBm.

Parameters

Parameter Type Default Description
type string β€” Must be "stimulus_multifractal"
amplitude double 1.0 Base amplitude of the coarsest octave
hurst double 0.5 Hurst exponent controlling roughness
lacunarity double 2.0 Frequency multiplier per octave
octaves integer 4 Number of octaves in the cascade
seed integer 0 Seed for reproducible octave phases
scale_by_dt boolean false Scale writes by dt

Plus coordinate mapping parameters (coord_mode, coord_axis, coord_combine, coord_angle, origin_x/y, spacing_x/y, coord_center_x/y, coord_velocity_x/y, coord_ellipse_u/v, spiral params).

Boundary & Initial Conditions

  • Purely coordinate-driven; no boundary bookkeeping
  • Seeded phases make the multiplicative pattern reproducible
  • Complex fields use a corresponding centered multiplicative sine cascade for the imaginary component

Stability & Convergence

  • More sensitive to octaves than additive fBm because octave interactions compound
  • Lower hurst values create rougher, more fragmented cascades
  • Useful when additive noise looks too independent across scales

Performance Notes

  • Similar octave cost to fBm, with extra multiplies from the cascade
  • Produces strong clustering and patchiness from relatively few octaves
  • Effective for terrain-like masks, porous media patterns, and multiplicative forcing fields

Examples

ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_multifractal",
    amplitude = 0.3,
    hurst = 0.58,
    octaves = 6
})

ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_multifractal",
    amplitude = 0.2,
    lacunarity = 2.4,
    seed = 21
})

Hybrid fBm πŸ”—

add_stimulus_operator(ctx, field, opts)

Generate hybrid fractal Brownian motion with bounded octave-to-octave cascade weights. This keeps the field zero-mean while letting strong coarse structure amplify finer detail.

Method Signature

add_stimulus_operator(ctx, field, [options]) -> operator

Returns: Operator handle (userdata)

Note: Requires type = "stimulus_hybrid_fbm".

Mathematical Formulation

u(x)=βˆ‘o=0Oβˆ’1A woβ€‰Ξ»βˆ’oHcos⁑ ⁣(2πλok ⁣⋅ ⁣x+Ο•o)u(\mathbf{x}) = \sum_{o=0}^{O-1} A\,w_o\,\lambda^{-oH} \cos\!\left(2\pi \lambda^o \mathbf{k}\!\cdot\!\mathbf{x} + \phi_o\right)

with bounded cascade weights

w0=1,wo+1=woβ‹…1+∣bo∣2w_0 = 1, \qquad w_{o+1} = w_o \cdot \frac{1 + |b_o|}{2}

so energetic coarse octaves feed stronger fine detail without introducing a DC offset.

Parameters

Parameter Type Default Description
type string β€” Must be "stimulus_hybrid_fbm"
amplitude double 1.0 Base amplitude of the coarsest octave
hurst double 0.5 Hurst exponent controlling roughness
lacunarity double 2.0 Frequency multiplier per octave
octaves integer 4 Number of octaves
seed integer 0 Seed for reproducible octave phases
scale_by_dt boolean false Scale writes by dt

Plus coordinate mapping parameters (coord_mode, coord_axis, coord_combine, coord_angle, origin_x/y, spacing_x/y, coord_center_x/y, coord_velocity_x/y, coord_ellipse_u/v, spiral params).

Boundary & Initial Conditions

  • Coordinate-driven synthesis with seeded octave phases
  • Same parameters reproduce the same hybrid cascade
  • Complex fields use a corresponding sine-basis cascade for the imaginary channel

Stability & Convergence

  • Smoother than ridged noise, but more coupled than additive fBm
  • Octave interactions remain bounded because the cascade weights stay in a stable range
  • Good middle ground between simple fBm and fully multiplicative multifractal structure

Performance Notes

  • Similar complexity to fBm plus a small recursive weight update per octave
  • Produces scale-coupled detail without the harsher geometry of ridged noise
  • Useful for hybrid textures, structured forcing, and nested pattern generation

Examples

ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_hybrid_fbm",
    amplitude = 0.35,
    hurst = 0.6,
    octaves = 5
})

ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_hybrid_fbm",
    amplitude = 0.2,
    seed = 9,
    lacunarity = 1.9
})

Ridged Noise ⛰️

add_stimulus_operator(ctx, field, opts)

Generate zero-mean ridged fractal noise by inverting and squaring absolute octave bands. This emphasizes crests, cracks, and folded mountain-like structures.

Method Signature

add_stimulus_operator(ctx, field, [options]) -> operator

Returns: Operator handle (userdata)

Note: Requires type = "stimulus_ridged_noise".

Mathematical Formulation

u(x)=βˆ‘o=0Oβˆ’1AΞ»βˆ’oH((1βˆ’βˆ£cos⁑ ⁣(2πλok ⁣⋅ ⁣x+Ο•o)∣)2βˆ’ΞΌr)u(\mathbf{x}) = \sum_{o=0}^{O-1} A \lambda^{-oH} \left( \left(1 - \left|\cos\!\left(2\pi \lambda^o \mathbf{k}\!\cdot\!\mathbf{x} + \phi_o\right)\right|\right)^2 - \mu_r \right)

where ΞΌr\mu_r centers the ridge profile to keep the overall write approximately zero-mean.

Parameters

Parameter Type Default Description
type string β€” Must be "stimulus_ridged_noise"
amplitude double 1.0 Base amplitude of the coarsest octave
hurst double 0.5 Hurst exponent controlling roughness
lacunarity double 2.0 Frequency multiplier per octave
octaves integer 4 Number of octaves
seed integer 0 Seed for reproducible octave phases
scale_by_dt boolean false Scale writes by dt

Plus coordinate mapping parameters (coord_mode, coord_axis, coord_combine, coord_angle, origin_x/y, spacing_x/y, coord_center_x/y, coord_velocity_x/y, coord_ellipse_u/v, spiral params).

Boundary & Initial Conditions

  • Synthesized directly from coordinates with no explicit boundary state
  • Same seed reproduces the same ridge placement
  • Complex fields use a matching centered squared-ridge sine profile for the imaginary part

Stability & Convergence

  • Produces sharper geometry than fBm or billowy turbulence at the same octave count
  • Lower hurst values accentuate fine ridges and crease detail
  • Well suited for crest detection, folded masks, and mountainous forcing fields

Performance Notes

  • Similar octave cost to turbulence with a slightly sharper nonlinear shaping stage
  • Useful when you want prominent ridges rather than soft billows
  • Often benefits from fewer octaves than turbulence because the ridge geometry is visually strong

Examples

ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_ridged_noise",
    amplitude = 0.35,
    hurst = 0.65,
    octaves = 5
})

ooc.add_stimulus_operator(ctx, field, {
    type = "stimulus_ridged_noise",
    amplitude = 0.2,
    lacunarity = 2.3,
    seed = 31
})