@@ -210,32 +210,32 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False,
210
210
211
211
T : array_like, optional for discrete LTI `sys`
212
212
Time steps at which the input is defined; values must be evenly spaced.
213
- If None, `U` must be given and and `len(U)` time steps of sys.dt are
214
- simulated. If sys.dt is None or True (undetermined time step), a dt
215
- of 1.0 is assumed.
213
+ If None, `U` must be given and `len(U)` time steps of sys.dt are
214
+ simulated. If sys.dt is None or True (undetermined time step), a time
215
+ step of 1.0 is assumed.
216
216
217
217
U : array_like or float, optional
218
- Input array giving input at each time `T`
218
+ Input array giving input at each time `T`.
219
+ If `U` is None or 0, `T` must be given, even for discrete
220
+ time systems. In this case, for continuous time systems, a direct
221
+ calculation of the matrix exponential is used, which is faster than the
222
+ general interpolating algorithm used otherwise.
219
223
220
- If `U` is ``None`` or ``0``, a special algorithm is used. This special
221
- algorithm is faster than the general algorithm, which is used
222
- otherwise.
223
-
224
- X0 : array_like or float, optional
224
+ X0 : array_like or float, default=0.
225
225
Initial condition.
226
226
227
- transpose : bool, optional
227
+ transpose : bool, default=False
228
228
If True, transpose all input and output arrays (for backward
229
229
compatibility with MATLAB and :func:`scipy.signal.lsim`).
230
230
231
- interpolate : bool, optional
231
+ interpolate : bool, default=False
232
232
If True and system is a discrete time system, the input will
233
233
be interpolated between the given time steps and the output
234
234
will be given at system sampling rate. Otherwise, only return
235
235
the output at the times given in `T`. No effect on continuous
236
236
time simulations.
237
237
238
- return_x : bool, optional
238
+ return_x : bool, default=None
239
239
- If False, return only the time and output vectors.
240
240
- If True, also return the the state vector.
241
241
- If None, determine the returned variables by
@@ -245,10 +245,10 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False,
245
245
squeeze : bool, optional
246
246
By default, if a system is single-input, single-output (SISO) then
247
247
the output response is returned as a 1D array (indexed by time). If
248
- squeeze= True, remove single-dimensional entries from the shape of
249
- the output even if the system is not SISO. If squeeze= False, keep
248
+ ` squeeze` is True, remove single-dimensional entries from the shape of
249
+ the output even if the system is not SISO. If ` squeeze` is False, keep
250
250
the output as a 2D array (indexed by the output number and time)
251
- even if the system is SISO. The default value can be overridden by
251
+ even if the system is SISO. The default behavior can be overridden by
252
252
config.defaults['control.squeeze_time_response'].
253
253
254
254
Returns
@@ -263,7 +263,7 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False,
263
263
time).
264
264
265
265
xout : array
266
- Time evolution of the state vector. Not affected by squeeze. Only
266
+ Time evolution of the state vector. Not affected by ` squeeze` . Only
267
267
returned if `return_x` is True, or `return_x` is None and
268
268
config.defaults['forced_response.return_x'] is True.
269
269
@@ -284,7 +284,8 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False,
284
284
--------
285
285
>>> T, yout, xout = forced_response(sys, T, u, X0)
286
286
287
- See :ref:`time-series-convention`.
287
+ See :ref:`time-series-convention` and
288
+ :ref:`package-configuration-parameters`.
288
289
289
290
"""
290
291
if not isinstance (sys , (StateSpace , TransferFunction )):
@@ -301,6 +302,13 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False,
301
302
"return_x specified for a transfer function system. Internal "
302
303
"conversion to state space used; results may meaningless." )
303
304
305
+ # If we are passed a transfer function and X0 is non-zero, warn the user
306
+ if isinstance (sys , TransferFunction ) and np .any (X0 != 0 ):
307
+ warnings .warn (
308
+ "Non-zero initial condition given for transfer function system. "
309
+ "Internal conversion to state space used; may not be consistent "
310
+ "with given X0." )
311
+
304
312
sys = _convert_to_statespace (sys )
305
313
A , B , C , D = np .asarray (sys .A ), np .asarray (sys .B ), np .asarray (sys .C ), \
306
314
np .asarray (sys .D )
@@ -348,7 +356,7 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False,
348
356
349
357
# equally spaced also implies strictly monotonic increase
350
358
dt = T [1 ] - T [0 ]
351
- if not np .allclose (np .diff (T ), np . full_like ( T [: - 1 ], dt ) ):
359
+ if not np .allclose (np .diff (T ), dt ):
352
360
raise ValueError ("Parameter ``T``: time values must be "
353
361
"equally spaced." )
354
362
n_steps = T .shape [0 ] # number of simulation steps
@@ -357,13 +365,6 @@ def forced_response(sys, T=None, U=0., X0=0., transpose=False,
357
365
X0 = _check_convert_array (X0 , [(n_states ,), (n_states , 1 )],
358
366
'Parameter ``X0``: ' , squeeze = True )
359
367
360
- # If we are passed a transfer function and X0 is non-zero, warn the user
361
- if isinstance (sys , TransferFunction ) and np .any (X0 != 0 ):
362
- warnings .warn (
363
- "Non-zero initial condition given for transfer function system. "
364
- "Internal conversion to state space used; may not be consistent "
365
- "with given X0." )
366
-
367
368
xout = np .zeros ((n_states , n_steps ))
368
369
xout [:, 0 ] = X0
369
370
yout = np .zeros ((n_outputs , n_steps ))
0 commit comments