Skip to content

Numerics

cartesian_product(*arrays)

Efficiently calculate the Cartesian product of the provided vectors A x B x C ... etc. This will maintain order in loops from the right most array.

Parameters:

Name Type Description Default
*arrays array_like

1D arrays to use for the Cartesian product

()

Returns:

Type Description
ndarray

np.ndarray: The Cartesian product of the provided vectors.

Source code in chmpy/util/num.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def cartesian_product(*arrays) -> np.ndarray:
    """
    Efficiently calculate the Cartesian product of the
    provided vectors A x B x C ... etc. This will maintain
    order in loops from the right most array.

    Args:
        *arrays (array_like): 1D arrays to use for the Cartesian product

    Returns:
        np.ndarray: The Cartesian product of the provided vectors.
    """
    arrays = [np.asarray(a) for a in arrays]
    la = len(arrays)
    dtype = np.result_type(*arrays)
    arr = np.empty([len(a) for a in arrays] + [la], dtype=dtype)
    for i, a in enumerate(np.ix_(*arrays)):
        arr[..., i] = a
    return arr.reshape(-1, la)

cartesian_to_spherical(xyz, dtype=<class 'numpy.float64'>)

Given an N by 3 array of (x, y, z) spherical coordinates return an N by 3 array of Cartesian(r, theta, phi) coordinates.

Uses the following convention::

x = r sin(theta) cos(phi)
y = r sin(theta) sin(phi)
z = r cos(theta)

Parameters:

Name Type Description Default
rtp array_like

(N,3) array of of r, theta, phi coordinates in the above spherical coordinate system.

required
dtype

numpy datatype or string

<class 'numpy.float64'>

Returns:

Type Description
ndarray

np.ndarray: (N,3) array of x,y,z Cartesian coordinates

Source code in chmpy/util/num.py
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
def cartesian_to_spherical(xyz: np.ndarray, dtype=np.float64) -> np.ndarray:
    """
    Given an N by 3 array of (x, y, z) spherical coordinates
    return an N by 3 array of Cartesian(r, theta, phi) coordinates.

    Uses the following convention::

        x = r sin(theta) cos(phi)
        y = r sin(theta) sin(phi)
        z = r cos(theta)

    Args:
        rtp (array_like): (N,3) array of of r, theta, phi coordinates
            in the above spherical coordinate system.
        dtype: numpy datatype or string

    Returns:
        np.ndarray: (N,3) array of x,y,z Cartesian coordinates
    """
    rtp = np.empty(xyz.shape, dtype=dtype)
    rtp[:, 0] = np.sqrt(xyz[:, 0] * xyz[:, 0] + xyz[:, 1] * xyz[:, 1] + xyz[:, 2] * xyz[:, 2]);
    rtp[:, 1] = np.fmod(np.arctan2(xyz[:, 1], xyz[:, 0]) + 4 * np.pi, 2 * np.pi)
    rtp[:, 2] = np.arccos(xyz[:, 2] / rtp[:, 0])
    return rtp

is_perfect_square(value)

Check if a number is perfect square.

Parameters:

Name Type Description Default
value Number

the number in question

required

Returns:

Type Description
bool

bool: True if the number is a perfect square, otherwise False

Source code in chmpy/util/num.py
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
def is_perfect_square(value: Number) -> bool:
    """
    Check if a number is perfect square.

    Args:
        value (Number): the number in question

    Returns:
        bool: `True` if the number is a perfect square, otherwise `False`
    """
    import math

    root = math.sqrt(value)
    if int(root + 0.5) ** 2 == value:
        return True
    else:
        return False

kabsch_rotation_matrix(A, B)

Calculate the optimal rotation matrix R to rotate A onto B, minimising root-mean-square deviation so that this may be then calculated.

See: https://en.wikipedia.org/wiki/Kabsch_algorithm

Reference:

Kabsch, W. Acta Cryst. A, 32, 922-923, (1976)
DOI: http://dx.doi.org/10.1107/S0567739476001873

Parameters:

Name Type Description Default
A np.ndarray

(N,D) matrix where N is the number of vectors and D is the dimension of each vector

required
B np.ndarray

(N,D) matrix where N is the number of vectors and D is the dimension of each vector

required

Returns:

Type Description

np.ndarray (D,D) rotation matrix where D is the dimension of each vector

Source code in chmpy/util/num.py
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
def kabsch_rotation_matrix(A, B):
    """
    Calculate the optimal rotation matrix `R` to rotate
    `A` onto `B`, minimising root-mean-square deviation so that
    this may be then calculated.

    See: https://en.wikipedia.org/wiki/Kabsch_algorithm

    Reference:
    ```
    Kabsch, W. Acta Cryst. A, 32, 922-923, (1976)
    DOI: http://dx.doi.org/10.1107/S0567739476001873
    ```
    Args:
        A (np.ndarray): (N,D) matrix where N is the number of vectors and D
            is the dimension of each vector
        B (np.ndarray): (N,D) matrix where N is the number of
            vectors and D is the dimension of each vector
    Returns:
        np.ndarray (D,D) rotation matrix where D is the dimension of each vector
    """

    # Calculate the covariance matrix
    cov = np.dot(np.transpose(A), B)

    # Use singular value decomposition to calculate
    # the optimal rotation matrix
    v, s, w = np.linalg.svd(cov)

    # check the determinant to ensure a right-handed
    # coordinate system
    if (np.linalg.det(v) * np.linalg.det(w)) < 0.0:
        s[-1] = -s[-1]
        v[:, -1] = -v[:, -1]
    R = np.dot(v, w)
    return R

reorient_points(A, B, method='kabsch')

Rotate the points in A onto B

Parameters:

Name Type Description Default
A np.ndarray

(N,D) matrix where N is the number of vectors and D is the dimension of each vector

required
B np.ndarray

(N,D) matrix where N is the number of vectors and D is the dimension of each vector

required

Returns:

Type Description
np.ndarray

(N,D) matrix where N is the number of vectors and D is the dimension of each vector, now rotated to align with B

Source code in chmpy/util/num.py
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
def reorient_points(A, B, method="kabsch"):
    """
    Rotate the points in `A` onto `B`

    Args:
        A (np.ndarray): (N,D) matrix where N is the number of vectors and D
            is the dimension of each vector
        B (np.ndarray): (N,D) matrix where N is the number of
            vectors and D is the dimension of each vector

    Returns:
        np.ndarray: (N,D) matrix where N is the number of vectors and D
            is the dimension of each vector, now rotated to align with B
    """
    if method != "kabsch":
        raise NotImplementedError("Only kabsch algorithm is currently implemented")
    R = kabsch_rotation_matrix(A, B)
    A = np.dot(A, R)
    return A

rmsd_points(A, B, reorient='kabsch')

Rotate the points in A onto B and calculate their RMSD

Parameters:

Name Type Description Default
A np.ndarray

(N,D) matrix where N is the number of vectors and D is the dimension of each vector

required
B np.ndarray

(N,D) matrix where N is the number of vectors and D is the dimension of each vector

required

Returns:

Type Description
float

root mean squared deviation

Source code in chmpy/util/num.py
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
def rmsd_points(A, B, reorient="kabsch"):
    """
    Rotate the points in `A` onto `B` and calculate
    their RMSD

    Args:
        A (np.ndarray): (N,D) matrix where N is the number of vectors and D
            is the dimension of each vector
        B (np.ndarray): (N,D) matrix where N is the number of
            vectors and D is the dimension of each vector

    Returns:
        float: root mean squared deviation
    """
    if reorient:
        A = reorient_points(A, B, method=reorient)
    diff = B - A
    return np.sqrt(np.vdot(diff, diff) / diff.shape[0])

spherical_to_cartesian(rtp, dtype=<class 'numpy.float64'>)

Given an N by 3 array of (r, theta, phi) spherical coordinates return an N by 3 array of Cartesian(x, y, z) coordinates.

Uses the following convention::

x = r sin(theta) cos(phi)
y = r sin(theta) sin(phi)
z = r cos(theta)

Parameters:

Name Type Description Default
rtp ndarray

(N,3) array of of r, theta, phi coordinates in the above spherical coordinate system.

required
dtype

numpy datatype or string

<class 'numpy.float64'>

Returns:

Type Description
ndarray

np.ndarray: (N,3) array of x,y,z Cartesian coordinates

Source code in chmpy/util/num.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
def spherical_to_cartesian(rtp: np.ndarray, dtype=np.float64) -> np.ndarray:
    """
    Given an N by 3 array of (r, theta, phi) spherical coordinates
    return an N by 3 array of Cartesian(x, y, z) coordinates.

    Uses the following convention::

        x = r sin(theta) cos(phi)
        y = r sin(theta) sin(phi)
        z = r cos(theta)

    Args:
        rtp (array_like): (N,3) array of of r, theta, phi coordinates
            in the above spherical coordinate system.
        dtype: numpy datatype or string

    Returns:
        np.ndarray: (N,3) array of x,y,z Cartesian coordinates
    """
    xyz = np.empty(rtp.shape, dtype=dtype)

    xyz[:, 0] = rtp[:, 0] * np.sin(rtp[:, 1]) * np.cos(rtp[:, 2])
    xyz[:, 1] = rtp[:, 0] * np.sin(rtp[:, 1]) * np.sin(rtp[:, 2])
    xyz[:, 2] = rtp[:, 0] * np.cos(rtp[:, 1])

    return xyz