I have a battery simulation script where the battery’s state-of-charge (SOC) is updated iteratively. The charge and discharge values (how much energy is added/taken from the battery) at each timestep depend amongst other things, on the SOC at the previous timestep.
# Parameters
E_max = 100.0 # Maximum battery capacity
P_B_max = 10.0 # Maximum power for charge/discharge
SOC_min = 20.0 # Minimum state of charge
total_timesteps = 10 # Number of time steps
surplus = np.array([5, 3, 0, 7, 8, 0, 0, 5, 4, 3])# Excess production available for charging
remaining = np.array([0, 2, 5, 1, 0, 4, 6, 0, 2, 5])# Unmet load that requires discharge
SOC = np.zeros(total_timesteps + 1)
SOC[0] = 0.5 * E_max
charge = np.zeros(total_timesteps)
discharge = np.zeros(total_timesteps)
for t in range(total_timesteps):
current_SOC = SOC[t]
charge[t] = min(surplus[t], P_B_max, (E_max - current_SOC))
discharge[t] = min(remaining[t], P_B_max, (current_SOC - SOC_min))
SOC[t + 1] = np.clip(current_SOC + charge[t] - discharge[t],SOC_min, E_max)
I want to vectorize this calculation to remove the explicit for loop over t. However, I ve found it challenging because:
Charge and discharge values depend on the previous SOC. The amount of charge is constrained by how much available capacity remains in the battery. The amount of discharge is constrained by how much energy is available above the minimum SOC.
SOC updates sequentially, meaning that the SOC at time t+1 depends on SOC at time t, which was influenced by previous charge and discharge decisions.
I’m looking for an efficient way to vectorize or accelerate this calculation, ideally avoiding an explicit loop over timesteps altogether, while maintaining the correct behavior. Any guidance would be much appreciated appreciated!

cumsumthose methods are not sequential. It's hard to write general purpose building blocks that do custom things at each 'time step'.