【问题标题】:Solving Linear Systems of equations with SVD Decomposition用 SVD 分解求解线性方程组
【发布时间】:2020-04-05 02:50:31
【问题描述】:

我想编写一个函数,使用 SVD 分解来求解方程组 ax=b,其中 a 是方阵,b 是值向量。 scipy 函数 scipy.linalg.svd() 应该将 a 转换为矩阵 U W V。对于 U 和 V,我可以简单地进行转置来找到它们的逆矩阵。但是对于 W,该函数给了我一个一维数组值,我需要放下矩阵的对角线,然后在值上输入一个。

def solveSVD(a,b):

    U,s,V=sp.svd(a,compute_uv=True)

    Ui=np.transpose(a)
    Vi=np.transpose(V)

    W=np.diag(s)

    Wi=np.empty(np.shape(W)[0],np.shape(W)[1])
    for i in range(np.shape(Wi)[0]):
        if W[i,i]!=0:
            Wi[i,i]=1/W[i,i]
    
    ai=np.matmul(Ui,np.matmul(Wi,Vi))
    x=np.matmul(ai,b)

    return(x)

但是,我收到“TypeError:无法理解的数据类型”错误。我认为部分问题在于

W=np.diag(s) 

没有产生方对角矩阵。

这是我第一次使用这个库,如果我做了一些非常愚蠢的事情,我深表歉意,但我无法弄清楚为什么这条线不起作用。谢谢大家!

【问题讨论】:

  • 空函数取一个元组,只用W.shape,而且你的函数不能正确求解线性系统
  • @Yacola 感谢您对元组的帮助,您能否详细说明为什么我的函数无法正确解决 LSs?
  • 抱歉,但我不确定您是否愿意通过您的实现来解决这个问题...Ui=np.transpose(a) 或更像Ui=np.transpose(U),也可以将for 循环替换为Wi=np.diag(1/s)?检查我代码中的 cmets 以帮助您了解该函数在做什么。

标签: python numpy scipy linear-algebra svd


【解决方案1】:

简而言之,使用奇异值分解可以让您将最初的问题 A x = b 替换为 U diag(s) Vh x = b。在后者上使用一点代数,给你以下 3 步函数,这真的很容易阅读:

import numpy as np
from scipy.linalg import svd

def solve_svd(A,b):
    # compute svd of A
    U,s,Vh = svd(A)

    # U diag(s) Vh x = b <=> diag(s) Vh x = U.T b = c
    c = np.dot(U.T,b)
    # diag(s) Vh x = c <=> Vh x = diag(1/s) c = w (trivial inversion of a diagonal matrix)
    w = np.dot(np.diag(1/s),c)
    # Vh x = w <=> x = Vh.H w (where .H stands for hermitian = conjugate transpose)
    x = np.dot(Vh.conj().T,w)
    return x

现在,让我们测试一下

A = np.random.random((100,100))
b = np.random.random((100,1))

并与np.linalg.solve函数的LU分解比较

x_svd = solve_svd(A,b)
x_lu = np.linalg.solve(A,b)

给了

np.allclose(x_lu,x_svd)
>>> True

如果需要,请随时在 cmets 中询问更多解释。希望这会有所帮助。

【讨论】:

  • @FatemehAsgarinejad,总是欢迎建设性的 cmets,请随时编辑此答案,因为它并不比 solve 更准确。
  • 不幸的是我做不到。我在做这个工作。但与某些矩阵的内置函数相比,它给出了不同的答案。
猜你喜欢
  • 1970-01-01
  • 2021-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多