-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
more more more more more more more more more test fix more more
- Loading branch information
Showing
12 changed files
with
240 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
.. automodule:: nnp.pbc | ||
.. automodule:: nnp.so3 | ||
:members: | ||
.. automodule:: nnp.md | ||
:members: | ||
.. automodule:: nnp.pbc | ||
:members: | ||
.. automodule:: nnp.vib | ||
:members: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,25 @@ | ||
Installation | ||
Introduction | ||
============ | ||
|
||
NNP is a python package that provide common tools used wo work with | ||
neural network potentials with PyTorch. Currently it includes tools | ||
to deal with periodic boundary condition, rotation in 3D space, analytical | ||
hessian, vibrational analysis, and molecular dynamics. | ||
|
||
To install NNP, just do | ||
|
||
.. code-block:: bash | ||
pip install nnp | ||
TODO: | ||
- [x] so3 | ||
- [x] test so3 | ||
- [ ] pbc | ||
- [ ] test pbc | ||
- [ ] md | ||
- [x] test md: autograd | ||
- [ ] test md: stress | ||
- [ ] vib | ||
- [ ] test vib |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
""" | ||
SO(3) Lie Group Operations | ||
========================== | ||
The module ``nnp.so3`` contains tools to rotate point clouds in 3D space. | ||
""" | ||
############################################################################### | ||
# Let's first import all the packages we will use: | ||
import torch | ||
from scipy.linalg import expm as scipy_expm | ||
from torch import Tensor | ||
|
||
|
||
############################################################################### | ||
# The following function implements rotation along an axis passing the origin. | ||
# Rotation in 3D is not as trivial as in 2D. Here we start from the equation of | ||
# motion. Let :math:`\vec{n}` be the unit vector pointing to | ||
# direction of the axis, then for an infinitesimal rotation, we have | ||
# | ||
# .. math:: | ||
# \frac{\mathrm{d}\vec{r}}{\mathrm{d}\theta} | ||
# = \vec{n} \times \vec{r} | ||
# | ||
# That is | ||
# | ||
# .. math:: | ||
# \frac{\mathrm{d}r_i}{\mathrm{d}\theta} = \epsilon_{ijk} n_j r_k | ||
# | ||
# where :math:`\epsilon_{ijk}` is the Levi-Civita symbol, let | ||
# :math:`W_{ik}=\epsilon_{ijk} n_j`, then the above equation becomes | ||
# a matrix equation: | ||
# | ||
# .. math:: | ||
# \frac{\mathrm{d}\vec{r}}{\mathrm{d}\theta} = W \cdot \vec{r} | ||
# | ||
# It is not hard to see that :math:`W` is a skew-symmetric matrix. | ||
# From the above equation and the knowledge of linear algebra, | ||
# matrix Lie algebra/group, it is not hard to see that the set of | ||
# all rotation operations along the axis :math:`\vec{n}` is a one | ||
# parameter Lie group. And the skew-symmetric matrices together | ||
# with standard matrix commutator is a Lie algebra.This Lie group | ||
# and Lie algebra is connected by the exponential map. See Wikipedia | ||
# `Exponential map (Lie theory)`_ for more detail. | ||
# | ||
# .. _Exponential map (Lie theory): | ||
# https://en.wikipedia.org/wiki/Exponential_map_(Lie_theory) | ||
# | ||
# So it is easy to tell that: | ||
# | ||
# .. math:: | ||
# \vec{r}\left(\theta\right) = \exp \left(\theta W\right) \cdot | ||
# \vec{r}\left(0\right) | ||
# | ||
# where :math:`\vec{r}\left(0\right)` is the initial coordinates, | ||
# and :math:`\vec{r}\left(\theta\right)` is the final coordinates | ||
# after rotating :math:`\theta`. | ||
# | ||
# To implement, let's first define the Levi-Civita symbol: | ||
levi_civita = torch.zeros(3, 3, 3) | ||
levi_civita[0, 1, 2] = levi_civita[1, 2, 0] = levi_civita[2, 0, 1] = 1 | ||
levi_civita[0, 2, 1] = levi_civita[2, 1, 0] = levi_civita[1, 0, 2] = -1 | ||
|
||
|
||
############################################################################### | ||
# PyTorch does not have matrix exp, let's implement it here using scipy | ||
def expm(matrix: Tensor) -> Tensor: | ||
# TODO: remove this part when pytorch support matrix_exp | ||
ndarray = matrix.detach().cpu().numpy() | ||
return torch.from_numpy(scipy_expm(ndarray)).to(matrix) | ||
|
||
|
||
############################################################################### | ||
# Now we are ready to implement the :math:`\exp \left(\theta W\right)` | ||
def rotate_along(axis: Tensor) -> Tensor: | ||
r"""Compute group elements of rotating along an axis passing origin. | ||
Arguments: | ||
axis: a vector (x, y, z) whose direction specifies the axis of the rotation, | ||
length specifies the radius to rotate, and sign specifies clockwise | ||
or anti-clockwise. | ||
Return: | ||
the rotational matrix :math:`\exp{\left(\theta W\right)}`. | ||
""" | ||
W = torch.einsum('ijk,j->ik', levi_civita.to(axis), axis) | ||
return expm(W) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
ase | ||
pytest | ||
scipy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
""" | ||
Rotation in 3D Space | ||
==================== | ||
This tutorial demonstrates how rotate a group of points in 3D space. | ||
""" | ||
############################################################################### | ||
# To begin with, we must understand that rotation is a linear transformation. | ||
# The set of all rotations forms the group SO(3). It is a Lie group that each | ||
# group element is described by an orthogonal 3x3 matrix. | ||
# | ||
# That is, if you have two points :math:`\vec{r}_1` and :math:`\vec{r}_2`, and | ||
# you want to rotate the two points along the same axis for the same number of | ||
# degrees, then there is a single orthogonal matrix :math:`R` that no matter | ||
# the value of :math:`\vec{r}_1` and :math:`\vec{r}_2`, their rotation is always | ||
# :math:`R\cdot\vec{r}_1` and :math:`R\cdot\vec{r}_2`. | ||
# | ||
# Let's import libraries first | ||
import math | ||
import torch | ||
import pytest | ||
import sys | ||
import nnp.so3 as so3 | ||
|
||
############################################################################### | ||
# Let's first take a look at a special case: rotating the three unit vectors | ||
# ``(1, 0, 0)``, ``(0, 1, 0)`` and ``(0, 0, 1)`` along the diagonal for 120 | ||
# degree, this should permute these points: | ||
rx = torch.tensor([1, 0, 0]) | ||
ry = torch.tensor([0, 1, 0]) | ||
rz = torch.tensor([0, 0, 1]) | ||
points = torch.stack([rx, ry, rz]) | ||
|
||
############################################################################### | ||
# Now let's compute the rotation matrix | ||
axis = torch.ones(3) / math.sqrt(3) * (math.pi * 2 / 3) | ||
R = so3.rotate_along(axis) | ||
|
||
############################################################################### | ||
# Note that we need to do matrix-vector product for all these unit vectors | ||
# so we need to do a transpose in order to use ``@`` operator. | ||
rotated = (R @ points.float().t()).t() | ||
print(rotated) | ||
|
||
|
||
############################################################################### | ||
# After this rotation, the three vector permutes: rx->ry, ry->rz, rz->rx. Let's | ||
# programmically check that. This check will be run by pytest later. | ||
def test_rotated_unit_vectors(): | ||
expected = torch.stack([ry, rz, rx]).float() | ||
assert torch.allclose(rotated, expected, atol=1e-5) | ||
|
||
|
||
############################################################################### | ||
# Now let's run all the tests | ||
if __name__ == '__main__': | ||
pytest.main([sys.argv[0]]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import torch | ||
import pytest | ||
import sys | ||
# import nnp.so3 as so3 | ||
import nnp.pbc as pbc | ||
# import nnp.vib as vib | ||
|
||
|
||
def test_script(): | ||
# torch.jit.script(so3.rotate_along) | ||
torch.jit.script(pbc.num_repeats) | ||
torch.jit.script(pbc.map2central) | ||
# torch.jit.script(vib.hessian) | ||
# torch.jit.script(vib.vibrational_analysis) | ||
|
||
|
||
if __name__ == '__main__': | ||
pytest.main([sys.argv[0]]) |