python/covar_m.py
author Puneeth Chaganti <punchagan@fossee.in>
Fri, 27 May 2011 14:24:59 +0530
changeset 0 0efde00f9229
permissions -rw-r--r--
Initial commit.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
     1
#!/usr/bin/python
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
     2
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
     3
import pylab as pl
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
     4
from scipy.linalg import schur
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
     5
from dscr import dscr
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
     6
from scipy import signal
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
     7
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
     8
def dlyap(a, b):
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
     9
    n = len(a)
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    10
    x = pl.zeros_like(a)
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    11
    s, u = schur(a)
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    12
    b = pl.dot(u.T, pl.dot(b,u))
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    13
    j = n-1
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    14
    while j>=0:
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    15
        k = j
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    16
        ## Check for Schur block.
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    17
        if j==0:
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    18
            blksiz = 1
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    19
        elif s[j, j-1]!=0:
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    20
            blksiz = 2
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    21
            j = j - 1
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    22
        else:
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    23
            blksiz = 1
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    24
        Ajj = pl.kron(s[j:k+1,j:k+1], s) - pl.eye(blksiz*n)
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    25
        rhs = pl.reshape(b[:,j:k+1].T, (blksiz*n, 1))
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    26
        if (k < n-1):
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    27
            rhs2 = pl.dot(s, pl.dot(x[:,k+1:n], s[j:k+1, k+1:n].T))
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    28
            rhs = rhs + pl.reshape(rhs2, (blksiz*n, 1))
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    29
        v = -pl.solve(Ajj, rhs)
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    30
        x[:,j] = v.squeeze()[:n]
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    31
        if(blksiz == 2):
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    32
            x[:, k] = v[n:blksiz*n].squeeze()
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    33
        j = j - 1
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    34
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    35
    ## Back-transform to original coordinates.
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    36
    x = pl.dot(u, pl.dot(x, u.T))
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    37
    return x 
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    38
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    39
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    40
def covar_m(H, W):
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    41
    """
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    42
    User defined equivalent function to Matlab covar function
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    43
    For discrete time domain only
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    44
    Uses Lyapunov's equation for computation
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    45
    W: noise intensity (scalar)
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    46
    """
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    47
    a = pl.roots(H.den)
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    48
    if pl.any(abs(a) > 1):
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    49
#        print "Warning: System being unstable has infinite covariance"
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    50
        P = pl.inf
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    51
        return P
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    52
    else:
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    53
        A, B, C, D = H.A, H.B, H.C, H.D
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    54
        # Sylvester and Lyapunov solver
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    55
        Q1 = pl.dot(-B, pl.dot(W, B.T))
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    56
        Q = dlyap(A, -Q1)
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    57
        # Q = linmeq(2,A,Q1,[1, 0],1)
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    58
        # A*X*A' - X + B*W*B' = 0,                          (2b)
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    59
        # Discrete time Lyapunov equation; A is general form. Hessenberg-Schur method.
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    60
        # linmeq(2, A, C, [1,0], 1)
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    61
        # A*X*A' - X = C,                          (2b)
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    62
        #
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    63
        P = pl.dot(C, pl.dot(Q,C.T)) + pl.dot(D, pl.dot(W,D.T)) 
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    64
0efde00f9229 Initial commit.
Puneeth Chaganti <punchagan@fossee.in>
parents:
diff changeset
    65
    return P