H2-Norm und Kovarianz lineare Systeme

Kybernetik
Systemtheorie
Kontrolltheorie
Autor:in

Johannes Kaisinger

Veröffentlichungsdatum

15. Dezember 2021

In Octave oder Matlab steht uns mit covar eine Methode zur Verfügung, mit welcher wir die stationäre Kovarianz des Zustandsvektors x und die stationäre Kovarianz des Ausgangsvektors y berechnen können. In Python existiert derzeit eine solche Methode weder in scipy noch in control.

Dabei ist covar wieder mit der H2-Norm verbunden.

Kovarianz eines zeitdiskretes Systems

Gegeben sei ein lineares System, das von Eingängen mit weißem Gauß’schen Rauschen gesteuert wird. Dieses Rauschen ist also kein Kontrolleingang sondern eine Störung. In Form eines Zustandsraums wird dieses System wie folgt dargestellt:

xk+1=Axk+Bwkyk=Cxk+Dwk

wobei ARn×n, BRn×p, CRq×n und DRq×p. n, m und p beschreiben die Anzahl der Zustände, Eingänge bzw. Ausgänge des linearen Systems.

Bei den Eingangsstörungen w handelt es sich um weißes Gauß’sches Rauschen mit der Spektraldichte ΣwRm×m mit Nullmittelwert. Anders ausgedückt: Der Erwartungswert von w ist E(wk)=0 und seine Kovarianzmatrix ist E(wkwlT)=Σwδkl, wobei das Kronecker-Symbol duch

δkl={1für k=l0für kl

gegeben ist.

Analyse stochastischer linearer Systeme

Wir wollen hier nun stochastische zeitdiskrete zeitinvariante lineare Systeme analysieren. Dafür verwenden wir ein etwas andere Notation. Um den zeitlichen Zusammenhang stärker herauszustellen schreiben wir statt xk, x[k].

Gegeben sei das System

x[k+1]=Ax[k]+Bw[k].

Der Anfangszustand x[0] ist ein Zufallsvektor, dessen Erwartungswert und Kovarianzmatrix wir kennen,

E{x[0]}=μx[0]=0E{[x[0]μx[0]][x[0]μx[0]]T}=Σx[0].

Der Eingangsvektor {wk} ist ein (vom Anfangszustand x[0] unabhäniges) weißes Rauschen, dessen momentanen Erwartungswert und Autokovarianzmatrix wir kennen,

E{w[k]}=μw[k]=0 für k0E{[w[k]μw[k]][w[l]μw[l]]T}=Σwδkl für k,l0 mit Σw=ΣwT0E{[w[k]μw[k]][x[0]μx[0]]T}=0. für k0 (Unkorreliertheit).

Der momentane Erwartungswert des Zustandsvektors kann offenbar aus der folgenden zeitdiskreten Bewegungsgleichung berechnet werden:

μx[k+1]=E(Axk+Buk)=Aμx[k]+Bμw[k]=0μx[0]=E{x[0]}=0

Da der Vektor-Zufallsprozeß {wk} ein weißes Rauschen und vom Anfangsvekor x[0] unabhängig ist, kann die momentane Kovarianzmatrix Σk des Zustandsvektors xk ebenfalls rekursiv berechnet werden:

Σx[k+1]=E{[x[k+1]μx[k+1]][x[k+1]μx[k+1]]T}=E{[A(x[k]μx[k])+B(w[k]μw[k])][A(x[k]μx[k])+B(w[k]μw[k])]T}=AΣx[k]AT+BΣwBTΣx[0]=Σx[0]

Für eine stabile Matrizen A konvergiert diese Gleichung gegen die Lyapunov Gleichung

Σx=AΣxAT+BΣwBT=0.

Die Kovarianzmatrix des Ausgangs y

Σy[k]=E{y[k]y[k]T}=E{[Cx[k]+Dw[k]][Cx[k]+Dw[k]]T}=CΣx[k]CT+DΣwDT

konvergiert für stabile System zu

Σy=CΣxCT+DΣwDT=0.

Für instabile System (Spektralradius ρ(A)>1) sind die Kovarinazmatrizen unendlich.

Die Verbindung zur H2-Norm ist nun mit

G22=limkE(ykykT)=tr(covar(G))=tr(Σy)

gegeben. Die H2-Norm ist ein Mass für die Energie am Ausgangs eines Systems, welches von einem weißen Gauß’schen Rauschen am Eingang angetrieben wird.

Tipp

Wir verwenden im Code statt Σ die Buchstaben P und W. Ähnliche Notationen werden von vielen Programmpaketen verwendet:

Σx=PxΣy=PyΣw=W

Zusammengefasst lässt sich ein Zustandsraumverfahren wie folgt berechnen:

  1. Berechne eine Zustandsrealisierung aus der Übertragungsfunktion

G(z):=[ABCD]

  1. Löse die Lyapunov Gleichung, (dabei muss gelten Px0)

Px=APxATPx+BWBT=0Py=CPxCT+DWDT

Code

import numpy as np
import scipy.linalg as linalg
import scipy.signal as signal


import warnings
warnings.filterwarnings("error")
def covar_d(A,B,C,D,W):
    """ naive implementation of covar for linear time-discrete systems (d-LTI)
        (there might be better ways to do that)
    """
    
    if np.all(np.abs(linalg.eigvals(A)) <= 1):
        Px = linalg.solve_discrete_lyapunov(A.T, B@W@B.T)
        Py = C@Px@C.T + D@W@D.T   
    else:
        Px = np.inf
        Py = np.inf
    return [Px, Py]
def covar_d_data(tout,yout,xout):
    """ data based approximation of covar for linear time-discrete systems (d-LTI)
        (there might be better ways to do that)
    """
    
    # catch overflow
    try:
        Px = xout.T@xout/len(tout)
        Py = yout.T@yout/len(tout)
    except RuntimeWarning:
        Px = np.inf
        Py = np.inf
    return [Px, Py]

Stabiles System

Ad_stable = np.array([[0.5, 0.1],[0.1, 0.5]])
print(np.abs(linalg.eigvals(Ad_stable)) <= 1.)

Bd = np.array([[0.],[1.]])
Cd = np.eye(2)*0.5
Dd = np.zeros((2,1))
Wd = np.eye(1)*5

Px, Py = covar_d(Ad_stable,Bd,Cd,Dd,Wd)
print(Px)
print(Py)
[ True  True]
[[0.15174655 0.46502976]
 [0.46502976 6.73069392]]
[[0.03793664 0.11625744]
 [0.11625744 1.68267348]]

Wir wollen die modellbasierte Variante mit einer datenbasierten Variante vergleichen. Dazu erzeugen wir Eingangsdaten und Ausgangsdaten.

G_sys = signal.StateSpace(Ad_stable, Bd, Cd, Dd,  dt=1.)
w_in = np.sqrt(Wd)*np.random.randn(100000)
tout, yout, xout = signal.dlsim(G_sys, w_in.T)
Px_data, Py_data = covar_d_data(tout, yout, xout)
print(Px_data)
print(Py_data)
[[0.15053712 0.45885585]
 [0.45885585 6.70173513]]
[[0.03763428 0.11471396]
 [0.11471396 1.67543378]]
print(linalg.norm(Px - Px_data)/linalg.norm(Px))
print(linalg.norm(Py - Py_data)/linalg.norm(Py))
0.004474953153232987
0.004474953153232987

Beide Varianten stimmen sehr gut überein. Die Differenz erklärt sich einerseits durch die endlichen Daten und die numerische Ungenaugikeit. np.float128 könnte bessere Ergebnisse liefern.

Instabiles System

Ad_unstable = np.array([[1.5, 0.1], [0.1, 1.5]])
print(np.abs(linalg.eigvals(Ad_unstable)) < 1.)

Px, Py = covar_d(Ad_unstable,Bd,Cd,Dd,Wd)
print(Px)
print(Py)
[False False]
inf
inf
G_sys = signal.StateSpace(Ad_unstable, Bd, Cd, Dd, dt=1.)
w_in = np.sqrt(Wd)*np.random.randn(100000)
tout, yout, xout = signal.dlsim(G_sys, w_in.T)
Px_data, Py_data = covar_d_data(tout,yout,xout)
print(Px_data)
print(Py_data)
inf
inf

Die Kovarianmatrizen werden zu groß und erzeugen deshalb eine Laufzeitwarnung, welche abgefangen wird.

Fazit

Die Kovarianzmatrizen kommen in vielen wissenschaftlichen Aufsätzen zum Einsatz, vor allem in Aufsätzen in denen Schätzer analysiert werden (Kalmanfilter, Systemidentifikation, Adaptive Regelung, Bestärkendes Lernen, …).

Die Kovarianzmatrizen stehen mit der H2 in Verbindung, was für die Implementierungsebene von Bedeutung ist.

Referenzen

  • Optimal Sampled-Data Control Systems (Tongwen Chen und Bruce Francis, 1994)
  • Essentials of Robust Control (Kemin, Zhoun, John C. Doyle, 1997)
  • Regelungstechnik, Mathematische Grundlagen, Entwurfsmethoden, Beispiele (Geering, 2004)