bundles / scipy latest / scipy / linalg / _solvers / solve_discrete_are
function
scipy.linalg._solvers:solve_discrete_are
source: /scipy/linalg/_solvers.py :557
Signature
def solve_discrete_are ( a , b , q , r , e = None , s = None , balanced = True ) Summary
Solves the discrete-time algebraic Riccati equation (DARE).
Extended Summary
The DARE is defined as
The limitations for a solution to exist are :
All eigenvalues of outside the unit disc, should be controllable.
The associated symplectic pencil (See Notes), should have eigenvalues sufficiently away from the unit circle.
Moreover, if e and s are not both precisely None, then the generalized version of DARE
is solved. When omitted, e is assumed to be the identity and s is assumed to be the zero matrix.
The documentation is written assuming array arguments are of specified "core" shapes. However, array argument(s) of this function may have additional "batch" dimensions prepended to the core shape. In this case, the array is treated as a batch of lower-dimensional slices; see linalg_batch for details.
Parameters
a: (M, M) array_likeSquare matrix
b: (M, N) array_likeInput
q: (M, M) array_likeInput
r: (N, N) array_likeSquare matrix
e: (M, M) array_like, optionalNonsingular square matrix
s: (M, N) array_like, optionalInput
balanced: boolThe boolean that indicates whether a balancing step is performed on the data. The default is set to True.
Returns
x: (M, M) ndarraySolution to the discrete algebraic Riccati equation.
Raises
: LinAlgErrorFor cases where the stable subspace of the pencil could not be isolated. See Notes section and the references for details.
Notes
The equation is solved by forming the extended symplectic matrix pencil, as described in [1], given by the block matrices
[ A 0 B ] [ E 0 B ] [ -Q E^H -S ] - \lambda * [ 0 A^H 0 ] [ S^H 0 R ] [ 0 -B^H 0 ]
and using a QZ decomposition method.
In this algorithm, the fail conditions are linked to the symmetry of the product and condition number of . Here, is the 2m-by-m matrix that holds the eigenvectors spanning the stable subspace with 2-m rows and partitioned into two m-row matrices. See [1] and [2] for more details.
In order to improve the QZ decomposition accuracy, the pencil goes through a balancing step where the sum of absolute values of and rows/cols (after removing the diagonal entries) is balanced following the recipe given in [3]. If the data has small numerical noise, balancing may amplify their effects and some clean up is required.
Examples
Given `a`, `b`, `q`, and `r` solve for `x`:import numpy as np from scipy import linalg as la a = np.array([[0, 1], [0, -1]]) b = np.array([[1, 0], [2, 1]]) q = np.array([[-4, -4], [-4, 7]]) r = np.array([[9, 3], [3, 1]]) x = la.solve_discrete_are(a, b, q, r) x R = la.solve(r + b.T.dot(x).dot(b), b.T.dot(x).dot(a)) np.allclose(a.T.dot(x).dot(a) - x - a.T.dot(x).dot(b).dot(R), -q)✓
See also
- solve_continuous_are
Solves the continuous algebraic Riccati equation
Aliases
-
scipy.linalg.solve_discrete_are