【问题标题】:Rotating high dimensional orthogonal vectors in python在python中旋转高维正交向量
【发布时间】:2020-11-15 06:04:42
【问题描述】:

假设我有维度为n 的正交向量。我有两个问题:

  1. 如何使用现有的包(numpy、scipy、pytorch 等)在 python 中创建/初始化 n 个这样的正交向量?理想情况下,考虑到约束,这些基向量应尽可能随机,即尽可能避免使用 1,0,-1 等值。
  2. 如何将它们旋转一个角度alpha 以使它们在高维空间中保持正交?同样,我想在 python 中执行此操作,最好使用某些包中的现有实现。

【问题讨论】:

  • 只需创建一个 n 维旋转矩阵并将基向量与它相乘。这到底有什么不清楚的地方?
  • 关于初始化的问题非常广泛。构造正交矩阵的方法有很多,这取决于您的需要。目标是什么?
  • @NilsWerner 我熟悉n=2n=3 的旋转矩阵。我在问如何为一般n 执行此操作。
  • @bnaecker 我编辑了问题以回答您的评论

标签: python numpy scipy rotational-matrices orthogonal


【解决方案1】:

您可以对随机矩阵进行 QR 分解,并将 R 分量设置为零。这将产生一个随机正交矩阵。

改变 Q 分量中的 Givens 角度之一,您会得到随机旋转。

【讨论】:

  • 感谢您的回答。你能解释一下“改变 Q 分量中的一个吉文斯角”是什么意思吗?另外,我实际上不需要随机旋转,而是需要角度alpha 的旋转。这可行吗?
【解决方案2】:

我已经回答了你的第一个问题,并且对如何处理第二个问题有一些想法。

1.

import numpy as np

#let's say we're working in 5-D space
n = 5

#set of orthogonal basis vectors
basis_vectors = []

for _ in range(n):
    vector = np.random.randn(n)
    for basis_vector in basis_vectors:
        vector -= basis_vector.dot(vector) * vector
    #uncomment following to make basis orthonormal
    #vector /= np.linalg.norm(rotation_axis)
    basis_vectors.append(vector)

for a_i in range(n):
    for b_i (a_i + 1, n):
        assert np.allclose(basis_vectors[a_i].dot(basis_vectors[b_i]), 0)

因为您想以相同的方式旋转两个向量,所以必须有一种方法来保存每次旋转执行方式的信息(例如旋转矩阵、旋转四元数)。

3D 旋转矩阵的现有实现包括 Scipy 函数 scipy.spatial.transform.Rotation.from_rotvec 和 Python 的四元数模块(请参阅 henneray's answer),但这些仅适用于 3D 向量。除非我忽略了什么,否则有必要从头开始实施 ND 旋转。

以下是我将采取的步骤的概要:

  • 找到 2D 平面的 2 个线性独立的 ND 基向量,要在其中旋转这两个向量。 (您要旋转的向量 ab 不一定在这个平面上)
  • 找出与前 2 个向量线性无关的剩余 (N-2)D 个基向量。组合的 N 个基向量应该跨越 ND 空间。
  • 将要旋转的两个 ND 正交向量中的每一个分解为两个向量之和:1) 向量在您构建的 2D 平面上的投影和 2) 向量的“剩余部分”不t 落在二维平面上。暂时把这个“剩余部分”放在一边。
  • 对投影的 N 维向量执行基更改,以便它们可以表示为 2D 向量和 Nx2 矩阵的乘积,该矩阵的列设置为计算的每个相应的基向量。请记住,二维矢量现在位于修改后的坐标空间中,而不是原始坐标空间中。
  • 在第一步中确定的 2D 平面内构造与所需旋转相对应的 2D 旋转矩阵。对二维向量执行旋转变换。
  • 通过将 乘以 Nx2 矩阵,将旋转后的 2D 向量转换回主坐标系中的 ND 向量。
  • 将之前留出的“剩余部分”添加回映射的 ND 向量。
  • 生成的两个向量已在特定 2D 平面上旋转任意角度,但仍保持正交性。

我希望这些想法对您有所帮助。保重。

【讨论】:

  • 感谢您的回答!我认为我最初的问题并不清楚,但我需要一个正交(可能是正交基),所以这将是一个维度为 n 的方阵。我发现了一个scipy函数可以做1,虽然看起来2不容易。
  • @sanjas 啊,我明白了。我刚刚更新了答案,以确保提供 n 个基向量的一致性。祝你好运!
【解决方案3】:

我发现了一个scipy函数可以做1,ortho_group,还在想2。

>>> from scipy.stats import ortho_group
>>> m = ortho_group.rvs(dim=4)
>>> m
array([[-0.25952499,  0.435163  ,  0.04561972,  0.86092902],
       [-0.44123728, -0.38814758, -0.80217271,  0.10568846],
       [ 0.16909943, -0.80707234,  0.35548632,  0.44007851],
       [-0.8422362 , -0.0927839 ,  0.47756387, -0.23229737]])
>>> m.dot(m.T)
array([[ 1.00000000e+00, -1.68203864e-16,  1.75471554e-16,
         9.74154717e-17],
       [-1.68203864e-16,  1.00000000e+00, -1.18506045e-16,
        -1.81879209e-16],
       [ 1.75471554e-16, -1.18506045e-16,  1.00000000e+00,
         1.16692720e-16],
       [ 9.74154717e-17, -1.81879209e-16,  1.16692720e-16,
         1.00000000e+00]])

【讨论】:

    猜你喜欢
    • 2018-06-24
    • 2021-11-02
    • 1970-01-01
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 1970-01-01
    相关资源
    最近更新 更多