numpy与Eigen SVD得到的结果不同?

下面的旋转矩阵近似的函数,分别调用了numpy和Eigen里面的SVD函数,得到了不同的结果:

Matrix3d ProjectToSO3(Matrix3d mat)
{
    JacobiSVD<Eigen::MatrixXd> svd(mat, ComputeThinU | ComputeThinV );  
    Matrix3d Vh = svd.matrixV(), U = svd.matrixU();   
    Matrix3d R = U*Vh.transpose();
    return R;
}

U:

 0.536118  0.594167   0.59962
0.0738052 -0.740602  0.667878
 0.840911 -0.313806 -0.440903
def ProjectToSO3(mat):
    U, s, Vh = np.linalg.svd(mat)
    R = np.dot(U, Vh)
    return R

U:

array([[ 0.53611771, -0.5941667 , -0.59961966],
       [ 0.07380517,  0.74060215, -0.66787817],
       [ 0.84091058,  0.31380629,  0.4409025 ]])

原因:
对于 A = U Σ V T A=U\Sigma V^T A=UΣVT A = − U Σ ( − V T ) A=-U\Sigma( -V^T) A=UΣVT等价,所以符号可能不同,而特征值顺序不同也会导致特征向量的顺序不同。

另外Eigen返回的是 V V V,而numpy是 V T V^T VT,这点需要注意。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,你的问题是如何自己编写矩阵分解函数并与numpy库中的函数进行比较。 对于特征分解,我们需要先找到矩阵的特征值和特征向量,具体步骤如下: 1. 求解矩阵的特征多项式,即求解 |A-λI| = 0,其中 A 是输入的矩阵,λ 是特征值, I 是单位矩阵。 2. 求解特征多项式的根,即特征值。 3. 对于每个特征值,求解对应的特征向量,即求解 (A-λI)x = 0,其中 x 是特征向量。 代码实现如下: ```python import numpy as np def eigen_decomposition(matrix): # 求解特征多项式 poly = np.poly(matrix) # 求解特征值 eigenvalues = np.roots(poly) # 求解特征向量 eigenvectors = [] for eigenvalue in eigenvalues: eigenvector = np.linalg.solve(matrix - eigenvalue * np.eye(matrix.shape[0]), np.zeros(matrix.shape[0])) eigenvectors.append(eigenvector) eigenvectors = np.array(eigenvectors).T return eigenvalues, eigenvectors ``` 对于SVD分解,我们需要先对矩阵进行奇异值分解,具体步骤如下: 1. 求解矩阵的转置矩阵与矩阵的积,即 A.T*A,得到一个对称半正定矩阵。 2. 对称半正定矩阵求解特征值和特征向量,得到对角矩阵和特征向量矩阵。 3. 根据对角矩阵求解奇异值,即对角矩阵的平方根。 4. 根据特征向量矩阵和奇异值求解左奇异矩阵和右奇异矩阵。 代码实现如下: ```python def svd_decomposition(matrix): # 求解对称半正定矩阵 symmetric_matrix = np.dot(matrix.T, matrix) # 求解特征值和特征向量 eigenvalues, eigenvectors = eigen_decomposition(symmetric_matrix) # 求解奇异值和左奇异矩阵、右奇异矩阵 singular_values = np.sqrt(eigenvalues) left_singular_matrix = np.dot(matrix, eigenvectors / singular_values) right_singular_matrix = eigenvectors return left_singular_matrix, singular_values, right_singular_matrix.T ``` 为了测试我们编写的函数是否正确,我们可以自定义一个矩阵,并将其作为参数传递给我们编写的函数和numpy库中的函数进行比较。代码如下: ```python # 自定义一个矩阵 matrix = np.array([[1, 2], [3, 4]]) # 使用我们编写的函数进行特征分解和SVD分解 eigenvalues, eigenvectors = eigen_decomposition(matrix) left_singular_matrix, singular_values, right_singular_matrix = svd_decomposition(matrix) # 使用numpy库中的函数进行特征分解和SVD分解 eigenvalues_np, eigenvectors_np = np.linalg.eig(matrix) left_singular_matrix_np, singular_values_np, right_singular_matrix_np = np.linalg.svd(matrix) # 输出结果进行比较 print("Eigenvalues:\n", eigenvalues, eigenvalues_np) print("Eigenvectors:\n", eigenvectors, eigenvectors_np) print("Left singular matrix:\n", left_singular_matrix, left_singular_matrix_np) print("Singular values:\n", singular_values, singular_values_np) print("Right singular matrix:\n", right_singular_matrix, right_singular_matrix_np) ``` 通过比较结果,我们可以发现我们编写的函数和numpy库中的函数得出的结果是一致的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值