GeezerVison is showing github.com — StateSpace constructor should not call _remove_useless_states · Issue #244 · python-control/python-control
StateSpace constructor should not call _remove_useless_states #244DescriptionState 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 !== A and 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.
import control
print(control.__version__)
print(control.ss(0,0,1,0)) # expected: A,B,C,D unchanged from input
print(control.ss(0,0,1,0).sample(1)) # expected: ss(1,0,1,0, dt=1)
output:
0.8.0
A = []
B = []
C = []
D = [[0]]
A = []
B = []
C = []
D = [[0]]
dt = 1
Is there a reason for the current behavior, or would it be okay to change it? Activitymurrayrm commented on Nov 14, 2018 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? MaxGaukler commented on Nov 20, 2018 DapRock commented on Aug 14, 2019 murrayrm commented on Aug 15, 2019 The current master branch allows you to specify the keyword remove_useless=False when 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. sawyerbfuller commented on Jul 23, 2020 Anybody know why _remove_useless_states was 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? murrayrm commented on Jan 15, 2021 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. murrayrm commented on Jan 15, 2021 Found something unexpected in the way that the feedback function was implemented: if you pass a constant as one of the arguments for feedback (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 switched remove_useless_states to False since systems had an "extra" state.
By changing the statesp._convert_to_state_space function 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 pass remove_useless_states=True to make that happen.
With that fix, everything appears to work. PR coming as soon as I confirm via CI. murrayrm commented on Jan 18, 2021
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|