def solve_discrete_are(a, b, q, r):
try:<EOL><INDENT>g = inv(r)<EOL><DEDENT>except LinAlgError:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>g = np.dot(np.dot(b, g), b.conj().transpose())<EOL>try:<EOL><INDENT>ait = inv(a).conj().transpose()  <EOL><DEDENT>except LinAlgError:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>z11 = a+np.dot(np.dot(g, ait), q)<EOL>z12 = -<NUM_LIT:1.0>*np.dot(g, ait)<EOL>z21 = -<NUM_LIT:1.0>*np.dot(ait, q)<EOL>z22 = ait<EOL>z = np.vstack((np.hstack((z11, z12)), np.hstack((z21, z22))))<EOL>[s, u, sorted] = schur(z, sort='<STR_LIT>')<EOL>(m,n) = u.shape<EOL>u11 = u[<NUM_LIT:0>:m//<NUM_LIT:2>, <NUM_LIT:0>:n//<NUM_LIT:2>]<EOL>u21 = u[m//<NUM_LIT:2>:m, <NUM_LIT:0>:n//<NUM_LIT:2>]<EOL>u11i = inv(u11)<EOL>return np.dot(u21, u11i)<EOL>
Solves the disctrete algebraic Riccati equation, or DARE, defined as
(X = A'XA-(A'XB)(R+B'XB)^-1(B'XA)+Q), directly using a Schur decomposition
method.

Parameters
----------
a : (M, M) array_like
    Non-singular, square matrix
b : (M, N) array_like
    Input
q : (M, M) array_like
    Input
r : (N, N) array_like
    Non-singular, square matrix

Returns
-------
x : ndarray
    Solution to the continuous Lyapunov equation

See Also
--------
solve_continuous_are : Solves the continuous algebraic Riccati equation

Notes
-----
Method taken from:
Laub, "A Schur Method for Solving Algebraic Riccati Equations."
U.S. Energy Research and Development Agency under contract
ERDA-E(49-18)-2087.
http://dspace.mit.edu/bitstream/handle/1721.1/1301/R-0859-05666488.pdf

.. versionadded:: 0.11.0