Skip to content
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

Use nstates instead of nx in lsimplot #508

Merged
merged 3 commits into from
May 16, 2021
Merged

Use nstates instead of nx in lsimplot #508

merged 3 commits into from
May 16, 2021

Conversation

albheim
Copy link
Member

@albheim albheim commented May 14, 2021

delay_example did not run for me, seemed to be this

@JuliaControlBot
Copy link

Something failed when generating plots. See the log at https://github.com/JuliaControl/ControlExamplePlots.jl/runs/843412760?check_suite_focus=true for more details.

@olof3
Copy link
Contributor

olof3 commented May 14, 2021

I think we are moving in the other direction actually, and that we instead should define the getproperty for .nx. And preferably deprecate nstates, noutputs, ninputs. But I'm not sure that this is the plan or if there is a plan. @mfalt @baggepinnen

I think that I prefer sys.nx since it is shorter.

@codecov
Copy link

codecov bot commented May 14, 2021

Codecov Report

❗ No coverage uploaded for pull request base (dev@0d9ec6f). Click here to learn what that means.
The diff coverage is n/a.

❗ Current head 7830922 differs from pull request most recent head 1c3cbb7. Consider uploading reports for the commit 1c3cbb7 to get more accurate results
Impacted file tree graph

@@          Coverage Diff           @@
##             dev     #508   +/-   ##
======================================
  Coverage       ?   84.56%           
======================================
  Files          ?       31           
  Lines          ?     3182           
  Branches       ?        0           
======================================
  Hits           ?     2691           
  Misses         ?      491           
  Partials       ?        0           

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0d9ec6f...1c3cbb7. Read the comment docs.

@baggepinnen
Copy link
Member

I generally prefer nx, but a function is much easier to broadcast and I don't think we should not depreciate those since it's a hassle to broadcast getproperty. Defining properties for transfer functions would be good though.

@albheim
Copy link
Member Author

albheim commented May 15, 2021

Ah, okay. I thought it was going towards nstates.

After a quick look it seems that tf, sisorational and sisozpk does not have either, delaylti has nstates and ss has nx.

Could we just have all of them implement getproperty on nu, ny, nx and then have one spot where we define ninputs(sys::LtiSystem) = sys.nu and same for the other?

@mfalt
Copy link
Member

mfalt commented May 15, 2021

I do prefer nstates(sys) for it's clarity in the package. But I think defining getproperty so the user can use .nx is fine.

@olof3
Copy link
Contributor

olof3 commented May 15, 2021

a function is much easier to broadcast

Okay, then we should definitely keep them around.

After a quick look it seems that tf, sisorational and sisozpk does not have either,

States are for statespace realizations. But I guess order or something like that could be useful for transfer functions, although it feels like we are coping quite well by just looking at the length of the denominator polynomial directly. Not sure what we do for zpk

delaylti has nstates and ss has nx.

Then we should define nstates for ss if that is convenient for broadcasting.

When you bring it up, delay systems have infinitely many states, so I don't think we should define nstates or nx for those (although it was me who implemented nstates for it). Rather one should have to call that function on the statespace realization used for representing the delay system, and nstates on the DelayLTISystem should throw an error.

I do prefer nstates(sys) for it's clarity in the package.

I partly see your point, and although I in general prefer long names, I don't see any problems here. I also think it is important with clarity in the package, and for this reason I think it is important to keep things short when there is no risk of confusion and then use longer names for less obvious things.

This piece of code is a good example:

feedback(G, Δ, U1=G.nu-Δ.ny+1:G.nu, Y1=G.ny-Δ.nu+1:G.ny, W1=1:G.ny-Δ.nu, Z1=1:G.nu-Δ.ny, pos_feedback=true)

of course, one could have defined variables G_ny Δ_nu, but that seems quite cumbersome and could potentially introduce errors, rather than just using G.ny, Δ.nu directly.

Here is an other less extreme example, but already here i find it a lot harder to quickly see what goes on in the first version of the code.

    A = [s1.A                             zeros(T, nstates(s1), nstates(s2));
            zeros(T, nstates(s2), nstates(s1))           s2.A]
    A = [s1.A                         zeros(T, s1.nx, s2.nx);
           zeros(T, s2.nx, s1.nx)            s2.A]

The number of states also very much feels like an inherent property of a statespace realization, so to me it feels much more natural to access it as a property rather than having to call a function on the object.

@baggepinnen
Copy link
Member

When you bring it up, delay systems have infinitely many states, so I don't think we should define nstates or nx for those (although it was me who implemented nstates for it). Rather one should have to call that function on the statespace realization used for representing the delay system, and nstates on the DelayLTISystem should throw an error.

I don't quite understand the suggestion, which statespace realization? Wouldn't it just be an annoyance and break a lot of generic code to not define nx for delay systems?

The number of states also very much feels like an inherent property of a statespace realization, so to me it feel much more natural to access it as a property rather than having to call a function on the object.

So does length, size, ndims of an array? Those are still functions in julia because functions are much more powerful than properties. The only upside with properties is visual.

@olof3
Copy link
Contributor

olof3 commented May 15, 2021

I don't quite understand the suggestion, which statespace realization?

The class of delay systems the DelayLTISytem models is those that can be expressed as a linear fractional transformation between a statespace system P and a number of "delay buffers". The delay system has infinitely many states, while P has a finite number of stats. (Currently P is implemented with a special type PartitionedStateSpace, but as we have discussed previously , we might move away from that. But that is an unrelated issue.)

Wouldn't it just be an annoyance and break a lot of generic code to not define nx for delay systems?

If it does, then I guess that something is wrong. Now I'm curious if something breaks, so I think I'll try it out and possibly make a PR.

The number of states also very much feels like an inherent property of a statespace realization, so to me it feels much more natural to access it as a property rather than having to call a function on the object.
So does length, size, ndims of an array? Those are still functions in julia because functions are much more powerful than properties. The only upside with properties is visual.

Ah, yes, that's a fair point. We should definitely keep the function versions around.

There are a few places in the code where nstates(sys) looks slightly better, but in many cases it would look significantly worse. If we want to go for consistency then I think we should go with .nx, but otherwise we can just take what feels more natural or whatever we feel like.

In the currently discussed case I'd say .nx only looks insignificantly better, so in this case I don't mind nstates.

@baggepinnen
Copy link
Member

The class of delay systems the DelayLTISytem models is those that can be expressed as a linear fractional transformation between a statespace system P and a number of "delay buffers". The delay system has infinitely many states, while P has a finite number of stats.

Ah, this makes sense. I was somehow only thinking about the PartitionedStateSpace type.

About the system dimensions, I find it the cleanest to introduce local variables with the sizes, e.g,

nx,nu,ny = sys.nx, sys.nu, sys.ny

and then use those in the function body. When doing that,

nx,ny,nu = nstates(sys), noutputs(sys), ninputs(sys)

would actually be more descriptive, but I often write the former since it's shorter.

@olof3
Copy link
Contributor

olof3 commented May 16, 2021

ny, nu = size(sys)
nx = nstates(sys)

slightly shorter, although two lines.

So if one is repeatedly using the dimensions I think this is quite nice, and here I'm in slightly in favor of nstates.

However, if one introduces nu, nx etc, in a lot of places in the code, then it does not seem very unclear to just use sys.nx if one only needs it in a few places.

However, it will be quite annoying if there is more than one system.

@albheim albheim merged commit 6853c47 into dev May 16, 2021
@baggepinnen baggepinnen deleted the lsimplot_nstates branch May 16, 2021 09:40
baggepinnen added a commit that referenced this pull request Nov 7, 2021
* Avoid unnecessarily large realization for feedback of TransferFunction (#485)

* Avoid unnecessarily large realization for feedback of TransferFunction

* Fix and added more tests.

* Change to numpoly, denpoly

* add dev brach to PR CI

* Switch u layout (#480)

* switch u layout for lsim

* Update src/timeresp.jl

Co-authored-by: Fredrik Bagge Carlson <baggepinnen@gmail.com>

* More updates, one error in test_timeresp

* Fix tests

* Change to AbstractVecOrMat

* Catch CuArray in matrix conversion

* General zero vectors for x0 to support GPUs

* Update src/timeresp.jl

Co-authored-by: Mattias Fält <mfalt@users.noreply.github.com>

* Update src/timeresp.jl

Co-authored-by: Mattias Fält <mfalt@users.noreply.github.com>

* Move f outside lsim

* Remove GPU compatible x0, save for later

* Fix doctest

* add kwargs

* Remove variable and generalize type

Co-authored-by: Fredrik Bagge Carlson <baggepinnen@gmail.com>
Co-authored-by: Mattias Fält <mfalt@users.noreply.github.com>

* Gangof4 fixes (#486)

* QOL improvements for plotting

* remove spurious getindex

* update docstring

* multiple Ms in nyquist

* bugfixes

* make rings appear in all subplots

* Minor fixes to gang-of-four functionality.

* Fixes to Nyquist plots.

* Updated the nyquistplot docstring

Co-authored-by: Fredrik Bagge Carlson <baggepinnen@gmail.com>

* add frequency in Hz to dampreport (#488)

* updates to nyquistplot (#493)

* updates to nyquistplot

* Update src/plotting.jl

Co-authored-by: olof3 <olof3@users.noreply.github.com>

* Update src/plotting.jl

Co-authored-by: olof3 <olof3@users.noreply.github.com>

Co-authored-by: olof3 <olof3@users.noreply.github.com>

* fix traces in rlocus (#491)

* fix traces in rlocus

* Update src/pid_design.jl

Co-authored-by: Albin Heimerson <albin.heimerson@control.lth.se>

Co-authored-by: Albin Heimerson <albin.heimerson@control.lth.se>

* let lsim handle arguments in lsimplot (#492)

* bugfix: avoid creating continuous system with Ts=0.0 (#496)

* Deactivate _preprocess_for_freqresp (#497)

until hessenberg is properly used

* allow balance when converting tf to ss (#495)

* allow balance when converting tf to ss

* use zeros(T) instead of fill(zero(T))

* Update src/types/StateSpace.jl

Co-authored-by: olof3 <olof3@users.noreply.github.com>

* Update src/types/conversion.jl

Co-authored-by: Albin Heimerson <albin.heimerson@control.lth.se>

Co-authored-by: olof3 <olof3@users.noreply.github.com>
Co-authored-by: Albin Heimerson <albin.heimerson@control.lth.se>

* Better handling of problematic cases for delay systems (#482)

* delay error should be correct now

* warn limit

* Add tustin c2d/d2c method (#487)

* add Tustin discretization

* no indexing after c2d

* implement f_prewarp in tustin and test vs. matlab

* fixe use wrong Ts

* f_prewarp -> w_prewarp

* w_prewarp in tests

* correct handling of x0 in lsimplot (#498)

* move eye def to framework.jl (#499)

* Fix UndefVarError: T not defined (#501)

* add axes for ss (#504)

* pi place and tests (#502)

* pi place and tests

* Fix test

* Add ending space in file

* Update numvec denvec

* Fixed error

* Update test/test_pid_design.jl

Co-authored-by: olof3 <olof3@users.noreply.github.com>

* Update test/test_pid_design.jl

Co-authored-by: olof3 <olof3@users.noreply.github.com>

* Update forms

* Fix test

* Fix test

* Update src/pid_design.jl

Co-authored-by: olof3 <olof3@users.noreply.github.com>

* Update src/pid_design.jl

Co-authored-by: olof3 <olof3@users.noreply.github.com>

* Update src/pid_design.jl

Co-authored-by: olof3 <olof3@users.noreply.github.com>

Co-authored-by: olof3 <olof3@users.noreply.github.com>

* Conver to tf in placepi (#507)

* Use nstates instead of nx in lsimplot (#508)

* Use nstates instead of nx in lsimplot

* Add predictor (#511)

* up innovation_form and add noise_model

* keep innovation_form, add predictor

* export predictor

* add hats

* updates to `obsv` (#517)

* updates to `obsv`

All computing an arbitrary number of rows in the observability matrix and accept `AbstractStateSpace`

* Update src/matrix_comps.jl

Co-authored-by: olof3 <olof3@users.noreply.github.com>

Co-authored-by: olof3 <olof3@users.noreply.github.com>

* `hz` keyword in `nyquistplot` similar to in `bodeplot` (#518)

* Fixes to place (#500)

* Add tests for place.

* Removed luenberger and exented place instead.

Co-authored-by: Fredrik Bagge Carlson <baggepinnen@gmail.com>

* allow AbstractStateSpace in several places (#520)

* allow AbstractStateSpace in several places

* Maintain type for zpk in c2d (#522)

* maintain zpk type in c2d

* Fix type in typeconversion for c2d tf

* Fix type in c2d tf/zpk

* Remove assertion on tf/zpk SISO for c2d

* Test for c2d(zpk(..)..) unbroken

* Keep MIMO assertion c2d tf

* Add comment and fix test

* Fix test

* h to Ts

* Fix test

* remove assert

* split into methods

* Remove asserts (#523)

* Replace asserts

* add error types

* fix conversion for custom types (#514)

* fix conversion for custom types

* special numeric_type for AbstractSS

* fix conversion from ss to tf without type

* more abstract statespaces (#521)

* omre abstract statespaces

* even more ASS

* remove simple feedback in favor of mor egeneral version

* propagate timeevol

* add block diagram to feedback docstring

* Updates to docstring

* fix docstring formatting

* delete redundancy in feedback docstring

Co-authored-by: olof3 <olof3@users.noreply.github.com>

* add controller function (#512)

* add controller function

* rename controller and predictor

* Move plot globals to runtests (#531)

* Move plot globals to runtests

* Move plot globals to framework.jl

* return similarity transform from `balreal` (#530)

* display error when covar fails

* return similarity transform from balreal

* Update src/matrix_comps.jl

Co-authored-by: olof3 <olof3@users.noreply.github.com>

Co-authored-by: olof3 <olof3@users.noreply.github.com>

* remove incorrect warning in pzmap (#535)

* support hz keyword in sigmaplot similar to bodeplot (#537)

* change formatting in dampreport (#536)

* change formatting in dampreport

* update dampreport to use ±

* even better formatting

* up formatting for complex systems

* add additive identity element for statespace and TF (#538)

* add additive identity element for statespace and TF

* rm zero from type. Test MIMO zero

* Fix struct_ctrb_obsv (#540)

* Fix struct_ctrb_obsv, closes #409

* Update src/simplification.jl

Co-authored-by: Fredrik Bagge Carlson <baggepinnen@gmail.com>

* add to docstring

Co-authored-by: olof3 <olof3@users.noreply.github.com>

* Yet another fix for  struct_ctrb_states. Closes #475 (#541)

* bugfix for negative real pole in damp (#539)

* Fix #546

* minor typographic changes

* optional epsilon in dcgain (#548)

* optional epsilon in dcgain

* Update analysis.jl

* bugfix: use correct type for saving dde solutions (#549)

Would be good to have a regression test for `BigFloat` data which was the reason I found this bug. That seems slightly involved to fix though.

I assume that this would also have failed for `ComplexF64`, so eventually a test for that too would be good.

* bugfix dcgain (#551)

* correct type of initial state in step (#553)

* remove version checks

* Fix spacing in type printing

* write `struct_ctrb_states` in terms of `iszero` instead of `== 0` (#557)

* write `struct_ctrb_states` in terms of `iszero` instead of `== 0`

The reason is that `iszero` always returns a bool, whereas `== 0` may return anything. The difference appears for symbolic variables where
```julia
julia> q0 == 0
q0(t) == 0

julia> iszero(q0)
false
```

* Update simplification.jl

* remove `issmooth` (#561)

* remove issmooth

* drop extra `]`

* Return a result structure from lsim (#529)

* Return a result structure from lsim

This is by design a non-breaking change to the lsim interface since the structure allows both getindex and destructuring to behave just like if lsim returned a tuple of arrays like before.  Indeed, the tests for lsim were not touched in this commit.

This commit also adds a plot recipe to the result structure. All plot recipes for lsimplot, stepplot, impulseplot have been replaced by the new recipe. This is a breaking change since the names of the previous plots no longer exist. A slight change is that the plots for a step response no longer show the text "step response", but I think that's an acceptable change, the user can supply any title they prefer themselves.

* remove automatic title

* introduce additional abstract result type

* do not destructure sys

* remove LQG (#564)

The functionality was very buggy and poorly tested. A much improved version with proper tests are available in https://github.com/JuliaControl/RobustAndOptimalControl.jl/blob/master/src/lqg.jl

* pole->poles tzero->tzeros (#562)

* update usage of plot for step simulation

* add doctest filters

* add release notes

* Update README.md

* Update README.md

Co-authored-by: olof3 <olof3@users.noreply.github.com>
Co-authored-by: Albin Heimerson <albin.heimerson@control.lth.se>
Co-authored-by: Mattias Fält <mfalt@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants