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) )