Source code for openff.recharge.utilities.geometry
"""Geometry centric functions such as computing pairwise distances"""
from typing import TYPE_CHECKING, overload
import numpy
from openff.recharge.utilities.tensors import inverse_cdist, pairwise_differences
if TYPE_CHECKING:
import torch
@overload
def compute_inverse_distance_matrix(
points_a: numpy.ndarray, points_b: numpy.ndarray
) -> numpy.ndarray: ...
@overload
def compute_inverse_distance_matrix(
points_a: "torch.Tensor", points_b: "torch.Tensor"
) -> "torch.Tensor": ...
[docs]def compute_inverse_distance_matrix(points_a, points_b):
"""Computes a matrix of the inverse distances between all of the points
in ``points_a`` and all of the points in ``points_b``.
Notes
-----
This function is not currently vectorised but may be in the future.
Parameters
----------
points_a
The first list of points with shape=(n_points_a, n_dim).
points_b
The second list of points with shape=(n_points_b, n_dim).
Returns
-------
The squared distance matrix where ``d_ij = 1.0 / sqrt((a_i - b_i) ^ 2)``
with shape=(n_points_a, n_points_b).
"""
assert type(points_a) is type(points_b)
return inverse_cdist(points_a, points_b)
@overload
def compute_vector_field(
points_a: numpy.ndarray, points_b: numpy.ndarray
) -> numpy.ndarray: ...
@overload
def compute_vector_field(
points_a: "torch.Tensor", points_b: "torch.Tensor"
) -> "torch.Tensor": ...
[docs]def compute_vector_field(points_a, points_b):
"""Computes a tensor containing the vectors which point from all of the points in
``points_a`` to all of the points in ``points_b`` and have magnitudes equal to
the inverse squared distance between the points.
Notes
-----
This function is not currently vectorised but may be in the future.
Parameters
----------
points_a
The first list of points with shape=(n_points_a, n_dim).
points_b
The second list of points with shape=(n_points_b, n_dim).
Returns
-------
The vector field tensor with shape=(n_points_b, n_dim, n_points_a) and where
``tensor[i, :, j] = (b_i - a_j) / ||b_i - a_j|| ^ 3)``
"""
directions = pairwise_differences(points_a, points_b)
inverse_distances = inverse_cdist(points_a, points_b)
inverse_distances_3 = inverse_distances * inverse_distances * inverse_distances
if isinstance(inverse_distances_3, numpy.ndarray):
return directions * inverse_distances_3.T[:, None, :]
else:
return directions * inverse_distances_3.transpose(0, 1)[:, None, :]