Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ authors:
orcid: "https://orcid.org/0000-0002-1987-9268"
affiliation: "McGill University"
title: "decargroup/dkpy"
version: v0.1.10
version: v0.1.11
url: "https://github.com/decargroup/dkpy"
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,6 @@ If you use this software in your research, please cite it as below or see
url={https://github.com/decargroup/dkpy},
publisher={Zenodo},
author={Steven Dahdah and Timothy Everett Adams and James Richard Forbes},
version = {{v0.1.10}},
version = {{v0.1.11}},
year={2025},
}
Binary file added doc/_static/example_1/1_plot_D.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_1/1_plot_mu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_2/2_plot_D.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_2/2_plot_mu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_3/3_plot_D.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_3/3_plot_mu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_4/4_interactive_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_4/4_interactive_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_4/4_interactive_3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_4/4_interactive_4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_4/4_plot_D.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_4/4_plot_mu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_5/5_plot_D.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_5/5_plot_mu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_6/6_plot_inputs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_6/6_plot_mu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/_static/example_6/6_plot_states.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed doc/_static/interactive_1.png
Binary file not shown.
Binary file removed doc/_static/interactive_2.png
Binary file not shown.
Binary file removed doc/_static/interactive_3.png
Binary file not shown.
Binary file removed doc/_static/interactive_4.png
Binary file not shown.
Binary file removed doc/_static/plot_D.png
Binary file not shown.
Binary file removed doc/_static/plot_mu.png
Binary file not shown.
4 changes: 2 additions & 2 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
project = "dkpy"
copyright = "2024, Steven Dahdah, Timothy Everett Adams and James Richard Forbes"
author = "Steven Dahdah, Timothy Everett Adams and James Richard Forbes"
version = "0.1.10"
release = "0.1.10"
version = "0.1.11"
release = "0.1.11"

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
3 changes: 3 additions & 0 deletions doc/dkpy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ with them. The abstract classes are provided below.
dkpy.DkIteration

The steps of the D-K iteration algorithm are as follows [SP06]_.

1. Controller synthesis (:class:`ControllerSynthesis`): Synthesize an
H-infinity controller for the scaled problem with fixed fitted D-scales.

2. Structured singular value and D-scale computation
(:class:`StructuredSingularValue`): Compute the structured singular value
and the D-scales over a discrete grid of frequencies with a fixed
controller.

3. D-scale fit (:class:`DScaleFit`): Fit the magnitude of each D-scale to a
stable minimum-phase LTI system.

Expand Down
117 changes: 75 additions & 42 deletions doc/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ to 4.

Output::

mu=1.0132789611816406
mu=1.0368156433105469

.. image:: _static/plot_mu.png
.. image:: _static/plot_D.png
.. image:: _static/example_1/1_plot_mu.png
.. image:: _static/example_1/1_plot_D.png

D-K iteration with list of fit orders
-------------------------------------
Expand All @@ -37,10 +37,10 @@ integer.

Output::

mu=1.0132789611816406
mu=1.0368156433105469

.. image:: _static/plot_mu.png
.. image:: _static/plot_D.png
.. image:: _static/example_2/2_plot_mu.png
.. image:: _static/example_2/2_plot_D.png

D-K iteration with automatically selected fit orders
----------------------------------------------------
Expand All @@ -53,34 +53,34 @@ with the lowest relative error is selected.

Output::

INFO:DkIterAutoOrder:Iteration: 0, mu: 1.1792325973510742
INFO:DkIterAutoOrder:Order 0 relative error: 0.5122457769147215
INFO:DkIterAutoOrder:Order 1 relative error: 0.34431183690576633
INFO:DkIterAutoOrder:Order 2 relative error: 0.8970100659296376
INFO:DkIterAutoOrder:Order 3 relative error: 0.030844892155775263
INFO:DkIterAutoOrder:Order 4 relative error: 0.015896380940858944
INFO:DkIterAutoOrder:Iteration: 0, mu: 1.1792182922363281
INFO:DkIterAutoOrder:Order 0 relative error: 0.5066119732511977
INFO:DkIterAutoOrder:Order 1 relative error: 0.3356881131800033
INFO:DkIterAutoOrder:Order 2 relative error: 0.643462672042705
INFO:DkIterAutoOrder:Order 3 relative error: 0.031649076289004166
INFO:DkIterAutoOrder:Order 4 relative error: 0.012866875729555234
INFO:DkIterAutoOrder:Reached max fit order, selecting order 4
INFO:DkIterAutoOrder:Iteration: 1, mu: 1.0256481170654297
INFO:DkIterAutoOrder:Order 0 relative error: 9.350642790785383
INFO:DkIterAutoOrder:Order 1 relative error: 1.327796980729705
INFO:DkIterAutoOrder:Order 2 relative error: 7.58063969442474
INFO:DkIterAutoOrder:Order 3 relative error: 0.13472058625314948
INFO:DkIterAutoOrder:Order 4 relative error: 0.05262584627773765
INFO:DkIterAutoOrder:Iteration: 1, mu: 1.0274028778076172
INFO:DkIterAutoOrder:Order 0 relative error: 9.780743577129419
INFO:DkIterAutoOrder:Order 1 relative error: 1.4151255816143613
INFO:DkIterAutoOrder:Order 2 relative error: 8.507402105789147
INFO:DkIterAutoOrder:Order 3 relative error: 0.15216618301078452
INFO:DkIterAutoOrder:Order 4 relative error: 0.05185270360448734
INFO:DkIterAutoOrder:Reached max fit order, selecting order 4
INFO:DkIterAutoOrder:Iteration: 2, mu: 1.0201168060302734
INFO:DkIterAutoOrder:Order 0 relative error: 28.96943897648902
INFO:DkIterAutoOrder:Order 1 relative error: 3.9918344794684804
INFO:DkIterAutoOrder:Order 2 relative error: 7.000978128580445
INFO:DkIterAutoOrder:Order 3 relative error: 0.22159755671770862
INFO:DkIterAutoOrder:Order 4 relative error: 0.06377761160336083
INFO:DkIterAutoOrder:Iteration: 2, mu: 1.0203123092651367
INFO:DkIterAutoOrder:Order 0 relative error: 30.002715934629506
INFO:DkIterAutoOrder:Order 1 relative error: 4.172954343879354
INFO:DkIterAutoOrder:Order 2 relative error: 9.026259323212026
INFO:DkIterAutoOrder:Order 3 relative error: 0.24098884948353583
INFO:DkIterAutoOrder:Order 4 relative error: 0.04541136749668787
INFO:DkIterAutoOrder:Reached max fit order, selecting order 4
INFO:DkIterAutoOrder:Iteration: 3, mu: 1.0132789611816406
INFO:DkIterAutoOrder:Iteration: 3, mu: 1.0144329071044922
INFO:DkIterAutoOrder:Iteration terminated: reached maximum number of iterations
INFO:DkIterAutoOrder:Iteration complete
mu=1.0132789611816406
mu=1.0144329071044922

.. image:: _static/plot_mu.png
.. image:: _static/plot_D.png
.. image:: _static/example_3/3_plot_mu.png
.. image:: _static/example_3/3_plot_D.png

D-K iteration with interactively selected fit orders
----------------------------------------------------
Expand All @@ -92,38 +92,38 @@ singular value plots at each iteration.
.. literalinclude:: ../examples/4_example_dk_iter_interactive.py
:language: python

.. image:: _static/interactive_1.png
.. image:: _static/example_4/4_interactive_1.png

Prompt::

Close plot to continue...
Select order (<Enter> to end iteration): 4

.. image:: _static/interactive_2.png
.. image:: _static/example_4/4_interactive_2.png

Prompt::

Close plot to continue...
Select order (<Enter> to end iteration): 4

.. image:: _static/interactive_3.png
.. image:: _static/example_4/4_interactive_3.png

Prompt::

Close plot to continue...
Select order (<Enter> to end iteration): 4

.. image:: _static/interactive_4.png
.. image:: _static/example_4/4_interactive_4.png

Output::

Close plot to continue...
Select order (<Enter> to end iteration):
Iteration ended.
mu=1.0132789611816406
mu=1.0144329071044922

.. image:: _static/plot_mu.png
.. image:: _static/plot_D.png
.. image:: _static/example_4/4_plot_mu.png
.. image:: _static/example_4/4_plot_D.png

D-K iteration with a custom fit order selection method
------------------------------------------------------
Expand All @@ -136,11 +136,44 @@ after 3 iterations of 4th order fits.

Output::

Iteration 0 with mu of 1.1792325973510742
Iteration 1 with mu of 1.0256481170654297
Iteration 2 with mu of 1.0201168060302734
Iteration 3 with mu of 1.0132789611816406
mu=1.0132789611816406
Iteration 0 with mu of 1.1792182922363281
Iteration 1 with mu of 1.0274028778076172
Iteration 2 with mu of 1.0203123092651367
Iteration 3 with mu of 1.0144329071044922
mu=1.0144329071044922

.. image:: _static/plot_mu.png
.. image:: _static/plot_D.png
.. image:: _static/example_5/5_plot_mu.png
.. image:: _static/example_5/5_plot_D.png


D-K iteration for non-square perturbation and simulation of perturbed systems
-----------------------------------------------------------------------------

In this example, the perturbation `Δ` is non-square. In other words, the inputs
and outputs of the perturbation are not identical. The orders are specified in
a list. Once the robust controller is synthesized, it is tested on a set of
perturbed systems by generating a set of perturbations `Δ` that have H-infinity
norm less than or equal to 1.

In this example, a controller is designed for the linearized lateral dynamics
of an aircraft from an example given in Section 14.1 of [M04]_.

.. literalinclude:: ../examples/6_dk_iteration_non_square_perturbation.py
:language: python

Output::

mu: 0.9824275970458984

.. image:: _static/example_6/6_plot_mu.png

After the controller is synthesized, a set of off-nominal models are generated
by interconnecting various admissible perturbations `Δ` with the nominal model.
Then, the closed-loop systems are formed for each perturbed system. The time
domain response of the systems can be obtained for a step response in the roll
angle reference signal, no external disturbances, and moderate sensor noise. In
particular, the response of the system states and actuator inputs are shown.

.. image:: _static/example_6/6_plot_states.png

.. image:: _static/example_6/6_plot_inputs.png
4 changes: 4 additions & 0 deletions doc/references.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ References
.. [SP06] S. Skogestad and I. Postlethwaite, Multivariable Feedback Control:
Analysis and Design. West Sussex, England: Wiley, 2006.
ISBN 978-0-47-001168-3.
.. [M04] U. Mackenroth, Robust Control Systems: Theory and Case Studies.
Berlin, Heidelberg: Springer, 2004. ISBN 978-3-642-05891-2.


18 changes: 8 additions & 10 deletions examples/1_example_dk_iter_fixed_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,22 @@ def example_dk_iter_fixed_order():

dk_iter = dkpy.DkIterFixedOrder(
controller_synthesis=dkpy.HinfSynSlicot(),
structured_singular_value=dkpy.SsvLmiBisection(),
structured_singular_value=dkpy.SsvLmiBisection(n_jobs=1),
d_scale_fit=dkpy.DScaleFitSlicot(),
n_iterations=3,
fit_order=4,
)

omega = np.logspace(-3, 3, 61)
# Alternative MATLAB descr.
# Alternative MATLAB block structure description
# uncertainty_structure = dkpy.UncertaintyBlockStructure(
# [[1, 1], [1, 1], [2, 2]]
# )
uncertainty_structure = dkpy.UncertaintyBlockStructure(
[
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(2, 2),
]
)
uncertainty_structure = [
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(2, 2),
]
K, N, mu, iter_results, info = dk_iter.synthesize(
eg["P"],
eg["n_y"],
Expand All @@ -46,7 +44,7 @@ def example_dk_iter_fixed_order():

ax = None
for i, ds in enumerate(iter_results):
_, ax = dkpy.plot_D(ds, ax=ax, plot_kw=dict(label=f"iter{i}"))
fig, ax = dkpy.plot_D(ds, ax=ax, plot_kw=dict(label=f"iter{i}"))

plt.show()

Expand Down
22 changes: 10 additions & 12 deletions examples/2_example_dk_iter_list_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,22 @@ def example_dk_iter_list_order():
d_scale_fit=dkpy.DScaleFitSlicot(),
# fit_orders=[4, 4, 4], # <- an alternative
fit_orders=[
np.diag([4, 4, 0, 0]),
np.diag([4, 4, 0, 0]),
np.diag([4, 4, 0, 0]),
[4, 4, 0],
[4, 4, 0],
[4, 4, 0],
],
)

omega = np.logspace(-3, 3, 61)
# Alternative MATLAB descr.
# Alternative MATLAB block structure description
# uncertainty_structure = dkpy.UncertaintyBlockStructure(
# [[1, 1], [1, 1], [2, 2]]
# )
uncertainty_structure = dkpy.UncertaintyBlockStructure(
[
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(2, 2),
]
)
uncertainty_structure = [
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(2, 2),
]
K, N, mu, iter_results, info = dk_iter.synthesize(
eg["P"],
eg["n_y"],
Expand All @@ -50,7 +48,7 @@ def example_dk_iter_list_order():

ax = None
for i, ds in enumerate(iter_results):
_, ax = dkpy.plot_D(ds, ax=ax, plot_kw=dict(label=f"iter{i}"))
fig, ax = dkpy.plot_D(ds, ax=ax, plot_kw=dict(label=f"iter{i}"))

plt.show()

Expand Down
18 changes: 8 additions & 10 deletions examples/3_example_dk_iter_auto_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def example_dk_iter_auto_order():
solver="MOSEK",
eps=1e-9,
),
n_jobs=1,
),
d_scale_fit=dkpy.DScaleFitSlicot(),
max_mu=1,
Expand All @@ -44,17 +45,15 @@ def example_dk_iter_auto_order():
)

omega = np.logspace(-3, 3, 61)
# Alternative MATLAB descr.
# Alternative MATLAB block structure description
# uncertainty_structure = dkpy.UncertaintyBlockStructure(
# [[1, 1], [1, 1], [2, 2]]
# )
uncertainty_structure = dkpy.UncertaintyBlockStructure(
[
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(2, 2),
]
)
uncertainty_structure = [
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(2, 2),
]
K, N, mu, iter_results, info = dk_iter.synthesize(
eg["P"],
eg["n_y"],
Expand All @@ -71,8 +70,7 @@ def example_dk_iter_auto_order():

ax = None
for i, ds in enumerate(iter_results):
_, ax = dkpy.plot_D(ds, ax=ax, plot_kw=dict(label=f"iter{i}"))

fig, ax = dkpy.plot_D(ds, ax=ax, plot_kw=dict(label=f"iter{i}"))
plt.show()


Expand Down
16 changes: 7 additions & 9 deletions examples/4_example_dk_iter_interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,15 @@ def example_dk_iter_interactive():
)

omega = np.logspace(-3, 3, 61)
# Alternative MATLAB descr.
# Alternative MATLAB block structure description
# uncertainty_structure = dkpy.UncertaintyBlockStructure(
# [[1, 1], [1, 1], [2, 2]]
# )
uncertainty_structure = dkpy.UncertaintyBlockStructure(
[
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(2, 2),
]
)
uncertainty_structure = [
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(1, 1),
dkpy.ComplexFullBlock(2, 2),
]
K, N, mu, iter_results, info = dk_iter.synthesize(
eg["P"],
eg["n_y"],
Expand All @@ -64,7 +62,7 @@ def example_dk_iter_interactive():

ax = None
for i, ds in enumerate(iter_results):
_, ax = dkpy.plot_D(ds, ax=ax, plot_kw=dict(label=f"iter{i}"))
fig, ax = dkpy.plot_D(ds, ax=ax, plot_kw=dict(label=f"iter{i}"))

plt.show()

Expand Down
Loading
Loading