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)}"

Online Calculator

The system transfer function, provided as numerator and denominator coefficients in consecutive rows.
An array of evenly spaced time steps at which the input is defined.
The input array defining the signal value at each corresponding point in timepts.