harold.kalman_decomposition(G, compute_T=False, output='system', cleanup_threshold=1e-09)

By performing a sequence of similarity transformations the State representation is transformed into a special structure such that if the system has uncontrollable/unobservable modes, the corresponding rows/columns of the B/C matrices have zero blocks and the modes are isolated in the A matrix. That is to say, there is no contribution of the controllable/observable states on the dynamics of these modes.

Note that, Kalman operations are numerically not robust. Hence the resulting decomposition might miss some ‘almost’ pole-zero cancellations. Hence, this should be used as a rough assesment tool but not as actual minimality check or maybe to demonstrate the concepts academic purposes to show the modal decomposition. Use cancellation_distance() and minimal_realization() functions instead with better numerical properties.

  • G (State) – The state representation that is to be converted into the block triangular form such that unobservable/uncontrollable modes corresponds to zero blocks in B/C matrices
  • compute_T (boolean) – Selects whether the similarity transformation matrix will be returned.
  • output ({'system','matrices'}) – Selects whether a State object or individual state matrices will be returned.
  • cleanup_threshold (float) – After the similarity transformation, the matrix entries smaller than this threshold in absolute value would be zeroed. Setting this value to zero turns this behavior off.

  • Gk (State, tuple) – Returns a state representation or its matrices as a tuple if output = 'matrices'
  • T (ndarray) – If compute_T is True, returns the similarity transform matrix that brings the state representation in the resulting decomposed form.


>>> G = State([[2, 1, 1],
...            [5, 3, 6],
...            [-5, -1, -4]],
...            [[1], [0], [0]],  # B array
...            [1, 0, 0])
>>> is_kalman_controllable(G)
>>> is_kalman_observable(G)
>>> F = kalman_decomposition(G)
>>> print(F.a, F.b, F.c, sep='\n')
[[ 2.          0.         -1.41421356]
 [ 7.07106781 -3.         -7.        ]
 [ 0.          0.          2.        ]]
 [ 0.]
 [ 0.]]
[[-1.  0.  0.]]
>>> H = minimal_realization(F)
>>> H.matrices
(array([[2.]]), array([[1.]]), array([[1.]]), array([[0.]]))