Nonlinear.Tests.PadeDelay
Test harness for the PadeDelay block.
A unit step (0 -> 1 at t = 0.5) is fed through three Padé delays with delayTime = 1:
pd1— first order (n = 1), balanced (default).pd3— third order (n = 3), balanced (default).pd3u— third order (n = 3), unbalanced (balance = false).
Expected behavior (an approximation of a 1-second delay):
Each output starts with the characteristic non-minimum-phase undershoot (
yjumps to -1 the instant the step arrives, because m = n gives direct feedthrough d = -1).Each settles to 1 (DC gain = 1: a delayed constant is the same constant).
pd3holds near zero longer and then rises more steeply thanpd1(a sharper delay approximation), at the cost of some ringing.pd3umust reproducepd3exactly: balancing is a state transformation that changes only the internal coordinates, not the input->output response.
A slow sine (sine, amplitude 1, frequency 0.25 → period 4, i.e. much slower than delayTime = 1) is also fed through pd_sine (n = 3). This demonstrates the block's core purpose — a time shift: pd_sine.y is the sine delayed by ~1 s (a quarter period), with amplitude preserved.
Usage
BlockComponents.Nonlinear.Tests.PadeDelay()
Behavior
Source
"""
Test harness for the PadeDelay block.
A unit step (0 -> 1 at t = 0.5) is fed through three Padé delays with
`delayTime = 1`:
- `pd1` — first order (n = 1), balanced (default).
- `pd3` — third order (n = 3), balanced (default).
- `pd3u` — third order (n = 3), unbalanced (`balance = false`).
Expected behavior (an approximation of a 1-second delay):
- Each output starts with the characteristic non-minimum-phase undershoot
(`y` jumps to -1 the instant the step arrives, because m = n gives direct
feedthrough d = -1).
- Each settles to 1 (DC gain = 1: a delayed constant is the same constant).
- `pd3` holds near zero longer and then rises more steeply than `pd1` (a sharper
delay approximation), at the cost of some ringing.
- `pd3u` must reproduce `pd3` exactly: balancing is a state transformation that
changes only the internal coordinates, not the input->output response.
A slow sine (`sine`, amplitude 1, frequency 0.25 → period 4, i.e. much slower
than `delayTime = 1`) is also fed through `pd_sine` (n = 3). This demonstrates the
block's core purpose — a time shift: `pd_sine.y` is the sine delayed by ~1 s
(a quarter period), with amplitude preserved.
"""
test component PadeDelay
"Unit step at t = 0.5"
step = BlockComponents.Sources.Step(height = 1.0, offset = 0.0, start_time = 0.5) {
"Dyad": {"placement": {"diagram": {"x1": 20, "y1": 230, "x2": 120, "y2": 330}}}
}
"First-order Padé delay, delayTime = 1"
pd1 = BlockComponents.Nonlinear.PadeDelay(n = 1, delayTime = 1.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 240, "y1": 20, "x2": 340, "y2": 120, "rot": 0}
}
}
}
"Third-order Padé delay, delayTime = 1 (balanced realization, default)"
pd3 = BlockComponents.Nonlinear.PadeDelay(n = 3, m = 3, delayTime = 1.0) {
"Dyad": {"placement": {"diagram": {"x1": 240, "y1": 230, "x2": 340, "y2": 330}}}
}
"Third-order Padé delay, unbalanced realization — output must match pd3"
pd3u = BlockComponents.Nonlinear.PadeDelay(n = 3, m = 3, delayTime = 1.0, balance = false) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 240, "y1": 420, "x2": 340, "y2": 520, "rot": 0}
}
}
}
"Slow sine input (period 4), to show the delay as a time shift"
sine = BlockComponents.Sources.Sine(amplitude = 1.0, frequency = 0.25) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 20, "y1": 620, "x2": 120, "y2": 720, "rot": 0}
}
}
}
"Third-order Padé delay applied to the slow sine"
pd_sine = BlockComponents.Nonlinear.PadeDelay(n = 3, m = 3, delayTime = 1.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 240, "y1": 620, "x2": 340, "y2": 720, "rot": 0}
}
}
}
relations
connect(step.y, pd1.u) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 161.66666666666666, "y": 280}, {"x": 161.66666666666666, "y": 70}],
"E": 2
}
]
}
}
connect(step.y, pd3.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}]}}
connect(step.y, pd3u.u) {
"Dyad": {"edges": [{"S": 1, "M": [{"x": 165, "y": 280}, {"x": 165, "y": 470}], "E": 2}]}
}
connect(sine.y, pd_sine.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}]}}
metadata {
"Dyad": {
"icons": {"default": "dyad://BlockComponents/Example.svg"},
"tests": {
"case1": {
"stop": 8,
"atol": {"pd1.y": 0.0001, "pd3.y": 0.0001, "pd3u.y": 0.0001, "pd_sine.y": 0.0001},
"expect": {"signals": ["step.y", "pd1.y", "pd3.y", "pd3u.y", "sine.y", "pd_sine.y"]}
}
}
}
}
endFlattened Source
"""
Test harness for the PadeDelay block.
A unit step (0 -> 1 at t = 0.5) is fed through three Padé delays with
`delayTime = 1`:
- `pd1` — first order (n = 1), balanced (default).
- `pd3` — third order (n = 3), balanced (default).
- `pd3u` — third order (n = 3), unbalanced (`balance = false`).
Expected behavior (an approximation of a 1-second delay):
- Each output starts with the characteristic non-minimum-phase undershoot
(`y` jumps to -1 the instant the step arrives, because m = n gives direct
feedthrough d = -1).
- Each settles to 1 (DC gain = 1: a delayed constant is the same constant).
- `pd3` holds near zero longer and then rises more steeply than `pd1` (a sharper
delay approximation), at the cost of some ringing.
- `pd3u` must reproduce `pd3` exactly: balancing is a state transformation that
changes only the internal coordinates, not the input->output response.
A slow sine (`sine`, amplitude 1, frequency 0.25 → period 4, i.e. much slower
than `delayTime = 1`) is also fed through `pd_sine` (n = 3). This demonstrates the
block's core purpose — a time shift: `pd_sine.y` is the sine delayed by ~1 s
(a quarter period), with amplitude preserved.
"""
test component PadeDelay
"Unit step at t = 0.5"
step = BlockComponents.Sources.Step(height = 1.0, offset = 0.0, start_time = 0.5) {
"Dyad": {"placement": {"diagram": {"x1": 20, "y1": 230, "x2": 120, "y2": 330}}}
}
"First-order Padé delay, delayTime = 1"
pd1 = BlockComponents.Nonlinear.PadeDelay(n = 1, delayTime = 1.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 240, "y1": 20, "x2": 340, "y2": 120, "rot": 0}
}
}
}
"Third-order Padé delay, delayTime = 1 (balanced realization, default)"
pd3 = BlockComponents.Nonlinear.PadeDelay(n = 3, m = 3, delayTime = 1.0) {
"Dyad": {"placement": {"diagram": {"x1": 240, "y1": 230, "x2": 340, "y2": 330}}}
}
"Third-order Padé delay, unbalanced realization — output must match pd3"
pd3u = BlockComponents.Nonlinear.PadeDelay(n = 3, m = 3, delayTime = 1.0, balance = false) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 240, "y1": 420, "x2": 340, "y2": 520, "rot": 0}
}
}
}
"Slow sine input (period 4), to show the delay as a time shift"
sine = BlockComponents.Sources.Sine(amplitude = 1.0, frequency = 0.25) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 20, "y1": 620, "x2": 120, "y2": 720, "rot": 0}
}
}
}
"Third-order Padé delay applied to the slow sine"
pd_sine = BlockComponents.Nonlinear.PadeDelay(n = 3, m = 3, delayTime = 1.0) {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 240, "y1": 620, "x2": 340, "y2": 720, "rot": 0}
}
}
}
relations
connect(step.y, pd1.u) {
"Dyad": {
"edges": [
{
"S": 1,
"M": [{"x": 161.66666666666666, "y": 280}, {"x": 161.66666666666666, "y": 70}],
"E": 2
}
]
}
}
connect(step.y, pd3.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}]}}
connect(step.y, pd3u.u) {
"Dyad": {"edges": [{"S": 1, "M": [{"x": 165, "y": 280}, {"x": 165, "y": 470}], "E": 2}]}
}
connect(sine.y, pd_sine.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}]}}
metadata {
"Dyad": {
"icons": {"default": "dyad://BlockComponents/Example.svg"},
"tests": {
"case1": {
"stop": 8,
"atol": {"pd1.y": 0.0001, "pd3.y": 0.0001, "pd3u.y": 0.0001, "pd_sine.y": 0.0001},
"expect": {"signals": ["step.y", "pd1.y", "pd3.y", "pd3u.y", "sine.y", "pd_sine.y"]}
}
}
}
}
endTest Cases
Test Case case1
pltpltpltpltpltplt