在SciPy中生成高而细的随机正交矩阵

时间:2018-01-21 07:01:58

标签: python numpy matrix scipy orthogonal

我需要在SciPy中生成一个高而细的随机列 - 正交矩阵;也就是说,行n的行数远远大于p列的数量级(比如n = 1e5p = 100。我知道scipy.stats.ortho_group 1}}生成一个正方形正交矩阵。但是,在我的情况下,生成n - by - n随机正交矩阵然后保留第一个p列是不可行的......是否有更节省时间和空间的方法?

3 个答案:

答案 0 :(得分:4)

您可以先生成高而细的随机矩阵,然后执行qr分解。

a = np.random.random(size=(100000, 100))
q, _ = np.linalg.qr(a)

此处q是您想要的矩阵。

答案 1 :(得分:3)

对我来说AA1 = 1scipy.linalg.orth快一点:

numpy.linalg.qr

答案 2 :(得分:1)

这是一个基准答案。请注意,我进行了一些转置,以便无论该矩阵是高又薄(给定列垂直)或短而宽(给定行垂直),都可以工作。

def qr_method(n, m):
    X = np.random.normal(0,1,(n,m))
    if n < m:
        X = X.T
    Q, _ = np.linalg.qr(X)
    if n < m:
        Q = Q.T
    return Q

def orth_method(n, m):
    X = np.random.normal(0,1,(n,m))
    if n < m:
        X = X.T
    Q = scipy.linalg.orth(X)
    if n < m:
        Q = Q.T
    return Q

def ortho_group_method(n, m):
    Q = scipy.stats.ortho_group.rvs(max(n, m))[:min(n, m),:]
    if m < n:
        Q = Q.T
    return Q

ortho_group方法(又称方阵然后取一个子集)是如此之慢,以至于我没有将其与其他方法一起作为基准:

%timeit ortho_group_method(500, 20)
2.73 s ± 57.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

在其他两个变量中,差异可以忽略不计,因为QR稍快一些。

%timeit qr_method(10000, 200)
168 ms ± 3.78 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit orth_method(10000, 200)
193 ms ± 4.09 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

基质的高度有区别吗?对于非常高的矩阵,它们接近等效值。

%timeit qr_method(100000, 20)
122 ms ± 1.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit orth_method(100000, 20)
130 ms ± 6.5 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

对于方矩阵,QR更快。

%timeit qr_method(500, 500)
47.5 ms ± 202 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit orth_method(500, 500)
137 ms ± 1.32 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)