回答此问题可获得 20 贡献值,回答如果被采纳可获得 50 分。
<p>我试图把我的问题弄清楚。这篇文章的结尾仍然可以找到老的离题</p>
<p><strong>问题</strong>:我有一个{<cd1>}由3个{<cd2>}(<code>np.ndarray</code>)的{<cd1>}点组成的三维矩阵。如果这些点作为无序集是平稳的,我们说它们相对于变换<code>R</code>(3×3矩阵)是对称的</p>
<p>这意味着<code>A</code>和<code>A @ R.T</code>相差1。最多一个排列和两个。在对排列进行校正后,两个矩阵可能会有一个数值公差参数不同:<code>np.allclose(A, permuted(A @ R.T)) == True</code>(我事先不知道<code>permuted()</code>,这肯定取决于<code>R</code>)</p>
<p><strong>问题</strong>:如何创建以下函数:</p>
<pre class="lang-py prettyprint-override"><code>def is_symmetric(A, R, atol=1e-5) -> bool:
# checks symmetry as defined above, considering both numerical noise
# and permutation of vectors.
</code></pre>
<p>(关于可能的方法以及我的疑问和尝试的一些讨论见下文。)</p>
<hr/>
<p><strong>旧题外话</strong>:</p>
<p>我想检查以向量表示的点集合中的对称性。这意味着检查这些点在空间中应用矩阵变换时是否不变,例如旋转或平面镜像</p>
<pre class="lang-py prettyprint-override"><code>import numpy as np
R = np.array([[0, -1, 0], # 90° rotation around z as an example
[1, 0, 0],
[0, 0, 1]])
</code></pre>
<p>关键是,<strong>我接受向量的排列:<strong>:只要某个初始位置被转换到另一个先前存在的位置,我就没事。这意味着检查从一个向量到另一个向量的变换对</p>
<p><em>天真的解决方案</em>将在<code>A @ R.T</code>的行上循环(其中<code>A</code>是一个矩阵,其行是点位置),并尝试为<code>A</code>的每个初始行匹配一个变换向量,该向量似乎随列数的平方增长</p>
<p>另一种可能是<em>对向量</em>进行预排序(例如,通过它们的坐标值):</p>
<pre class="lang-py prettyprint-override"><code>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
</code></pre>
<p>(这种方法有两种排序,所以O(n ln(n))?)
第三个想法是比较从原始向量和旋转向量创建的集合。我有一种直觉,这就像比较排序向量一样好</p>
<p>但还有一件事:如何处理近似比较?我想接受两个向量<code>v</code>和<code>w</code>相等,如果是<code>np.allclose(v, w) == True</code>或等效(即<code>abs(v - w) < eps</code>或类似):</p>
<pre class="lang-py prettyprint-override"><code>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
</code></pre>
<p><strong>所以这里有一个问题</strong>:如何(有效地)比较两组(无序)向量的相等性,同时考虑数值近似(例如<code>np.allclose</code>)</p>