In [24]: from scipy.stats import ortho_group # Requires version 0.18 of scipy
In [25]: m = ortho_group.rvs(dim=3)
In [26]: m
Out[26]:
array([[-0.23939017, 0.58743526, -0.77305379],
[ 0.81921268, -0.30515101, -0.48556508],
[-0.52113619, -0.74953498, -0.40818426]])
In [27]: np.set_printoptions(suppress=True)
In [28]: m.dot(m.T)
Out[28]:
array([[ 1., 0., -0.],
[ 0., 1., 0.],
[-0., 0., 1.]])
import numpy as np
def rvs(dim=3):
random_state = np.random
H = np.eye(dim)
D = np.ones((dim,))
for n in range(1, dim):
x = random_state.normal(size=(dim-n+1,))
D[n-1] = np.sign(x[0])
x[0] -= D[n-1]*np.sqrt((x*x).sum())
# Householder transformation
Hx = (np.eye(dim-n+1) - 2.*np.outer(x, x)/(x*x).sum())
mat = np.eye(dim)
mat[n-1:, n-1:] = Hx
H = np.dot(H, mat)
# Fix the last sign such that the determinant is 1
D[-1] = (-1)**(1-(dim % 2))*D.prod()
# Equivalent to np.dot(np.diag(D), H) but faster, apparently
H = (D*H.T).T
return H
7条答案
按热度按时间unguejic1#
scipy的0.18版本有
scipy.stats.ortho_group
和scipy.stats.special_ortho_group
。例如,
vngu2lb82#
通过对
n x n
矩阵进行QR
分解,可以得到一个随机n x n
正交矩阵Q
(均匀分布在n x n
正交矩阵的流形上),该矩阵的元素为i.i.d.高斯随机变量,均值为0
,方差为1
。下面是一个例子:编辑:(在@g g的评论之后重新访问这个答案。)上面关于高斯矩阵的QR分解的权利要求提供了均匀分布的(在所谓的Stiefel流形上)正交矩阵由该参考文献的定理2.3.18-19提出。* 其中三角矩阵
R
具有正元素 *。显然scipy的
qr
功能(numpy)函数 * 不能保证R
* 的正对角元素,相应的Q
实际上 * 不是 * 均匀分布的。这在this专题文章第4.6节中已经观察到。(讨论参考MATLAB,但我猜MATLAB和scipy都使用相同的LAPACK例程)。这里建议通过将qr
提供的矩阵Q
与随机酉对角矩阵后乘来修改该矩阵。下面,我再现上述参考文献中的实验,绘制由
qr
提供的“直接”Q
矩阵以及“修改”版本的特征值相位的经验分布(直方图),其中可以看出,修改版本确实具有均匀的特征值相位,正如从均匀分布的正交矩阵所预期的那样。9wbgstp73#
这是从https://github.com/scipy/scipy/pull/5622/files中提取的
rvs
方法,改动很小--足以作为一个独立的numpy函数运行。它符合沃伦的测试https://stackoverflow.com/a/38426572/901925
vc9ivgsu4#
创建任意形状(
n x m
)正交矩阵的简单方法:注意,如果
n > m
,则将获得mat.T @ mat = eye(m)
。tquggr8v5#
文件
jljoyd4f6#
如果你想要一个非方阵的正交列向量,你可以创建一个正方形的任何提到的方法,并删除一些列。
drkbr07n7#
Numpy也有qr因子分解。https://numpy.org/doc/stable/reference/generated/numpy.linalg.qr.html