@@ -411,7 +411,7 @@ def dlyap(A,Q,C=None,E=None):
411411
412412#### Riccati equation solvers care and dare
413413
414- def care (A ,B , Q , R = None ,S = None ,E = None ):
414+ def care (A , B , Q , R = None , S = None , E = None , stabilizing = True ):
415415 """ (X,L,G) = care(A,B,Q,R=None) solves the continuous-time algebraic Riccati
416416 equation
417417
@@ -527,7 +527,11 @@ def care(A,B,Q,R=None,S=None,E=None):
527527 raise e
528528
529529 try :
530- X ,rcond ,w ,S_o ,U ,A_inv = sb02md (n ,A ,G ,Q ,'C' )
530+ if stabilizing :
531+ sort = 'S'
532+ else :
533+ sort = 'U'
534+ X , rcond , w , S_o , U , A_inv = sb02md (n , A , G , Q , 'C' , sort = sort )
531535 except ValueError as ve :
532536 if ve .info < 0 or ve .info > 5 :
533537 e = ValueError (ve .message )
@@ -613,8 +617,12 @@ def care(A,B,Q,R=None,S=None,E=None):
613617 # Solve the generalized algebraic Riccati equation by calling the
614618 # Slycot function sg02ad
615619 try :
616- rcondu ,X ,alfar ,alfai ,beta ,S_o ,T ,U ,iwarn = \
617- sg02ad ('C' ,'B' ,'N' ,'U' ,'N' ,'N' ,'S' ,'R' ,n ,m ,0 ,A ,E ,B ,Q ,R ,S )
620+ if stabilizing :
621+ sort = 'S'
622+ else :
623+ sort = 'U'
624+ rcondu , X , alfar , alfai , beta , S_o , T , U , iwarn = \
625+ sg02ad ('C' , 'B' , 'N' , 'U' , 'N' , 'N' , sort , 'R' , n , m , 0 , A , E , B , Q , R , S )
618626 except ValueError as ve :
619627 if ve .info < 0 or ve .info > 7 :
620628 e = ValueError (ve .message )
@@ -671,7 +679,7 @@ def care(A,B,Q,R=None,S=None,E=None):
671679 else :
672680 raise ControlArgument ("Invalid set of input parameters." )
673681
674- def dare (A ,B , Q , R , S = None ,E = None ):
682+ def dare (A , B , Q , R , S = None , E = None , stabilizing = True ):
675683 """ (X,L,G) = dare(A,B,Q,R) solves the discrete-time algebraic Riccati
676684 equation
677685
@@ -692,8 +700,8 @@ def dare(A,B,Q,R,S=None,E=None):
692700 matrix :math:`G = (B^T X B + R)^{-1} (B^T X A + S^T)` and the closed loop
693701 eigenvalues L, i.e., the eigenvalues of A - B G , E.
694702 """
695- if S is not None or E is not None :
696- return dare_old (A , B , Q , R , S , E )
703+ if S is not None or E is not None or not stabilizing :
704+ return dare_old (A , B , Q , R , S , E , stabilizing )
697705 else :
698706 Rmat = asmatrix (R )
699707 Qmat = asmatrix (Q )
@@ -702,7 +710,7 @@ def dare(A,B,Q,R,S=None,E=None):
702710 L = eigvals (A - B .dot (G ))
703711 return X , L , G
704712
705- def dare_old (A ,B , Q , R , S = None ,E = None ):
713+ def dare_old (A , B , Q , R , S = None , E = None , stabilizing = True ):
706714 # Make sure we can import required slycot routine
707715 try :
708716 from slycot import sb02md
@@ -795,7 +803,12 @@ def dare_old(A,B,Q,R,S=None,E=None):
795803 raise e
796804
797805 try :
798- X ,rcond ,w ,S ,U ,A_inv = sb02md (n ,A ,G ,Q ,'D' )
806+ if stabilizing :
807+ sort = 'S'
808+ else :
809+ sort = 'U'
810+
811+ X , rcond , w , S , U , A_inv = sb02md (n , A , G , Q , 'D' , sort = sort )
799812 except ValueError as ve :
800813 if ve .info < 0 or ve .info > 5 :
801814 e = ValueError (ve .message )
@@ -884,8 +897,12 @@ def dare_old(A,B,Q,R,S=None,E=None):
884897 # Solve the generalized algebraic Riccati equation by calling the
885898 # Slycot function sg02ad
886899 try :
887- rcondu ,X ,alfar ,alfai ,beta ,S_o ,T ,U ,iwarn = \
888- sg02ad ('D' ,'B' ,'N' ,'U' ,'N' ,'N' ,'S' ,'R' ,n ,m ,0 ,A ,E ,B ,Q ,R ,S )
900+ if stabilizing :
901+ sort = 'S'
902+ else :
903+ sort = 'U'
904+ rcondu , X , alfar , alfai , beta , S_o , T , U , iwarn = \
905+ sg02ad ('D' , 'B' , 'N' , 'U' , 'N' , 'N' , sort , 'R' , n , m , 0 , A , E , B , Q , R , S )
889906 except ValueError as ve :
890907 if ve .info < 0 or ve .info > 7 :
891908 e = ValueError (ve .message )
0 commit comments