Source code for SOAPify.distances

"""This submodules contaisn a collection of SOAP distances"""
import numpy as np
import numpy.linalg as la
import scipy


[docs]def simpleKernelSoap(x: np.ndarray, y: np.ndarray) -> float: """a simpler SOAP Kernel than :func:`KernelSoap`, power is always 1 Args: x (np.ndarray): a SOAP fingerprint y (np.ndarray): a SOAP fingerprint Returns: float: kernel value """ return 1 - scipy.spatial.distance.cosine(x, y)
# return np.dot(x, y) / (la.norm(x) * la.norm(y))
[docs]def simpleSOAPdistance(x: np.ndarray, y: np.ndarray) -> float: """a simpler SOAP distance than :func:`SOAPdistance`, power is always 1 Args: x (np.ndarray): a SOAP fingerprint y (np.ndarray): a SOAP fingerprint Returns: float: the distance between the two fingerprints, between :math:`0` and :math:`2` """ try: return np.sqrt(2.0 - 2.0 * simpleKernelSoap(x, y)) except FloatingPointError: return 0.0
[docs]def kernelSoap(x: np.ndarray, y: np.ndarray, n: int) -> float: """The SOAP Kernel with a variable power Args: x (np.ndarray): a SOAP fingerprint y (np.ndarray): a SOAP fingerprint n (int): the power to elevate the result of the kernel Returns: float: kernel value """ # return (1 - scipy.spatial.distance.cosine(x, y)) ** n return (np.dot(x, y) / (la.norm(x) * la.norm(y))) ** n
[docs]def SOAPdistance(x: np.ndarray, y: np.ndarray, n: int = 1) -> float: """the SOAP distance between two SOAP fingerprints Args: x (np.ndarray): a SOAP fingerprint y (np.ndarray): a SOAP fingerprint n (int): the power to elevate the result of the kernel Returns: float: the distance between the two fingerprints, between :math:`0` and :math:`2` """ try: return np.sqrt(2.0 - 2.0 * kernelSoap(x, y, n)) except FloatingPointError: return 0.0
[docs]def SOAPdistanceNormalized(x: np.ndarray, y: np.ndarray) -> float: """the SOAP distance between two normalized SOAP fingerprints The pre-normalized vectors should net some performace over the classic kernel Args: x (np.ndarray): a normalized SOAP fingerprint y (np.ndarray): a normalized SOAP fingerprint Returns: float: the distance between the two fingerprints, between :math:`0` and :math:`2` """ return np.sqrt(np.abs(2.0 - 2.0 * x.dot(y)))