@@ -355,12 +355,13 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False,
355355 'Parameter ``T``: ' , squeeze = True ,
356356 transpose = transpose )
357357
358- # equally spaced also implies strictly monotonic increase
359- dt = T [1 ] - T [0 ]
358+ n_steps = T .shape [0 ] # number of simulation steps
359+
360+ # equally spaced also implies strictly monotonic increase,
361+ dt = (T [- 1 ] - T [0 ]) / (n_steps - 1 )
360362 if not np .allclose (np .diff (T ), dt ):
361363 raise ValueError ("Parameter ``T``: time values must be "
362364 "equally spaced." )
363- n_steps = T .shape [0 ] # number of simulation steps
364365
365366 # create X0 if not given, test if X0 has correct shape
366367 X0 = _check_convert_array (X0 , [(n_states ,), (n_states , 1 )],
@@ -432,12 +433,24 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False,
432433
433434 # Now check to make sure it is a multiple (with check against
434435 # sys.dt because floating point mod can have small errors
435- elif not (np .isclose (dt % sys .dt , 0 ) or
436- np .isclose (dt % sys .dt , sys .dt )):
436+ if not (np .isclose (dt % sys .dt , 0 ) or
437+ np .isclose (dt % sys .dt , sys .dt )):
437438 raise ValueError ("Time steps ``T`` must be multiples of "
438439 "sampling time" )
439440 sys_dt = sys .dt
440441
442+ # sp.signal.dlsim returns not enough samples if
443+ # T[-1] - T[0] < sys_dt * decimation * (n_steps - 1)
444+ # due to rounding errors. Give it an additional time step
445+ # to discard
446+ decimation_dt = (T [- 1 ] - T [0 ]) / (n_steps - 1 )
447+ if (decimation_dt / sys_dt ) % 1. > 0.5 :
448+ T = np .append (T , T [- 1 ] + decimation_dt )
449+ if U .ndim == 1 :
450+ U = np .append (U , U [- 1 ])
451+ else :
452+ U = np .append (U , U [:, - 1 ], 1 )
453+
441454 else :
442455 sys_dt = dt # For unspecified sampling time, use time incr
443456
0 commit comments