Compare two molecules for numerical equality.

    Args:
        a (Cartesian):
        b (Cartesian):
        align (bool): a and b are
            prealigned along their principal axes of inertia and moved to their
            barycenters before comparing.
        rtol (float): Relative tolerance for the numerical equality comparison
            look into :func:`numpy.isclose` for further explanation.
        atol (float): Relative tolerance for the numerical equality comparison
            look into :func:`numpy.isclose` for further explanation.

    Returns:
        :class:`numpy.ndarray`: Boolean array.

def isclose(a, b, align=False, rtol=1.e-5, atol=1.e-8):
    """Compare two molecules for numerical equality.

    Args:
        a (Cartesian):
        b (Cartesian):
        align (bool): a and b are
            prealigned along their principal axes of inertia and moved to their
            barycenters before comparing.
        rtol (float): Relative tolerance for the numerical equality comparison
            look into :func:`numpy.isclose` for further explanation.
        atol (float): Relative tolerance for the numerical equality comparison
            look into :func:`numpy.isclose` for further explanation.

    Returns:
        :class:`numpy.ndarray`: Boolean array.
    """
    coords = ['x', 'y', 'z']
    if not (set(a.index) == set(b.index)
            and np.alltrue(a.loc[:, 'atom'] == b.loc[a.index, 'atom'])):
        message = 'Can only compare molecules with the same atoms and labels'
        raise ValueError(message)

    if align:
        a = a.get_inertia()['transformed_Cartesian']
        b = b.get_inertia()['transformed_Cartesian']
    A, B = a.loc[:, coords], b.loc[a.index, coords]
    out = a._frame.copy()
    out['atom'] = True
    out.loc[:, coords] = np.isclose(A, B, rtol=rtol, atol=atol)
    return out