使用 Scipy 对称正交化后如何保持向量的顺序?

问题描述 投票:0回答:1

scipy.linalg.orth 使用 SVD 使矩阵正交。正交化后,向量按奇异值降序排列。然而,由于某些原因,我需要正交化向量在形状和顺序上尽可能与原始向量相似。

例如,对于矩阵,

>>> import scipy.linalg as sl
>>> import numpy as np
>>> A=np.array([[5,0,0],[0,2,0],[0,0,4]])
>>> A
array([[5, 0, 0],
       [0, 2, 0],
       [0, 0, 4]])

而不是按照奇异值5,4,2,

的降序得到正交化结果
>>> sl.orth(A)
array([[1., 0., 0.],
       [0., 0., 1.],
       [0., 1., 0.]])

我想要的结果是

1 0 0
0 1 0
0 0 1

保持原始向量的顺序。有什么方法可以让我意识到这一点吗?感谢您的帮助!

python scipy linear-algebra svd orthogonal
1个回答
0
投票

您不能直接要求 SciPy 执行此操作。 SciPy 内部使用名为 gesdd 的 LAPACK 函数来执行此操作,该函数已经执行此排序,并且没有办法禁用它。

但是,您可以做的是比较每个正交向量与每个输入向量的余弦相似度,并根据与输入向量的相似度对正交向量进行排序。

示例:

import scipy.linalg
from scipy.spatial.distance import cdist
import numpy as np


def orth_preserving_order(A):
    orthogonals_unordered = scipy.linalg.orth(A)
    # Compute distance matrix
    distance = cdist(A, orthogonals_unordered, metric='cosine')
    # Convert cosine distance into cosine similarity
    similarity_matrix = 1 - distance
    # Consider vectors which are pointing in opposite direction to be "similar"
    similarity_matrix = np.abs(similarity_matrix)
    orthogonal_order_idx = []
    for i in range(A.shape[0]):
        vec_to_match = A[i]
        # Pick element in orthogonals_unordered which is most similar to this row of A
        best_vec_idx = similarity_matrix[i].argmax()
        orthogonal_order_idx.append(best_vec_idx)
        # Prevent this vector from being picked again
        similarity_matrix[:, best_vec_idx] = -np.inf

    # Sanity check - did we put any orthogonal vector in twice?
    assert len(set(orthogonal_order_idx)) == len(orthogonal_order_idx), "duplicate orthogonal_order_idx"
    # Did we use every vector?
    assert len(orthogonal_order_idx) == A.shape[0], "missing vector in orthogonal_order_idx"
    # Reorder orthogonals
    orthogonal_reordered = orthogonals_unordered[orthogonal_order_idx]
    return orthogonal_reordered


A=np.array([[5,0,0],[0,2,0],[0,0,4]])
print(orth_preserving_order(A))

输出:

[[1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]]
© www.soinside.com 2019 - 2024. All rights reserved.