201208-PyTorch求解矩阵正交基

博客介绍了在MATLAB里,通过奇异值分解 [U,S] = svd(A,‘econ’) 中的U获取正交基orth,若r = rank(A),U的前r列构成A值域的标准正交基。还提及步骤包括svd分解、按秩索引等,当参数过大有误差时可设64位精度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

orth is obtained from U in the singular value decomposition, [U,S] = svd(A,‘econ’). If r = rank(A), the first r columns of U form an orthonormal basis for the range of A.

  • 步骤:

    • svd分解
    • 按秩索引
  • 代码

from scipy import linalg as LA
import torch


# Step 1: 创建相关矩阵
print('Step 1: 创建相关矩阵')
A = np.array([[1.,0,1],[0,1,0],[1,0,1]])
B = torch.Tensor(A)
print(B)
print('\n')

# Step 2: 求矩阵的秩
print('Step 2: 求矩阵的秩')
r = torch.matrix_rank(B)
print(r)
print('\n')

# Step 3: 矩阵的svd分解
print('Step 3: 矩阵的svd分解及正交基索引')
u,s,v = torch.svd(B)
torchResult = u[:,:r]
print('u:\n',u)
print('s:\n',s)
print('v:\n',v)
print('\n')

# Step 4: 对比scipy直接计算与pytorch间接计算结果
print('Step 4: 对比scipy直接计算与pytorch间接计算结果')
scipyResult = LA.orth(B)
print('scipy.LA.orth():\n',scipyResult)
scipyResult.dtype

print('scipyResult - torchResult\n',torch.dist(torch.Tensor(scipyResult), torchResult,2))
  • 结果
Step 1: 创建相关矩阵
tensor([[1., 0., 1.],
        [0., 1., 0.],
        [1., 0., 1.]])


Step 2: 求矩阵的秩
tensor(2)


Step 3: 矩阵的svd分解及正交基索引
u:
 tensor([[-0.7071,  0.0000,  0.7071],
        [ 0.0000, -1.0000,  0.0000],
        [-0.7071,  0.0000, -0.7071]])
s:
 tensor([2.0000e+00, 1.0000e+00, 1.3491e-08])
v:
 tensor([[-7.0711e-01, -0.0000e+00,  7.0711e-01],
        [ 0.0000e+00, -1.0000e+00,  0.0000e+00],
        [-7.0711e-01, -1.1921e-07, -7.0711e-01]])


Step 4: 对比scipy直接计算与pytorch间接计算结果
scipy.LA.orth():
 [[-0.7071068   0.        ]
 [ 0.         -1.        ]
 [-0.70710677  0.        ]]
scipyResult - torchResult
 tensor(0.)
  • 函数
def torchOrth(A):
    r = torch.matrix_rank(A)
    u,s,v = torch.svd(A)
    return u[:,:r]

A = np.array([[1.,0,1],[0,1,0],[1,0,1]])
B = torch.Tensor(A)
torchOrth(B)
  • 实践

当参数过大的时候,仍旧存在一定的误差, 此时可设置64位精度
torch.set_default_dtype(torch.float64)

def torchOrth(A):
    r = torch.matrix_rank(A)
    u,s,v = torch.svd(A)
    return u[:,:r]

nFea = 10
nWin = 10
nOrt = 500

randomOth = random.randn(nWin * nFea + 1, nOrt)

if nFea * nWin >= nOrt:
    wenh1 = LA.orth(2 * randomOth)-1
else:
    wenh1 = LA.orth(2 * randomOth.T-1).T

randomOth = torch.Tensor(randomOth)
if nFea * nWin >= nOrt:
    wenh2 = torchOrth(2 * randomOth)-1
else:
    wenh2 = torchOrth(2 * randomOth.T-1).T

torch.dist(torch.Tensor(wenh1),wenh2,2)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GuokLiu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值