1414except ImportError :
1515 cvx = None
1616
17- eps = np .nextafter (0 , 1 )
1817
1918__all__ = ["get_output_fb_index" , "get_input_ff_index" , "ispassive" ,
2019 "solve_passivity_LMI" ]
@@ -28,8 +27,8 @@ def solve_passivity_LMI(sys, rho=None, nu=None):
2827 passive. Inputs of None for `rho` or `nu` indicate that the function should
2928 solve for that index (they are mutually exclusive, they can't both be
3029 None, otherwise you're trying to solve a nonconvex bilinear matrix
31- inequality.) The last element of `solution` is either the output or input
32- passivity index, for `rho` = None and `nu` = None respectively.
30+ inequality.) The last element of the output `solution` is either the output or input
31+ passivity index, for `rho` = None and `nu` = None respectively.
3332
3433 The sources for the algorithm are:
3534
@@ -74,11 +73,8 @@ def solve_passivity_LMI(sys, rho=None, nu=None):
7473 D = sys .D
7574
7675 # account for strictly proper systems
77- [n , m ] = D .shape
78- D = D + eps * np .eye (n , m )
79-
76+ [_ , m ] = D .shape
8077 [n , _ ] = A .shape
81- A = A - eps * np .eye (n )
8278
8379 def make_LMI_matrix (P , rho , nu , one ):
8480 q = sys .noutputs
@@ -113,7 +109,7 @@ def make_P_basis_matrices(n, rho, nu):
113109 P [i , j ] = 1
114110 P [j , i ] = 1
115111 matrix_list .append (make_LMI_matrix (P , 0 , 0 , 0 ).flatten ())
116- zeros = eps * np .eye (n )
112+ zeros = 0.0 * np .eye (n )
117113 if rho is None :
118114 matrix_list .append (make_LMI_matrix (zeros , 1 , 0 , 0 ).flatten ())
119115 elif nu is None :
@@ -149,9 +145,9 @@ def P_pos_def_constraint(n):
149145 if rho is not None and nu is not None :
150146 sys_constants = - make_LMI_matrix (np .zeros_like (A ), rho , nu , 1.0 )
151147 elif rho is not None :
152- sys_constants = - make_LMI_matrix (np .zeros_like (A ), rho , eps , 1.0 )
148+ sys_constants = - make_LMI_matrix (np .zeros_like (A ), rho , 0.0 , 1.0 )
153149 elif nu is not None :
154- sys_constants = - make_LMI_matrix (np .zeros_like (A ), eps , nu , 1.0 )
150+ sys_constants = - make_LMI_matrix (np .zeros_like (A ), 0.0 , nu , 1.0 )
155151
156152 sys_coefficents = np .vstack (sys_matrix_list ).T
157153
@@ -174,8 +170,15 @@ def P_pos_def_constraint(n):
174170
175171 # crunch feasibility solution
176172 cvx .solvers .options ['show_progress' ] = False
177- sol = cvx .solvers .sdp (c , Gs = Gs , hs = hs )
178- return sol ["x" ]
173+ try :
174+ sol = cvx .solvers .sdp (c , Gs = Gs , hs = hs )
175+ return sol ["x" ]
176+
177+ except ZeroDivisionError as e :
178+ raise ValueError ("The system is probably ill conditioned. "
179+ "Consider perturbing the system matrices by a small amount."
180+ ) from e
181+
179182
180183
181184def get_output_fb_index (sys ):
@@ -194,7 +197,7 @@ def get_output_fb_index(sys):
194197 float
195198 The OFP index
196199 """
197- sol = solve_passivity_LMI (sys , nu = eps )
200+ sol = solve_passivity_LMI (sys , nu = 0.0 )
198201 if sol is None :
199202 raise RuntimeError ("LMI passivity problem is infeasible" )
200203 else :
@@ -218,7 +221,7 @@ def get_input_ff_index(sys):
218221 float
219222 The IFP index
220223 """
221- sol = solve_passivity_LMI (sys , rho = eps )
224+ sol = solve_passivity_LMI (sys , rho = 0.0 )
222225 if sol is None :
223226 raise RuntimeError ("LMI passivity problem is infeasible" )
224227 else :
0 commit comments