MATLAB有一个gsvd函数来执行广义SVD。自2013年以来,我认为关于github pages关于将其置于scipy中的问题进行了大量讨论,有些页面有我可以使用的代码,例如here,对于像我这样的新手来说这是非常复杂的(对于让它运行)。
我还找到了implementation的LJWilliams github页面。这很不好,因为转移到python 3时有很多错误。尝试纠正断言和打印等简单的错误。它很快变得复杂。
有人可以帮我使用python的gsvd代码或告诉我如何使用在线的吗?
此外,一旦打印和断言语句得到纠正,这就是我在LJWilliams实现中得到的结果。代码看起来很复杂,我不确定花时间做它是最好的事情!还有一些人报告了同一个github页面上的问题,我不确定它是固定还是已连接。
n = 10
m = 6
p = 6
A = np.random.rand(m,n)
B = np.random.rand(p,n)
gsvd(A,B)
文件“/home/eghx/agent18/master_thesis/AMfe/amfe/gsvd.py”,第260行, 在gsvd U,V,Z,C,S = csd(Q [0:m,:],Q [m:m + n,:])
文件“/home/eghx/agent18/master_thesis/AMfe/amfe/gsvd.py”,第107行, 在csd Q,R = scipy.linalg.qr(S [q:n,m:p])
文件 “/home/eghx/anaconda3/lib/python3.5/site-packages/scipy/linalg/decomp_qr.py” 第141行,第2行 overwrite_a = overwrite_a)
文件 “/home/eghx/anaconda3/lib/python3.5/site-packages/scipy/linalg/decomp_qr.py” 第19行,在safecall ret = f(* args,** kwargs)
ValueError:无法创建意图(缓存|隐藏)|可选数组 - 必须 定义了尺寸但得到了(0,)
答案 0 :(得分:4)
如果你想在github上使用LJWillams实现,那就有一些bug。但是,要完全理解这项技术,我可能会建议您自己去实施它。我查看了Octave(相当于MATLAB的免费软件)和他们的"code is a wrapper to the corresponding Lapack dggsvd and zggsvd routines.",这是scipy应该做的事情。
我会发布我发现的错误,但我不打算将代码发布到完整的工作状态,因为我不确定版权方面的代码是什么,因为受版权保护的MATLAB实现,用于翻译它。
警告 :我不是广义SVD的专家,只是从调试的角度来看这个问题,而不是基础算法是否正确。我已经在你的原始随机数组和Python文件中已经存在的测试用例上工作了。
设置k
在第63行附近,设置k
的条件和对numpy.argparse
的误解(特别是与MATLAB' s find
相比)似乎设置了k
错误在某些情况下。将该代码更改为
if q == 1:
k = 0
elif m < p:
k = n;
else:
k = max([0,sum((np.diag(C) <= 1/np.sqrt(2)))])
S [1,1]应该是S [0,0],我认为(Python 0索引数组)
这里的numpy矩阵切片似乎错了。我通过将第83-95行改为:
来获得代码 UT, ST, VT = scipy.linalg.svd(slice_matrix(S,i,j))
ST = add_zeros(ST,np.zeros([n-k,r-k]))
if k > 0:
print('Zeroing elements of S in row indices > r, to be replaced by ST')
S[0:k,k:r] = 0
S[k:n,k:r] = ST
C[:,j] = np.dot(C[:,j],VT)
V[:,i] = np.dot(V[:,i],UT)
Z[:,j] = np.dot(Z[:,j],VT)
i = np.arange(k,q)
Q,R = scipy.linalg.qr(C[k:q,k:r])
C[i,j] = np.diag(diagf(R))
U[:,k:q] = np.dot(U[:,k:q],Q)
<{1}} 中的使用diagp()
的两个矩阵乘法应该是X*Y
而是np.dot(X,Y)
中的*
element-wise multiplication,而不是矩阵乘法。)