scipy.linalg.

solve_discrete_are#

scipy.linalg.solve_discrete_are(a, b, q, r, e=None, s=None, balanced=True)[源代码][源代码]#

求解离散时间代数Riccati方程(DARE)。

DARE 被定义为

\[A^HXA - X - (A^HXB) (R + B^HXB)^{-1} (B^HXA) + Q = 0\]

解决方案存在的限制是:

  • 单位圆外的 \(A\) 的所有特征值,应是可控的。

  • 相关的辛矩阵束(见注释),其特征值应充分远离单位圆。

此外,如果 es 不都是精确的 None,那么DARE的广义版本

\[A^HXA - E^HXE - (A^HXB+S) (R+B^HXB)^{-1} (B^HXA+S^H) + Q = 0\]

已解决。如果省略,则假定 e 为单位矩阵,s 为零矩阵。

参数:
a(M, M) array_like

方阵

b(M, N) array_like

toctree 是一个 reStructuredText 指令 ,这是一个非常多功能的标记。指令可以有参数、选项和内容。

q(M, M) array_like

toctree 是一个 reStructuredText 指令 ,这是一个非常多功能的标记。指令可以有参数、选项和内容。

r(N, N) array_like

方阵

e(M, M) array_like, 可选

非奇异方阵

s(M, N) array_like, 可选

toctree 是一个 reStructuredText 指令 ,这是一个非常多功能的标记。指令可以有参数、选项和内容。

平衡的布尔

指示是否对数据执行平衡步骤的布尔值。默认设置为 True。

返回:
x(M, M) ndarray

离散代数Riccati方程的解。

Raises:
LinAlgError

对于无法分离铅笔稳定子空间的情况。详见注释部分和参考文献。

参见

solve_continuous_are

求解连续代数Riccati方程

注释

该方程通过形成扩展的辛矩阵束来求解,如[Rd293c2673a30-1]_中所述,给定的块矩阵为

[  A   0   B ]             [ E   0   B ]
[ -Q  E^H -S ] - \lambda * [ 0  A^H  0 ]
[ S^H  0   R ]             [ 0 -B^H  0 ]

并使用QZ分解方法。

在这个算法中,失败条件与产品 \(U_2 U_1^{-1}\) 的对称性和 \(U_1\) 的条件数有关。这里,\(U\) 是包含跨越稳定子空间的特征向量的 2m-by-m 矩阵,具有 2-m 行并被划分为两个 m 行矩阵。更多细节请参见 [1][2]

为了提高QZ分解的精度,铅笔会经过一个平衡步骤,其中 \(H\)\(J\) 行/列(在去除对角线元素后)的绝对值之和按照[Rd293c2673a30-3]_中的方法进行平衡。如果数据存在小的数值噪声,平衡可能会放大它们的影响,因此需要进行一些清理。

Added in version 0.11.0.

参考文献

[1]

P. van Dooren , “A Generalized Eigenvalue Approach For Solving Riccati Equations.”, SIAM Journal on Scientific and Statistical Computing, Vol.2(2), DOI:10.1137/0902010

[2]

A.J. Laub, “求解代数Riccati方程的Schur方法。”, 麻省理工学院。信息与决策系统实验室。LIDS-R ; 859. 在线获取: http://hdl.handle.net/1721.1/1301

[3]

P. Benner, “Symplectic Balancing of Hamiltonian Matrices”, 2001, SIAM J. Sci. Comput., 2001, Vol.22(5), DOI:10.1137/S1064827500367993

示例

给定 a, b, q, 和 r 求解 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
array([[-4., -4.],
       [-4.,  7.]])
>>> 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)
True