Calculate angle between two vector/s

    Parameters
    ----------
    x : 1D or 2D array
        First vector or array of first vectors
    y : 1D or 2D array
        Second vector or array of second vectors
    multiple : bool
        If ``x`` and ``y`` are array of vector then use ``True`` otherwise
        use ``False``
    norm : vector
        Normal vector. useful to determine signed angle.

    Returns
    -------
    value : float or 1D array
        Calculated angle value. If ``x`` and ``y`` are array of vector, then array
        of angle is returned otherwise a single angle value is returned.

def vector_angle(x, y, multiple=True, norm=None):
    """Calculate angle between two vector/s

    Parameters
    ----------
    x : 1D or 2D array
        First vector or array of first vectors
    y : 1D or 2D array
        Second vector or array of second vectors
    multiple : bool
        If ``x`` and ``y`` are array of vector then use ``True`` otherwise
        use ``False``
    norm : vector
        Normal vector. useful to determine signed angle.

    Returns
    -------
    value : float or 1D array
        Calculated angle value. If ``x`` and ``y`` are array of vector, then array
        of angle is returned otherwise a single angle value is returned.
    """
    x = np.asarray(x)
    y = np.asarray(y)

    angle = []
    if multiple:
        # Element-wise angle between arrays of vectors. Taken from following links
        # http://codereview.stackexchange.com/questions/54347/calculating-element-wise-the-angles-between-two-lists-of-vectors
        dot_x_y = np.einsum('ij, ij->i', x, y)
        dot_x_x = np.einsum('ij, ij->i', x, x)
        dot_y_y = np.einsum('ij, ij->i', y, y)
        angle = np.arccos(dot_x_y / (np.sqrt(dot_x_x) * np.sqrt(dot_y_y)))

        if norm is not None:
            cross_x_y = np.cross(x, y)
            sign = np.einsum('ij, ij->i', cross_x_y, np.tile(norm, (x.shape[0], 1)))
            angle = angle * np.sign(sign)
    else:
        # Angle between two vectors
        dot = np.dot(x, y)
        cross = np.cross(x, y)
        cross_modulus = np.sqrt((cross * cross).sum())
        angle = np.arctan2(cross_modulus, dot)
    return angle