diff --git a/control/statesp.py b/control/statesp.py index c12583111..bfa55b357 100644 --- a/control/statesp.py +++ b/control/statesp.py @@ -391,11 +391,8 @@ def __str__(self): "\n ".join(str(M).splitlines())) for Mvar, M in zip(["A", "B", "C", "D"], [self.A, self.B, self.C, self.D])]) - # TODO: replace with standard calls to lti functions - if (type(self.dt) == bool and self.dt is True): - string += "\ndt unspecified\n" - elif (not (self.dt is None) and type(self.dt) != bool and self.dt > 0): - string += "\ndt = " + self.dt.__str__() + "\n" + if self.isdtime(strict=True): + string += f"\ndt = {self.dt}\n" return string # represent to implement a re-loadable version @@ -418,8 +415,8 @@ def _latex_partitioned_stateless(self): """ lines = [ r'\[', - r'\left(', - (r'\begin{array}' + (r'\left(' + + r'\begin{array}' + r'{' + 'rll' * self.ninputs + '}') ] @@ -429,7 +426,8 @@ def _latex_partitioned_stateless(self): lines.extend([ r'\end{array}' - r'\right)', + r'\right)' + + self._latex_dt(), r'\]']) return '\n'.join(lines) @@ -449,8 +447,8 @@ def _latex_partitioned(self): lines = [ r'\[', - r'\left(', - (r'\begin{array}' + (r'\left(' + + r'\begin{array}' + r'{' + 'rll' * self.nstates + '|' + 'rll' * self.ninputs + '}') ] @@ -466,7 +464,8 @@ def _latex_partitioned(self): lines.extend([ r'\end{array}' - r'\right)', + + r'\right)' + + self._latex_dt(), r'\]']) return '\n'.join(lines) @@ -509,11 +508,21 @@ def fmt_matrix(matrix, name): lines.extend(fmt_matrix(self.D, 'D')) lines.extend([ - r'\end{array}', + r'\end{array}' + + self._latex_dt(), r'\]']) return '\n'.join(lines) + def _latex_dt(self): + if self.isdtime(strict=True): + if self.dt is True: + return r"~,~dt=~\mathrm{True}" + else: + fmt = config.defaults['statesp.latex_num_format'] + return f"~,~dt={self.dt:{fmt}}" + return "" + def _repr_latex_(self): """LaTeX representation of state-space model @@ -534,9 +543,9 @@ def _repr_latex_(self): elif config.defaults['statesp.latex_repr_type'] == 'separate': return self._latex_separate() else: - cfg = config.defaults['statesp.latex_repr_type'] raise ValueError( - "Unknown statesp.latex_repr_type '{cfg}'".format(cfg=cfg)) + "Unknown statesp.latex_repr_type '{cfg}'".format( + cfg=config.defaults['statesp.latex_repr_type'])) # Negation of a system def __neg__(self): diff --git a/control/tests/statesp_test.py b/control/tests/statesp_test.py index 71e7cc4bc..ab62bc1b6 100644 --- a/control/tests/statesp_test.py +++ b/control/tests/statesp_test.py @@ -743,9 +743,9 @@ def test_str(self, sys322): " [ 0. 1.]]\n") assert str(tsys) == tref tsysdtunspec = StateSpace(tsys.A, tsys.B, tsys.C, tsys.D, True) - assert str(tsysdtunspec) == tref + "\ndt unspecified\n" + assert str(tsysdtunspec) == tref + "\ndt = True\n" sysdt1 = StateSpace(tsys.A, tsys.B, tsys.C, tsys.D, 1.) - assert str(sysdt1) == tref + "\ndt = 1.0\n" + assert str(sysdt1) == tref + "\ndt = {}\n".format(1.) def test_pole_static(self): """Regression: pole() of static gain is empty array.""" @@ -997,9 +997,9 @@ def test_statespace_defaults(self, matarrayout): [[1.2345, -2e-200], [-1, 0]]) LTX_G1_REF = { - 'p3_p' : '\\[\n\\left(\n\\begin{array}{rllrll|rll}\n3.&\\hspace{-1em}14&\\hspace{-1em}\\phantom{\\cdot}&1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{100}&0\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n-1.&\\hspace{-1em}23&\\hspace{-1em}\\phantom{\\cdot}&5\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{-23}&1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\hline\n9.&\\hspace{-1em}88&\\hspace{-1em}\\cdot10^{8}&0.&\\hspace{-1em}00123&\\hspace{-1em}\\phantom{\\cdot}&5\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\end{array}\\right)\n\\]', + 'p3_p' : '\\[\n\\left(\\begin{array}{rllrll|rll}\n3.&\\hspace{-1em}14&\\hspace{-1em}\\phantom{\\cdot}&1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{100}&0\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n-1.&\\hspace{-1em}23&\\hspace{-1em}\\phantom{\\cdot}&5\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{-23}&1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\hline\n9.&\\hspace{-1em}88&\\hspace{-1em}\\cdot10^{8}&0.&\\hspace{-1em}00123&\\hspace{-1em}\\phantom{\\cdot}&5\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\end{array}\\right)\n\\]', - 'p5_p' : '\\[\n\\left(\n\\begin{array}{rllrll|rll}\n3.&\\hspace{-1em}1416&\\hspace{-1em}\\phantom{\\cdot}&1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{100}&0\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n-1.&\\hspace{-1em}2346&\\hspace{-1em}\\phantom{\\cdot}&5\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{-23}&1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\hline\n9.&\\hspace{-1em}8765&\\hspace{-1em}\\cdot10^{8}&0.&\\hspace{-1em}001234&\\hspace{-1em}\\phantom{\\cdot}&5\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\end{array}\\right)\n\\]', + 'p5_p' : '\\[\n\\left(\\begin{array}{rllrll|rll}\n3.&\\hspace{-1em}1416&\\hspace{-1em}\\phantom{\\cdot}&1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{100}&0\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n-1.&\\hspace{-1em}2346&\\hspace{-1em}\\phantom{\\cdot}&5\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{-23}&1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\hline\n9.&\\hspace{-1em}8765&\\hspace{-1em}\\cdot10^{8}&0.&\\hspace{-1em}001234&\\hspace{-1em}\\phantom{\\cdot}&5\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\end{array}\\right)\n\\]', 'p3_s' : '\\[\n\\begin{array}{ll}\nA = \\left(\\begin{array}{rllrll}\n3.&\\hspace{-1em}14&\\hspace{-1em}\\phantom{\\cdot}&1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{100}\\\\\n-1.&\\hspace{-1em}23&\\hspace{-1em}\\phantom{\\cdot}&5\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{-23}\\\\\n\\end{array}\\right)\n&\nB = \\left(\\begin{array}{rll}\n0\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\end{array}\\right)\n\\\\\nC = \\left(\\begin{array}{rllrll}\n9.&\\hspace{-1em}88&\\hspace{-1em}\\cdot10^{8}&0.&\\hspace{-1em}00123&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\end{array}\\right)\n&\nD = \\left(\\begin{array}{rll}\n5\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\end{array}\\right)\n\\end{array}\n\\]', @@ -1007,9 +1007,9 @@ def test_statespace_defaults(self, matarrayout): } LTX_G2_REF = { - 'p3_p' : '\\[\n\\left(\n\\begin{array}{rllrll}\n1.&\\hspace{-1em}23&\\hspace{-1em}\\phantom{\\cdot}&-2\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{-200}\\\\\n-1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}&0\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\end{array}\\right)\n\\]', + 'p3_p' : '\\[\n\\left(\\begin{array}{rllrll}\n1.&\\hspace{-1em}23&\\hspace{-1em}\\phantom{\\cdot}&-2\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{-200}\\\\\n-1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}&0\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\end{array}\\right)\n\\]', - 'p5_p' : '\\[\n\\left(\n\\begin{array}{rllrll}\n1.&\\hspace{-1em}2345&\\hspace{-1em}\\phantom{\\cdot}&-2\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{-200}\\\\\n-1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}&0\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\end{array}\\right)\n\\]', + 'p5_p' : '\\[\n\\left(\\begin{array}{rllrll}\n1.&\\hspace{-1em}2345&\\hspace{-1em}\\phantom{\\cdot}&-2\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{-200}\\\\\n-1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}&0\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\end{array}\\right)\n\\]', 'p3_s' : '\\[\n\\begin{array}{ll}\nD = \\left(\\begin{array}{rllrll}\n1.&\\hspace{-1em}23&\\hspace{-1em}\\phantom{\\cdot}&-2\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\cdot10^{-200}\\\\\n-1\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}&0\\phantom{.}&\\hspace{-1em}&\\hspace{-1em}\\phantom{\\cdot}\\\\\n\\end{array}\\right)\n\\end{array}\n\\]', @@ -1022,9 +1022,14 @@ def test_statespace_defaults(self, matarrayout): @pytest.mark.parametrize(" gmats, ref", [(LTX_G1, LTX_G1_REF), (LTX_G2, LTX_G2_REF)]) +@pytest.mark.parametrize("dt, dtref", + [(0, ""), + (None, ""), + (True, r"~,~dt=~\mathrm{{True}}"), + (0.1, r"~,~dt={dt:{fmt}}")]) @pytest.mark.parametrize("repr_type", [None, "partitioned", "separate"]) @pytest.mark.parametrize("num_format", [None, ".3g", ".5g"]) -def test_latex_repr(gmats, ref, repr_type, num_format, editsdefaults): +def test_latex_repr(gmats, ref, dt, dtref, repr_type, num_format, editsdefaults): """Test `._latex_repr_` with different config values This is a 'gold image' test, so if you change behaviour, @@ -1040,9 +1045,11 @@ def test_latex_repr(gmats, ref, repr_type, num_format, editsdefaults): if repr_type is not None: set_defaults('statesp', latex_repr_type=repr_type) - g = StateSpace(*gmats) + g = StateSpace(*(gmats+(dt,))) refkey = "{}_{}".format(refkey_n[num_format], refkey_r[repr_type]) - assert g._repr_latex_() == ref[refkey] + dt_latex = dtref.format(dt=dt, fmt=defaults['statesp.latex_num_format']) + ref_latex = ref[refkey][:-3] + dt_latex + ref[refkey][-3:] + assert g._repr_latex_() == ref_latex @pytest.mark.parametrize(
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: