Skip to main content

Quaternion data structure based on MindSpore Framework

Project description

mindspore-quaternion--基于MindSpore深度学习框架的四元数数据结构

四元数在自动化等领域有非常广泛的应用,其必要性在于解决了使用欧拉角旋转的过程中有可能出现的欧拉角死锁问题。 关于更多的四元数的原理和计算方法,可以阅读本readme末尾的参考博客。

安装与更新

本软件支持pip一键安装与更新(这里推荐使用pypi原始的资源,国内的一些镜像源同步的并不是很及时):

$ python3 -m pip install mindspore-quaternion --upgrade -i https://pypi.Python.org/simple/

也可以使用源码进行安装:

$ git clone https://gitee.com/dechin/mindspore-quaternion.git
$ cd mindspore-quaternion
$ python3 setup.py install

定义四元数

详细的代码可以参考该链接下的内容,这里我们只作为简单介绍。首先我们需要import一些必要的软件包:

from quaternion import Quaternion
import numpy as np
import mindspore as ms
from mindspore import Tensor

接下来我们可以看一下各个不同shape的四元数定义。首先是定义一个常数的四元数,其实也就是[s, 0, 0, 0]这样的一个四元数:

element = Tensor([0.], ms.float32)
element_quaternion = Quaternion(element)
print ('The type of element is: {}'.format(type(element_quaternion)))
print ('The value of element is: {}'.format(element_quaternion.to_tensor()))

上述代码的执行结果为:

The type of element is: <class 'quaternion.Quaternion'>
The value of element is: [[0. 0. 0. 0.]]

还可以定义三维矢量所对应的四元数,是如同[0, vx, vy, vz]这样的形式:

vector = Tensor(np.arange(3), ms.float32)
vector_quaternion = Quaternion(vector)
print('The type of vector is: {}'.format(type(vector_quaternion)))
print('The value of vector is: {}'.format(vector_quaternion.to_tensor()))

上述代码的执行结果为:

The type of vector is: <class 'quaternion.Quaternion'>
The value of vector is: [[0. 0. 1. 2.]]

当然,如果一开始我们就定义好了一个完整的四维的四元数[s, vx, vy, vz],那么也是可以用来直接构造一个四元数对象的:

quater = Tensor(np.arange(4), ms.float32)
quater_quaternion = Quaternion(quater)
print('The type of quater is: {}'.format(type(quater_quaternion)))
print('The value of quater is: {}'.format(quater_quaternion.to_tensor()))

上述代码的执行结果为:

The type of quater is: <class 'quaternion.Quaternion'>
The value of quater is: [[0. 1. 2. 3.]]

这里必须要提一个最重要的point,那就是当我们使用一个深度学习框架去实现四元数这样的数据结构的时候,我们当然更多的是考虑到GPU加速在多batch的四元数计算 下的性能优势。所以这里我们也可以去定义一个更高维度的,多batch的四元数:

batch_quater = Tensor(np.arange(16).reshape((4, 4)), ms.float32)
batch_quater_quaternion = Quaternion(batch_quater)
print('The type of batch_quater is: {}'.format(type(batch_quater_quaternion)))
print('The value of batch_quater is: {}'.format(batch_quater_quaternion.to_tensor()))

上述代码的执行结果为:

The type of batch_quater is: <class 'quaternion.Quaternion'>
The value of batch_quater is: [[ 0.  1.  2.  3.]
                               [ 4.  5.  6.  7.]
                               [ 8.  9. 10. 11.]
                               [12. 13. 14. 15.]]

四元数运算

在mindspore-quaternion中我们支持了一些四元数的基本运算,这里我们仅展示一些最常用的四元数基本运算:

from quaternion import Quaternion
import mindspore as ms
from mindspore import Tensor
q1 = Tensor([1, 2, 3, 4], ms.float32)
q1_quaternion = Quaternion(q1)
q2 = Tensor([3, 1, 0, 5], ms.float32)
q2_quaternion = Quaternion(q2)
print ('The sum of q1 and q2 is: {}'.format(q1_quaternion + q2_quaternion))
print ('The product of q1 and q2 is: {}'.format(q1_quaternion * q2_quaternion))

上述代码的运行结果如下:

The sum of q1 and q2 is: [[4. 3. 3. 9.]]
The product of q1 and q2 is: [[-19.  22.   3.  14.]]

除了普通的四元数运算之外,mindspore-quaternion还可用于计算四元数与向量的哈密顿积:

vector = Tensor([1, 2, 3], ms.float32)
hamiltonian = Tensor([0.5, 0.5, 0.5, 0.5], ms.float32)
hamiltonian_quaternion = Quaternion(hamiltonian)
print ('The Hamiltonian product of hamiltonian | vector > is: {}'.format(hamiltonian_quaternion | vector))

上述代码的运行结果如下:

The Hamiltonian product of hamiltonian | vector > is: [[3. 1. 2.]]

同时我们也可以使用逆变换:

vector_transform = hamiltonian_quaternion.conjugate() | (hamiltonian_quaternion | vector)
print('The Hamiltonian product of hamiltonian^(-1) | hamiltonian | vector > is: {}'.format(vector_transform))

得到的结果如下所示:

The Hamiltonian product of hamiltonian^(-1) | hamiltonian | vector > is: [[1. 2. 3.]]

可用发现,我们经过一重四元数的变换和一重对应的逆变换之后,又得到了跟原来一样的向量。除此之外,我们最经常使用四元数的场景, 是对空间向量之间进行一个变换,比如我们可以获取两个向量之间的旋转四元数。首先我们需要定义一些初始向量和目标向量:

src_vector = Tensor([1, 0, 0], ms.float32)
src_vector_quaternion = Quaternion(src_vector)
dst_vector1 = Tensor([0, 0, 1], ms.float32)
dst_vector1_quaternion = Quaternion(dst_vector1)
dst_vector2 = Tensor([np.sqrt(3) / 3, np.sqrt(3) / 3, np.sqrt(3) / 3], ms.float32)
dst_vector2_quaternion = Quaternion(dst_vector2)

然后可以研究其中从初始向量到目标向量的变换四元数,再使用变换四元数作用到初始向量上:

transform_quaternion = src_vector_quaternion >> dst_vector1_quaternion
print ('The quaternion transform from vector to target_vector is: {}'.format(transform_quaternion))
print ('The transform result is: {}'.format(transform_quaternion | src_vector))
transform_quaternion = src_vector_quaternion >> dst_vector2_quaternion
print('The quaternion transform from vector to target_vector is: {}'.format(transform_quaternion))
print('The transform result is: {}'.format(transform_quaternion | src_vector))

运行的结果如下所示:

The quaternion transform from vector to target_vector is: [[ 0.70710677  0.         -0.7071068   0.        ]]
The transform result is: [[0.         0.         0.99999994]]
The quaternion transform from vector to target_vector is: [[ 0.88807386  0.         -0.32505763  0.32505763]]
The transform result is: [[0.57735026 0.5773504  0.5773504 ]]

以上就是一些常用的四元数操作,更多操作可以参考examples/路径下的示例。

函数式运算

为了更好的支持MindSpore框架中对计算图的编译,这里如果我们使用MindSpore框架去构建一个Quaternion的对象,会引发Jit-FallBack 的报错,因此需要支持一些函数式的操作——保留Tensor的数据结构,仅引入一些四元数的操作。下述代码是一些比较简单的案例:

from quaternion.functions import quaternion_multiply, quaternion_inverse, hamiltonian_product, quaternion_diff
import mindspore as ms
from mindspore import Tensor
import numpy as np

hamiltonian = Tensor([0.5, 0.5, 0.5, 0.5], ms.float32)
q1 = Tensor([1, 2, 3, 4], ms.float32)
q2 = Tensor([3, 1, 0, 5], ms.float32)
vector = Tensor([1, 2, 3], ms.float32)
src_vector = Tensor([1, 0, 0], ms.float32)
dst_vector1 = Tensor([0, 0, 1], ms.float32)
dst_vector2 = Tensor([np.sqrt(3) / 3, np.sqrt(3) / 3, np.sqrt(3) / 3], ms.float32)

assert np.allclose(quaternion_inverse(hamiltonian).asnumpy(), np.array([[0.5, -0.5, -0.5, -0.5]], np.float32))
assert np.allclose(quaternion_multiply(q1, q2).asnumpy(), np.array([[-19., 22., 3., 14.]], np.float32))
assert np.allclose(quaternion_multiply(q2, q1).asnumpy(), np.array([[-19., -8., 15., 20.]], np.float32))
assert np.allclose(hamiltonian_product(hamiltonian, vector).asnumpy(), np.array([[0., 3., 1., 2.]], np.float32))
assert np.allclose(quaternion_diff(src_vector, dst_vector1).asnumpy(),
                       np.array([[0.70710677,  0.,         -0.7071068,   0.]], np.float32))
assert np.allclose(quaternion_diff(src_vector, dst_vector2).asnumpy(),
                       np.array([[0.88807386,  0.,         -0.32505763,  0.32505763]], np.float32))

如果运行正确,上述代码可以正常执行通过,否则会报错。

Numpy函数式运算

为了方便本地环境中没有MindSpore的用户使用,mindspore-quaternion也提供了numpy版本的四元数运算支持,使用方法与上述 函数式运算中的内容基本一致,相关接口为:

from quaternion.np_functions import inverse, multiply, hamiltonian, transform

并且,基于numpy版本的四元数运算,用户可以对蛋白质的pdb文件进行旋转平移变换的操作,例如:

import numpy as np
from quaternion.rotate_pdb import rotate

if __name__ == '__main__':
    pdb_in = 'test_in.pdb'
    pdb_out = 'test_out.pdb'
    # 新原点
    o1 = np.array([42.882, 32.025, 38.245], np.float32)
    # 新X轴
    x1 = np.array([38.326, 24.174, 48.484], np.float32)
    # 新XY平面上的一个点,但不能在OX方向上
    m1 = np.array([53.187, 51.701, 33.301], np.float32)
    rotate(pdb_in, pdb_out, o1, x1, m1)

这样,就可以把经过旋转和平移变换之后的坐标保存到指定的新的pdb文件中。

代码贡献

欢迎外部协作者提PR过来,有如下几点PR要求:

  1. 先提Issue再提交PR,说清楚特性;
  2. 贡献代码部分的flake8需要清空。

参考博客

  1. https://www.cnblogs.com/dechinphy/p/quaternion-calc.html

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mindspore-quaternion-0.7.1.tar.gz (10.7 kB view details)

Uploaded Source

Built Distribution

mindspore_quaternion-0.7.1-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

Details for the file mindspore-quaternion-0.7.1.tar.gz.

File metadata

  • Download URL: mindspore-quaternion-0.7.1.tar.gz
  • Upload date:
  • Size: 10.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.6.0 importlib_metadata/4.11.3 pkginfo/1.8.3 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.8.5

File hashes

Hashes for mindspore-quaternion-0.7.1.tar.gz
Algorithm Hash digest
SHA256 b276e40f766d91c6588dd84449dfa3242e388e93200a33a4230f8b4676325ae2
MD5 ebaaa83efb60477118f6ccd8918e69ec
BLAKE2b-256 81748ba0baa9cac5f02ea27744edb0f74406cd2c60689cb782e277de5246a1b8

See more details on using hashes here.

File details

Details for the file mindspore_quaternion-0.7.1-py3-none-any.whl.

File metadata

  • Download URL: mindspore_quaternion-0.7.1-py3-none-any.whl
  • Upload date:
  • Size: 13.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.6.0 importlib_metadata/4.11.3 pkginfo/1.8.3 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.8.5

File hashes

Hashes for mindspore_quaternion-0.7.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e1bc572941df885dca7fd420c42a57e3e68f3b2da6fd05ba0f9c27a0deffcbf2
MD5 4cb26d0f52903ce9ba1631178260ca1d
BLAKE2b-256 0d9bf60bc6771253a8aa7bfa51e2f9c9f1ce3b7f91b51efa0783d3040b05ffd1

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page