You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR #276 adds latex output for transfer functions. It would be nice to add this for other LTI types as well (particularly StateSpace objects). Having the output match the text approximation in __repr__ seems like a good first cut at format to use.
Here's a proof of concept for SS, presenting the system in "partitioned matrix" form.
The format is loosely based on Sympy's LaTeX output for matrices with floating point entries, which centre-aligns and uses a \cdot to separate the 10^x part.
Some points:
MathJax doesn't support @ in \array preamble [1], so one can't align columns on the decimal point. One could left-align, and use \llap{-} for the minus signs; then the leading digits are aligned in each column. MathJax limitations only apply for notebook output.
If one uses a "tabular" output like this, perhaps _repr_html_ would be better than _repr_latex_; I haven't investigated that. That might be better if one, e.g., labelled rows with state and output names, and columns with state and input names.
this doesn't match the current repr output (A = [[ ... ]] B = [[ ... ]], etc.)
a complete display doesn't make sense for big (nx, ny, nu > 10?) systems; we could have something like numpy's or panda's display limits. I think something similar applies to TFs, i.e., we should omit intermediate polynomial terms for high-degree denominators and numerators. One trick would be still showing the partitions, so this could get pretty untidy-looking.
One could argue how much space to leave after the decimal separator and if the phantom ".00" for integer mantissae when there is an exponent part should be visible. And whether the \phantom entries or the whole column will need no be removed for systems where the whole column for the fractional part is empty:
Nice to have something in place. I would probably got for something that is as "plain latex" (or MathJax) as possible. It won't look as pretty, but it can be updated later as more functionality is added to the formatting packages.
Another possibility would be to allow the user to pass a formatting string for the table style, item entries, etc with some sort of reasonable default value.
I've taken @bnavigator 's idea a little further by adding a third set of columns for the exponents; this makes easy to scan down the column for orders of magnitude, and it also Does The Right Thing when there are no exponents to display.
One special case is a gain-only system, which shows the partitions even though the A/B/C entries are empty. This makes it clear this is a "D-only" system, but it doesn't look that good. I think I'll change this.
It's probably not too diffiicult to make the formatting somewhat customizable, though we would need to be able to parse the resulting string to insert the column separators and so on. I'm not familiar with the python-control control config system (I think there is one?), will take a look.
It's probably not too diffiicult to make the formatting somewhat customizable, though we would need to be able to parse the resulting string to insert the column separators and so on. I'm not familiar with the python-control control config system (I think there is one?), will take a look.
It's called config.defaults and IMHO should be renamed anyway.
I would like to have the option to display the matrices (possibly still arranged in a table) without the partitioned matrix like this.
[ ... ... ] [ ... ]
A = [ ... ... ] B = [ ... ]
[ ... ... ] [ ... ]
C = [ ... ... ] D = [ ... ]
Branch and gist updated. User can select from 'partitioned' and 'separate' types, and specify format string.
Static-gain ("stateless") systems are special-cased.
How should configuration options be documented?
I think this should have some minimal testing, though I'll probably use a "gold image" approach, i.e., generate reference strings using the implementation.
Yes. #450 did not close this. It added the functionality for StateSpace, but not for other system objects. (TransferFunction._repr_latex_ already exists, FRD and iosys don't have it yet`)
Having Jupyter display the Mathjax is useful for small state spaces, but I've had some problems with larger ones causing Jupyter Notebook to hang. I then have to forcibly stop my browser and then reopening, hoping that I can clear all outputs before it starts rendering.
Using display(ss) to show the Mathjax version might be more appropriate, or maybe have some size limit where it falls back to just showing a string, or a flag to switch this feature off. I had this issue when I just want to check what a variable in a notebook is quickly or run some function that returns a statespace, then I end up printing a 100x100 StateSpace I'm working with and crashing everything.
I like the idea of requiring display() to get mathjax. Then, as suggested, we could use the config module to set defaults for when display is automatically called.
Having Jupyter display the Mathjax is useful for small state spaces, but I've had some problems with larger ones causing Jupyter Notebook to hang. I then have to forcibly stop my browser and then reopening, hoping that I can clear all outputs before it starts rendering.
A short-term workaround is to remove the related method after importing python-control:
import control as ct
del ct.statesp.StateSpace._repr_latex_
Using display(ss) to show the Mathjax version might be more appropriate,
My understanding is that display just a way to force output of a variable, so IPython cells
a = ss(1,2,3,4);
display(a)
and
a = ss(1,2,3,4)
a
are equivalent.
A switch back to "plain old repr" for bigger systems seems like a reasonable idea. We could add a config.defaults['statesp.latex_maxsize'] and if either (nstates + ninputs) or (nstate + noutputs) > latex_maxsize, have _repr_latex_ return None. One could then set latex_maxsize to -1 to disable the LaTeX display altogether. See https://ipython.readthedocs.io/en/stable/config/integrating.html
Activity
repagh commentedon Jun 21, 2019
I got this representation in a Spyder console

I think we need to get the numbers printed in exponent form a bit nicer still.
roryyorke commentedon Aug 2, 2020
Here's a proof of concept for SS, presenting the system in "partitioned matrix" form.
The format is loosely based on Sympy's LaTeX output for matrices with floating point entries, which centre-aligns and uses a
\cdotto separate the10^xpart.Some points:
@in\arraypreamble [1], so one can't align columns on the decimal point. One could left-align, and use\llap{-}for the minus signs; then the leading digits are aligned in each column. MathJax limitations only apply for notebook output._repr_html_would be better than_repr_latex_; I haven't investigated that. That might be better if one, e.g., labelled rows with state and output names, and columns with state and input names.reproutput (A = [[ ... ]] B = [[ ... ]], etc.)[1] mathjax/MathJax-docs#205
bnavigator commentedon Aug 2, 2020
How about
\hspace{-1em}? The MathJaxcolumnspacingis1emby default and I could not find any place, that overrides the default:\begin{array}-> https://github.com/mathjax/MathJax-src/blob/master/ts/input/tex/base/BaseMappings.ts#L659-> https://github.com/mathjax/MathJax-src/blob/master/ts/input/tex/base/BaseMethods.ts#L1433
-> https://github.com/mathjax/MathJax-src/blob/master/ts/input/tex/base/BaseMethods.ts#L1377
Jupyter Notebook:

Jupyter console:

One could argue how much space to leave after the decimal separator and if the phantom ".00" for integer mantissae when there is an exponent part should be visible. And whether the
\phantomentries or the whole column will need no be removed for systems where the whole column for the fractional part is empty:roryyorke commentedon Aug 4, 2020
Ha! Ingenious. This does tie us to MathJax, but we could add features for "real" LaTeX (for exporting notebooks to LaTeX) if anyone ever asks for it.
As for the extra spacing introduced by the extra column: it would be ideal to remove it, but that is a finesse.
Mathematica uses a similar output format for its state-space objects [1].
@murrayrm, do you think this is worth pursuing?
[1] https://reference.wolfram.com/language/ref/StateSpaceModel.html
bnavigator commentedon Aug 4, 2020
"real" LaTeX would have a set length
\arraycolsep. Maybe that could be included into the\hspaceoverriding the1emwith some clever LaTeX hack?murrayrm commentedon Aug 5, 2020
Nice to have something in place. I would probably got for something that is as "plain latex" (or MathJax) as possible. It won't look as pretty, but it can be updated later as more functionality is added to the formatting packages.
Another possibility would be to allow the user to pass a formatting string for the table style, item entries, etc with some sort of reasonable default value.
roryyorke commentedon Aug 8, 2020
WIP rendered https://nbviewer.jupyter.org/gist/roryyorke/6879e0b20735f533410dad883eb687e5 from code at roryyorke/python-control/tree/rory/ss-repr-latex
I've taken @bnavigator 's idea a little further by adding a third set of columns for the exponents; this makes easy to scan down the column for orders of magnitude, and it also Does The Right Thing when there are no exponents to display.
One special case is a gain-only system, which shows the partitions even though the A/B/C entries are empty. This makes it clear this is a "D-only" system, but it doesn't look that good. I think I'll change this.
It's probably not too diffiicult to make the formatting somewhat customizable, though we would need to be able to parse the resulting string to insert the column separators and so on. I'm not familiar with the python-control control config system (I think there is one?), will take a look.
roryyorke commentedon Aug 8, 2020
Oh, one thing I'm not sure about is how to write tests for this. I don't see a lot tests for this sort of thing in, e.g., sympy.
bnavigator commentedon Aug 8, 2020
It's called
config.defaultsand IMHO should be renamed anyway.I would like to have the option to display the matrices (possibly still arranged in a table) without the partitioned matrix like this.
roryyorke commentedon Aug 9, 2020
Branch and gist updated. User can select from 'partitioned' and 'separate' types, and specify format string.
Static-gain ("stateless") systems are special-cased.
How should configuration options be documented?
I think this should have some minimal testing, though I'll probably use a "gold image" approach, i.e., generate reference strings using the implementation.
sawyerbfuller commentedon Feb 12, 2021
@bnavigator was that on purpose that you unlinked this issue to #450 ?
bnavigator commentedon Feb 12, 2021
Yes. #450 did not close this. It added the functionality for
StateSpace, but not for other system objects. (TransferFunction._repr_latex_already exists, FRD and iosys don't have it yet`)danielbrown2 commentedon Apr 1, 2021
Having Jupyter display the Mathjax is useful for small state spaces, but I've had some problems with larger ones causing Jupyter Notebook to hang. I then have to forcibly stop my browser and then reopening, hoping that I can clear all outputs before it starts rendering.
Using
display(ss)to show the Mathjax version might be more appropriate, or maybe have some size limit where it falls back to just showing a string, or a flag to switch this feature off. I had this issue when I just want to check what a variable in a notebook is quickly or run some function that returns a statespace, then I end up printing a 100x100 StateSpace I'm working with and crashing everything.murrayrm commentedon Apr 1, 2021
I like the idea of requiring
display()to get mathjax. Then, as suggested, we could use theconfigmodule to set defaults for when display is automatically called.roryyorke commentedon Apr 11, 2021
A short-term workaround is to remove the related method after importing python-control:
My understanding is that
displayjust a way to force output of a variable, so IPython cellsand
are equivalent.
A switch back to "plain old repr" for bigger systems seems like a reasonable idea. We could add a
config.defaults['statesp.latex_maxsize']and if either (nstates + ninputs) or (nstate + noutputs) > latex_maxsize, have_repr_latex_return None. One could then setlatex_maxsizeto -1 to disable the LaTeX display altogether. See https://ipython.readthedocs.io/en/stable/config/integrating.html