polydat 0.1.0

Polydat — generation kernel for deterministic variate generation in nb-rs (formerly nbrs-variates)
Documentation
// Copyright 2024-2026 Jonathan Shook
// SPDX-License-Identifier: Apache-2.0

// @category: Math
// fourier.gk — Fourier synthesis: periodic waveforms from harmonics.
//
// Uses type-aware infix operators: `mod(input, period)` and `to_f64`
// for u64→f64 conversion, then infix `/` and `*` resolve to f64
// variants automatically since the operands are f64.
//
// All modules are P3 JIT-ready.

// Pure sine wave: sin(2π * cycle / period).
// Output range: [-1.0, 1.0].
//
// Example:
//   wave := sine_wave(input: cycle, period: 100)
sine_wave(input: u64, period: u64) -> (value: f64) := {
    pos := to_f64(input % period)
    per := to_f64(identity(period))
    t := (pos / per) * 6.283185307179586
    value := sin(t)
}

// Pure cosine wave: cos(2π * cycle / period).
cosine_wave(input: u64, period: u64) -> (value: f64) := {
    pos := to_f64(input % period)
    per := to_f64(identity(period))
    t := (pos / per) * 6.283185307179586
    value := cos(t)
}

// Bipolar sine mapped to [0.0, 1.0]: (sin(t) + 1) / 2.
sine_unit(input: u64, period: u64) -> (value: f64) := {
    pos := to_f64(input % period)
    per := to_f64(identity(period))
    t := (pos / per) * 6.283185307179586
    raw := sin(t)
    value := lerp(raw, 0.5, 1.0)
}

// Square wave from 5 odd harmonics.
square_wave(input: u64, period: u64) -> (value: f64) := {
    pos := to_f64(input % period)
    per := to_f64(identity(period))
    phase := pos / per

    t := phase * 6.283185307179586
    h1 := sin(t)

    t3 := phase * 18.84955592153876
    h3 := sin(t3) * 0.3333333333333333

    t5 := phase * 31.41592653589793
    h5 := sin(t5) * 0.2

    t7 := phase * 43.982297150257104
    h7 := sin(t7) * 0.14285714285714285

    t9 := phase * 56.548667764616276
    h9 := sin(t9) * 0.1111111111111111

    s1 := h1 + h3
    s2 := s1 + h5
    s3 := s2 + h7
    s4 := s3 + h9
    value := s4 * 1.2732395447351628
}

// Triangle wave from 4 odd harmonics.
triangle_wave(input: u64, period: u64) -> (value: f64) := {
    pos := to_f64(input % period)
    per := to_f64(identity(period))
    phase := pos / per

    t := phase * 6.283185307179586
    h1 := sin(t)

    t3 := phase * 18.84955592153876
    h3 := sin(t3) * -0.1111111111111111

    t5 := phase * 31.41592653589793
    h5 := sin(t5) * 0.04

    t7 := phase * 43.982297150257104
    h7 := sin(t7) * -0.020408163265306124

    s1 := h1 + h3
    s2 := s1 + h5
    s3 := s2 + h7
    value := s3 * 0.8105694691387022
}