Source code for dipy.utils.arrfuncs
"""Utilities to manipulate numpy arrays"""
from nibabel.volumeutils import endian_codes, native_code
import numpy as np
from dipy.testing.decorators import warning_for_keywords
[docs]
def as_native_array(arr):
    """Return `arr` as native byteordered array
    If arr is already native byte ordered, return unchanged.  If it is opposite
    endian, then make a native byte ordered copy and return that
    Parameters
    ----------
    arr : ndarray
    Returns
    -------
    native_arr : ndarray
        If `arr` was native order, this is just `arr`. Otherwise it's a new
        array such that ``np.all(native_arr == arr)``, with native byte
        ordering.
    """
    if endian_codes[arr.dtype.byteorder] == native_code:
        return arr
    return arr.view(arr.dtype.newbyteorder()).byteswap() 
@warning_for_keywords()
def pinv(a, *, rcond=1e-15):
    """Vectorized version of `numpy.linalg.pinv`
    If numpy version is less than 1.8, it falls back to iterating over
    `np.linalg.pinv` since there isn't a vectorized version of `np.linalg.svd`
    available.
    Parameters
    ----------
    a : array_like (..., M, N)
        Matrix to be pseudo-inverted.
    rcond : float
        Cutoff for small singular values.
    Returns
    -------
    B : ndarray (..., N, M)
        The pseudo-inverse of `a`.
    Raises
    ------
    LinAlgError
        If the SVD computation does not converge.
    See Also
    --------
    np.linalg.pinv
    """
    a = np.asarray(a)
    swap = np.arange(a.ndim)
    swap[[-2, -1]] = swap[[-1, -2]]
    u, s, v = np.linalg.svd(a, full_matrices=False)
    cutoff = np.maximum.reduce(s, axis=-1, keepdims=True) * rcond
    mask = s > cutoff
    s[mask] = 1.0 / s[mask]
    s[~mask] = 0
    return np.einsum(
        "...ij,...jk", np.transpose(v, swap) * s[..., None, :], np.transpose(u, swap)
    )