def multiple_fast_inv(a): """Compute the inverse of a set of arrays. Parameters ---------- a: array_like of shape (n_samples, n_dim, n_dim) Set of square matrices to be inverted. A is changed in place. Returns ------- a: ndarray yielding the inverse of the inputs Raises ------ LinAlgError : If `a` is singular. ValueError : If `a` is not square, or not 2-dimensional. Notes ----- This function is borrowed from scipy.linalg.inv, but with some customizations for speed-up. """ if a.shape[1] != a.shape[2]: raise ValueError('a must have shape(n_samples, n_dim, n_dim)') from scipy.linalg import calc_lwork from scipy.linalg.lapack import get_lapack_funcs a1, n = a[0], a.shape[0] getrf, getri = get_lapack_funcs(('getrf', 'getri'), (a1, )) for i in range(n): if (getrf.module_name[:7] == 'clapack' and getri.module_name[:7] != 'clapack'): # ATLAS 3.2.1 has getrf but not getri. lu, piv, info = getrf(np.transpose(a[i]), rowmajor=0, overwrite_a=True) a[i] = np.transpose(lu) else: a[i], piv, info = getrf(a[i], overwrite_a=True) if info == 0: if getri.module_name[:7] == 'flapack': lwork = calc_lwork.getri(getri.prefix, a1.shape[0]) lwork = lwork[1] # XXX: the following line fixes curious SEGFAULT when # benchmarking 500x500 matrix inverse. This seems to # be a bug in LAPACK ?getri routine because if lwork is # minimal (when using lwork[0] instead of lwork[1]) then # all tests pass. Further investigation is required if # more such SEGFAULTs occur. lwork = int(1.01 * lwork) a[i], _ = getri(a[i], piv, lwork=lwork, overwrite_lu=1) else: # clapack a[i], _ = getri(a[i], piv, overwrite_lu=1) else: raise ValueError('Matrix LU decomposition failed') return a
def multiple_fast_inv(a): """Compute the inverse of a set of arrays. Parameters ---------- a: array_like of shape (n_samples, n_dim, n_dim) Set of square matrices to be inverted. A is changed in place. Returns ------- a: ndarray yielding the inverse of the inputs Raises ------ LinAlgError : If `a` is singular. ValueError : If `a` is not square, or not 2-dimensional. Notes ----- This function is borrowed from scipy.linalg.inv, but with some customizations for speed-up. """ if a.shape[1] != a.shape[2]: raise ValueError('a must have shape (n_samples, n_dim, n_dim)') from scipy.linalg import calc_lwork from scipy.linalg.lapack import get_lapack_funcs a1, n = a[0], a.shape[0] getrf, getri = get_lapack_funcs(('getrf', 'getri'), (a1,)) for i in range(n): if (getrf.module_name[:7] == 'clapack' and getri.module_name[:7] != 'clapack'): # ATLAS 3.2.1 has getrf but not getri. lu, piv, info = getrf(np.transpose(a[i]), rowmajor=0, overwrite_a=True) a[i] = np.transpose(lu) else: a[i], piv, info = getrf(a[i], overwrite_a=True) if info == 0: if getri.module_name[:7] == 'flapack': lwork = calc_lwork.getri(getri.prefix, a1.shape[0]) lwork = lwork[1] # XXX: the following line fixes curious SEGFAULT when # benchmarking 500x500 matrix inverse. This seems to # be a bug in LAPACK ?getri routine because if lwork is # minimal (when using lwork[0] instead of lwork[1]) then # all tests pass. Further investigation is required if # more such SEGFAULTs occur. lwork = int(1.01 * lwork) a[i], _ = getri(a[i], piv, lwork=lwork, overwrite_lu=1) else: # clapack a[i], _ = getri(a[i], piv, overwrite_lu=1) else: raise ValueError('Matrix LU decomposition failed') return a
def inv(a): global getrf, getri lu, piv, info = getrf(a, overwrite_a=True) if info == 0: lwork = calc_lwork.getri(getri.typecode, a.shape[0]) lwork = lwork[1] lwork = int(1.01 * lwork) inv_a, info = getri(lu, piv, lwork=lwork, overwrite_lu=1) if info > 0: raise LinAlgError("singular matrix") if info < 0: raise ValueError('illegal value in %d-th argument of internal ' 'getrf|getri' % -info) return inv_a
def inv(a, overwrite_a=0): """ inv(a, overwrite_a=0) -> a_inv Return inverse of square matrix a. """ a1 = asarray_chkfinite(a) if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]: raise ValueError, 'expected square matrix' overwrite_a = overwrite_a or (a1 is not a and not hasattr(a,'__array__')) #XXX: I found no advantage or disadvantage of using finv. ## finv, = get_flinalg_funcs(('inv',),(a1,)) ## if finv is not None: ## a_inv,info = finv(a1,overwrite_a=overwrite_a) ## if info==0: ## return a_inv ## if info>0: raise LinAlgError, "singular matrix" ## if info<0: raise ValueError,\ ## 'illegal value in %-th argument of internal inv.getrf|getri'%(-info) getrf,getri = get_lapack_funcs(('getrf','getri'),(a1,)) #XXX: C ATLAS versions of getrf/i have rowmajor=1, this could be # exploited for further optimization. But it will be probably # a mess. So, a good testing site is required before trying # to do that. if getrf.module_name[:7]=='clapack'!=getri.module_name[:7]: # ATLAS 3.2.1 has getrf but not getri. lu,piv,info = getrf(transpose(a1), rowmajor=0,overwrite_a=overwrite_a) lu = transpose(lu) else: lu,piv,info = getrf(a1,overwrite_a=overwrite_a) if info==0: if getri.module_name[:7] == 'flapack': lwork = calc_lwork.getri(getri.prefix,a1.shape[0]) lwork = lwork[1] # XXX: the following line fixes curious SEGFAULT when # benchmarking 500x500 matrix inverse. This seems to # be a bug in LAPACK ?getri routine because if lwork is # minimal (when using lwork[0] instead of lwork[1]) then # all tests pass. Further investigation is required if # more such SEGFAULTs occur. lwork = int(1.01*lwork) inv_a,info = getri(lu,piv, lwork=lwork,overwrite_lu=1) else: # clapack inv_a,info = getri(lu,piv,overwrite_lu=1) if info>0: raise LinAlgError, "singular matrix" if info<0: raise ValueError,\ 'illegal value in %-th argument of internal getrf|getri'%(-info) return inv_a
def inv(a, overwrite_a=False, check_finite=True): """ Compute the inverse of a matrix. Parameters ---------- a : array_like Square matrix to be inverted. overwrite_a : bool, optional Discard data in `a` (may improve performance). Default is False. check_finite : boolean, optional Whether to check the input matrixes contain only finite numbers. Disabling may give a performance gain, but may result to problems (crashes, non-termination) if the inputs do contain infinities or NaNs. Returns ------- ainv : ndarray Inverse of the matrix `a`. Raises ------ LinAlgError : If `a` is singular. ValueError : If `a` is not square, or not 2-dimensional. Examples -------- >>> a = np.array([[1., 2.], [3., 4.]]) >>> sp.linalg.inv(a) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> np.dot(a, sp.linalg.inv(a)) array([[ 1., 0.], [ 0., 1.]]) """ if check_finite: a1 = np.asarray_chkfinite(a) else: a1 = np.asarray(a) if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]: raise ValueError('expected square matrix') overwrite_a = overwrite_a or _datacopied(a1, a) #XXX: I found no advantage or disadvantage of using finv. ## finv, = get_flinalg_funcs(('inv',),(a1,)) ## if finv is not None: ## a_inv,info = finv(a1,overwrite_a=overwrite_a) ## if info==0: ## return a_inv ## if info>0: raise LinAlgError, "singular matrix" ## if info<0: raise ValueError,\ ## 'illegal value in %d-th argument of internal inv.getrf|getri'%(-info) getrf, getri = get_lapack_funcs(('getrf','getri'), (a1,)) lu, piv, info = getrf(a1, overwrite_a=overwrite_a) if info == 0: lwork = calc_lwork.getri(getri.typecode, a1.shape[0]) lwork = lwork[1] # XXX: the following line fixes curious SEGFAULT when # benchmarking 500x500 matrix inverse. This seems to # be a bug in LAPACK ?getri routine because if lwork is # minimal (when using lwork[0] instead of lwork[1]) then # all tests pass. Further investigation is required if # more such SEGFAULTs occur. lwork = int(1.01 * lwork) inv_a, info = getri(lu, piv, lwork=lwork, overwrite_lu=1) if info > 0: raise LinAlgError("singular matrix") if info < 0: raise ValueError('illegal value in %d-th argument of internal ' 'getrf|getri' % -info) return inv_a
def inv(a, overwrite_a=False): """ Compute the inverse of a matrix. Parameters ---------- a : array_like Square matrix to be inverted. overwrite_a : bool, optional Discard data in `a` (may improve performance). Default is False. Returns ------- ainv : ndarray Inverse of the matrix `a`. Raises ------ LinAlgError : If `a` is singular. ValueError : If `a` is not square, or not 2-dimensional. Examples -------- >>> a = np.array([[1., 2.], [3., 4.]]) >>> sp.linalg.inv(a) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> np.dot(a, sp.linalg.inv(a)) array([[ 1., 0.], [ 0., 1.]]) """ a1 = asarray_chkfinite(a) if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]: raise ValueError('expected square matrix') overwrite_a = overwrite_a or _datacopied(a1, a) #XXX: I found no advantage or disadvantage of using finv. ## finv, = get_flinalg_funcs(('inv',),(a1,)) ## if finv is not None: ## a_inv,info = finv(a1,overwrite_a=overwrite_a) ## if info==0: ## return a_inv ## if info>0: raise LinAlgError, "singular matrix" ## if info<0: raise ValueError,\ ## 'illegal value in %d-th argument of internal inv.getrf|getri'%(-info) getrf, getri = get_lapack_funcs(('getrf', 'getri'), (a1, )) getrf_info = get_func_info(getrf) getri_info = get_func_info(getri) #XXX: C ATLAS versions of getrf/i have rowmajor=1, this could be # exploited for further optimization. But it will be probably # a mess. So, a good testing site is required before trying # to do that. if (getrf_info.module_name[:7] == 'clapack' != getri_info.module_name[:7]): # ATLAS 3.2.1 has getrf but not getri. lu, piv, info = getrf(transpose(a1), rowmajor=0, overwrite_a=overwrite_a) lu = transpose(lu) else: lu, piv, info = getrf(a1, overwrite_a=overwrite_a) if info == 0: if getri_info.module_name[:7] == 'flapack': lwork = calc_lwork.getri(getri_info.prefix, a1.shape[0]) lwork = lwork[1] # XXX: the following line fixes curious SEGFAULT when # benchmarking 500x500 matrix inverse. This seems to # be a bug in LAPACK ?getri routine because if lwork is # minimal (when using lwork[0] instead of lwork[1]) then # all tests pass. Further investigation is required if # more such SEGFAULTs occur. lwork = int(1.01 * lwork) inv_a, info = getri(lu, piv, lwork=lwork, overwrite_lu=1) else: # clapack inv_a, info = getri(lu, piv, overwrite_lu=1) if info > 0: raise LinAlgError("singular matrix") if info < 0: raise ValueError('illegal value in %d-th argument of internal ' 'getrf|getri' % -info) return inv_a
def inv(a, overwrite_a=False, check_finite=True): """ Compute the inverse of a matrix. Parameters ---------- a : array_like Square matrix to be inverted. overwrite_a : bool, optional Discard data in `a` (may improve performance). Default is False. check_finite : boolean, optional Whether to check that the input matrix contains only finite numbers. Disabling may give a performance gain, but may result in problems (crashes, non-termination) if the inputs do contain infinities or NaNs. Returns ------- ainv : ndarray Inverse of the matrix `a`. Raises ------ LinAlgError : If `a` is singular. ValueError : If `a` is not square, or not 2-dimensional. Examples -------- >>> a = np.array([[1., 2.], [3., 4.]]) >>> sp.linalg.inv(a) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> np.dot(a, sp.linalg.inv(a)) array([[ 1., 0.], [ 0., 1.]]) """ if check_finite: a1 = np.asarray_chkfinite(a) else: a1 = np.asarray(a) if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]: raise ValueError('expected square matrix') overwrite_a = overwrite_a or _datacopied(a1, a) #XXX: I found no advantage or disadvantage of using finv. ## finv, = get_flinalg_funcs(('inv',),(a1,)) ## if finv is not None: ## a_inv,info = finv(a1,overwrite_a=overwrite_a) ## if info==0: ## return a_inv ## if info>0: raise LinAlgError, "singular matrix" ## if info<0: raise ValueError,\ ## 'illegal value in %d-th argument of internal inv.getrf|getri'%(-info) getrf, getri = get_lapack_funcs(('getrf', 'getri'), (a1, )) lu, piv, info = getrf(a1, overwrite_a=overwrite_a) if info == 0: lwork = calc_lwork.getri(getri.typecode, a1.shape[0]) lwork = lwork[1] # XXX: the following line fixes curious SEGFAULT when # benchmarking 500x500 matrix inverse. This seems to # be a bug in LAPACK ?getri routine because if lwork is # minimal (when using lwork[0] instead of lwork[1]) then # all tests pass. Further investigation is required if # more such SEGFAULTs occur. lwork = int(1.01 * lwork) inv_a, info = getri(lu, piv, lwork=lwork, overwrite_lu=1) if info > 0: raise LinAlgError("singular matrix") if info < 0: raise ValueError('illegal value in %d-th argument of internal ' 'getrf|getri' % -info) return inv_a
def multiple_fast_inv(a): """ Compute the inverse of a set of arrays in-place Parameters ---------- a: array_like of shape (n_samples, M, M) Set of square matrices to be inverted. `a` is changed in place. Returns ------- a: ndarray shape (n_samples, M, M) The input array `a`, overwritten with the inverses of the original 2D arrays in ``a[0], a[1], ...``. Thus ``a[0]`` replaced with ``inv(a[0])`` etc. Raises ------ LinAlgError : If `a` is singular. ValueError : If `a` is not square, or not 2-dimensional. Notes ----- This function is copied from scipy.linalg.inv, but with some customizations for speed-up from operating on multiple arrays. It also has some conditionals to work with different scipy versions. """ # Consider errors for sparse, masked, object arrays, as for # _asarray_validated? from scipy.linalg.lapack import get_lapack_funcs S, M, N = a.shape if M != N: raise ValueError('a must have shape(n_samples, M, M)') a = np.asarray_chkfinite(a) getrf, getri = get_lapack_funcs(('getrf','getri'), (a[0],)) # Calculate lwork on different scipy versions try: getri_lwork, = get_lapack_funcs(('getri_lwork',), (a[0],)) except (ValueError, AttributeError): # scipy < 0.15 # scipy 0.10, 0.11 -> AttributeError # scipy 0.12, 0.13, 0.14 -> ValueError from scipy.linalg import calc_lwork lwork = calc_lwork.getri(getri.prefix, M)[1] else: # scipies >= 0.15 have getri_lwork function lwork, info = getri_lwork(M) if info != 0: raise ValueError('internal getri work space query failed: %d' % (info,)) lwork = int(lwork.real) # XXX: the following line fixes curious SEGFAULT when # benchmarking 500x500 matrix inverse. This seems to # be a bug in LAPACK ?getri routine because if lwork is # minimal (when using lwork[0] instead of lwork[1]) then # all tests pass. Further investigation is required if # more such SEGFAULTs occur. lwork = int(1.01 * lwork) for i, ai in enumerate(a): lu, piv, info = getrf(ai, overwrite_a=True) if info == 0: a[i], info = getri(lu, piv, lwork=lwork, overwrite_lu=1) if info > 0: raise np.linalg.LinAlgError("singular matrix") if info < 0: raise ValueError('illegal value in %d-th argument of internal ' 'getrf|getri' % -info) return a
def inv(a, overwrite_a=0): """Compute the inverse of a matrix. Parameters ---------- a : array-like, shape (M, M) Matrix to be inverted Returns ------- ainv : array-like, shape (M, M) Inverse of the matrix a Raises LinAlgError if a is singular Examples -------- >>> a = array([[1., 2.], [3., 4.]]) >>> inv(a) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> dot(a, inv(a)) array([[ 1., 0.], [ 0., 1.]]) """ a1 = asarray_chkfinite(a) if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]: raise ValueError, "expected square matrix" overwrite_a = overwrite_a or (a1 is not a and not hasattr(a, "__array__")) # XXX: I found no advantage or disadvantage of using finv. ## finv, = get_flinalg_funcs(('inv',),(a1,)) ## if finv is not None: ## a_inv,info = finv(a1,overwrite_a=overwrite_a) ## if info==0: ## return a_inv ## if info>0: raise LinAlgError, "singular matrix" ## if info<0: raise ValueError,\ ## 'illegal value in %-th argument of internal inv.getrf|getri'%(-info) getrf, getri = get_lapack_funcs(("getrf", "getri"), (a1,)) # XXX: C ATLAS versions of getrf/i have rowmajor=1, this could be # exploited for further optimization. But it will be probably # a mess. So, a good testing site is required before trying # to do that. if getrf.module_name[:7] == "clapack" != getri.module_name[:7]: # ATLAS 3.2.1 has getrf but not getri. lu, piv, info = getrf(transpose(a1), rowmajor=0, overwrite_a=overwrite_a) lu = transpose(lu) else: lu, piv, info = getrf(a1, overwrite_a=overwrite_a) if info == 0: if getri.module_name[:7] == "flapack": lwork = calc_lwork.getri(getri.prefix, a1.shape[0]) lwork = lwork[1] # XXX: the following line fixes curious SEGFAULT when # benchmarking 500x500 matrix inverse. This seems to # be a bug in LAPACK ?getri routine because if lwork is # minimal (when using lwork[0] instead of lwork[1]) then # all tests pass. Further investigation is required if # more such SEGFAULTs occur. lwork = int(1.01 * lwork) inv_a, info = getri(lu, piv, lwork=lwork, overwrite_lu=1) else: # clapack inv_a, info = getri(lu, piv, overwrite_lu=1) if info > 0: raise LinAlgError, "singular matrix" if info < 0: raise ValueError, "illegal value in %-th argument of internal getrf|getri" % (-info) return inv_a
def inv(a, overwrite_a=False): """ Compute the inverse of a matrix. Parameters ---------- a : array_like Square matrix to be inverted. overwrite_a : bool, optional Discard data in `a` (may improve performance). Default is False. Returns ------- ainv : ndarray Inverse of the matrix `a`. Raises ------ LinAlgError : If `a` is singular. ValueError : If `a` is not square, or not 2-dimensional. Examples -------- >>> a = np.array([[1., 2.], [3., 4.]]) >>> sp.linalg.inv(a) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> np.dot(a, sp.linalg.inv(a)) array([[ 1., 0.], [ 0., 1.]]) """ a1 = asarray_chkfinite(a) if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]: raise ValueError('expected square matrix') overwrite_a = overwrite_a or (a1 is not a and not hasattr(a,'__array__')) #XXX: I found no advantage or disadvantage of using finv. ## finv, = get_flinalg_funcs(('inv',),(a1,)) ## if finv is not None: ## a_inv,info = finv(a1,overwrite_a=overwrite_a) ## if info==0: ## return a_inv ## if info>0: raise LinAlgError, "singular matrix" ## if info<0: raise ValueError,\ ## 'illegal value in %d-th argument of internal inv.getrf|getri'%(-info) getrf, getri = get_lapack_funcs(('getrf','getri'), (a1,)) #XXX: C ATLAS versions of getrf/i have rowmajor=1, this could be # exploited for further optimization. But it will be probably # a mess. So, a good testing site is required before trying # to do that. if getrf.module_name[:7] == 'clapack' != getri.module_name[:7]: # ATLAS 3.2.1 has getrf but not getri. lu, piv, info = getrf(transpose(a1), rowmajor=0, overwrite_a=overwrite_a) lu = transpose(lu) else: lu, piv, info = getrf(a1, overwrite_a=overwrite_a) if info == 0: if getri.module_name[:7] == 'flapack': lwork = calc_lwork.getri(getri.prefix, a1.shape[0]) lwork = lwork[1] # XXX: the following line fixes curious SEGFAULT when # benchmarking 500x500 matrix inverse. This seems to # be a bug in LAPACK ?getri routine because if lwork is # minimal (when using lwork[0] instead of lwork[1]) then # all tests pass. Further investigation is required if # more such SEGFAULTs occur. lwork = int(1.01 * lwork) inv_a, info = getri(lu, piv, lwork=lwork, overwrite_lu=1) else: # clapack inv_a, info = getri(lu, piv, overwrite_lu=1) if info > 0: raise LinAlgError("singular matrix") if info < 0: raise ValueError('illegal value in %d-th argument of internal ' 'getrf|getri' % -info) return inv_a
def inv(a, overwrite_a=0): """Compute the inverse of a matrix. Parameters ---------- a : array-like, shape (M, M) Matrix to be inverted Returns ------- ainv : array-like, shape (M, M) Inverse of the matrix a Raises LinAlgError if a is singular Examples -------- >>> a = array([[1., 2.], [3., 4.]]) >>> inv(a) array([[-2. , 1. ], [ 1.5, -0.5]]) >>> dot(a, inv(a)) array([[ 1., 0.], [ 0., 1.]]) """ a1 = asarray_chkfinite(a) if len(a1.shape) != 2 or a1.shape[0] != a1.shape[1]: raise ValueError, 'expected square matrix' overwrite_a = overwrite_a or (a1 is not a and not hasattr(a, '__array__')) #XXX: I found no advantage or disadvantage of using finv. ## finv, = get_flinalg_funcs(('inv',),(a1,)) ## if finv is not None: ## a_inv,info = finv(a1,overwrite_a=overwrite_a) ## if info==0: ## return a_inv ## if info>0: raise LinAlgError, "singular matrix" ## if info<0: raise ValueError,\ ## 'illegal value in %-th argument of internal inv.getrf|getri'%(-info) getrf, getri = get_lapack_funcs(('getrf', 'getri'), (a1, )) #XXX: C ATLAS versions of getrf/i have rowmajor=1, this could be # exploited for further optimization. But it will be probably # a mess. So, a good testing site is required before trying # to do that. if getrf.module_name[:7] == 'clapack' != getri.module_name[:7]: # ATLAS 3.2.1 has getrf but not getri. lu, piv, info = getrf(transpose(a1), rowmajor=0, overwrite_a=overwrite_a) lu = transpose(lu) else: lu, piv, info = getrf(a1, overwrite_a=overwrite_a) if info == 0: if getri.module_name[:7] == 'flapack': lwork = calc_lwork.getri(getri.prefix, a1.shape[0]) lwork = lwork[1] # XXX: the following line fixes curious SEGFAULT when # benchmarking 500x500 matrix inverse. This seems to # be a bug in LAPACK ?getri routine because if lwork is # minimal (when using lwork[0] instead of lwork[1]) then # all tests pass. Further investigation is required if # more such SEGFAULTs occur. lwork = int(1.01 * lwork) inv_a, info = getri(lu, piv, lwork=lwork, overwrite_lu=1) else: # clapack inv_a, info = getri(lu, piv, overwrite_lu=1) if info > 0: raise LinAlgError, "singular matrix" if info < 0: raise ValueError,\ 'illegal value in %-th argument of internal getrf|getri'%(-info) return inv_a