【发布时间】:2023-04-08 15:20:01
【问题描述】:
我试图让我的问题更清楚。在这最后还能找到老题外话。
问题:我有一个n x 3 矩阵A (np.ndarray) 的n 点在三个维度上。如果这些点作为无序集是静止的,则我们说这些点相对于变换R(3 x 3 矩阵)是对称的。
这意味着 A 和 A @ R.T 相差 1. 最多一个排列和 2. 校正排列后,两个矩阵可能会因数值容差参数而有所不同:np.allclose(A, permuted(A @ R.T)) == True(我不知道@987654329事先@,这肯定取决于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 是一个矩阵,其行是点位置)并尝试为@ 的每个初始行匹配一个变换向量987654335@,它似乎随着列数呈二次方增长。
另一种可能性是对向量进行预排序(例如,通过它们的坐标值):
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)?
【问题讨论】:
-
请准确一点,解释一下
isclose()是什么意思,并举例说明。 -
@CatalinaChircu 我编辑以更好地表达我的意思。我对
isclose产生了一些混淆,我的意思是allclose(我将两个不同的ndarrays 作为单个实体进行比较)。
标签: python numpy vector comparison numpy-ndarray