Python 大向量集上的部分Gram-Schmidt格式

Python 大向量集上的部分Gram-Schmidt格式,python,vector,Python,Vector,在一次模拟中,我创建了一大组向量,在这些向量上我部分地应用了Gram-Schmidt方案。我的意思是,我首先去掉向量的分量,然后计算它的长度(检查下面代码中的orth_2或orth_3公式)。然后存储长度,以便稍后计算所需的值(l值,请参见下面的代码)。只有在那之后,我才规范化向量 以下代码显示了上述步骤的三个向量: from numpy import random N = 3 'Numer of rows and columns. In my real ca

在一次模拟中,我创建了一大组向量,在这些向量上我部分地应用了Gram-Schmidt方案。我的意思是,我首先去掉向量的分量,然后计算它的长度(检查下面代码中的orth_2或orth_3公式)。然后存储长度,以便稍后计算所需的值(l值,请参见下面的代码)。只有在那之后,我才规范化向量

以下代码显示了上述步骤的三个向量:

from numpy import random

N = 3                  'Numer of rows and columns. In my real case N is equal to 100'

l1, l2, l3 = 0, 0, 0   'Quantities that i want to compute. Again in my case i have 100s of them l1, l2,...,l100' 


for t in range(10**3):  'Simulate Computation' 

    ''' for i in range(10**5):

        Computation where i compute Matrix A with its vectors A[0], A[1]... '''

    A = random.rand(N, N) 'A is generated randomly to keep the code short'

   'Apply the Gram-Schmidt-Scheme on the vectors A[0], A[1], A[2]. Again in my case i have 100 vectors'

    orth_1 = A[0]                   
    l1    += log(norm(orth_1)) 
    A[0]   = orth_1 / norm(orth_1)        

    orth_2 = A[1] - dot(A[1], A[0]) * A[0] 'Remove any A[0] components from A[1]'
    l2    += log(norm(orth_2))             'Store the values that i want to compute later'
    A[1]   = orth_2 / norm(orth_2)           

    orth_3 = A[2] - (dot(A[2], A[1]) * A[1]) - (dot(A[2], A[0]) * A[0]) 'Remove any A[0] and A[1] components from A[2]'
    l3    += log(norm(orth_3)) 
    A[2]   = orth_3 / norm(orth_3)
正如你所见,的公式随着向量数量的增加而变得越来越长。对于N=3是 仍然可行,但对于N=100,写出所有用于计算期望值l1、l2、…、l100的公式变得非常困难


有人知道我如何将这个过程原子化吗

有一个非常简单的解决方案,应用已经存在于
numpy.linalg
(或
scipy.linalg
)中的QR分解

那么结果呢,

A=R.T*Q.T
Q
的列或您使用的
Q.T
的行包含正交标准化近似特征向量,
R
R.T=A*Q
的对角线包含缩短的长度,可能带有符号。要在
R
中获得具有正对角线的归一化QR分解,请使用

S = np.diag(np.sign(np.diag(R))); Q, R = Q.dot(S), S.dot(R); 

numpy
使用LAPACK的QR例程,通过更稳定的Householder反射器。但结果是,最多符号/方向相同。

有一个非常简单的解决方案,应用已经存在于
numpy.linalg
(或
scipy.linalg
)中的QR分解

那么结果呢,

A=R.T*Q.T
Q
的列或您使用的
Q.T
的行包含正交标准化近似特征向量,
R
R.T=A*Q
的对角线包含缩短的长度,可能带有符号。要在
R
中获得具有正对角线的归一化QR分解,请使用

S = np.diag(np.sign(np.diag(R))); Q, R = Q.dot(S), S.dot(R); 

numpy
使用LAPACK的QR例程,通过更稳定的Householder反射器。但结果是,最多符号/方向相同。

我复制了您的原始代码,以便对答案进行比较,以确保数学正确。我相信这个函数返回的结果与代码计算的结果相同

def removeOrthos(Arr, N, l):
    remove = 0
    for i in range(N):
        remove -= np.dot(Arr[N], Arr[i]) * Arr[i]
    ortho = Arr[N] + remove
    l[N] += np.log(np.linalg.norm(ortho))
    return ortho / np.linalg.norm(ortho)
这是您的原始代码,与my function和linalg.qr()进行了比较

下面请注意[2,0]处的假条件。尽管实际数字似乎匹配,但一定存在超过小数点后7位的舍入误差

>>> A, B, Q, R = ortho()
-74.2981307378 -838.247442533 -1628.34240096 [  -74.29813074  -838.24744253 -1628.34240096]
>>> A==B
array([[ True,  True,  True],
       [ True,  True,  True],
       [False,  True,  True]], dtype=bool)
>>> A
array([[ 0.01225148,  0.554242  ,  0.8322654 ],
       [ 0.99376938, -0.09896161,  0.05127395],
       [ 0.1107805 ,  0.82645169, -0.55200116]])
>>> B
array([[ 0.01225148,  0.554242  ,  0.8322654 ],
       [ 0.99376938, -0.09896161,  0.05127395],
       [ 0.1107805 ,  0.82645169, -0.55200116]])
>>> A==Q
array([[False, False, False],
       [False, False, False],
       [False, False, False]], dtype=bool)
>>> Q
array([[-0.01225148,  0.99376938, -0.1107805 ],
       [-0.554242  , -0.09896161, -0.82645169],
       [-0.8322654 ,  0.05127395,  0.55200116]])

我复制了你的原始代码,所以我可以对答案进行比较,以确保计算结果正确。我相信这个函数返回的结果与代码计算的结果相同

def removeOrthos(Arr, N, l):
    remove = 0
    for i in range(N):
        remove -= np.dot(Arr[N], Arr[i]) * Arr[i]
    ortho = Arr[N] + remove
    l[N] += np.log(np.linalg.norm(ortho))
    return ortho / np.linalg.norm(ortho)
这是您的原始代码,与my function和linalg.qr()进行了比较

下面请注意[2,0]处的假条件。尽管实际数字似乎匹配,但一定存在超过小数点后7位的舍入误差

>>> A, B, Q, R = ortho()
-74.2981307378 -838.247442533 -1628.34240096 [  -74.29813074  -838.24744253 -1628.34240096]
>>> A==B
array([[ True,  True,  True],
       [ True,  True,  True],
       [False,  True,  True]], dtype=bool)
>>> A
array([[ 0.01225148,  0.554242  ,  0.8322654 ],
       [ 0.99376938, -0.09896161,  0.05127395],
       [ 0.1107805 ,  0.82645169, -0.55200116]])
>>> B
array([[ 0.01225148,  0.554242  ,  0.8322654 ],
       [ 0.99376938, -0.09896161,  0.05127395],
       [ 0.1107805 ,  0.82645169, -0.55200116]])
>>> A==Q
array([[False, False, False],
       [False, False, False],
       [False, False, False]], dtype=bool)
>>> Q
array([[-0.01225148,  0.99376938, -0.1107805 ],
       [-0.554242  , -0.09896161, -0.82645169],
       [-0.8322654 ,  0.05127395,  0.55200116]])

Q中的正交化向量未规范化,正确吗?Q由分解定义,作为反射的产物,正交矩阵。行和列系统是正交的。Q中的正交化向量不是标准化的,正确吗?Q是由分解定义的,并且作为反射的产物,是正交矩阵。行和列系统是正交的。你能用pythons函数linalg.qr()计算L吗?结果是相同的l1、l2、l3吗?我以前从未使用过linalg.qr(),所以这对莱曼来说可能是个好问题,但我眼泪中linalg.qr()的R结果与l1、l2或l3没有任何相似之处。我在上面提出的removeOrthos函数可以计算你需要的L值。是的,我知道。我用你的方法处理我的案子。计算时间相当长,所以我认为使用qr()方法可以增加计算时间。您是否对原始代码运行性能分析并删除了removeOrthos()?我只是好奇。今天晚些时候我可能会跑一些。如果这是一个问题,有几种方法可以提高性能。将for循环更改为list comprehension,在removeOthos()上使用np.vectorize,使用Numba或Cython。你指的是性能分析,我的计算机执行代码所需的时间吗?你能用pythons函数linalg.qr()计算L吗?结果是相同的l1、l2、l3吗?我以前从未使用过linalg.qr(),所以这对莱曼来说可能是个好问题,但我眼泪中linalg.qr()的R结果与l1、l2或l3没有任何相似之处。我在上面提出的removeOrthos函数可以计算你需要的L值。是的,我知道。我用你的方法处理我的案子。计算时间相当长,所以我认为使用qr()方法可以增加计算时间。您是否对原始代码运行性能分析并删除了removeOrthos()?我只是好奇。今天晚些时候我可能会跑一些。如果这是一个问题,有几种方法可以提高性能。将for循环更改为list comprehension,在removeOthos()上使用np.vectorize,使用Numba或Cython。您是指性能分析,即我的计算机执行代码所需的时间吗?