TheAlgorithms/Java · error · IllegalArgumentException
Time step must be positive.
Error message
Time step must be positive.
What it means
Thrown by DampedOscillator.stepEuler when dt <= 0. The Euler integration step advances the state by dt; a non-positive time step produces no forward progress (dt = 0 yields the identical state) or reverses integration (dt < 0), both of which corrupt a time-marching simulation. This is the second guard, checked after the state-array validation.
Source
Thrown at src/main/java/com/thealgorithms/physics/DampedOscillator.java:87
double omegaD = Math.sqrt(Math.max(0.0, omega0 * omega0 - gamma * gamma));
return amplitude * Math.exp(-gamma * time) * Math.cos(omegaD * time + phase);
}
/**
* Performs a single integration step using the explicit Euler method.
* State vector format: [x, v], where v = dx/dt.
*
* @param state the current state [x, v]
* @param dt the time step (seconds)
* @return the next state [x_next, v_next]
* @throws IllegalArgumentException if the state array is invalid or dt is non-positive
*/
public double[] stepEuler(double[] state, double dt) {
if (state == null || state.length != 2) {
throw new IllegalArgumentException("State must be a non-null array of length 2.");
}
if (dt <= 0) {
throw new IllegalArgumentException("Time step must be positive.");
}
double x = state[0];
double v = state[1];
double acceleration = -2.0 * gamma * v - omega0 * omega0 * x;
double xNext = x + dt * v;
double vNext = v + dt * acceleration;
return new double[] {xNext, vNext};
}
/** @return the natural (undamped) angular frequency (rad/s). */
public double getOmega0() {
return omega0;
}
/** @return the damping coefficient (s⁻¹). */View on GitHub (pinned to fdfb9a395b)
Solutions
- Pass a strictly positive dt (e.g. 1e-3 or 1e-4 for stiff systems).
- In a time-marching loop, clamp the final step: double step = Math.min(dt, tEnd - t); only call stepEuler when step > 0.
- Validate dt at the boundary where the integration schedule is configured.
Example fix
// before double[] next = osc.stepEuler(state, tEnd - t); // after double step = tEnd - t; if (step <= 0) break; double[] next = osc.stepEuler(state, step);
Defensive patterns
Strategy: validation
Validate before calling
double step = dt;
if (step <= 0) {
throw new IllegalStateException("integration step resolved to non-positive dt");
}
double[] next = osc.stepEuler(state, step); Prevention
- Clamp the final loop step: Math.min(dt, tEnd - t) and skip when <= 0.
- Treat dt as a positive constant from validated config.
- Add an assertion at the loop entry that the remaining interval is positive.
When it happens
Trigger: Calling stepEuler(state, 0) or stepEuler(state, negativeValue). Commonly happens when dt is computed as an end-minus-start difference that resolves to zero, or when a step counter runs past the loop bound producing a negative remainder.
Common situations: Adaptive step code that undershoots to dt = 0 at the final step, a loop where (tEnd - t) becomes negative in the last iteration, or a config default of 0.
Related errors
- Time step must be positive
- State must be a non-null array of length 2.
- State must be array of length 2
- Orbiting mass and radius must be positive.
- Natural frequency must be positive.
AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13).
Data as JSON: /api/errors/a666d43b9ef8b987.
Report an issue: GitHub.