phyz is a differentiable simulation engine for articulated rigid bodies, particles, electromagnetic fields, molecular dynamics, and beyond. Every algorithm computes gradients for optimization, control, and learning.
Built on Featherstone's spatial algebra, phyz runs O(n) forward dynamics with analytical Jacobians. Plug in semi-implicit Euler, RK4, or your own solver. Load MuJoCo MJCF models. Batch thousands of environments on GPU.
phyz is early, ambitious, and open source.
use phyz::{ModelBuilder, Simulator, Vec3}; use phyz_diff::analytical_step_jacobians; // Double pendulum: two revolute joints let model = ModelBuilder::new() .add_revolute_body("upper", -1, 1.0, Vec3::new(0., 0., -1.)) .add_revolute_body("lower", 0, 0.8, Vec3::new(0., 0., -1.)) .build(); let mut state = model.default_state(); state.q = vec![0.5, -0.3]; // joint angles state.qd = vec![0.0, 0.0]; // velocities // Simulate with analytical Jacobians at every step let sim = Simulator::rk4(); let dt = 0.002; for _ in 0..500 { let jac = analytical_step_jacobians(&model, &state, dt); sim.step(&model, &mut state, dt); // jac.dq_dq0: ∂(next state) / ∂(current state) // jac.dq_dtau: ∂(next state) / ∂(applied torques) // → chain rule through the trajectory for end-to-end gradients } let tip = state.body_position(1); println!("tip = ({:.3}, {:.3})", tip.x, tip.y); println!("sensitivity ‖∂q'/∂q₀‖ = {:.2e}", jac.dq_dq0.norm());