function [X,K,L,INFO] = icare(A,B,Q,varargin)
%ICARE  Implicit solver for continuous-time Riccati equations.
%
%   [X,K,L] = ICARE(A,B,Q,R,S,E,G) computes the stabilizing solution X of
%   the continuous-time algebraic Riccati equation
%                                         -1
%      A'XE + E'XA + E'XGXE - (E'XB + S) R  (B'XE + S') + Q = 0 .
%
%   The matrices Q,R,G must be Hermitian and R,E must be invertible. When 
%   omitted or set to [], B,R,S,E,G default to the values B=0, R=I, S=0, 
%   E=I, and G=0. Scalar-valued Q,R,G are interpreted as multiples of the 
%   identity matrix. ICARE also returns the state-feedback gain K and the 
%   closed-loop eigenvalues L given by
%           -1
%      K = R  (B'XE + S'),    L = EIG(A+G*X*E-B*K,E) .
%
%   ICARE returns [] for X,K when there is no finite stabilizing solution.
%
%   [X,K,L,INFO] = ICARE(...) also returns a structure INFO with the
%   following data:
%      * Vectors SX and SR of state and R scalings
%      * Basis [U;V;W] of the stable invariant subspace of the associated
%        scaled matrix pencil
%      * Diagnostic "Report" with value
%           0    Accurate solution found (success)
%           1    Solution accuracy may be poor
%           2    Solution is not finite
%           3    Hamiltonian spectrum [L;-L] has eigenvalues on imag. axis.
%           4    Pencil is singular ([B;S;R] rank deficient)
%   The solution X and gain K are related to DX=diag(SX), DR=diag(SR), and
%   U,V,W by
%                -1    -1                -1
%      X = DX V U  DX E ,    K = - DR W U  DX .
%
%   [...] = ICARE(...,'noscaling') turns off the built-in scaling and
%   sets all entries of SX and SR to one. This speeds up computation but 
%   can be detrimental to accuracy when A,B,Q,R,S,E,G are poorly scaled.
%
%   [...] = ICARE(...,'anti') computes the anti-stabilizing solution X
%   that puts all eigenvalues of (A+G*X*E-B*K,E) in the right half-plane.
%
%   See the reference page for additional algorithmic details.
%
%   See also IDARE.

%   Author(s): Pascal Gahinet and Alan J. Laub.
%   Copyright 1986-2018 The MathWorks, Inc.

%   (A-sE,B) must be stabilizable and E,R must be invertible for a finite
%   stabilizing solution to exist. While these conditions are not sufficient 
%   in general, they become sufficient when [Q S;S' R]>=0 and
%   (A-B*(R\S'),Q-S*(R\S')) is detectable.
%
%   Reference: W.F. Arnold, III and A.J. Laub, "Generalized Eigenproblem
%	 Algorithms and Software for Algebraic Riccati Equations," Proc. IEEE, 
%   72(1984), 1746--1754.

% Parse inputs
try
   [A,B,G,Q,R,S,E,AutoScaling,JOB] = ricpack.parseInputs('c',A,B,Q,varargin{:});
catch ME
   throw(ME)
end

% Scale
[n,m] = size(B);
if AutoScaling
   [Sx,Sr,A,B,G,Q,R,S,E] = ricpack.scaleData('c',A,B,G,Q,R,S,E);
else
   Sx = ones(n,1);  Sr = ones(m,1);
end

% Solve in scaled coordinates
[U,V,W,L,RES] = ricpack.CARE(JOB,A,B,G,Q,R,S,E);

% Compute X,K and construct INFO
[X,K,Report] = ricpack.getXK('c',JOB,A,B,G,E,U,V,W,L,RES,Sx,Sr);
if nargout>3
   INFO = struct('Sx',Sx,'Sr',Sr,'U',U,'V',V,'W',W,'Report',Report);
elseif Report==1
   % Warn if accuracy is poor
   warning(message('Control:foundation:ARE03'))
end