GeezerVison is showing github.com — Update I/O system repr() and str() by murrayrm · Pull Request #1091 · python-control/python-control
Update I/O system repr() and str()
#1091
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and
privacy statement . We’ll occasionally send you account related emails.
Already on GitHub?
Sign in
to your account
Uh oh!
There was an error while loading. Please reload this page.
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
f363e7b
updated iosys class/factory function documentation + docstring unit t…
murrayrm Dec 16, 2024
5076298
update state space system repr() to include signal/system names
murrayrm Dec 7, 2024
6f7cbfa
update transfer function repr() + signal/system names
murrayrm Dec 7, 2024
4cedb6c
update FRD repr() + copy signal/system names on sampling
murrayrm Dec 7, 2024
b0397e0
add unit tests for consistent systems repr() processing
murrayrm Dec 7, 2024
85772f5
add iosys_repr and set default __repr__ to short form
murrayrm Dec 15, 2024
9897ab2
use NumPy printoptions in LaTeX representations
murrayrm Dec 17, 2024
376c28e
refactor I/O system repr() processing via iosys_repr and _repr_<fmt>
murrayrm Dec 20, 2024
42eaff9
small docstring and comment updates
murrayrm Dec 20, 2024
964c3aa
expanded __str__ for IC systems (subsys list + connection map)
murrayrm Dec 22, 2024
9ca6833
add Parameters to NonlinearIOSystem.__str__() + avoid double empty lines
murrayrm Dec 22, 2024
ea7d3ed
Update split_tf and combine_tf docstrings + combine_tf kwargs
murrayrm Dec 28, 2024
1434540
add repr_gallery + update formatting for style and consistency
murrayrm Dec 31, 2024
b083212
add context manager functionality to config.defaults
murrayrm Dec 31, 2024
8402605
update latex processing + repr_gallery.ipynb
murrayrm Dec 31, 2024
7863690
update unit tests + tweak formatting for consistency
murrayrm Dec 31, 2024
e0a612f
change default repr to 'eval' + adjust HTML formatting
murrayrm Dec 31, 2024
5ae33b0
add iosys.repr_show_count and defualt to True
murrayrm Jan 4, 2025
32f65d6
add params to sys_nl in repr_gallery; fix combine/split_tf outputs
murrayrm Jan 4, 2025
41d92d3
address @murrayrm and preliminary @slivingston review comments
murrayrm Jan 8, 2025
0f0fad0
address final (?) @slivingston comments
murrayrm Jan 13, 2025
File filter
Filter by extension
.ipynb
(1)
.py
(19)
All 2 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Hide whitespace
Diff view
Hide whitespace
There are no files selected for viewing
Original file line number
Diff line number
Diff line change
Expand Up
@@ -164,7 +164,7 @@ def parallel(sys1, *sysn, **kwargs):
or `y`). See :class:`InputOutputSystem` for more information.
states : str, or list of str, optional
List of names for system states. If not given, state names will be
of of the form `x[i]` for interconnections of linear systems or
of the form `x[i]` for interconnections of linear systems or
'<subsys_name>.<state_name>' for interconnected nonlinear systems.
name : string, optional
System name (used for specifying signals). If unspecified, a generic
Expand Down
Expand Up
@@ -511,7 +511,7 @@ def connect(sys, Q, inputv, outputv):
return Ytrim * sys * Utrim
def combine_tf(tf_array):
def combine_tf(tf_array, **kwargs ):
"""Combine array-like of transfer functions into MIMO transfer function.
Parameters
Expand All
@@ -527,6 +527,16 @@ def combine_tf(tf_array):
TransferFunction
Transfer matrix represented as a single MIMO TransferFunction object.
Other Parameters
----------------
inputs, outputs : str, or list of str, optional
List of strings that name the individual signals. If not given,
signal names will be of the form `s[i]` (where `s` is one of `u`,
or `y`). See :class:`InputOutputSystem` for more information.
name : string, optional
System name (used for specifying signals). If unspecified, a generic
name <sys[id]> is generated with a unique integer id.
Raises
------
ValueError
Expand All
@@ -541,26 +551,34 @@ def combine_tf(tf_array):
--------
Combine two transfer functions
>>> s = control.TransferFunction.s
>>> control.combine_tf([
... [1 / (s + 1)],
... [s / (s + 2)],
... ])
TransferFunction([[array([1])], [array([1, 0])]],
[[array([1, 1])], [array([1, 2])]])
>>> s = ct.tf('s')
>>> ct.combine_tf(
... [[1 / (s + 1)],
... [s / (s + 2)]],
... name='G'
... )
TransferFunction(
[[array([1])],
[array([1, 0])]],
[[array([1, 1])],
[array([1, 2])]],
name='G', outputs=2, inputs=1)
Combine NumPy arrays with transfer functions
>>> control.combine_tf([
... [np.eye(2), np.zeros((2, 1))],
... [np.zeros((1, 2)), control.TransferFunction([1], [1, 0])],
... ])
TransferFunction([[array([1.]), array([0.]), array([0.])],
[array([0.]), array([1.]), array([0.])],
[array([0.]), array([0.]), array([1])]],
[[array([1.]), array([1.]), array([1.])],
[array([1.]), array([1.]), array([1.])],
[array([1.]), array([1.]), array([1, 0])]])
>>> ct.combine_tf(
... [[np.eye(2), np.zeros((2, 1))],
... [np.zeros((1, 2)), ct.tf([1], [1, 0])]],
... name='G'
... )
TransferFunction(
[[array([1.]), array([0.]), array([0.])],
[array([0.]), array([1.]), array([0.])],
[array([0.]), array([0.]), array([1])]],
[[array([1.]), array([1.]), array([1.])],
[array([1.]), array([1.]), array([1.])],
[array([1.]), array([1.]), array([1, 0])]],
name='G', outputs=3, inputs=3)
"""
# Find common timebase or raise error
dt_list = []
Expand Down
Expand Up
@@ -616,10 +634,14 @@ def combine_tf(tf_array):
"Mismatched number transfer function inputs in row "
f"{row_index} of denominator."
)
return tf.TransferFunction(num, den, dt=dt)
return tf.TransferFunction(num, den, dt=dt, **kwargs)
def split_tf(transfer_function):
"""Split MIMO transfer function into NumPy array of SISO tranfer functions.
"""Split MIMO transfer function into NumPy array of SISO transfer functions.
System and signal names for the array of SISO transfer functions are
copied from the MIMO system.
Parameters
----------
Expand All
@@ -635,21 +657,29 @@ def split_tf(transfer_function):
--------
Split a MIMO transfer function
>>> G = control.TransferFunction(
... [
... [[87.8], [-86.4]],
... [[108.2], [-109.6]],
... ],
... [
... [[1, 1], [1, 1]],
... [[1, 1], [1, 1]],
... ],
>>> G = ct.tf(
... [ [[87.8], [-86.4]],
... [[108.2], [-109.6]] ],
... [ [[1, 1], [1, 1]],
... [[1, 1], [1, 1]], ],
... name='G'
... )
>>> control.split_tf(G)
array([[TransferFunction(array([87.8]), array([1, 1])),
TransferFunction(array([-86.4]), array([1, 1]))],
[TransferFunction(array([108.2]), array([1, 1])),
TransferFunction(array([-109.6]), array([1, 1]))]], dtype=object)
>>> ct.split_tf(G)
array([[TransferFunction(
array([87.8]),
array([1, 1]),
name='G', outputs=1, inputs=1), TransferFunction(
array([-86.4]),
array([1, 1]),
name='G', outputs=1, inputs=1)],
[TransferFunction(
array([108.2]),
array([1, 1]),
name='G', outputs=1, inputs=1), TransferFunction(
array([-109.6]),
array([1, 1]),
name='G', outputs=1, inputs=1)]],
dtype=object)
"""
tf_split_lst = []
for i_out in range(transfer_function.noutputs):
Expand All
@@ -660,6 +690,9 @@ def split_tf(transfer_function):
transfer_function.num_array[i_out, i_in],
transfer_function.den_array[i_out, i_in],
dt=transfer_function.dt,
inputs=transfer_function.input_labels[i_in],
outputs=transfer_function.output_labels[i_out],
name=transfer_function.name
)
)
tf_split_lst.append(row)
Expand Down
Original file line number
Diff line number
Diff line change
Expand Up
@@ -73,6 +73,28 @@ def _check_deprecation(self, key):
else:
return key
#
# Context manager functionality
#
def __call__(self, mapping):
self.saved_mapping = dict()
self.temp_mapping = mapping.copy()
return self
def __enter__(self):
for key, val in self.temp_mapping.items():
if not key in self:
raise ValueError(f"unknown parameter '{key}'")
self.saved_mapping[key] = self[key]
self[key] = val
return self
def __exit__(self, exc_type, exc_val, exc_tb):
for key, val in self.saved_mapping.items():
self[key] = val
del self.saved_mapping, self.temp_mapping
return None
defaults = DefaultDict(_control_defaults)
Expand Down
Expand Up
@@ -266,7 +288,7 @@ def use_legacy_defaults(version):
Parameters
----------
version : string
Version number of the defaults desired. Ranges from '0.1' to '0.8.4 '.
Version number of the defaults desired. Ranges from '0.1' to '0.10.1 '.
Examples
--------
Expand All
@@ -279,26 +301,26 @@ def use_legacy_defaults(version):
(major, minor, patch) = (None, None, None) # default values
# Early release tag format: REL-0.N
match = re.match(" REL-0.([12])", version)
match = re.match(r"^ REL-0.([12])$ ", version)
if match: (major, minor, patch) = (0, int(match.group(1)), 0)
# Early release tag format: control-0.Np
match = re.match(" control-0.([3-6])([a-d])", version)
match = re.match(r"^ control-0.([3-6])([a-d])$ ", version)
if match: (major, minor, patch) = \
(0, int(match.group(1)), ord(match.group(2)) - ord('a') + 1)
# Early release tag format: v0.Np
match = re.match(" [vV]?0.([3-6])([a-d])", version)
match = re.match(r"^ [vV]?0\ .([3-6])([a-d])$ ", version)
if match: (major, minor, patch) = \
(0, int(match.group(1)), ord(match.group(2)) - ord('a') + 1)
# Abbreviated version format: vM.N or M.N
match = re.match("( [vV]?[0-9]) .([0-9]) ", version)
match = re.match(r"^ [vV]?( [0-9]*)\ .([0-9]*)$ ", version)
if match: (major, minor, patch) = \
(int(match.group(1)), int(match.group(2)), 0)
# Standard version format: vM.N.P or M.N.P
match = re.match(" [vV]?([0-9]) .([0-9]) .([0-9]) ", version)
match = re.match(r"^ [vV]?([0-9]*)\ .([0-9]*)\ .([0-9]*)$ ", version)
if match: (major, minor, patch) = \
(int(match.group(1)), int(match.group(2)), int(match.group(3)))
Expand Down
Original file line number
Diff line number
Diff line change
Expand Up
@@ -285,7 +285,6 @@ def __init__(self, *args, **kwargs):
if self.squeeze not in (None, True, False):
raise ValueError("unknown squeeze value")
# Process iosys keywords
defaults = {
'inputs': self.fresp.shape[1] if not getattr(
self, 'input_index', None) else self.input_labels,
Expand Down
Expand Up
@@ -401,30 +400,37 @@ def __str__(self):
mimo = self.ninputs > 1 or self.noutputs > 1
outstr = [f"{InputOutputSystem.__str__(self)}"]
nl = "\n " if mimo else "\n"
sp = " " if mimo else ""
for i in range(self.ninputs):
for j in range(self.noutputs):
if mimo:
outstr.append("Input %i to output %i:" % (i + 1, j + 1))
outstr.append('Freq [rad/s] Response')
outstr.append('------------ ---------------------')
outstr.append(
"\nInput %i to output %i:" % (i + 1, j + 1))
outstr.append(nl + 'Freq [rad/s] Response')
outstr.append(sp + '------------ ---------------------')
outstr.extend(
['%12.3f %10.4g%+10.4gj' % (w, re, im)
[sp + '%12.3f %10.4g%+10.4gj' % (w, re, im)
for w, re, im in zip(self.omega,
real(self.fresp[j, i, :]),
imag(self.fresp[j, i, :]))])
return '\n'.join(outstr)
def __repr__(self):
"""Loadable string representation,
limited for number of data points.
"""
return "FrequencyResponseData({d}, {w}{smooth})".format(
def _repr_eval_(self):
# Loadable format
out = "FrequencyResponseData(\n{d},\n{w}{smooth}".format(
d=repr(self.fresp), w=repr(self.omega),
smooth=(self._ifunc and ", smooth=True") or "")
out += self._dt_repr()
if len(labels := self._label_repr()) > 0:
out += ",\n" + labels
out += ")"
return out
def __neg__(self):
"""Negate a transfer function."""
Expand Down
Loading
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.