The current [working] RK2/RK4 implementation creates temporary InlineArray allocations inside step when calling fn_deriv, which is not ideal for real-time audio. The correct fix as I see it is a Differentiable[num_dims: Int] trait that structs implement, allowing the derivative function to live alongside its runtime state (e.g. frequency, damping). This was designed but blocked on Mojo not yet supporting parametric traits. When that feature lands, refactor RK2/RK4 to take a Differentiable conforming struct as a parameter instead of fn_deriv.
trait Differentiable[num_dims: Int]:
fn derivatives(mut self, state: InlineArray[Float64, num_dims], mut derivs: InlineArray[Float64, num_dims]) -> None
struct RK2[num_dims: Int, T: Differentiable[num_dims]](Copyable, Movable):
var state: InlineArray[Float64, Self.num_dims]
var world: World
var dt: Float64
var k1: InlineArray[Float64, Self.num_dims]
var k2: InlineArray[Float64, Self.num_dims]
var temp_state: InlineArray[Float64, Self.num_dims]
var differentiable: T
fn __init__(out self, world: World, differentiable: T):
self.world = world
self.dt = 1.0 / world[].sample_rate
self.state = InlineArray[Float64, Self.num_dims](fill=0.0)
self.k1 = InlineArray[Float64, Self.num_dims](fill=0.0)
self.k2 = InlineArray[Float64, Self.num_dims](fill=0.0)
self.temp_state = InlineArray[Float64, Self.num_dims](fill=0.0)
self.differentiable = differentiable
fn step(mut self):
self.differentiable.derivatives(self.state, self.k1)
for i in range(Self.num_dims):
self.temp_state[i] = self.state[i] + self.k1[i] * (self.dt / 2.0)
self.differentiable.derivatives(self.temp_state, self.k2)
for i in range(Self.num_dims):
self.state[i] = self.state[i] + self.k2[i] * self.dt
The current [working] RK2/RK4 implementation creates temporary
InlineArrayallocations inside step when callingfn_deriv, which is not ideal for real-time audio. The correct fix as I see it is aDifferentiable[num_dims: Int]trait that structs implement, allowing the derivative function to live alongside its runtime state (e.g. frequency, damping). This was designed but blocked on Mojo not yet supporting parametric traits. When that feature lands, refactorRK2/RK4to take aDifferentiableconforming struct as a parameter instead offn_deriv.