我试图把我的问题弄清楚。这篇文章的结尾仍然可以找到老的离题
问题:我有一个{np.ndarray
)的{R
(3×3矩阵)是对称的
这意味着A
和A @ R.T
相差1。最多一个排列和两个。在对排列进行校正后,两个矩阵可能会有一个数值公差参数不同:np.allclose(A, permuted(A @ R.T)) == True
(我事先不知道permuted()
,这肯定取决于R
)
问题:如何创建以下函数:
def is_symmetric(A, R, atol=1e-5) -> bool:
# checks symmetry as defined above, considering both numerical noise
# and permutation of vectors.
(关于可能的方法以及我的疑问和尝试的一些讨论见下文。)
旧题外话:
我想检查以向量表示的点集合中的对称性。这意味着检查这些点在空间中应用矩阵变换时是否不变,例如旋转或平面镜像
import numpy as np
R = np.array([[0, -1, 0], # 90° rotation around z as an example
[1, 0, 0],
[0, 0, 1]])
关键是,我接受向量的排列::只要某个初始位置被转换到另一个先前存在的位置,我就没事。这意味着检查从一个向量到另一个向量的变换对
天真的解决方案将在A @ R.T
的行上循环(其中A
是一个矩阵,其行是点位置),并尝试为A
的每个初始行匹配一个变换向量,该向量似乎随列数的平方增长
另一种可能是对向量进行预排序(例如,通过它们的坐标值):
A = np.array([[1, 0, 0], # some points
[0, 1, 0],
[0, 0, 1],
[0.5, 0.5, 0]])
A = np.array(sorted(A, key=lambda v: (v[2], v[1], v[0]))) # sort by z, y, x values
# array([[1. , 0. , 0. ],
# [0.5, 0.5, 0. ],
# [0. , 1. , 0. ],
# [0. , 0. , 1. ]])
A_rotated = np.array(sorted(A @ R.T, key=lambda v: (v[2], v[1], v[0])))
# array([[-1. , 0. , 0. ], # no match
# [-0.5, 0.5, 0. ], # no match
# [ 0. , 1. , 0. ], # match
# [ 0. , 0. , 1. ]]) # match
(这种方法有两种排序,所以O(n ln(n))?) 第三个想法是比较从原始向量和旋转向量创建的集合。我有一种直觉,这就像比较排序向量一样好
但还有一件事:如何处理近似比较?我想接受两个向量v
和w
相等,如果是np.allclose(v, w) == True
或等效(即abs(v - w) < eps
或类似):
np.allclose([1, 0, 0], [1, 0, 0])
# True
np.allclose([1, 0, 0], [1 + 1e-5, 0, 0], atol=1e-5)
# True
np.allclose([1, 0, 0], [1 + 1e-4, 0, 0], atol=1e-5)
# False
所以这里有一个问题:如何(有效地)比较两组(无序)向量的相等性,同时考虑数值近似(例如np.allclose
)
很简单,您可以将向量的所有值
<atol
转换为0。您可以使用numpy.vectorize
,查找文档here现在您可以进行符号验证
如果我回答了你的问题,请告诉我
更新
我看到您已经在
numpy
中有了函数isclose()
,您应该使用它,而不是从头开始使用我的函数不过,我不会删除我的答复,以便保留与之有关的评论
下面是一个使用
np.lexsort
的函数:一些结果:
对于100000个随机向量,性能似乎很好:
相关问题 更多 >
编程相关推荐