subtract_mic

mdtools.numpy_helper_functions.subtract_mic(x1, x2, amin=None, amax=None, **kwargs)[source]

Subtract two arrays element-wise respecting the minium image convention.

Parameters:
  • x1, x2 (array_like) – The arrays to be subtracted from each other. If x1.shape != x2.shape, they must be broadcastable to a common shape (which becomes the shape of the output).

  • amin, amax (scalar or array_like, optional) – The lower and upper bound(s) for the minimum image convention. If None, the minium and maximum value of a is taken, respectively. If amin and/or amax is an array, they must be broadcastable to a common shape and the difference amax - amin must be broadcastable to the shape of numpy.subtract(x1, x2, **kwargs). amin must be smaller than amax. If the difference between the x1 and x2 is larger than 0.5 * (amax - amin), it is wrapped back to lie within that range (see Notes section).

  • kwargs (dict, optional) – Keyword arguments to parse to numpy.subtract(). Note that the keyword argument dtype is always set to numpy.float64.

Returns:

diff (numpy.ndarray) – The element-wise difference x1 - x2.

See also

numpy.subtract()

Subtract two arrays element-wise

mdtools.numpy_helper_functions.diff_mic()

Calculate the difference between array elements respecting the minimum image convention.

mdtools.box.vdist()

Calculate the distance vectors between two position arrays

Notes

This function is just a wrapper around numpy.subtract() that respects the minimum image convention. The minimum image convention is taken into account using algorithm C4 from Deiters[1] (diff -= numpy.floor(diff / (amax - amin) + 0.5) * (amax - amin)).

In contrast to numpy.subtract(), the output array of this function always has dtype numpy.float64.

If you want to calculate distance vectors between particle positions, use mdtools.box.vdist(), because this function interprets position and box arrays correctly.

References

Examples

>>> x1 = np.array([0, 2, 4])
>>> x2 = np.array([5, 3, 1])
>>> np.subtract(x1, x2)
array([-5, -1,  3])
>>> mdt.nph.subtract_mic(x1, x2)
array([ 0., -1., -2.])
>>> mdt.nph.subtract_mic(x1, x2, amin=0, amax=[3, 2, 2])
array([ 1., -1., -1.])
>>> x1 = np.array([[0, 2, 4],
...                [5, 3, 1]])
>>> x2 = np.array([[5, 3, 1],
...                [0, 2, 4]])
>>> np.subtract(x1, x2)
array([[-5, -1,  3],
       [ 5,  1, -3]])
>>> mdt.nph.subtract_mic(x1, x2)
array([[ 0., -1., -2.],
       [ 0.,  1.,  2.]])
>>> mdt.nph.subtract_mic(x1, x2, amin=0, amax=[3, 2, 2])
array([[ 1., -1., -1.],
       [-1., -1., -1.]])
>>> mdt.nph.subtract_mic(
...     x1, x2, amin=0, amax=[[3, 2, 2], [2, 3, 4]]
... )
array([[ 1., -1., -1.],
       [-1.,  1.,  1.]])
>>> x1 = np.array([[[0, 2, 4],
...                 [5, 3, 1]],
...
...                [[4, 0, 2],
...                 [5, 3, 1]]])
>>> x2 = np.array([[[5, 3, 1],
...                 [0, 2, 4]],
...
...                [[5, 3, 1],
...                 [4, 0, 2]]])
>>> np.subtract(x1, x2)
array([[[-5, -1,  3],
        [ 5,  1, -3]],

       [[-1, -3,  1],
        [ 1,  3, -1]]])
>>> mdt.nph.subtract_mic(x1, x2)
array([[[ 0., -1., -2.],
        [ 0.,  1.,  2.]],

       [[-1.,  2.,  1.],
        [ 1., -2., -1.]]])
>>> mdt.nph.subtract_mic(x1, x2, amin=0, amax=[3, 2, 2])
array([[[ 1., -1., -1.],
        [-1., -1., -1.]],

       [[-1., -1., -1.],
        [ 1., -1., -1.]]])
>>> # The following behavior is different to `mdtools.box.vdist`!
>>> mdt.nph.subtract_mic(
...     x1, x2, amin=0, amax=[[3, 2, 2], [2, 3, 4]]
... )
array([[[ 1., -1., -1.],
        [-1.,  1.,  1.]],

       [[-1., -1., -1.],
        [-1.,  0., -1.]]])
>>> x1 = np.array([0, 2, 4])
>>> x2 = np.array([[5, 3, 1],
...                [0, 2, 4]])
>>> np.subtract(x1, x2)
array([[-5, -1,  3],
       [ 0,  0,  0]])
>>> mdt.nph.subtract_mic(x1, x2)
array([[ 0., -1., -2.],
       [ 0.,  0.,  0.]])
>>> mdt.nph.subtract_mic(x1, x2, amin=0, amax=[3, 2, 2])
array([[ 1., -1., -1.],
       [ 0.,  0.,  0.]])
>>> mdt.nph.subtract_mic(
...     x1, x2, amin=0, amax=[[3, 2, 2], [2, 3, 4]]
... )
array([[ 1., -1., -1.],
       [ 0.,  0.,  0.]])
>>> x1 = np.array([0, 2, 4])
>>> x2 = np.array([[[5, 3, 1],
...                 [0, 2, 4]],
...
...                [[5, 3, 1],
...                 [4, 0, 2]]])
>>> np.subtract(x1, x2)
array([[[-5, -1,  3],
        [ 0,  0,  0]],

       [[-5, -1,  3],
        [-4,  2,  2]]])
>>> mdt.nph.subtract_mic(x1, x2)
array([[[ 0., -1., -2.],
        [ 0.,  0.,  0.]],

       [[ 0., -1., -2.],
        [ 1.,  2.,  2.]]])
>>> mdt.nph.subtract_mic(x1, x2, amin=0, amax=[3, 2, 2])
array([[[ 1., -1., -1.],
        [ 0.,  0.,  0.]],

       [[ 1., -1., -1.],
        [-1.,  0.,  0.]]])
>>> # The following behavior is different to `mdtools.box.vdist`!
>>> mdt.nph.subtract_mic(
...     x1, x2, amin=0, amax=[[3, 2, 2], [2, 3, 4]]
... )
array([[[ 1., -1., -1.],
        [ 0.,  0.,  0.]],

       [[ 1., -1., -1.],
        [ 0., -1., -2.]]])
>>> x1 = np.array([[0, 2, 4],
...                [5, 3, 1]])
>>> x2 = np.array([[[5, 3, 1],
...                 [0, 2, 4]],
...
...                [[5, 3, 1],
...                 [4, 0, 2]]])
>>> np.subtract(x1, x2)
array([[[-5, -1,  3],
        [ 5,  1, -3]],

       [[-5, -1,  3],
        [ 1,  3, -1]]])
>>> mdt.nph.subtract_mic(x1, x2)
array([[[ 0., -1., -2.],
        [ 0.,  1.,  2.]],

       [[ 0., -1., -2.],
        [ 1., -2., -1.]]])
>>> mdt.nph.subtract_mic(x1, x2, amin=0, amax=[3, 2, 2])
array([[[ 1., -1., -1.],
        [-1., -1., -1.]],

       [[ 1., -1., -1.],
        [ 1., -1., -1.]]])
>>> # The following behavior is different to `mdtools.box.vdist`!
>>> mdt.nph.subtract_mic(
...     x1, x2, amin=0, amax=[[3, 2, 2], [2, 3, 4]]
... )
array([[[ 1., -1., -1.],
        [-1.,  1.,  1.]],

       [[ 1., -1., -1.],
        [-1.,  0., -1.]]])