Repository navigation
lqe default input noise matrix is undocumented and differs from Octave #1159
Description
Activity
Hi @ovhnw I think the library is doing the right thing here.
In the first call to
lqe, yourG = diag([1,1,1])matrix has three columns, corresponding to three disturbance inputs, so it works because you have specified a 3x3 disturbance covariance matrixQN.In your second call,
Gis assumed to be theBin your state-space system, which has one column (as doesD), sosyshas one disturbance input. So it raises a an error because you ahve specified the same 3x3 disturbance covariance matrix, which assumes three inputs.Feel free to reopen if you think I'm missing something.
In your second call, G is assumed to be the B in your state-space system, which has one column (as does D), so sys has one disturbance input.
Are you sure this is what is conventionally assumed?
For example, octave has a similar method signature, and it works just fine with both methods and returns the same result in each case:
pkg load control A = [ 0 1 0; 0 0 1; 0 0 0]; B = [0;0;1]; C = [1 0 0]; D = [0]; sys=ss(A,B,C,D); rank(ctrb(A,B)); rank(obsv(A,C)); [L,_,_]=lqe(A,diag([1 1 1]),C,diag([1 1 1]),[1]); L [L,_,_]=lqe(sys,diag([1 1 1]),[1]); L
returns
L = 2.4142 2.4142 1.0000 L = 2.4142 2.4142 1.0000I remember when we chose to use B as G when passed a system, and that I wasn’t convinced one way or the other at the time whether that was the right choice.
It may be (I will have to double check) that Octave is assuming G=diag(ones(m)), which may turn out to be a better assumption.
What do you think?
Here's my two cents: when we are talking about the "noise" entering the state, we are usually talking about external disturbances (eg, wind forces on an aircraft). To me, these disturbances need to enter the system in a structure way and they rarely affect all of the states. For the aircraft, for example, wind acts as a force => it directly affects the derivative of the velocity but not derivative of the position (except through the velocity) => you need a
$G$ matrix to capture that. For an example of this type of thinking, see OBC, Section 6.5.If no
$G$ matrix is specified, then a reasonable assumption is that the disturbances enter in the same places as the inputs, and so disturbances are the same as "input noise".Note that for the outputs, we don't have an equivalent matrix. This makes sense to me since usually measurement noise affects all measurements (with different amounts of noise being reflected in the covariance matrix
RN.The one thing we do need to take care of is documenting the fact that if
$G$ is not specified, then its default value is$B$ .If you don't mind my thoughts:
- My college course notes "book" does not use a G matrix. (implied identity?)
- There is a duality between LQR and LQE. They have the same Algebraic Riccati Equation structure. So you can do
lqr(A,C',Q,R)'(or something, i don't remember for sure offhand) as an equivalent for lqe. If there is no dual to the G matrix in lqr (is there? i'm not sure), then perhaps the identity may be the only default that preserves this duality. - I took a quick look at matlab's
kalmanand G seems to be included as part of B.
My vote would go to an identity for default.
The one thing we do need to take care of is documenting the fact that if G is not specified, then its default value is B .
:D yes. and thank you.
Thoughts definitely welcome @ovhnw!
I don't have a strong preference, as long as we leave in the option for
$G$ to be specified somehow. We should also be aware that if we change the default, we could break existing code => we should probably either issues a warning or provide some other indication that behavior has changed (and we might wait until v0.11.x before changing the default).Reopening this issue, but changing the title.
- changed the title
[-]lqe does not work with 3 arguments[/-][+]lqe default input noise matrix differs from Octave[/+]on Jul 4, 2025 - changed the title
[-]lqe default input noise matrix differs from Octave[/-][+]lqe default input noise matrix is undocumented and differs from Octave[/+]on Jul 4, 2025 i should point out, although the current behavior deceptively differs from octave's
lqe, it may be compatible with matlab'skalman. You might even be able to adapt your code to accept the[B G]style B matrices without breaking existing code.sidenote: it is unfortunate that matlab decided to format the B matrices as
[B G], instead of[G B], which is the convention for robust control.
outputs
if the G matrix is manually specified
lqeworks, otherwise it seems to find a dimension mismatch