"""W05: velocity Verlet for x''=-omega^2*x, unit mass, fixed time step."""importmathdefverlet(x=1.,v=0.,omega=1.,dt=.1,steps=100):ifnotall(math.isfinite(z)forzin(x,v,omega,dt))oromega<=0ordt<=0:raiseValueError("finite state, positive frequency and step required")iftype(steps)isnotintornot0<=steps<=100000:raiseValueError("bounded nonnegative step count required")energy0=.5*(v*v+omega*omega*x*x)ifnotmath.isfinite(energy0):raiseValueError("initial energy is not finite; rescale the problem")rows=[(0.,x,v,energy0)]forkinrange(1,steps+1):half=v-.5*dt*omega*omega*xnew_x=x+dt*halfnew_v=half-.5*dt*omega*omega*new_xx,v=new_x,new_venergy=.5*(v*v+omega*omega*x*x)ifnotall(math.isfinite(z)forzin(x,v,energy,k*dt)):raiseValueError("nonfinite trajectory; check step and scale")rows.append((k*dt,x,v,energy))returnrowsdefexact(t,x0=1.,v0=0.,omega=1.):ifnotall(math.isfinite(z)forzin(t,x0,v0,omega))oromega<=0:raiseValueError("finite inputs and positive frequency required")phase=omega*tifnotmath.isfinite(phase):raiseValueError("nonfinite phase; rescale the problem")result=(x0*math.cos(phase)+(v0/omega)*math.sin(phase),-omega*x0*math.sin(phase)+v0*math.cos(phase))ifnotall(math.isfinite(z)forzinresult):raiseValueError("nonfinite analytic state; rescale the problem")returnresultif__name__=='__main__':fordtin(.1,.05,.025):t,x,v,e=verlet(dt=dt,steps=round(1/dt))[-1]target=exact(t)print(dt,math.hypot(x-target[0],v-target[1]),e)