FEEDBACK
This function forms the closed-loop interconnection of a plant G and a feedback path H. It is useful for analyzing the equivalent transfer function of standard control architectures without manually expanding the loop algebra.
For negative feedback, the closed-loop transfer function is
T(s) = \frac{G(s)}{1 + G(s)H(s)}
For positive feedback, the denominator changes sign to 1 - G(s)H(s). The wrapper accepts both systems as 2-row coefficient arrays of the form [[numerator], [denominator]], applies either negative or positive feedback, and returns the resulting transfer function as the library’s formatted string.
Excel Usage
=FEEDBACK(sysdata_plant, sysdata_feedback, positive)
sysdata_plant(list[list], required): Numerator and denominator of the plant G.sysdata_feedback(list[list], optional, default: [[1],[1]]): Numerator and denominator of the feedback path H.positive(bool, optional, default: false): Set to true for positive feedback. Defaults to false (negative feedback).
Returns (str): String representation of the resulting closed-loop system.
Example 1: Unity negative feedback
Inputs:
| sysdata_plant | sysdata_feedback | positive |
|---|---|---|
| 1 | 1 | false |
| 1 | 1 |
Excel formula:
=FEEDBACK({1;1,1}, {1;1}, FALSE)
Expected output:
"<TransferFunction>: sys[2]\nInputs (1): ['u[0]']\nOutputs (1): ['y[0]']\n\n 1\n -----\n s + 2"
Example 2: Negative feedback using the default unity path
Inputs:
| sysdata_plant | positive |
|---|---|
| 2 | false |
| 1 |
Excel formula:
=FEEDBACK({2;1,2}, FALSE)
Expected output:
"<TransferFunction>: sys[5]\nInputs (1): ['u[0]']\nOutputs (1): ['y[0]']\n\n 2\n -----\n s + 4"
Example 3: Positive feedback on a first-order plant
Inputs:
| sysdata_plant | sysdata_feedback | positive |
|---|---|---|
| 1 | 1 | true |
| 1 | 1 |
Excel formula:
=FEEDBACK({1;1,3}, {1;1}, TRUE)
Expected output:
"<TransferFunction>: sys[8]\nInputs (1): ['u[0]']\nOutputs (1): ['y[0]']\n\n 1\n -----\n s + 2"
Example 4: Dynamic feedback path with first-order sensor dynamics
Inputs:
| sysdata_plant | sysdata_feedback | positive |
|---|---|---|
| 5 | 1 | false |
| 1 | 1 |
Excel formula:
=FEEDBACK({5;1,4}, {1;1,2}, FALSE)
Expected output:
"<TransferFunction>: sys[11]\nInputs (1): ['u[0]']\nOutputs (1): ['y[0]']\n\n 5 s + 10\n --------------\n s^2 + 6 s + 13"
Python Code
Show Code
import control as ct
def feedback(sysdata_plant, sysdata_feedback=[[1], [1]], positive=False):
"""
Feedback interconnection of two LTI systems.
See: https://python-control.readthedocs.io/en/latest/generated/control.feedback.html
This example function is provided as-is without any representation of accuracy.
Args:
sysdata_plant (list[list]): Numerator and denominator of the plant G.
sysdata_feedback (list[list], optional): Numerator and denominator of the feedback path H. Default is [[1], [1]].
positive (bool, optional): Set to true for positive feedback. Defaults to false (negative feedback). Default is False.
Returns:
str: String representation of the resulting closed-loop system.
"""
try:
def to2d(value):
return [[value]] if not isinstance(value, list) else value
def parse_coefficients(row, label):
if not isinstance(row, list):
return None, f"Error: {label} must be a list of coefficients"
coefficients = []
for item in row:
if item is None or str(item).strip() == "":
continue
try:
coefficients.append(float(item))
except (TypeError, ValueError):
return None, f"Error: {label} contains a non-numeric coefficient"
if not coefficients:
return None, f"Error: {label} must contain at least one numeric coefficient"
return coefficients, None
def to_tf(data, label):
matrix = to2d(data)
if not isinstance(matrix, list) or len(matrix) < 2:
return None, f"Error: {label} must be provided as [[numerator], [denominator]]"
numerator, error = parse_coefficients(matrix[0], f"{label} numerator")
if error:
return None, error
denominator, error = parse_coefficients(matrix[1], f"{label} denominator")
if error:
return None, error
return ct.tf(numerator, denominator), None
plant, error = to_tf(sysdata_plant, "sysdata_plant")
if error:
return error
feedback_sys, error = to_tf(sysdata_feedback, "sysdata_feedback")
if error:
return error
sign = 1 if positive else -1
res = ct.feedback(plant, feedback_sys, sign=sign)
return str(res)
except Exception as e:
return f"Error: {str(e)}"