FORCED_RESPONSE
The forced response computes how a linear system evolves when it is driven by a user-supplied input signal u(t) over a specified time grid.
For a continuous-time state-space model, the response satisfies the differential equation
\dot{x}(t) = A x(t) + B u(t), \quad y(t) = C x(t) + D u(t)
This wrapper accepts transfer-function numerator and denominator coefficients together with matching time and input arrays. It returns a 2D spreadsheet-friendly array whose first row contains time values and whose second row contains the corresponding system output values.
Excel Usage
=FORCED_RESPONSE(sysdata, timepts, inputs)
sysdata(list[list], required): The system transfer function, provided as numerator and denominator coefficients in consecutive rows.timepts(list[list], required): An array of evenly spaced time steps at which the input is defined.inputs(list[list], required): The input array defining the signal value at each corresponding point in timepts.
Returns (list[list]): A 2D array where the first row contains the time array values and the second row contains the system output response.
Example 1: Linear system trailing a sine wave
Inputs:
| sysdata | timepts | inputs | ||||||
|---|---|---|---|---|---|---|---|---|
| 1 | 0 | 1 | 2 | 3 | 0 | 0.841 | 0.909 | 0.141 |
| 1 |
Excel formula:
=FORCED_RESPONSE({1;1,1}, {0,1,2,3}, {0,0.841,0.909,0.141})
Expected output:
| Result | |||
|---|---|---|---|
| 0 | 1 | 2 | 3 |
| 0 | 0.309387 | 0.670446 | 0.53871 |
Python Code
Show Code
import control as ct
import numpy as np
def forced_response(sysdata, timepts, inputs):
"""
Compute the output of a linear system given an arbitrary input signal.
See: https://python-control.readthedocs.io/en/latest/generated/control.forced_response.html
This example function is provided as-is without any representation of accuracy.
Args:
sysdata (list[list]): The system transfer function, provided as numerator and denominator coefficients in consecutive rows.
timepts (list[list]): An array of evenly spaced time steps at which the input is defined.
inputs (list[list]): The input array defining the signal value at each corresponding point in timepts.
Returns:
list[list]: A 2D array where the first row contains the time array values and the second row contains the system output response.
"""
try:
def to_row_list(values):
arr = np.asarray(values)
if arr.ndim == 0:
return [float(arr)]
return [float(value) for value in arr.reshape(-1)]
def flatten_to_1d(x):
if not isinstance(x, list):
return [float(x)] if str(x) != "" else []
flat = []
for row in x:
if isinstance(row, list):
for val in row:
if str(val) != "":
flat.append(float(val))
elif str(row) != "":
flat.append(float(row))
return flat
if not sysdata or len(sysdata) < 2:
return "Error: sysdata must contain numerator and denominator rows"
num = flatten_to_1d(sysdata[0])
den = flatten_to_1d(sysdata[1])
if not num or not den:
return "Error: Invalid numerator or denominator arrays"
sys = ct.tf(num, den)
t_arr = np.array(flatten_to_1d(timepts), dtype=float)
u_arr = np.array(flatten_to_1d(inputs), dtype=float)
if len(t_arr) != len(u_arr):
return "Error: timepts and inputs arrays must have the same length"
if len(t_arr) == 0:
return "Error: Arrays cannot be empty"
resp = ct.forced_response(sys, T=t_arr, U=u_arr)
t_list = to_row_list(resp.time)
y_list = to_row_list(np.squeeze(resp.outputs))
return [t_list, y_list]
except Exception as e:
return f"Error: {str(e)}"