Python 大向量集上的部分Gram-Schmidt格式
在一次模拟中,我创建了一大组向量,在这些向量上我部分地应用了Gram-Schmidt方案。我的意思是,我首先去掉向量的分量,然后计算它的长度(检查下面代码中的orth_2或orth_3公式)。然后存储长度,以便稍后计算所需的值(l值,请参见下面的代码)。只有在那之后,我才规范化向量 以下代码显示了上述步骤的三个向量: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
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。您是指性能分析,即我的计算机执行代码所需的时间吗?