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 @@ -10,5 +10,5 @@ authors:
orcid: "https://orcid.org/0000-0002-1987-9268"
affiliation: "McGill University"
title: "decargroup/dkpy"
version: v0.1.7
version: v0.1.8
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 @@ -137,6 +137,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 James Richard Forbes},
version = {{v0.1.7}},
version = {{v0.1.8}},
year={2024},
}
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 and James Richard Forbes"
author = "Steven Dahdah and James Richard Forbes"
version = "0.1.7"
release = "0.1.7"
version = "0.1.8"
release = "0.1.8"

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
36 changes: 32 additions & 4 deletions doc/dkpy.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
D-K iteration methods
=====================

The D-K iteration methods provided by ``dkpy`` are presented below. Each one
implements the interface specified in :class:`DkIteration`. The difference
between these methods is the way the D-scale fit order is selected. It can
either be fixed, specified via a list, selected automatically, or selected
interactively.

.. autosummary::
:toctree: _autosummary/

Expand All @@ -9,19 +15,26 @@ D-K iteration methods
dkpy.DkIterAutoOrder
dkpy.DkIterInteractiveOrder

D-K iteration extras
====================
Each :func:`DkIteration.synthesize` method returns (among other things) a list
of :class:`IterResult` objects. These objects summarize the status of the D-K
iteration process at each step. They can be plotted with :func:`plot_D` and
:func:`plot_mu` to assess the accuracy of the D-scale fit and its impact on the
structured singular value.

.. autosummary::
:toctree: _autosummary/

dkpy.DScaleFitInfo
dkpy.plot_D
dkpy.IterResult
dkpy.plot_mu
dkpy.plot_D

Controller synthesis
====================

Supported continuous-time H-infinity controller synthesis methods are provided
below. Each one implements the interface specified in
:class:`ControllerSynthesis`.

.. autosummary::
:toctree: _autosummary/

Expand All @@ -33,6 +46,11 @@ Controller synthesis
Structured singular value
=========================

Supported structured singular value computation methods are provided below.
Only one approach is provided, which implements the interface in
:class:`StructuredSingularValue`. The LMI solver settings may need to be
adjusted depending on the problem.

.. autosummary::
:toctree: _autosummary/

Expand All @@ -41,13 +59,23 @@ Structured singular value
D-scale fit
===========

Supported D-scale fitting methods are provided below. Only one approach is
provided currently, which implements the interface in :class:`DScaleFit`. There
are currently no ways to customize the D-scale magnitude fitting process beyond
selecting the order in :func:`DScaleFit.fit`.

.. autosummary::
:toctree: _autosummary/

dkpy.DScaleFitSlicot

Extending ``dkpy``
==================

The abstract classes defining the structure of ``dkpy`` are presented below.
Anyone aiming to extend or customize ``dkpy`` should familiarize themselves
with them.

.. autosummary::
:toctree: _autosummary/

Expand Down
7 changes: 5 additions & 2 deletions doc/examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ Examples
========

In all the examples on this page, three iterations with 4th order D-scale fits
are used to reprouce the example from [SP06]_, Table 8.2 (p. 325). Each example
are used to reproduce the example from [SP06]_, Table 8.2 (p. 325). Each example
recovers the same result, but with a different way to specify the D-scale fit
orders.

This example is quite numerically challenging, so if you encounter a solver
error, you may need to experiment with solver tolerances.

D-K iteration with fixed fit order
----------------------------------

Expand Down Expand Up @@ -42,7 +45,7 @@ Output::
D-K iteration with automatically selected fit orders
----------------------------------------------------

In this example, multiple fit orders are atempted up to a maximum, and the one
In this example, multiple fit orders are attempted up to a maximum, and the one
with the lowest relative error is selected.

.. literalinclude:: ../examples/3_example_dk_iter_auto_order.py
Expand Down
6 changes: 3 additions & 3 deletions examples/1_example_dk_iter_fixed_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def example_dk_iter_fixed_order():

omega = np.logspace(-3, 3, 61)
block_structure = np.array([[1, 1], [1, 1], [2, 2]])
K, N, mu, d_scale_fit_info, info = dk_iter.synthesize(
K, N, mu, iter_results, info = dk_iter.synthesize(
eg["P"],
eg["n_y"],
eg["n_u"],
Expand All @@ -31,11 +31,11 @@ def example_dk_iter_fixed_order():
print(f"mu={mu}")

fig, ax = plt.subplots()
for i, ds in enumerate(d_scale_fit_info):
for i, ds in enumerate(iter_results):
dkpy.plot_mu(ds, ax=ax, plot_kw=dict(label=f"iter{i}"))

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

plt.show()
Expand Down
6 changes: 3 additions & 3 deletions examples/2_example_dk_iter_list_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def example_dk_iter_list_order():

omega = np.logspace(-3, 3, 61)
block_structure = np.array([[1, 1], [1, 1], [2, 2]])
K, N, mu, d_scale_fit_info, info = dk_iter.synthesize(
K, N, mu, iter_results, info = dk_iter.synthesize(
eg["P"],
eg["n_y"],
eg["n_u"],
Expand All @@ -35,11 +35,11 @@ def example_dk_iter_list_order():
print(f"mu={mu}")

fig, ax = plt.subplots()
for i, ds in enumerate(d_scale_fit_info):
for i, ds in enumerate(iter_results):
dkpy.plot_mu(ds, ax=ax, plot_kw=dict(label=f"iter{i}"))

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

plt.show()
Expand Down
6 changes: 3 additions & 3 deletions examples/3_example_dk_iter_auto_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def example_dk_iter_auto_order():

omega = np.logspace(-3, 3, 61)
block_structure = np.array([[1, 1], [1, 1], [2, 2]])
K, N, mu, d_scale_fit_info, info = dk_iter.synthesize(
K, N, mu, iter_results, info = dk_iter.synthesize(
eg["P"],
eg["n_y"],
eg["n_u"],
Expand All @@ -56,11 +56,11 @@ def example_dk_iter_auto_order():
print(f"mu={mu}")

fig, ax = plt.subplots()
for i, ds in enumerate(d_scale_fit_info):
for i, ds in enumerate(iter_results):
dkpy.plot_mu(ds, ax=ax, plot_kw=dict(label=f"iter{i}"))

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

plt.show()
Expand Down
6 changes: 3 additions & 3 deletions examples/4_example_dk_iter_interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def example_dk_iter_interactive():

omega = np.logspace(-3, 3, 61)
block_structure = np.array([[1, 1], [1, 1], [2, 2]])
K, N, mu, d_scale_fit_info, info = dk_iter.synthesize(
K, N, mu, iter_results, info = dk_iter.synthesize(
eg["P"],
eg["n_y"],
eg["n_u"],
Expand All @@ -49,11 +49,11 @@ def example_dk_iter_interactive():
print(f"mu={mu}")

fig, ax = plt.subplots()
for i, ds in enumerate(d_scale_fit_info):
for i, ds in enumerate(iter_results):
dkpy.plot_mu(ds, ax=ax, plot_kw=dict(label=f"iter{i}"))

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

plt.show()
Expand Down
6 changes: 3 additions & 3 deletions examples/5_example_dk_iteration_custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def example_dk_iter_custom():

omega = np.logspace(-3, 3, 61)
block_structure = np.array([[1, 1], [1, 1], [2, 2]])
K, N, mu, d_scale_fit_info, info = dk_iter.synthesize(
K, N, mu, iter_results, info = dk_iter.synthesize(
eg["P"],
eg["n_y"],
eg["n_u"],
Expand All @@ -82,11 +82,11 @@ def example_dk_iter_custom():
print(f"mu={mu}")

fig, ax = plt.subplots()
for i, ds in enumerate(d_scale_fit_info):
for i, ds in enumerate(iter_results):
dkpy.plot_mu(ds, ax=ax, plot_kw=dict(label=f"iter{i}"))

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

plt.show()
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "dkpy"
version = "0.1.7"
version = "0.1.8"
dependencies = [
"numpy>=1.21.0",
"scipy>=1.7.0",
Expand Down
12 changes: 10 additions & 2 deletions src/dkpy/d_scale_fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def fit(
block_structure : np.ndarray
2D array with 2 columns and as many rows as uncertainty blocks
in Delta. The columns represent the number of rows and columns in
each uncertainty block.
each uncertainty block. See [#mussv]_.

Returns
-------
Expand All @@ -54,6 +54,10 @@ def fit(
ValueError
If ``order`` is an array but its dimensions are inconsistent with
``block_structure``.

References
----------
.. [#mussv] https://www.mathworks.com/help/robust/ref/mussv.html
"""
raise NotImplementedError()

Expand Down Expand Up @@ -162,13 +166,17 @@ def _mask_from_block_structure(block_structure: np.ndarray) -> np.ndarray:
block_structure : np.ndarray
2D array with 2 columns and as many rows as uncertainty blocks
in Delta. The columns represent the number of rows and columns in
each uncertainty block.
each uncertainty block. See [#mussv]_.

Returns
-------
np.ndarray
Array of integers indicating zero, one, and unknown elements in the
block structure.

References
----------
.. [#mussv] https://www.mathworks.com/help/robust/ref/mussv.html
"""
X_lst = []
for i in range(block_structure.shape[0]):
Expand Down
Loading
Loading