Пример #1
0
    def mini_sylvester(S, V, Yt, R=None, U=None):
        '''
        A helper function to solve the 1x1 or 2x2 Sylvester equations
        arising in the solution of the generalized continuous-time
        Lyapunov equations

        Note that, this doesn't have any protection against LinAlgError
        hence the caller needs to `try` to see whether it is properly
        executed.
        '''
        if R is None:
            if S.size == 1:
                return -Yt / (S**2 - V**2)
            else:
                a, b, c, d = S.ravel().tolist()
                e, f, g, h = V.ravel().tolist()

                mat33[0, :] = [
                    a * a - e * e, 2 * (a * c - e * g), c * c - g * g
                ]
                mat33[1, :] = [
                    a * b - e * f, a * d - e * h + c * b - g * f, c * d - g * h
                ]
                mat33[2, :] = [
                    b * b - f * f, 2 * (b * d - f * h), d * d - h * h
                ]

                a, b, c = solve(
                    mat33, -Yt.reshape(-1, 1)[[0, 1, 3], :]).ravel().tolist()

                return np.array([[a, b], [b, c]], dtype=float)

        elif S.size == 4:
            if R.size == 4:
                a, b, c, d = R.ravel().tolist()
                e, f, g, h = S.ravel().tolist()
                k, l, m, n = U.ravel().tolist()
                p, q, r, s = V.ravel().tolist()

                mat44[0, :] = [
                    a * e - k * p, a * g - k * r, c * e - m * p, c * g - m * r
                ]
                mat44[1, :] = [
                    a * f - k * q, a * h - k * s, c * f - m * q, c * h - m * s
                ]
                mat44[2, :] = [
                    b * e - l * p, b * g - l * r, d * e - n * p, d * g - n * r
                ]
                mat44[3, :] = [
                    b * f - l * q, b * h - l * s, d * f - n * q, d * h - n * s
                ]

                return solve(mat44, -Yt.reshape(-1, 1)).reshape(2, 2)

            else:
                return solve(R[0, 0] * S.T - U[0, 0] * V.T, -Yt.T).T
        elif R.size == 4:
            return solve(S[0, 0] * R.T - V[0, 0] * U.T, -Yt)
        else:
            return -Yt / (R * S - U * V)
Пример #2
0
    def mini_sylvester(R, S, Yt, U=None, V=None):
        '''
        A helper function to solve the 1x1 or 2x2 Sylvester equations
        arising in the solution of the generalized continuous-time
        Lyapunov equations

        Note that, this doesn't have any protection against LinAlgError
        hence the caller needs to `try` to see whether it is properly
        executed.
        '''
        if U is None:
            if R.size == 1:
                return -Yt / (2 * R * S)
            else:
                a, b, c, d = R.ravel().tolist()
                e, f, g, h = S.ravel().tolist()

                mat33[0, :] = [2 * a * e, 2 * (a * g + e * c), 2 * c * g]
                mat33[1, :] = [
                    a * f + e * b, a * h + e * d + c * f + b * g, c * h + g * d
                ]
                mat33[2, :] = [2 * b * f, 2 * (b * h + f * d), 2 * d * h]

                a, b, c = solve(
                    mat33, -Yt.reshape(-1, 1)[[0, 1, 3], :]).ravel().tolist()

                return np.array([[a, b], [b, c]], dtype=float)

        elif R.size == 4:
            if S.size == 4:
                a, b, c, d = R.reshape(1, 4).tolist()[0]
                e, f, g, h = S.reshape(1, 4).tolist()[0]
                k, l, m, n = U.reshape(1, 4).tolist()[0]
                p, q, r, s = V.reshape(1, 4).tolist()[0]

                mat44[0, :] = [
                    a * e + k * p, a * g + k * r, c * e + m * p, c * g + m * r
                ]
                mat44[1, :] = [
                    a * f + k * q, a * h + k * s, c * f + m * q, c * h + m * s
                ]
                mat44[2, :] = [
                    b * e + l * p, b * g + l * r, d * e + n * p, d * g + n * r
                ]
                mat44[3, :] = [
                    b * f + l * q, b * h + l * s, d * f + n * q, d * h + n * s
                ]

                return solve(mat44, -Yt.reshape(-1, 1)).reshape(2, 2)
            else:
                return solve(S[0, 0] * R.T + V[0, 0] * U.T, -Yt)
        elif S.size == 4:
            return solve(R[0, 0] * S.T + U[0, 0] * V.T, -Yt.T).T
        else:
            return -Yt / (R * S + U * V)
Пример #3
0
    def mini_sylvester(S, V, Yt, R=None, U=None):
        '''
        A helper function to solve the 1x1 or 2x2 Sylvester equations
        arising in the solution of the generalized continuous-time
        Lyapunov equations

        Note that, this doesn't have any protection against LinAlgError
        hence the caller needs to `try` to see whether it is properly
        executed.
        '''
        if R is None:
            if S.size == 1:
                return -Yt / (S ** 2 - V ** 2)
            else:
                a, b, c, d = S.ravel().tolist()
                e, f, g, h = V.ravel().tolist()

                mat33[0, :] = [a*a - e*e, 2 * (a*c - e*g), c*c - g*g]
                mat33[1, :] = [a*b - e*f, a*d - e*h + c*b - g*f, c*d - g*h]
                mat33[2, :] = [b*b - f*f, 2 * (b*d - f*h), d*d - h*h]

                a, b, c = solve(mat33, -Yt.reshape(-1, 1)[[0, 1, 3], :]
                                ).ravel().tolist()

                return np.array([[a, b], [b, c]], dtype=float)

        elif S.size == 4:
            if R.size == 4:
                a, b, c, d = R.ravel().tolist()
                e, f, g, h = S.ravel().tolist()
                k, l, m, n = U.ravel().tolist()
                p, q, r, s = V.ravel().tolist()

                mat44[0, :] = [a*e - k*p, a*g - k*r, c*e - m*p, c*g - m*r]
                mat44[1, :] = [a*f - k*q, a*h - k*s, c*f - m*q, c*h - m*s]
                mat44[2, :] = [b*e - l*p, b*g - l*r, d*e - n*p, d*g - n*r]
                mat44[3, :] = [b*f - l*q, b*h - l*s, d*f - n*q, d*h - n*s]

                return solve(mat44, -Yt.reshape(-1, 1)).reshape(2, 2)

            else:
                return solve(R[0, 0]*S.T - U[0, 0]*V.T, -Yt.T).T
        elif R.size == 4:
            return solve(S[0, 0]*R.T - V[0, 0]*U.T, -Yt)
        else:
            return -Yt / (R * S - U * V)
Пример #4
0
    def mini_sylvester(Ar, Yt, Al=None):
        '''
        A helper function to solve the 1x1 or 2x2 Sylvester equations
        arising in the solution of the continuous-time Lyapunov equations

        Note that, this doesn't have any protection against LinAlgError
        hence the caller needs to `try` to see whether it is properly
        executed.
        '''

        # The symmetric problem
        if Al is None:
            if Ar.size == 1:
                return -Yt / (Ar * 2)
            else:
                a, b, c, d = Ar.reshape(1, 4).tolist()[0]

                mat33[0, :] = [2 * a, 2 * c, 0]
                mat33[1, :] = [b, a + d, c]
                mat33[2, :] = [0, 2 * b, 2 * d]
                a, b, c = solve(
                    mat33, -Yt.reshape(-1, 1)[[0, 1, 3], :]).ravel().tolist()

                return np.array([[a, b], [b, c]], dtype=float)

        # Nonsymmetric
        elif Ar.size == 4:
            if Al.size == 4:
                a00, a01, a10, a11 = Al.reshape(1, 4).tolist()[0]
                b00, b01, b10, b11 = Ar.reshape(1, 4).tolist()[0]

                mat44[0, :] = [a00 + b00, b10, a10, 0]
                mat44[1, :] = [b01, a00 + b11, 0, a10]
                mat44[2, :] = [a01, 0, a11 + b00, b10]
                mat44[3, :] = [0, a01, b01, a11 + b11]

                return solve(mat44, -Yt.reshape(-1, 1)).reshape(2, 2)
            # Ar is 2x2 , Al is scalar
            else:
                return solve(Ar.T + Al[0, 0] * i2, -Yt.T).T

        elif Al.size == 4:
            return solve(Al.T + Ar[0, 0] * i2, -Yt)
        else:
            return -Yt / (Ar + Al)
Пример #5
0
    def mini_sylvester(Ar, Yt, Al=None):
        '''
        A helper function to solve the 1x1 or 2x2 Sylvester equations
        arising in the solution of the continuous-time Lyapunov equations

        Note that, this doesn't have any protection against LinAlgError
        hence the caller needs to `try` to see whether it is properly
        executed.
        '''

        # The symmetric problem
        if Al is None:
            if Ar.size == 1:
                return - Yt / (Ar * 2)
            else:
                a, b, c, d = Ar.reshape(1, 4).tolist()[0]

                mat33[0, :] = [2*a, 2*c, 0]
                mat33[1, :] = [b, a + d, c]
                mat33[2, :] = [0, 2*b, 2*d]
                a, b, c = solve(mat33, -Yt.reshape(-1, 1)[[0, 1, 3], :]
                                ).ravel().tolist()

                return np.array([[a, b], [b, c]], dtype=float)

        # Nonsymmetric
        elif Ar.size == 4:
            if Al.size == 4:
                a00, a01, a10, a11 = Al.reshape(1, 4).tolist()[0]
                b00, b01, b10, b11 = Ar.reshape(1, 4).tolist()[0]

                mat44[0, :] = [a00+b00, b10, a10, 0]
                mat44[1, :] = [b01, a00 + b11, 0, a10]
                mat44[2, :] = [a01, 0, a11 + b00, b10]
                mat44[3, :] = [0, a01, b01, a11 + b11]

                return solve(mat44, -Yt.reshape(-1, 1)).reshape(2, 2)
            # Ar is 2x2 , Al is scalar
            else:
                return solve(Ar.T + Al[0, 0] * i2, -Yt.T).T

        elif Al.size == 4:
            return solve(Al.T + Ar[0, 0] * i2, -Yt)
        else:
            return -Yt / (Ar + Al)
Пример #6
0
    def mini_sylvester(R, S, Yt, U=None, V=None):
        '''
        A helper function to solve the 1x1 or 2x2 Sylvester equations
        arising in the solution of the generalized continuous-time
        Lyapunov equations

        Note that, this doesn't have any protection against LinAlgError
        hence the caller needs to `try` to see whether it is properly
        executed.
        '''
        if U is None:
            if R.size == 1:
                return -Yt / (2 * R * S)
            else:
                a, b, c, d = R.ravel().tolist()
                e, f, g, h = S.ravel().tolist()

                mat33[0, :] = [2*a*e, 2*(a*g + e*c), 2*c*g]
                mat33[1, :] = [a*f + e*b, a*h + e*d + c*f + b*g, c*h + g*d]
                mat33[2, :] = [2*b*f, 2*(b*h + f*d), 2*d*h]

                a, b, c = solve(mat33, -Yt.reshape(-1, 1)[[0, 1, 3], :]
                                ).ravel().tolist()

                return np.array([[a, b], [b, c]], dtype=float)

        elif R.size == 4:
            if S.size == 4:
                a, b, c, d = R.reshape(1, 4).tolist()[0]
                e, f, g, h = S.reshape(1, 4).tolist()[0]
                k, l, m, n = U.reshape(1, 4).tolist()[0]
                p, q, r, s = V.reshape(1, 4).tolist()[0]

                mat44[0, :] = [a*e + k*p, a*g + k*r, c*e + m*p, c*g + m*r]
                mat44[1, :] = [a*f + k*q, a*h + k*s, c*f + m*q, c*h + m*s]
                mat44[2, :] = [b*e + l*p, b*g + l*r, d*e + n*p, d*g + n*r]
                mat44[3, :] = [b*f + l*q, b*h + l*s, d*f + n*q, d*h + n*s]

                return solve(mat44, -Yt.reshape(-1, 1)).reshape(2, 2)
            else:
                return solve(S[0, 0]*R.T + V[0, 0]*U.T, -Yt)
        elif S.size == 4:
            return solve(R[0, 0]*S.T+U[0, 0]*V.T, -Yt.T).T
        else:
            return -Yt / (R * S + U * V)
Пример #7
0
    def mini_sylvester(Al, Yt, Ar=None):
        '''
        A helper function to solve the 1x1 or 2x2 Sylvester equations
        arising in the solution of the continuous-time Lyapunov equations

        Note that, this doesn't have any protection against LinAlgError
        hence the caller needs to `try` to see whether it is properly
        executed.
        '''
        # The symmetric problem
        if Ar is None:
            if Al.size == 1:
                return -Yt / (Al**2 - 1)
            else:
                a, b, c, d = Al.reshape(1, 4).tolist()[0]

                mat33[0, :] = [a**2 - 1, 2 * a * c, c**2]
                mat33[1, :] = [a * b, a * d + b * c - 1, c * d]
                mat33[2, :] = [b**2, 2 * b * d, d**2 - 1]
                a, b, c = solve(
                    mat33, -Yt.reshape(-1, 1)[[0, 1, 3], :]).ravel().tolist()

                return np.array([[a, b], [b, c]], dtype=float)

        # Nonsymmetric
        elif Al.size == 4:
            if Ar.size == 4:
                a00, a01, a10, a11 = Al.ravel().tolist()
                b00, b01, b10, b11 = Ar.ravel().tolist()

                mat44[0, :] = [a00 * b00 - 1, a00 * b10, a10 * b00, a10 * b10]
                mat44[1, :] = [a00 * b01, a00 * b11 - 1, a10 * b01, a10 * b11]
                mat44[2, :] = [a01 * b00, a01 * b10, a11 * b00 - 1, a11 * b10]
                mat44[3, :] = [a01 * b01, a01 * b11, a11 * b01, a11 * b11 - 1]

                return solve(mat44, -Yt.reshape(-1, 1)).reshape(2, 2)
            else:
                return solve(Al.T * Ar[0, 0] - i2, -Yt)

        elif Ar.size == 4:
            return solve(Ar.T * Al[0, 0] - i2, -Yt.T).T
        else:
            return -Yt / (Ar * Al - 1)
Пример #8
0
    def mini_sylvester(Al, Yt, Ar=None):
        '''
        A helper function to solve the 1x1 or 2x2 Sylvester equations
        arising in the solution of the continuous-time Lyapunov equations

        Note that, this doesn't have any protection against LinAlgError
        hence the caller needs to `try` to see whether it is properly
        executed.
        '''
        # The symmetric problem
        if Ar is None:
            if Al.size == 1:
                return - Yt / (Al ** 2 - 1)
            else:
                a, b, c, d = Al.reshape(1, 4).tolist()[0]

                mat33[0, :] = [a**2 - 1, 2*a*c, c ** 2]
                mat33[1, :] = [a*b, a*d + b*c - 1, c*d]
                mat33[2, :] = [b ** 2, 2*b*d, d ** 2 - 1]
                a, b, c = solve(mat33, -Yt.reshape(-1, 1)[[0, 1, 3], :]
                                ).ravel().tolist()

                return np.array([[a, b], [b, c]], dtype=float)

        # Nonsymmetric
        elif Al.size == 4:
            if Ar.size == 4:
                a00, a01, a10, a11 = Al.ravel().tolist()
                b00, b01, b10, b11 = Ar.ravel().tolist()

                mat44[0, :] = [a00*b00 - 1, a00*b10, a10*b00, a10*b10]
                mat44[1, :] = [a00*b01, a00*b11 - 1, a10*b01, a10*b11]
                mat44[2, :] = [a01*b00, a01*b10, a11*b00 - 1, a11*b10]
                mat44[3, :] = [a01*b01, a01*b11, a11*b01, a11*b11 - 1]

                return solve(mat44, -Yt.reshape(-1, 1)).reshape(2, 2)
            else:
                return solve(Al.T * Ar[0, 0] - i2, -Yt)

        elif Ar.size == 4:
            return solve(Ar.T * Al[0, 0] - i2, -Yt.T).T
        else:
            return -Yt / (Ar * Al - 1)