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)
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)
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)
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)
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)
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)
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)
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)