Repository navigation
StateSpace constructor should not call _remove_useless_states #244
Description
Activity
I agree with this comment.
One thing to think through is whether anything "breaks" if we stop calling
_remove_useless_states(). Eg, are there operations that create spurious states that were getting reduced out?Perhaps create a branch, try removing that call to
_remove_useless_states()and see if unit tests pass?Lots of tests break if the call is removed, mainly blockdiagram algebra (LTI system interconnection) and some others which may be caused by that (rlocus, LQR). It seems that some more effort is required.
https://github.com/MaxGaukler/python-control/tree/remove-useless-states
https://travis-ci.org/MaxGaukler/python-control/jobs/457349504#L4054I'm having the same problem with the system order reduction. I've tried to use the library to work with a Luenberger observer which assumes a state as invariant in time and I'm getting this same state being reduced in the problem. I have better description here: https://stackoverflow.com/questions/57484563/why-some-a-state-is-removed-from-the-model-while-using-control-ss-in-python
Do you have any tip to workaround in this case? Thanks for your time!
The current master branch allows you to specify the keyword
remove_useless=Falsewhen creating a state space system, which will keep all states. This is not yet in the release code, but should be part of release 0.8.3.Anybody know why _
remove_useless_stateswas added in the first place? I ran unit tests and a lot of failures are simply because the test assumes. rows of zeros ought to be removed.Is it something to do with extra states being added in the the course of interconnecting systems, e.g. feedback?
This may be something useful to fix in 0.9.0, since we will be breaking some user code in any case.
I'll take a crack at removing it and seeing how much change is required to unit tests and whether there is anything that seems like it is going to cause problems.
Found something unexpected in the way that the
feedbackfunction was implemented: if you pass a constant as one of the arguments forfeedback(eg,feedback(P*C, 1)) then the constant was being converted to a state space system with a single state and B=0, C=0. This gives the right input/output response, but created an unobservable/uncontrollable (= "useless") state. This generated a half dozen or so errors when I switchedremove_useless_statestoFalsesince systems had an "extra" state.By changing the
statesp._convert_to_state_spacefunction to create a state space with no state (A = []) the problem went away and all but one unit test passed. That unit test was explicitly testing that useless states were removed, so had to passremove_useless_states=Trueto make that happen.With that fix, everything appears to work. PR coming as soon as I confirm via CI.
Reacted by Ben GreinerFixed in #509.
State space representations should, in my opinion, not be reduced automatically with StateSpace._remove_useless_states(), similar to the fact that we don't call minreal() automatically.
Unlike transfer functions, state space models can model non-observable or non-controllable behaviour, and cannot always be considered equivalent to their minimized form. Additionally, it is rather confusing to have
ss(A,B,C,D).A !== Aand e.g.ss(A,B,C,D).sample(T).A !== expm(A*T). For a more object-oriented interface, it would also be great to have member functions like stateSpace.isControllable(), which do not make sense if the system has already been minimized.To give an example: The autonomous system x'=0, y=x is a signal model for the constant output y=x(0). It is not equivalent to the system y=0 if you consider the initial response for x(0) !== 0.
output:
Is there a reason for the current behavior, or would it be okay to change it?