DAMP
The damp function summarizes the modal behavior of a linear time-invariant system by computing the natural frequency, damping ratio, and pole location associated with each mode.
For a continuous-time pole located at s = -\sigma \pm j\omega_d, the natural frequency and damping ratio are:
\omega_n = |s| = \sqrt{\sigma^2 + \omega_d^2}
\zeta = -\frac{\Re(s)}{\omega_n}
The result is returned as a rectangular 2D array with one column per pole. The rows contain natural frequency, damping ratio, pole real part, and pole imaginary part, making the output easy to inspect in a spreadsheet.
Excel Usage
=DAMP(sysdata)
sysdata(list[list], required): The system transfer function, provided as numerator and denominator coefficients in consecutive rows.
Returns (list[list]): A 4xN array where N is the number of poles. Row 1 = Natural Frequencies (rad/s). Row 2 = Damping Ratios. Row 3 = Pole Real parts. Row 4 = Pole Imaginary parts.
Example 1: Underdamped second order system
Inputs:
| sysdata |
|---|
| 1 |
| 1 |
Excel formula:
=DAMP({1;1,2,5})
Expected output:
| Result | |
|---|---|
| 2.23607 | 2.23607 |
| 0.447214 | 0.447214 |
| -1 | -1 |
| 2 | -2 |
Example 2: Overdamped system
Inputs:
| sysdata |
|---|
| 1 |
| 1 |
Excel formula:
=DAMP({1;1,5,4})
Expected output:
| Result | |
|---|---|
| 4 | 1 |
| 1 | 1 |
| -4 | -1 |
| 0 | 0 |
Example 3: Undamped oscillator
Inputs:
| sysdata |
|---|
| 1 |
| 1 |
Excel formula:
=DAMP({1;1,0,9})
Expected output:
| Result | |
|---|---|
| 3 | 3 |
| 0 | 0 |
| 0 | 0 |
| 3 | -3 |
Python Code
Show Code
import control as ct
import numpy as np
def damp(sysdata):
"""
Compute the system's natural frequencies, damping ratios, and poles.
See: https://python-control.readthedocs.io/en/latest/generated/control.damp.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.
Returns:
list[list]: A 4xN array where N is the number of poles. Row 1 = Natural Frequencies (rad/s). Row 2 = Damping Ratios. Row 3 = Pole Real parts. Row 4 = Pole Imaginary parts.
"""
try:
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)
wn, zeta, poles = ct.damp(sys, doprint=False)
# Prepare 4 rows: wn, zeta, poles_real, poles_imag
# If there are no poles, return empty arrays
if len(poles) == 0:
return [[""], [""], [""], [""]]
wn_list = [float(value) for value in wn]
zeta_list = [float(value) for value in zeta]
poles_real = [float(value) for value in np.real(poles)]
poles_imag = [float(value) for value in np.imag(poles)]
return [wn_list, zeta_list, poles_real, poles_imag]
except Exception as e:
return f"Error: {str(e)}"