def check_and_set_idx(ids, idx, prefix): """ Reconciles passed-in IDs and indices and returns indices, as well as unique IDs in the order specified by the indices. If only IDs supplied, returns the sort-arg as the index. If only indices supplied, returns None for IDs. If both supplied, checks that the correspondence is unique and returns unique IDs in the sort order of the associated index. :param np.ndarray ids: array of IDs :param np.ndarray[int] idx: array of indices :param str prefix: variable name (for error logging) :return: unique IDs and indices (passed in or derived from the IDs) :rtype: np.ndarray, np.ndarray """ if ids is None and idx is None: raise ValueError('Both {}_ids and {}_idx cannot be None'.format(prefix, prefix)) if ids is None: return None, np.asarray_chkfinite(idx) if idx is None: return np.unique(ids, return_inverse=True) else: ids = np.asarray(ids) idx = np.asarray_chkfinite(idx) if len(idx) != len(ids): raise ValueError('{}_ids ({}) and {}_idx ({}) must have the same length'.format( prefix, len(ids), prefix, len(idx))) uniq_idx, idx_sort_index = np.unique(idx, return_index=True) # make sure each unique index corresponds to a unique id if not all(len(set(ids[idx == i])) == 1 for i in uniq_idx): raise ValueError("Each index must correspond to a unique {}_id".format(prefix)) return ids[idx_sort_index], idx
def orthogonal_procrustes(A, B, check_finite=True): """ Compute the matrix solution of the orthogonal Procrustes problem. Given matrices A and B of equal shape, find an orthogonal matrix R that most closely maps A to B [1]_. Note that unlike higher level Procrustes analyses of spatial data, this function only uses orthogonal transformations like rotations and reflections, and it does not use scaling or translation. Parameters ---------- A : (M, N) array_like Matrix to be mapped. B : (M, N) array_like Target matrix. check_finite : bool, optional Whether to check that the input matrices contain 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 ------- R : (N, N) ndarray The matrix solution of the orthogonal Procrustes problem. Minimizes the Frobenius norm of dot(A, R) - B, subject to dot(R.T, R) == I. scale : float Sum of the singular values of ``dot(A.T, B)``. Raises ------ ValueError If the input arrays are incompatibly shaped. This may also be raised if matrix A or B contains an inf or nan and check_finite is True, or if the matrix product AB contains an inf or nan. References ---------- .. [1] Peter H. Schonemann, "A generalized solution of the orthogonal Procrustes problem", Psychometrica -- Vol. 31, No. 1, March, 1996. """ if check_finite: A = np.asarray_chkfinite(A) B = np.asarray_chkfinite(B) else: A = np.asanyarray(A) B = np.asanyarray(B) if A.ndim != 2: raise ValueError('expected ndim to be 2, but observed %s' % A.ndim) if A.shape != B.shape: raise ValueError('the shapes of A and B differ (%s vs %s)' % ( A.shape, B.shape)) # Be clever with transposes, with the intention to save memory. u, w, vt = svd(B.T.dot(A).T) R = u.dot(vt) scale = w.sum() return R, scale
def __init__(self, correct, student_ids=None, item_ids=None, student_idx=None, item_idx=None, is_held_out=None, num_students=None, num_items=None, **bn_learner_kwargs): """ :param np.ndarray[bool] correct: a 1D array of correctness values :param np.ndarray|None student_ids: student identifiers for each interaction; if no student indices provided, sort order of these ids determines theta indices. :param np.ndarray|None item_ids: item identifiers for each interaction; if no item indices are provided, sort order of these ids determines item indices. :param np.ndarray[int]|None student_idx: a 1D array mapping `correct` to student index :param np.ndarray[int]|None item_idx: a 1D array mapping `correct` to item index :param np.ndarray[bool] is_held_out: a 1D array indicating whether the interaction should be held out from training (if not all zeros, a held_out test node will be added to learner) :param int|None num_students: optional number of students. Default is one plus the maximum index. :param int|None num_items: optional number of items. Default is one plus the maximum index. :param bn_learner_kwargs: arguments to be passed on to the BayesNetLearner init """ # convert pandas Series to np.ndarray and check argument dimensions correct = np.asarray_chkfinite(correct, dtype=bool) student_ids, student_idx = check_and_set_idx(student_ids, student_idx, 'student') item_ids, item_idx = check_and_set_idx(item_ids, item_idx, 'item') if len(correct) != len(student_idx) or len(correct) != len(item_idx): raise ValueError("number of elements in correct ({}), student_idx ({}), and item_idx" "({}) must be the same".format(len(correct), len(student_idx), len(item_idx))) if is_held_out is not None and ( len(is_held_out) != len(correct) or is_held_out.dtype != bool): raise ValueError("held_out ({}) must be None or an array of bools the same length as " "correct ({})".format(len(is_held_out), len(correct))) self.num_students = set_or_check_min(num_students, np.max(student_idx) + 1, 'num_students') self.num_items = set_or_check_min(num_items, np.max(item_idx) + 1, 'num_items') theta_node = DefaultGaussianNode(THETAS_KEY, self.num_students, ids=student_ids) offset_node = DefaultGaussianNode(OFFSET_COEFFS_KEY, self.num_items, ids=item_ids) nodes = [theta_node, offset_node] # add response nodes (train/test if there is held-out data; else just the train set) if is_held_out is not None and np.sum(is_held_out): if np.sum(is_held_out) == len(is_held_out): raise ValueError("some interactions must be not held out") is_held_out = np.asarray_chkfinite(is_held_out, dtype=bool) node_names = (TRAIN_RESPONSES_KEY, TEST_RESPONSES_KEY) response_idxs = (np.logical_not(is_held_out), is_held_out) else: node_names = (TRAIN_RESPONSES_KEY,) response_idxs = (np.ones_like(correct, dtype=bool),) for node_name, response_idx in zip(node_names, response_idxs): cpd = OnePOCPD(item_idx=item_idx[response_idx], theta_idx=student_idx[response_idx], num_thetas=self.num_students, num_items=self.num_items) param_nodes = {THETAS_KEY: theta_node, OFFSET_COEFFS_KEY: offset_node} nodes.append(Node(name=node_name, data=correct[response_idx], cpd=cpd, solver_pars=SolverPars(learn=False), param_nodes=param_nodes, held_out=(node_name == TEST_RESPONSES_KEY))) # store leaf nodes for learning super(OnePOLearner, self).__init__(nodes=nodes, **bn_learner_kwargs)
def __init__( self, griddata, lo, hi, maps=None, copy=True, verbose=1, order=1, prefilter=False ): griddata = np.asanyarray( griddata ) dim = griddata.ndim # - (griddata.shape[-1] == 1) # ?? assert dim >= 2, griddata.shape self.dim = dim if np.isscalar(lo): lo *= np.ones(dim) if np.isscalar(hi): hi *= np.ones(dim) self.loclip = lo = np.asarray_chkfinite( lo ).copy() self.hiclip = hi = np.asarray_chkfinite( hi ).copy() assert lo.shape == (dim,), lo.shape assert hi.shape == (dim,), hi.shape self.copy = copy self.verbose = verbose self.order = order if order > 1 and 0 < prefilter < 1: # 1/3: Mitchell-Netravali = 1/3 B + 2/3 fit exactfit = spline_filter( griddata ) # see Unser griddata += prefilter * (exactfit - griddata) prefilter = False self.griddata = griddata self.prefilter = (prefilter == True) if maps is None: maps = [None,] * len(lo) self.maps = maps self.nmap = 0 if len(maps) > 0: assert len(maps) == dim, "maps must have len %d, not %d" % ( dim, len(maps)) # linear maps (map None): Xcol -= lo *= scale -> [0, n-1] # nonlinear: np.interp e.g. [50 52 62 63] -> [0 1 2 3] self._lo = np.zeros(dim) self._scale = np.ones(dim) for j, (map, n, l, h) in enumerate( zip( maps, griddata.shape, lo, hi )): ## print "test: j map n l h:", j, map, n, l, h if map is None or callable(map): self._lo[j] = l if h > l: self._scale[j] = (n - 1) / (h - l) # _map lo -> 0, hi -> n - 1 else: self._scale[j] = 0 # h <= l: X[:,j] -> 0 continue self.maps[j] = map = np.asanyarray(map) self.nmap += 1 assert len(map) == n, "maps[%d] must have len %d, not %d" % ( j, n, len(map) ) mlo, mhi = map.min(), map.max() if not (l <= mlo <= mhi <= h): print "Warning: Intergrid maps[%d] min %.3g max %.3g " \ "are outside lo %.3g hi %.3g" % ( j, mlo, mhi, l, h )
def cho_solve(c_and_lower, b, overwrite_b=False, check_finite=True): """Solve the linear equations A x = b, given the Cholesky factorization of A. Parameters ---------- (c, lower) : tuple, (array, bool) Cholesky factorization of a, as given by cho_factor b : array Right-hand side overwrite_b : bool, optional Whether to overwrite data in b (may improve performance) check_finite : bool, optional Whether to check that the input matrices contain 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 ------- x : array The solution to the system A x = b See also -------- cho_factor : Cholesky factorization of a matrix Examples -------- >>> from scipy.linalg import cho_factor, cho_solve >>> A = np.array([[9, 3, 1, 5], [3, 7, 5, 1], [1, 5, 9, 2], [5, 1, 2, 6]]) >>> c, low = cho_factor(A) >>> x = cho_solve((c, low), [1, 1, 1, 1]) >>> np.allclose(A @ x - [1, 1, 1, 1], np.zeros(4)) True """ (c, lower) = c_and_lower if check_finite: b1 = asarray_chkfinite(b) c = asarray_chkfinite(c) else: b1 = asarray(b) c = asarray(c) if c.ndim != 2 or c.shape[0] != c.shape[1]: raise ValueError("The factored matrix c is not square.") if c.shape[1] != b1.shape[0]: raise ValueError("incompatible dimensions.") overwrite_b = overwrite_b or _datacopied(b1, b) potrs, = get_lapack_funcs(('potrs',), (c, b1)) x, info = potrs(c, b1, lower=lower, overwrite_b=overwrite_b) if info != 0: raise ValueError('illegal value in %d-th argument of internal potrs' % -info) return x
def cho_solve_banded(cb_and_lower, b, overwrite_b=False, check_finite=True): """Solve the linear equations A x = b, given the Cholesky factorization of A. Parameters ---------- (cb, lower) : tuple, (array, bool) `cb` is the Cholesky factorization of A, as given by cholesky_banded. `lower` must be the same value that was given to cholesky_banded. b : array Right-hand side overwrite_b : bool If True, the function will overwrite the values in `b`. check_finite : boolean, optional Whether to check that the input matrices contain 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 ------- x : array The solution to the system A x = b See also -------- cholesky_banded : Cholesky factorization of a banded matrix Notes ----- .. versionadded:: 0.8.0 """ (cb, lower) = cb_and_lower if check_finite: cb = asarray_chkfinite(cb) b = asarray_chkfinite(b) else: cb = asarray(cb) b = asarray(b) # Validate shapes. if cb.shape[-1] != b.shape[0]: raise ValueError("shapes of cb and b are not compatible.") pbtrs, = get_lapack_funcs(('pbtrs',), (cb, b)) x, info = pbtrs(cb, b, lower=lower, overwrite_b=overwrite_b) if info > 0: raise LinAlgError("%d-th leading minor not positive definite" % info) if info < 0: raise ValueError('illegal value in %d-th argument of internal pbtrs' % -info) return x
def rq(a, overwrite_a=False, lwork=None): """Compute RQ decomposition of a square real matrix. Calculate the decomposition :lm:`A = R Q` where Q is unitary/orthogonal and R upper triangular. Parameters ---------- a : array, shape (M, M) Square real matrix to be decomposed overwrite_a : boolean Whether data in a is overwritten (may improve performance) lwork : integer Work array size, lwork >= a.shape[1]. If None or -1, an optimal size is computed. econ : boolean Returns ------- R : double array, shape (M, N) or (K, N) for econ==True Size K = min(M, N) Q : double or complex array, shape (M, M) or (M, K) for econ==True Raises LinAlgError if decomposition fails """ # TODO: implement support for non-square and complex arrays a1 = asarray_chkfinite(a) if len(a1.shape) != 2: raise ValueError('expected matrix') M,N = a1.shape if M != N: raise ValueError('expected square matrix') if issubclass(a1.dtype.type, complexfloating): raise ValueError('expected real (non-complex) matrix') overwrite_a = overwrite_a or (_datanotshared(a1, a)) gerqf, = get_lapack_funcs(('gerqf',), (a1,)) if lwork is None or lwork == -1: # get optimal work array rq, tau, work, info = gerqf(a1, lwork=-1, overwrite_a=1) lwork = work[0] rq, tau, work, info = gerqf(a1, lwork=lwork, overwrite_a=overwrite_a) if info < 0: raise ValueError('illegal value in %d-th argument of internal geqrf' % -info) gemm, = get_blas_funcs(('gemm',), (rq,)) t = rq.dtype.char R = special_matrices.triu(rq) Q = numpy.identity(M, dtype=t) ident = numpy.identity(M, dtype=t) zeros = numpy.zeros k = min(M, N) for i in range(k): v = zeros((M,), t) v[N-k+i] = 1 v[0:N-k+i] = rq[M-k+i, 0:N-k+i] H = gemm(-tau[i], v, v, 1+0j, ident, trans_b=2) Q = gemm(1, Q, H) return R, Q
def det(a, overwrite_a=0): """Compute the determinant of a matrix Parameters ---------- a : array, shape (M, M) Returns ------- det : float or complex Determinant of a Notes ----- The determinant is computed via LU factorization, LAPACK routine z/dgetrf. """ 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__")) fdet, = get_flinalg_funcs(("det",), (a1,)) a_det, info = fdet(a1, overwrite_a=overwrite_a) if info < 0: raise ValueError, "illegal value in %-th argument of internal det.getrf" % (-info) return a_det
def find_disjoint_biclusters(self, biclusters_number=50): data = np.asarray_chkfinite(self.matrix) data[data == 0] = 0.000001 coclustering = SpectralCoclustering(n_clusters=biclusters_number, random_state=0) coclustering.fit(data) biclusters = set() for i in range(biclusters_number): rows, columns = coclustering.get_indices(i) row_set = set(rows) columns_set = set(columns) if len(row_set) > 0 and len(columns_set) > 0: density = self._calculate_box_cluster_density(row_set, columns_set) odd_columns = set() for column in columns_set: col_density = self._calculate_column_density(column, row_set) if col_density < density / 4: odd_columns.add(column) columns_set.difference_update(odd_columns) if len(columns_set) == 0: continue odd_rows = set() for row in row_set: row_density = self._calculate_row_density(row, columns_set) if row_density < density / 4: odd_rows.add(row) row_set.difference_update(odd_rows) if len(row_set) > 0 and len(columns_set) > 0: density = self._calculate_box_cluster_density(row_set, columns_set) biclusters.add(Bicluster(row_set, columns_set, density)) return biclusters
def det(a, overwrite_a=False): """Compute the determinant of a matrix Parameters ---------- a : array, shape (M, M) Returns ------- det : float or complex Determinant of a Notes ----- The determinant is computed via LU factorization, LAPACK routine z/dgetrf. """ 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) fdet, = get_flinalg_funcs(('det',), (a1,)) a_det, info = fdet(a1, overwrite_a=overwrite_a) if info < 0: raise ValueError('illegal value in %d-th argument of internal ' 'det.getrf' % -info) return a_det
def lu(a,permute_l=0,overwrite_a=0): """Return LU decompostion of a matrix. Inputs: a -- An M x N matrix. permute_l -- Perform matrix multiplication p * l [disabled]. Outputs: p,l,u -- LU decomposition matrices of a [permute_l=0] pl,u -- LU decomposition matrices of a [permute_l=1] Definitions: a = p * l * u [permute_l=0] a = pl * u [permute_l=1] p - An M x M permutation matrix l - An M x K lower triangular or trapezoidal matrix with unit-diagonal u - An K x N upper triangular or trapezoidal matrix K = min(M,N) """ a1 = asarray_chkfinite(a) if len(a1.shape) != 2: raise ValueError, 'expected matrix' overwrite_a = overwrite_a or (_datanotshared(a1,a)) flu, = get_flinalg_funcs(('lu',),(a1,)) p,l,u,info = flu(a1,permute_l=permute_l,overwrite_a = overwrite_a) if info<0: raise ValueError,\ 'illegal value in %-th argument of internal lu.getrf'%(-info) if permute_l: return l,u return p,l,u
def _cholesky(a, lower=False, overwrite_a=False, clean=True, check_finite=True): """Common code for cholesky() and cho_factor().""" a1 = asarray_chkfinite(a) if check_finite else asarray(a) a1 = atleast_2d(a1) # Dimension check if a1.ndim != 2: raise ValueError('Input array needs to be 2 dimensional but received ' 'a {}d-array.'.format(a1.ndim)) # Squareness check if a1.shape[0] != a1.shape[1]: raise ValueError('Input array is expected to be square but has ' 'the shape: {}.'.format(a1.shape)) # Quick return for square empty array if a1.size == 0: return a1.copy(), lower overwrite_a = overwrite_a or _datacopied(a1, a) potrf, = get_lapack_funcs(('potrf',), (a1,)) c, info = potrf(a1, lower=lower, overwrite_a=overwrite_a, clean=clean) if info > 0: raise LinAlgError("%d-th leading minor of the array is not positive " "definite" % info) if info < 0: raise ValueError('LAPACK reported an illegal value in {}-th argument' 'on entry to "POTRF".'.format(-info)) return c, lower
def __init__(self, data, segment_iterator, uri=None): # make sure data does not contain NaN nor inf data = np.asarray_chkfinite(data) # make sure segment_iterator is actually one of those if not isinstance(segment_iterator, (SlidingWindow, Timeline)): raise TypeError("segment_iterator must 'Timeline' or " "'SlidingWindow'.") # make sure it iterates the correct number of segments try: N = len(segment_iterator) except Exception: # an exception is raised by `len(sliding_window)` # in case sliding window has infinite end. # this is acceptable, no worry... pass else: n = data.shape[0] if n != N: raise ValueError("mismatch between number of segments (%d) " "and number of feature vectors (%d)." % (N, n)) super(BasePrecomputedSegmentFeature, self).__init__(uri=uri) self.__data = data self._segment_iterator = segment_iterator
def schur(a,output='real',lwork=None,overwrite_a=0): """Compute Schur decomposition of matrix a. Description: Return T, Z such that a = Z * T * (Z**H) where Z is a unitary matrix and T is either upper-triangular or quasi-upper triangular for output='real' """ if not output in ['real','complex','r','c']: raise ValueError, "argument must be 'real', or 'complex'" a1 = asarray_chkfinite(a) if len(a1.shape) != 2 or (a1.shape[0] != a1.shape[1]): raise ValueError, 'expected square matrix' typ = a1.dtype.char if output in ['complex','c'] and typ not in ['F','D']: if typ in _double_precision: a1 = a1.astype('D') typ = 'D' else: a1 = a1.astype('F') typ = 'F' overwrite_a = overwrite_a or (_datanotshared(a1,a)) gees, = get_lapack_funcs(('gees',),(a1,)) if lwork is None or lwork == -1: # get optimal work array result = gees(lambda x: None,a,lwork=-1) lwork = result[-2][0] result = gees(lambda x: None,a,lwork=result[-2][0],overwrite_a=overwrite_a) info = result[-1] if info<0: raise ValueError,\ 'illegal value in %-th argument of internal gees'%(-info) elif info>0: raise LinAlgError, "Schur form not found. Possibly ill-conditioned." return result[0], result[-3]
def orthogonal_procrustes(A, ref_matrix, reflection=False): # Adaptation of scipy.linalg.orthogonal_procrustes -> https://github.com/scipy/scipy/blob/v0.16.0/scipy/linalg/_procrustes.py#L14 # Info here: http://compgroups.net/comp.soft-sys.matlab/procrustes-analysis-without-reflection/896635 # goal is to find unitary matrix R with det(R) > 0 such that ||A*R - ref_matrix||^2 is minimized from scipy.linalg.decomp_svd import svd # Singular Value Decomposition, factors matrices from scipy.linalg import det import numpy as np A = np.asarray_chkfinite(A) ref_matrix = np.asarray_chkfinite(ref_matrix) if A.ndim != 2: raise ValueError('expected ndim to be 2, but observed %s' % A.ndim) if A.shape != ref_matrix.shape: raise ValueError('the shapes of A and ref_matrix differ (%s vs %s)' % (A.shape, ref_matrix.shape)) u, w, vt = svd(ref_matrix.T.dot(A).T) # Goal: minimize ||A*R - ref||^2, switch to trace # trace((A*R-ref).T*(A*R-ref)), now we distribute # trace(R'*A'*A*R) + trace(ref.T*ref) - trace((A*R).T*ref) - trace(ref.T*(A*R)), trace doesn't care about order, so re-order # trace(R*R.T*A.T*A) + trace(ref.T*ref) - trace(R.T*A.T*ref) - trace(ref.T*A*R), simplify # trace(A.T*A) + trace(ref.T*ref) - 2*trace(ref.T*A*R) # Thus, to minimize we want to maximize trace(ref.T * A * R) # u*w*v.T = (ref.T*A).T # ref.T * A = w * u.T * v # trace(ref.T * A * R) = trace (w * u.T * v * R) # differences minimized when trace(ref.T * A * R) is maximized, thus when trace(u.T * v * R) is maximized # This occurs when u.T * v * R = I (as u, v and R are all unitary matrices so max is 1) # R is a rotation matrix so R.T = R^-1 # u.T * v * I = R^-1 = R.T # R = u * v.T # Thus, R = u.dot(vt) R = u.dot(vt) # Get the rotation matrix, including reflections if not reflection and det(R) < 0: # If we don't want reflection # To remove reflection, we change the sign of the rightmost column of u (or v) and the scalar associated # with that column u[:,-1] *= -1 w[-1] *= -1 R = u.dot(vt) scale = w.sum() # Get the scaled difference return R,scale
def expm_cond(A, check_finite=True): """ Relative condition number of the matrix exponential in the Frobenius norm. Parameters ---------- A : 2d array_like Square input matrix with shape (N, N). check_finite : bool, 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 ------- kappa : float The relative condition number of the matrix exponential in the Frobenius norm Notes ----- A faster estimate for the condition number in the 1-norm has been published but is not yet implemented in scipy. .. versionadded:: 0.14.0 See also -------- expm : Compute the exponential of a matrix. expm_frechet : Compute the Frechet derivative of the matrix exponential. Examples -------- >>> from scipy.linalg import expm_cond >>> A = np.array([[-0.3, 0.2, 0.6], [0.6, 0.3, -0.1], [-0.7, 1.2, 0.9]]) >>> k = expm_cond(A) >>> k 1.7787805864469866 """ if check_finite: A = np.asarray_chkfinite(A) else: A = np.asarray(A) if len(A.shape) != 2 or A.shape[0] != A.shape[1]: raise ValueError('expected a square matrix') X = scipy.linalg.expm(A) K = expm_frechet_kronform(A, check_finite=False) # The following norm choices are deliberate. # The norms of A and X are Frobenius norms, # and the norm of K is the induced 2-norm. A_norm = scipy.linalg.norm(A, 'fro') X_norm = scipy.linalg.norm(X, 'fro') K_norm = scipy.linalg.norm(K, 2) kappa = (K_norm * A_norm) / X_norm return kappa
def qr_old(a, overwrite_a=False, lwork=None, check_finite=True): """Compute QR decomposition of a matrix. Calculate the decomposition :lm:`A = Q R` where Q is unitary/orthogonal and R upper triangular. Parameters ---------- a : array, shape (M, N) Matrix to be decomposed overwrite_a : boolean Whether data in a is overwritten (may improve performance) lwork : integer Work array size, lwork >= a.shape[1]. If None or -1, an optimal size is computed. 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 ------- Q : float or complex array, shape (M, M) R : float or complex array, shape (M, N) Size K = min(M, N) Raises LinAlgError if decomposition fails """ if check_finite: a1 = numpy.asarray_chkfinite(a) else: a1 = numpy.asarray(a) if len(a1.shape) != 2: raise ValueError('expected matrix') M,N = a1.shape overwrite_a = overwrite_a or (_datacopied(a1, a)) geqrf, = get_lapack_funcs(('geqrf',), (a1,)) if lwork is None or lwork == -1: # get optimal work array qr, tau, work, info = geqrf(a1, lwork=-1, overwrite_a=1) lwork = work[0] qr, tau, work, info = geqrf(a1, lwork=lwork, overwrite_a=overwrite_a) if info < 0: raise ValueError('illegal value in %d-th argument of internal geqrf' % -info) gemm, = get_blas_funcs(('gemm',), (qr,)) t = qr.dtype.char R = numpy.triu(qr) Q = numpy.identity(M, dtype=t) ident = numpy.identity(M, dtype=t) zeros = numpy.zeros for i in range(min(M, N)): v = zeros((M,), t) v[i] = 1 v[i+1:M] = qr[i+1:M, i] H = gemm(-tau[i], v, v, 1+0j, ident, trans_b=2) Q = gemm(1, Q, H) return Q, R
def _cho_inv_batch(a, check_finite=True): """ Invert the matrices a_i, using a Cholesky factorization of A, where a_i resides in the last two dimensions of a and the other indices describe the index i. Overwrites the data in a. Parameters ---------- a : array Array of matrices to invert, where the matrices themselves are stored in the last two dimensions. check_finite : boolean, optional Whether to check that the input matrices contain 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 ------- x : array Array of inverses of the matrices a_i See also -------- scipy.linalg.cholesky : Cholesky factorization of a matrix """ if check_finite: a1 = asarray_chkfinite(a) else: a1 = asarray(a) if len(a1.shape) < 2 or a1.shape[-2] != a1.shape[-1]: raise ValueError('expected square matrix in last two dimensions') potrf, potri = get_lapack_funcs(('potrf','potri'), (a1,)) tril_idx = np.tril_indices(a.shape[-2], k=-1) triu_idx = np.triu_indices(a.shape[-2], k=1) for index in np.ndindex(a1.shape[:-2]): # Cholesky decomposition a1[index], info = potrf(a1[index], lower=True, overwrite_a=False, clean=False) if info > 0: raise LinAlgError("%d-th leading minor not positive definite" % info) if info < 0: raise ValueError('illegal value in %d-th argument of internal' ' potrf' % -info) # Inversion a1[index], info = potri(a1[index], lower=True, overwrite_c=False) if info > 0: raise LinAlgError("the inverse could not be computed") if info < 0: raise ValueError('illegal value in %d-th argument of internal' ' potrf' % -info) # Make symmetric (dpotri only fills in the lower triangle) a1[index][triu_idx] = a1[index][tril_idx] return a1
def pinv(a, cond=None, rcond=None, return_rank=False, check_finite=True): """ Compute the (Moore-Penrose) pseudo-inverse of a matrix. Calculate a generalized inverse of a matrix using a least-squares solver. Parameters ---------- a : array, shape (M, N) Matrix to be pseudo-inverted. cond, rcond : float, optional Cutoff for 'small' singular values in the least-squares solver. Singular values smaller than ``rcond * largest_singular_value`` are considered zero. return_rank : bool, optional if True, return the effective rank of the matrix 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 ------- B : array, shape (N, M) The pseudo-inverse of matrix `a`. rank : int The effective rank of the matrix. Returned if return_rank == True Raises ------ LinAlgError If computation does not converge. Examples -------- >>> a = np.random.randn(9, 6) >>> B = linalg.pinv(a) >>> np.allclose(a, dot(a, dot(B, a))) True >>> np.allclose(B, dot(B, dot(a, B))) True """ if check_finite: a = np.asarray_chkfinite(a) else: a = np.asarray(a) b = np.identity(a.shape[0], dtype=a.dtype) if rcond is not None: cond = rcond x, resids, rank, s = lstsq(a, b, cond=cond) if return_rank: return x, rank else: return x
def det(a, overwrite_a=False, check_finite=True): """ Compute the determinant of a matrix The determinant of a square matrix is a value derived arithmetically from the coefficients of the matrix. The determinant for a 3x3 matrix, for example, is computed as follows:: a b c d e f = A g h i det(A) = a*e*i +b*f*g + c*d*h - c*e*g - b*d*i - a*f*h Parameters ---------- a : array_like, shape (M, M) A square matrix. overwrite_a : bool Allow overwriting data in a (may enhance performance). 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 ------- det : float or complex Determinant of `a`. Notes ----- The determinant is computed via LU factorization, LAPACK routine z/dgetrf. Examples -------- >>> a = np.array([[1,2,3],[4,5,6],[7,8,9]]) >>> linalg.det(a) 0.0 >>> a = np.array([[0,2,3],[4,5,6],[7,8,9]]) >>> linalg.det(a) 3.0 """ 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) fdet, = get_flinalg_funcs(('det',), (a1,)) a_det, info = fdet(a1, overwrite_a=overwrite_a) if info < 0: raise ValueError('illegal value in %d-th argument of internal ' 'det.getrf' % -info) return a_det
def __init__( self, griddata, lo, hi, maps=[], copy=True, verbose=1, order=1, prefilter=False ): griddata = np.asanyarray( griddata ) dim = griddata.ndim # - (griddata.shape[-1] == 1) # ?? assert dim >= 2, griddata.shape self.dim = dim if np.isscalar(lo): lo *= np.ones(dim) if np.isscalar(hi): hi *= np.ones(dim) assert lo.shape == (dim,), lo.shape assert hi.shape == (dim,), hi.shape self.loclip = lo = np.asarray_chkfinite( lo ).copy() self.hiclip = hi = np.asarray_chkfinite( hi ).copy() self.copy = copy self.verbose = verbose self.order = order if order > 1 and 0 < prefilter < 1: # 1/3: Mitchell-Netravali = 1/3 B + 2/3 fit exactfit = spline_filter( griddata ) # see Unser griddata += prefilter * (exactfit - griddata) prefilter = False self.griddata = griddata self.prefilter = (prefilter == True) self.nmap = 0 if maps != []: # sanity check maps -- assert len(maps) == dim, "maps must have len %d, not %d" % ( dim, len(maps)) for j, (map, n, l, h) in enumerate( zip( maps, griddata.shape, lo, hi )): if map is None or callable(map): lo[j], hi[j] = 0, 1 continue maps[j] = map = np.asanyarray(map) self.nmap += 1 assert len(map) == n, "maps[%d] must have len %d, not %d" % ( j, n, len(map) ) mlo, mhi = map.min(), map.max() if not (l <= mlo <= mhi <= h): print "Warning: Intergrid maps[%d] min %.3g max %.3g " \ "are outside lo %.3g hi %.3g" % ( j, mlo, mhi, l, h ) self.maps = maps self._lo = lo # caller's lo for linear, 0 nonlinear maps shape_1 = np.array( self.griddata.shape, float ) - 1 self._linearmap = shape_1 / np.where( hi > lo, hi - lo, np.inf ) # 25jun
def _pinvh(a, cond=None, rcond=None, lower=True): """Compute the (Moore-Penrose) pseudo-inverse of a hermetian matrix. Calculate a generalized inverse of a symmetric matrix using its eigenvalue decomposition and including all 'large' eigenvalues. Parameters ---------- a : array, shape (N, N) Real symmetric or complex hermetian matrix to be pseudo-inverted cond, rcond : float or None Cutoff for 'small' eigenvalues. Singular values smaller than rcond * largest_eigenvalue are considered zero. If None or -1, suitable machine precision is used. lower : boolean Whether the pertinent array data is taken from the lower or upper triangle of a. (Default: lower) Returns ------- B : array, shape (N, N) Raises ------ LinAlgError If eigenvalue does not converge Examples -------- >>> import numpy as np >>> a = np.random.randn(9, 6) >>> a = np.dot(a, a.T) >>> B = _pinvh(a) >>> np.allclose(a, np.dot(a, np.dot(B, a))) True >>> np.allclose(B, np.dot(B, np.dot(a, B))) True """ a = np.asarray_chkfinite(a) s, u = linalg.eigh(a, lower=lower) if rcond is not None: cond = rcond if cond in [None, -1]: t = u.dtype.char.lower() factor = {'f': 1E3, 'd': 1E6} cond = factor[t] * np.finfo(t).eps # unlike svd case, eigh can lead to negative eigenvalues above_cutoff = (abs(s) > cond * np.max(abs(s))) psigma_diag = np.zeros_like(s) psigma_diag[above_cutoff] = 1.0 / s[above_cutoff] return np.dot(u * psigma_diag, np.conjugate(u).T)
def cho_solve(clow, b): """Solve a previously factored symmetric system of equations. First input is a tuple (LorU, lower) which is the output to cho_factor. Second input is the right-hand side. """ c, lower = clow c = asarray_chkfinite(c) _assert_squareness(c) b = asarray_chkfinite(b) potrs, = get_lapack_funcs(('potrs',),(c,)) b, info = potrs(c,b,lower) if info < 0: msg = "Argument %d to lapack's ?potrs() has an illegal value." % info raise TypeError, msg if info > 0: msg = "Unknown error occured int ?potrs(): error code = %d" % info raise TypeError, msg return b
def cho_solve(c_and_lower, b, overwrite_b=False, check_finite=True): """Solve the linear equations A x = b, given the Cholesky factorization of A. Parameters ---------- (c, lower) : tuple, (array, bool) Cholesky factorization of a, as given by cho_factor b : array Right-hand side check_finite : boolean, optional Whether to check that the input matrices contain 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 ------- x : array The solution to the system A x = b See also -------- cho_factor : Cholesky factorization of a matrix """ (c, lower) = c_and_lower if check_finite: b1 = asarray_chkfinite(b) c = asarray_chkfinite(c) else: b1 = asarray(b) c = asarray(c) if c.ndim != 2 or c.shape[0] != c.shape[1]: raise ValueError("The factored matrix c is not square.") if c.shape[1] != b1.shape[0]: raise ValueError("incompatible dimensions.") overwrite_b = overwrite_b or _datacopied(b1, b) potrs, = get_lapack_funcs(('potrs',), (c, b1)) x, info = potrs(c, b1, lower=lower, overwrite_b=overwrite_b) if info != 0: raise ValueError('illegal value in %d-th argument of internal potrs' % -info) return x
def pinv2(a, cond=None, rcond=None): """ Compute the (Moore-Penrose) pseudo-inverse of a matrix. Calculate a generalized inverse of a matrix using its singular-value decomposition and including all 'large' singular values. Parameters ---------- a : array, shape (M, N) Matrix to be pseudo-inverted. cond, rcond : float or None Cutoff for 'small' singular values. Singular values smaller than ``rcond*largest_singular_value`` are considered zero. If None or -1, suitable machine precision is used. Returns ------- B : array, shape (N, M) The pseudo-inverse of matrix `a`. Raises ------ LinAlgError If SVD computation does not converge. Examples -------- >>> a = np.random.randn(9, 6) >>> B = linalg.pinv2(a) >>> np.allclose(a, dot(a, dot(B, a))) True >>> np.allclose(B, dot(B, dot(a, B))) True """ a = np.asarray_chkfinite(a) u, s, vh = decomp_svd.svd(a) t = u.dtype.char if rcond is not None: cond = rcond if cond in [None,-1]: eps = np.finfo(np.float).eps feps = np.finfo(np.single).eps _array_precision = {'f': 0, 'd': 1, 'F': 0, 'D': 1} cond = {0: feps*1e3, 1: eps*1e6}[_array_precision[t]] m, n = a.shape cutoff = cond*np.maximum.reduce(s) psigma = np.zeros((m, n), t) for i in range(len(s)): if s[i] > cutoff: psigma[i,i] = 1.0/np.conjugate(s[i]) #XXX: use lapack/blas routines for dot return np.transpose(np.conjugate(np.dot(np.dot(u,psigma),vh)))
def lu_factor(a, overwrite_a=False, check_finite=True): """ Compute pivoted LU decomposition of a matrix. The decomposition is:: A = P L U where P is a permutation matrix, L lower triangular with unit diagonal elements, and U upper triangular. Parameters ---------- a : (M, M) array_like Matrix to decompose overwrite_a : bool, optional Whether to overwrite data in A (may increase performance) check_finite : bool, 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 ------- lu : (N, N) ndarray Matrix containing U in its upper triangle, and L in its lower triangle. The unit diagonal elements of L are not stored. piv : (N,) ndarray Pivot indices representing the permutation matrix P: row i of matrix was interchanged with row piv[i]. See also -------- lu_solve : solve an equation system using the LU factorization of a matrix Notes ----- This is a wrapper to the ``*GETRF`` routines from LAPACK. """ if check_finite: a1 = asarray_chkfinite(a) else: a1 = 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)) getrf, = get_lapack_funcs(('getrf',), (a1,)) lu, piv, info = getrf(a1, overwrite_a=overwrite_a) if info < 0: raise ValueError('illegal value in %d-th argument of ' 'internal getrf (lu_factor)' % -info) if info > 0: warn("Diagonal number %d is exactly zero. Singular matrix." % info, RuntimeWarning) return lu, piv
def norm(a, ord=None): # Differs from numpy only in non-finite handling and the use of # blas a = np.asarray_chkfinite(a) if ord in (None, 2) and (a.ndim == 1) and (a.dtype.char in 'fdFD'): # use blas for fast and stable euclidean norm func_name = _nrm2_prefix.get(a.dtype.char, 'd') + 'nrm2' nrm2 = getattr(fblas, func_name) return nrm2(a) return np.linalg.norm(a, ord=ord)
def pinv(a, cond=None, rcond=None): """ pinv(a, rcond=None) -> a_pinv Compute generalized inverse of A using least-squares solver. """ a = asarray_chkfinite(a) b = numpy.identity(a.shape[0], dtype=a.dtype) if rcond is not None: cond = rcond return lstsq(a, b, cond=cond)[0]
def lu_solve(a_lu_pivots,b): """Solve a previously factored system. First input is a tuple (lu, pivots) which is the output to lu_factor. Second input is the right hand side. """ a_lu, pivots = a_lu_pivots a_lu = asarray_chkfinite(a_lu) pivots = asarray_chkfinite(pivots) b = asarray_chkfinite(b) _assert_squareness(a_lu) getrs, = get_lapack_funcs(('getrs',),(a_lu,)) b, info = getrs(a_lu,pivots,b) if info < 0: msg = "Argument %d to lapack's ?getrs() has an illegal value." % info raise TypeError, msg if info > 0: msg = "Unknown error occured int ?getrs(): error code = %d" % info raise TypeError, msg return b
def rq(a,overwrite_a=0,lwork=None): """RQ decomposition of an M x N matrix a. Description: Find an upper-triangular matrix r and a unitary (orthogonal) matrix q such that r * q = a Inputs: a -- the matrix overwrite_a=0 -- if non-zero then discard the contents of a, i.e. a is used as a work array if possible. lwork=None -- >= shape(a)[1]. If None (or -1) compute optimal work array size. Outputs: r, q -- matrices such that r * q = a """ # TODO: implement support for non-square and complex arrays a1 = asarray_chkfinite(a) if len(a1.shape) != 2: raise ValueError, 'expected matrix' M,N = a1.shape if M != N: raise ValueError, 'expected square matrix' if issubclass(a1.dtype.type,complexfloating): raise ValueError, 'expected real (non-complex) matrix' overwrite_a = overwrite_a or (_datanotshared(a1,a)) gerqf, = get_lapack_funcs(('gerqf',),(a1,)) if lwork is None or lwork == -1: # get optimal work array rq,tau,work,info = gerqf(a1,lwork=-1,overwrite_a=1) lwork = work[0] rq,tau,work,info = gerqf(a1,lwork=lwork,overwrite_a=overwrite_a) if info<0: raise ValueError, \ 'illegal value in %-th argument of internal geqrf'%(-info) gemm, = get_blas_funcs(('gemm',),(rq,)) t = rq.dtype.char R = basic.triu(rq) Q = numpy.identity(M,dtype=t) ident = numpy.identity(M,dtype=t) zeros = numpy.zeros k = min(M,N) for i in range(k): v = zeros((M,),t) v[N-k+i] = 1 v[0:N-k+i] = rq[M-k+i,0:N-k+i] H = gemm(-tau[i],v,v,1+0j,ident,trans_b=2) Q = gemm(1,Q,H) return R, Q
def pinvh(a, cond=None, rcond=None, lower=True): """Compute the (Moore-Penrose) pseudo-inverse of a hermetian matrix. Calculate a generalized inverse of a symmetric matrix using its eigenvalue decomposition and including all 'large' eigenvalues. Parameters ---------- a : array, shape (N, N) Real symmetric or complex hermetian matrix to be pseudo-inverted cond : float or None, default None Cutoff for 'small' eigenvalues. Singular values smaller than rcond * largest_eigenvalue are considered zero. If None or -1, suitable machine precision is used. rcond : float or None, default None (deprecated) Cutoff for 'small' eigenvalues. Singular values smaller than rcond * largest_eigenvalue are considered zero. If None or -1, suitable machine precision is used. lower : boolean Whether the pertinent array data is taken from the lower or upper triangle of a. (Default: lower) Returns ------- B : array, shape (N, N) Raises ------ LinAlgError If eigenvalue does not converge Examples -------- >>> import numpy as np >>> a = np.random.randn(9, 6) >>> a = np.dot(a, a.T) >>> B = pinvh(a) >>> np.allclose(a, np.dot(a, np.dot(B, a))) True >>> np.allclose(B, np.dot(B, np.dot(a, B))) True """ a = np.asarray_chkfinite(a) s, u = linalg.eigh(a, lower=lower) if rcond is not None: cond = rcond if cond in [None, -1]: t = u.dtype.char.lower() factor = {'f': 1E3, 'd': 1E6} cond = factor[t] * np.finfo(t).eps # unlike svd case, eigh can lead to negative eigenvalues above_cutoff = (abs(s) > cond * np.max(abs(s))) psigma_diag = np.zeros_like(s) psigma_diag[above_cutoff] = 1.0 / s[above_cutoff] return np.dot(u * psigma_diag, np.conjugate(u).T)
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 nnls_predotted(A_dot_A, A_dot_b, tol=1e-8): """ Solve ``argmin_x || Ax - b ||_2`` for ``x>=0``. This version may be superior to the FORTRAN implementation when ``A`` has more rows than columns, and especially when ``A`` is sparse. Note that the arguments and return values differ from the FORTRAN implementation; in particular, this implementation does not expect the actual design matrix ``A`` nor the RHS vector ``b``, but rather ``A.T.dot(A)`` and ``A.T.dot(b)``. These are smaller than the original ``A`` and ``b`` iff ``A`` has more rows than columns. This function also does not return the residual. The squared residual ``|| Ax-b ||^2`` may be calculated efficiently as: ``b.dot(b) + x.dot(A_dot_A.dot(x) - 2*A_dot_b)`` where ``x`` is the output of this function Parameters ---------- A_dot_A : ndarray Square matrix corresponding to ``A.T.dot(A)``, where ``A`` is as shown above. A_dot_b : ndarray Vector corresponding to ``A.T.dot(b)``, where ``A`` and ``b`` are as shown above. Returns ------- x : ndarray Solution vector. """ A_dot_A = np.asarray_chkfinite(A_dot_A) A_dot_b = np.asarray_chkfinite(A_dot_b) if len(A_dot_A.shape) != 2: raise ValueError("expected matrix") if len(A_dot_b.shape) != 1: raise ValueError("expected vector") nvar = A_dot_A.shape[0] if nvar != A_dot_A.shape[1]: raise ValueError("expected square matrix") if nvar != A_dot_b.shape[0]: raise ValueError("incompatible dimensions") P_bool = np.zeros(nvar, np.bool) x = np.zeros(nvar, dtype=A_dot_A.dtype) s = np.empty_like(x) w = A_dot_b while not P_bool.all() and w.max() > tol: j_idx = w[~P_bool].argmax() newly_allowed = np.flatnonzero(~P_bool)[j_idx] P_bool[newly_allowed] = True s[:] = 0 currPs = np.flatnonzero(P_bool) if len(currPs) > 1: s[currPs] = np.linalg.solve( A_dot_A[currPs[:, None], currPs[None, :]], A_dot_b[currPs]) else: currP = currPs[0] s[currP] = A_dot_b[currP] / A_dot_A[currP, currP] s_P_l_0 = (s[currPs] < 0) while s_P_l_0.any(): currPs_s_P_l_0 = currPs[s_P_l_0] alpha = (x[currPs_s_P_l_0] / (x[currPs_s_P_l_0] - s[currPs_s_P_l_0])).min() x += alpha * (s - x) P_bool[currPs] = (x[currPs] > tol) s[:] = 0 currPs = np.flatnonzero(P_bool) if len(currPs) > 1: s[currPs] = np.linalg.solve( A_dot_A[currPs[:, None], currPs[None, :]], A_dot_b[currPs]) elif len(currPs) == 1: currP = currPs[0] s[currP] = A_dot_b[currP] / A_dot_A[currP, currP] s_P_l_0 = (s[currPs] < 0) x[:] = s[:] if x[newly_allowed] == 0: break # avoid infinite loop w = A_dot_b - A_dot_A.dot(x) return x
def eggholder(x): x = np.asarray_chkfinite(x) return (-(x[1] + 47) * np.sin(np.sqrt(abs(x[0] / 2 + (x[1] + 47)))) - x[0] * np.sin(np.sqrt(abs(x[0] - (x[1] + 47)))))
def norm(a, ord=None, axis=None, keepdims=False, check_finite=True): """ Matrix or vector norm. This function is able to return one of seven different matrix norms, or one of an infinite number of vector norms (described below), depending on the value of the ``ord`` parameter. Parameters ---------- a : (M,) or (M, N) array_like Input array. If `axis` is None, `a` must be 1D or 2D. ord : {non-zero int, inf, -inf, 'fro'}, optional Order of the norm (see table under ``Notes``). inf means NumPy's `inf` object axis : {int, 2-tuple of ints, None}, optional If `axis` is an integer, it specifies the axis of `a` along which to compute the vector norms. If `axis` is a 2-tuple, it specifies the axes that hold 2-D matrices, and the matrix norms of these matrices are computed. If `axis` is None then either a vector norm (when `a` is 1-D) or a matrix norm (when `a` is 2-D) is returned. keepdims : bool, optional If this is set to True, the axes which are normed over are left in the result as dimensions with size one. With this option the result will broadcast correctly against the original `a`. check_finite : bool, 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 ------- n : float or ndarray Norm of the matrix or vector(s). Notes ----- For values of ``ord <= 0``, the result is, strictly speaking, not a mathematical 'norm', but it may still be useful for various numerical purposes. The following norms can be calculated: ===== ============================ ========================== ord norm for matrices norm for vectors ===== ============================ ========================== None Frobenius norm 2-norm 'fro' Frobenius norm -- inf max(sum(abs(x), axis=1)) max(abs(x)) -inf min(sum(abs(x), axis=1)) min(abs(x)) 0 -- sum(x != 0) 1 max(sum(abs(x), axis=0)) as below -1 min(sum(abs(x), axis=0)) as below 2 2-norm (largest sing. value) as below -2 smallest singular value as below other -- sum(abs(x)**ord)**(1./ord) ===== ============================ ========================== The Frobenius norm is given by [1]_: :math:`||A||_F = [\\sum_{i,j} abs(a_{i,j})^2]^{1/2}` The ``axis`` and ``keepdims`` arguments are passed directly to ``numpy.linalg.norm`` and are only usable if they are supported by the version of numpy in use. References ---------- .. [1] G. H. Golub and C. F. Van Loan, *Matrix Computations*, Baltimore, MD, Johns Hopkins University Press, 1985, pg. 15 Examples -------- >>> from scipy.linalg import norm >>> a = np.arange(9) - 4.0 >>> a array([-4., -3., -2., -1., 0., 1., 2., 3., 4.]) >>> b = a.reshape((3, 3)) >>> b array([[-4., -3., -2.], [-1., 0., 1.], [ 2., 3., 4.]]) >>> norm(a) 7.745966692414834 >>> norm(b) 7.745966692414834 >>> norm(b, 'fro') 7.745966692414834 >>> norm(a, np.inf) 4 >>> norm(b, np.inf) 9 >>> norm(a, -np.inf) 0 >>> norm(b, -np.inf) 2 >>> norm(a, 1) 20 >>> norm(b, 1) 7 >>> norm(a, -1) -4.6566128774142013e-010 >>> norm(b, -1) 6 >>> norm(a, 2) 7.745966692414834 >>> norm(b, 2) 7.3484692283495345 >>> norm(a, -2) 0 >>> norm(b, -2) 1.8570331885190563e-016 >>> norm(a, 3) 5.8480354764257312 >>> norm(a, -3) 0 """ # Differs from numpy only in non-finite handling and the use of blas. if check_finite: a = np.asarray_chkfinite(a) else: a = np.asarray(a) # Only use optimized norms if axis and keepdims are not specified. if a.dtype.char in 'fdFD' and axis is None and not keepdims: if ord in (None, 2) and (a.ndim == 1): # use blas for fast and stable euclidean norm nrm2 = get_blas_funcs('nrm2', dtype=a.dtype) return nrm2(a) if a.ndim == 2 and axis is None and not keepdims: # Use lapack for a couple fast matrix norms. # For some reason the *lange frobenius norm is slow. lange_args = None # Make sure this works if the user uses the axis keywords # to apply the norm to the transpose. if ord == 1: if np.isfortran(a): lange_args = '1', a elif np.isfortran(a.T): lange_args = 'i', a.T elif ord == np.inf: if np.isfortran(a): lange_args = 'i', a elif np.isfortran(a.T): lange_args = '1', a.T if lange_args: lange = get_lapack_funcs('lange', dtype=a.dtype) return lange(*lange_args) # Filter out the axis and keepdims arguments if they aren't used so they # are never inadvertently passed to a version of numpy that doesn't # support them. if axis is not None: if keepdims: return np.linalg.norm(a, ord=ord, axis=axis, keepdims=keepdims) return np.linalg.norm(a, ord=ord, axis=axis) return np.linalg.norm(a, ord=ord)
def moments(timeseries: np.ndarray, bw: float = None, bins: np.ndarray = None, power: int = 6, lag: list = [1], correction: bool = True, norm: bool = False, kernel: callable = None, tol: float = 1e-10, conv_method: str = 'auto', verbose: bool = False) -> np.ndarray: r""" Estimates the moments of the Kramers─Moyal expansion from a timeseries using a Nadaraya─Watson kernel estimator method. These later can be turned into the drift and diffusion coefficients after normalisation. Parameters ---------- timeseries: np.ndarray A 1-dimensional timeseries. bw: float Desired bandwidth of the kernel. A value of 1 occupies the full space of the bin space. Recommended are values ``0.005 < bw < 0.4``. bins: np.ndarray (default ``None``) The number of bins for each dimension, defaults to ``np.array([5000])``. This is the underlying space for the Kramers─Moyal conditional moments. power: int (default ``6``) Upper limit of the the Kramers─Moyal conditional moments to calculate. It will generate all Kramers─Moyal conditional moments up to power. lag: list (default ``1``) Calculates the Kramers─Moyal conditional moments at each indicated lag, i.e., for ``timeseries[::lag[]]``. Defaults to ``1``, the shortest timestep in the data. corrections: bool (default ``True``) Implements the second-order corrections of the Kramers─Moyal conditional moments directly norm: bool (default ``False``) Sets the normalisation. ``False`` returns the Kramers─Moyal conditional moments, and ``True`` returns the Kramers─Moyal coefficients. kernel: callable (default ``None``) Kernel used to convolute with the Kramers─Moyal conditional moments. To select example an Epanechnikov kernel use kernel = kernels.epanechnikov If None the Epanechnikov kernel will be used. tol: float (default ``1e-10``) Round to zero absolute values smaller than ``tol``, after convolutions. conv_method: str (default ``auto``) A string indicating which method to use to calculate the convolution. docs.scipy.org/doc/scipy/reference/generated/scipy.signal.convolve. verbose: bool (default ``False``) If ``True`` will report on the bandwidth used. Returns ------- edges: np.ndarray The bin edges with shape (D,bins.shape) of the calculated moments. moments: np.ndarray The calculated moments from the Kramers─Moyal expansion of the timeseries at each lag. To extract the selected orders of the moments, use ``moments[i,:,j]``, with ``i`` the order according to powers, ``j`` the lag (if any given). """ timeseries = np.asarray_chkfinite(timeseries, dtype=float) if len(timeseries.shape) == 1: timeseries = timeseries.reshape(-1, 1) assert len(timeseries.shape) == 2, "Timeseries must be 1-dimensional" assert timeseries.shape[0] > 0, "No data in timeseries" if bins is None: bins = np.array([5000]) if lag is None: lag = [1] powers = np.linspace(0, power, power + 1).astype(int) if len(powers.shape) == 1: powers = powers.reshape(-1, 1) if bw is None: bw = silvermans_rule(timeseries) elif callable(bw): bw = bw(timeseries) assert bw > 0.0, "Bandwidth must be > 0" if kernel is None: kernel = epanechnikov assert kernel in _kernels, "Kernel not found" if verbose == True: print(r'bandwidth = {:f}'.format(bw) + r', bins = {:d}'.format(bins[0])) edges, moments = _moments(timeseries, bins, powers, lag, kernel, bw, tol, conv_method) if correction == True: moments = corrections(m=moments, power=power) if norm == True: for i in range(power): moments = moments / float(factorial(i)) return (edges, moments)
def norm(a, ord=None): """ Matrix or vector norm. This function is able to return one of seven different matrix norms, or one of an infinite number of vector norms (described below), depending on the value of the ``ord`` parameter. Parameters ---------- x : (M,) or (M, N) array_like Input array. ord : {non-zero int, inf, -inf, 'fro'}, optional Order of the norm (see table under ``Notes``). inf means numpy's `inf` object. Returns ------- norm : float Norm of the matrix or vector. Notes ----- For values of ``ord <= 0``, the result is, strictly speaking, not a mathematical 'norm', but it may still be useful for various numerical purposes. The following norms can be calculated: ===== ============================ ========================== ord norm for matrices norm for vectors ===== ============================ ========================== None Frobenius norm 2-norm 'fro' Frobenius norm -- inf max(sum(abs(x), axis=1)) max(abs(x)) -inf min(sum(abs(x), axis=1)) min(abs(x)) 0 -- sum(x != 0) 1 max(sum(abs(x), axis=0)) as below -1 min(sum(abs(x), axis=0)) as below 2 2-norm (largest sing. value) as below -2 smallest singular value as below other -- sum(abs(x)**ord)**(1./ord) ===== ============================ ========================== The Frobenius norm is given by [1]_: :math:`||A||_F = [\\sum_{i,j} abs(a_{i,j})^2]^{1/2}` References ---------- .. [1] G. H. Golub and C. F. Van Loan, *Matrix Computations*, Baltimore, MD, Johns Hopkins University Press, 1985, pg. 15 Examples -------- >>> from scipy.linalg import norm >>> a = np.arange(9) - 4 >>> a array([-4, -3, -2, -1, 0, 1, 2, 3, 4]) >>> b = a.reshape((3, 3)) >>> b array([[-4, -3, -2], [-1, 0, 1], [ 2, 3, 4]]) >>> norm(a) 7.745966692414834 >>> norm(b) 7.745966692414834 >>> norm(b, 'fro') 7.745966692414834 >>> norm(a, np.inf) 4 >>> norm(b, np.inf) 9 >>> norm(a, -np.inf) 0 >>> norm(b, -np.inf) 2 >>> norm(a, 1) 20 >>> norm(b, 1) 7 >>> norm(a, -1) -4.6566128774142013e-010 >>> norm(b, -1) 6 >>> norm(a, 2) 7.745966692414834 >>> norm(b, 2) 7.3484692283495345 >>> norm(a, -2) nan >>> norm(b, -2) 1.8570331885190563e-016 >>> norm(a, 3) 5.8480354764257312 >>> norm(a, -3) nan """ # Differs from numpy only in non-finite handling and the use of # blas a = np.asarray_chkfinite(a) if ord in (None, 2) and (a.ndim == 1) and (a.dtype.char in 'fdFD'): # use blas for fast and stable euclidean norm func_name = _nrm2_prefix.get(a.dtype.char, 'd') + 'nrm2' nrm2 = getattr(blas, func_name) return nrm2(a) return np.linalg.norm(a, ord=ord)
def rastrigin(x): # rast.m x = np.asarray_chkfinite(x) n = len(x) return 10 * n + sum(x**2 - 10 * cos(2 * pi * x))
# In[41]: a=np.asfarray([2, 3]) a # ## 29. numpy.asarray_chkfinite # Convert a list into an array. # If all elements are finite asarray_chkfinite is identical to asarray. # In[42]: a = [90,80,70] np.asarray_chkfinite(a,dtype=float) # ## 30. numpy.asscalar # Convert an array of size 1 to its scalar equivalent. # In[43]: np.asscalar(np.array([10000000])) # ## 31. numpy.concatenate # Join a sequence of arrays along an existing axis. # In[44]:
def rq(a, overwrite_a=False, lwork=None, mode='full', check_finite=True): """ Compute RQ decomposition of a matrix. Calculate the decomposition ``A = R Q`` where Q is unitary/orthogonal and R upper triangular. Parameters ---------- a : (M, N) array_like Matrix to be decomposed overwrite_a : bool, optional Whether data in a is overwritten (may improve performance) lwork : int, optional Work array size, lwork >= a.shape[1]. If None or -1, an optimal size is computed. mode : {'full', 'r', 'economic'}, optional Determines what information is to be returned: either both Q and R ('full', default), only R ('r') or both Q and R but computed in economy-size ('economic', see Notes). check_finite : bool, 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 ------- R : float or complex ndarray Of shape (M, N) or (M, K) for ``mode='economic'``. ``K = min(M, N)``. Q : float or complex ndarray Of shape (N, N) or (K, N) for ``mode='economic'``. Not returned if ``mode='r'``. Raises ------ LinAlgError If decomposition fails. Notes ----- This is an interface to the LAPACK routines sgerqf, dgerqf, cgerqf, zgerqf, sorgrq, dorgrq, cungrq and zungrq. If ``mode=economic``, the shapes of Q and R are (K, N) and (M, K) instead of (N,N) and (M,N), with ``K=min(M,N)``. Examples -------- >>> from scipy import linalg >>> a = np.random.randn(6, 9) >>> r, q = linalg.rq(a) >>> np.allclose(a, r @ q) True >>> r.shape, q.shape ((6, 9), (9, 9)) >>> r2 = linalg.rq(a, mode='r') >>> np.allclose(r, r2) True >>> r3, q3 = linalg.rq(a, mode='economic') >>> r3.shape, q3.shape ((6, 6), (6, 9)) """ if mode not in ['full', 'r', 'economic']: raise ValueError( "Mode argument should be one of ['full', 'r', 'economic']") if check_finite: a1 = numpy.asarray_chkfinite(a) else: a1 = numpy.asarray(a) if len(a1.shape) != 2: raise ValueError('expected matrix') M, N = a1.shape overwrite_a = overwrite_a or (_datacopied(a1, a)) gerqf, = get_lapack_funcs(('gerqf', ), (a1, )) rq, tau = safecall(gerqf, 'gerqf', a1, lwork=lwork, overwrite_a=overwrite_a) if not mode == 'economic' or N < M: R = numpy.triu(rq, N - M) else: R = numpy.triu(rq[-M:, -M:]) if mode == 'r': return R gor_un_grq, = get_lapack_funcs(('orgrq', ), (rq, )) if N < M: Q, = safecall(gor_un_grq, "gorgrq/gungrq", rq[-N:], tau, lwork=lwork, overwrite_a=1) elif mode == 'economic': Q, = safecall(gor_un_grq, "gorgrq/gungrq", rq, tau, lwork=lwork, overwrite_a=1) else: rq1 = numpy.empty((N, N), dtype=rq.dtype) rq1[-M:] = rq Q, = safecall(gor_un_grq, "gorgrq/gungrq", rq1, tau, lwork=lwork, overwrite_a=1) return R, Q
def curve_fit(f, xdata, ydata, p0=None, sigma=None, absolute_sigma=False, check_finite=True, bounds=(-np.inf, np.inf), method=None, jac=None, **kwargs): """ Use non-linear least squares to fit a function, f, to data. Assumes ``ydata = f(xdata, *params) + eps`` Parameters ---------- f : callable The model function, f(x, ...). It must take the independent variable as the first argument and the parameters to fit as separate remaining arguments. xdata : array_like or object The independent variable where the data is measured. Should usually be an M-length sequence or an (k,M)-shaped array for functions with k predictors, but can actually be any object. ydata : array_like The dependent data, a length M array - nominally ``f(xdata, ...)``. p0 : array_like, optional Initial guess for the parameters (length N). If None, then the initial values will all be 1 (if the number of parameters for the function can be determined using introspection, otherwise a ValueError is raised). sigma : None or M-length sequence or MxM array, optional Determines the uncertainty in `ydata`. If we define residuals as ``r = ydata - f(xdata, *popt)``, then the interpretation of `sigma` depends on its number of dimensions: - A 1-d `sigma` should contain values of standard deviations of errors in `ydata`. In this case, the optimized function is ``chisq = sum((r / sigma) ** 2)``. - A 2-d `sigma` should contain the covariance matrix of errors in `ydata`. In this case, the optimized function is ``chisq = r.T @ inv(sigma) @ r``. .. versionadded:: 0.19 None (default) is equivalent of 1-d `sigma` filled with ones. absolute_sigma : bool, optional If True, `sigma` is used in an absolute sense and the estimated parameter covariance `pcov` reflects these absolute values. If False, only the relative magnitudes of the `sigma` values matter. The returned parameter covariance matrix `pcov` is based on scaling `sigma` by a constant factor. This constant is set by demanding that the reduced `chisq` for the optimal parameters `popt` when using the *scaled* `sigma` equals unity. In other words, `sigma` is scaled to match the sample variance of the residuals after the fit. Mathematically, ``pcov(absolute_sigma=False) = pcov(absolute_sigma=True) * chisq(popt)/(M-N)`` check_finite : bool, optional If True, check that the input arrays do not contain nans of infs, and raise a ValueError if they do. Setting this parameter to False may silently produce nonsensical results if the input arrays do contain nans. Default is True. bounds : 2-tuple of array_like, optional Lower and upper bounds on parameters. Defaults to no bounds. Each element of the tuple must be either an array with the length equal to the number of parameters, or a scalar (in which case the bound is taken to be the same for all parameters.) Use ``np.inf`` with an appropriate sign to disable bounds on all or some parameters. .. versionadded:: 0.17 method : {'lm', 'trf', 'dogbox'}, optional Method to use for optimization. See `least_squares` for more details. Default is 'lm' for unconstrained problems and 'trf' if `bounds` are provided. The method 'lm' won't work when the number of observations is less than the number of variables, use 'trf' or 'dogbox' in this case. .. versionadded:: 0.17 jac : callable, string or None, optional Function with signature ``jac(x, ...)`` which computes the Jacobian matrix of the model function with respect to parameters as a dense array_like structure. It will be scaled according to provided `sigma`. If None (default), the Jacobian will be estimated numerically. String keywords for 'trf' and 'dogbox' methods can be used to select a finite difference scheme, see `least_squares`. .. versionadded:: 0.18 kwargs Keyword arguments passed to `leastsq` for ``method='lm'`` or `least_squares` otherwise. Returns ------- popt : array Optimal values for the parameters so that the sum of the squared residuals of ``f(xdata, *popt) - ydata`` is minimized pcov : 2d array The estimated covariance of popt. The diagonals provide the variance of the parameter estimate. To compute one standard deviation errors on the parameters use ``perr = np.sqrt(np.diag(pcov))``. How the `sigma` parameter affects the estimated covariance depends on `absolute_sigma` argument, as described above. If the Jacobian matrix at the solution doesn't have a full rank, then 'lm' method returns a matrix filled with ``np.inf``, on the other hand 'trf' and 'dogbox' methods use Moore-Penrose pseudoinverse to compute the covariance matrix. Raises ------ ValueError if either `ydata` or `xdata` contain NaNs, or if incompatible options are used. RuntimeError if the least-squares minimization fails. OptimizeWarning if covariance of the parameters can not be estimated. See Also -------- least_squares : Minimize the sum of squares of nonlinear functions. scipy.stats.linregress : Calculate a linear least squares regression for two sets of measurements. Notes ----- With ``method='lm'``, the algorithm uses the Levenberg-Marquardt algorithm through `leastsq`. Note that this algorithm can only deal with unconstrained problems. Box constraints can be handled by methods 'trf' and 'dogbox'. Refer to the docstring of `least_squares` for more information. Examples -------- >>> import matplotlib.pyplot as plt >>> from scipy.optimize import curve_fit >>> def func(x, a, b, c): ... return a * np.exp(-b * x) + c Define the data to be fit with some noise: >>> xdata = np.linspace(0, 4, 50) >>> y = func(xdata, 2.5, 1.3, 0.5) >>> np.random.seed(1729) >>> y_noise = 0.2 * np.random.normal(size=xdata.size) >>> ydata = y + y_noise >>> plt.plot(xdata, ydata, 'b-', label='data') Fit for the parameters a, b, c of the function `func`: >>> popt, pcov = curve_fit(func, xdata, ydata) >>> popt array([ 2.55423706, 1.35190947, 0.47450618]) >>> plt.plot(xdata, func(xdata, *popt), 'r-', ... label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt)) Constrain the optimization to the region of ``0 <= a <= 3``, ``0 <= b <= 1`` and ``0 <= c <= 0.5``: >>> popt, pcov = curve_fit(func, xdata, ydata, bounds=(0, [3., 1., 0.5])) >>> popt array([ 2.43708906, 1. , 0.35015434]) >>> plt.plot(xdata, func(xdata, *popt), 'g--', ... label='fit: a=%5.3f, b=%5.3f, c=%5.3f' % tuple(popt)) >>> plt.xlabel('x') >>> plt.ylabel('y') >>> plt.legend() >>> plt.show() """ if p0 is None: # determine number of parameters by inspecting the function from scipy._lib._util import getargspec_no_self as _getargspec args, varargs, varkw, defaults = _getargspec(f) if len(args) < 2: raise ValueError("Unable to determine number of fit parameters.") n = len(args) - 1 else: p0 = np.atleast_1d(p0) n = p0.size lb, ub = prepare_bounds(bounds, n) if p0 is None: p0 = _initialize_feasible(lb, ub) bounded_problem = np.any((lb > -np.inf) | (ub < np.inf)) if method is None: if bounded_problem: method = 'trf' else: method = 'lm' if method == 'lm' and bounded_problem: raise ValueError("Method 'lm' only works for unconstrained problems. " "Use 'trf' or 'dogbox' instead.") # optimization may produce garbage for float32 inputs, cast them to float64 # NaNs can not be handled if check_finite: ydata = np.asarray_chkfinite(ydata, float) else: ydata = np.asarray(ydata, float) if isinstance(xdata, (list, tuple, np.ndarray)): # `xdata` is passed straight to the user-defined `f`, so allow # non-array_like `xdata`. if check_finite: xdata = np.asarray_chkfinite(xdata, float) else: xdata = np.asarray(xdata, float) if ydata.size == 0: raise ValueError("`ydata` must not be empty!") # Determine type of sigma if sigma is not None: sigma = np.asarray(sigma) # if 1-d, sigma are errors, define transform = 1/sigma if sigma.shape == (ydata.size, ): transform = 1.0 / sigma # if 2-d, sigma is the covariance matrix, # define transform = L such that L L^T = C elif sigma.shape == (ydata.size, ydata.size): try: # scipy.linalg.cholesky requires lower=True to return L L^T = A transform = cholesky(sigma, lower=True) except LinAlgError: raise ValueError("`sigma` must be positive definite.") else: raise ValueError("`sigma` has incorrect shape.") else: transform = None func = _wrap_func(f, xdata, ydata, transform) if callable(jac): jac = _wrap_jac(jac, xdata, transform) elif jac is None and method != 'lm': jac = '2-point' if method == 'lm': # Remove full_output from kwargs, otherwise we're passing it in twice. return_full = kwargs.pop('full_output', False) res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs) popt, pcov, infodict, errmsg, ier = res ysize = len(infodict['fvec']) cost = np.sum(infodict['fvec']**2) if ier not in [1, 2, 3, 4]: raise RuntimeError("Optimal parameters not found: " + errmsg) else: # Rename maxfev (leastsq) to max_nfev (least_squares), if specified. if 'max_nfev' not in kwargs: kwargs['max_nfev'] = kwargs.pop('maxfev', None) res = least_squares(func, p0, jac=jac, bounds=bounds, method=method, **kwargs) if not res.success: raise RuntimeError("Optimal parameters not found: " + res.message) ysize = len(res.fun) cost = 2 * res.cost # res.cost is half sum of squares! popt = res.x # Do Moore-Penrose inverse discarding zero singular values. _, s, VT = svd(res.jac, full_matrices=False) threshold = np.finfo(float).eps * max(res.jac.shape) * s[0] s = s[s > threshold] VT = VT[:s.size] pcov = np.dot(VT.T / s**2, VT) return_full = False warn_cov = False if pcov is None: # indeterminate covariance pcov = zeros((len(popt), len(popt)), dtype=float) pcov.fill(inf) warn_cov = True elif not absolute_sigma: if ysize > p0.size: s_sq = cost / (ysize - p0.size) pcov = pcov * s_sq else: pcov.fill(inf) warn_cov = True if warn_cov: warnings.warn('Covariance of the parameters could not be estimated', category=OptimizeWarning) if return_full: return popt, pcov, infodict, errmsg, ier else: return popt, pcov
def qr_multiply(a, c, mode='right', pivoting=False, conjugate=False, overwrite_a=False, overwrite_c=False): """ Calculate the QR decomposition and multiply Q with a matrix. Calculate the decomposition ``A = Q R`` where Q is unitary/orthogonal and R upper triangular. Multiply Q with a vector or a matrix c. Parameters ---------- a : (M, N), array_like Input array c : array_like Input array to be multiplied by ``q``. mode : {'left', 'right'}, optional ``Q @ c`` is returned if mode is 'left', ``c @ Q`` is returned if mode is 'right'. The shape of c must be appropriate for the matrix multiplications, if mode is 'left', ``min(a.shape) == c.shape[0]``, if mode is 'right', ``a.shape[0] == c.shape[1]``. pivoting : bool, optional Whether or not factorization should include pivoting for rank-revealing qr decomposition, see the documentation of qr. conjugate : bool, optional Whether Q should be complex-conjugated. This might be faster than explicit conjugation. overwrite_a : bool, optional Whether data in a is overwritten (may improve performance) overwrite_c : bool, optional Whether data in c is overwritten (may improve performance). If this is used, c must be big enough to keep the result, i.e. ``c.shape[0]`` = ``a.shape[0]`` if mode is 'left'. Returns ------- CQ : ndarray The product of ``Q`` and ``c``. R : (K, N), ndarray R array of the resulting QR factorization where ``K = min(M, N)``. P : (N,) ndarray Integer pivot array. Only returned when ``pivoting=True``. Raises ------ LinAlgError Raised if QR decomposition fails. Notes ----- This is an interface to the LAPACK routines ``?GEQRF``, ``?ORMQR``, ``?UNMQR``, and ``?GEQP3``. .. versionadded:: 0.11.0 Examples -------- >>> from scipy.linalg import qr_multiply, qr >>> A = np.array([[1, 3, 3], [2, 3, 2], [2, 3, 3], [1, 3, 2]]) >>> qc, r1, piv1 = qr_multiply(A, 2*np.eye(4), pivoting=1) >>> qc array([[-1., 1., -1.], [-1., -1., 1.], [-1., -1., -1.], [-1., 1., 1.]]) >>> r1 array([[-6., -3., -5. ], [ 0., -1., -1.11022302e-16], [ 0., 0., -1. ]]) >>> piv1 array([1, 0, 2], dtype=int32) >>> q2, r2, piv2 = qr(A, mode='economic', pivoting=1) >>> np.allclose(2*q2 - qc, np.zeros((4, 3))) True """ if mode not in ['left', 'right']: raise ValueError("Mode argument can only be 'left' or 'right' but " "not '{}'".format(mode)) c = numpy.asarray_chkfinite(c) if c.ndim < 2: onedim = True c = numpy.atleast_2d(c) if mode == "left": c = c.T else: onedim = False a = numpy.atleast_2d(numpy.asarray(a)) # chkfinite done in qr M, N = a.shape if mode == 'left': if c.shape[0] != min(M, N + overwrite_c * (M - N)): raise ValueError('Array shapes are not compatible for Q @ c' ' operation: {} vs {}'.format(a.shape, c.shape)) else: if M != c.shape[1]: raise ValueError('Array shapes are not compatible for c @ Q' ' operation: {} vs {}'.format(c.shape, a.shape)) raw = qr(a, overwrite_a, None, "raw", pivoting) Q, tau = raw[0] gor_un_mqr, = get_lapack_funcs(('ormqr', ), (Q, )) if gor_un_mqr.typecode in ('s', 'd'): trans = "T" else: trans = "C" Q = Q[:, :min(M, N)] if M > N and mode == "left" and not overwrite_c: if conjugate: cc = numpy.zeros((c.shape[1], M), dtype=c.dtype, order="F") cc[:, :N] = c.T else: cc = numpy.zeros((M, c.shape[1]), dtype=c.dtype, order="F") cc[:N, :] = c trans = "N" if conjugate: lr = "R" else: lr = "L" overwrite_c = True elif c.flags["C_CONTIGUOUS"] and trans == "T" or conjugate: cc = c.T if mode == "left": lr = "R" else: lr = "L" else: trans = "N" cc = c if mode == "left": lr = "L" else: lr = "R" cQ, = safecall(gor_un_mqr, "gormqr/gunmqr", lr, trans, Q, tau, cc, overwrite_c=overwrite_c) if trans != "N": cQ = cQ.T if mode == "right": cQ = cQ[:, :min(M, N)] if onedim: cQ = cQ.ravel() return (cQ, ) + raw[1:]
def schur(a, output='real', lwork=None, overwrite_a=False, sort=None, check_finite=True): """ Compute Schur decomposition of a matrix. The Schur decomposition is:: A = Z T Z^H where Z is unitary and T is either upper-triangular, or for real Schur decomposition (output='real'), quasi-upper triangular. In the quasi-triangular form, 2x2 blocks describing complex-valued eigenvalue pairs may extrude from the diagonal. Parameters ---------- a : (M, M) array_like Matrix to decompose output : {'real', 'complex'}, optional Construct the real or complex Schur decomposition (for real matrices). lwork : int, optional Work array size. If None or -1, it is automatically computed. overwrite_a : bool, optional Whether to overwrite data in a (may improve performance). sort : {None, callable, 'lhp', 'rhp', 'iuc', 'ouc'}, optional Specifies whether the upper eigenvalues should be sorted. A callable may be passed that, given a eigenvalue, returns a boolean denoting whether the eigenvalue should be sorted to the top-left (True). Alternatively, string parameters may be used:: 'lhp' Left-hand plane (x.real < 0.0) 'rhp' Right-hand plane (x.real > 0.0) 'iuc' Inside the unit circle (x*x.conjugate() <= 1.0) 'ouc' Outside the unit circle (x*x.conjugate() > 1.0) Defaults to None (no sorting). check_finite : bool, 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 ------- T : (M, M) ndarray Schur form of A. It is real-valued for the real Schur decomposition. Z : (M, M) ndarray An unitary Schur transformation matrix for A. It is real-valued for the real Schur decomposition. sdim : int If and only if sorting was requested, a third return value will contain the number of eigenvalues satisfying the sort condition. Raises ------ LinAlgError Error raised under three conditions: 1. The algorithm failed due to a failure of the QR algorithm to compute all eigenvalues. 2. If eigenvalue sorting was requested, the eigenvalues could not be reordered due to a failure to separate eigenvalues, usually because of poor conditioning. 3. If eigenvalue sorting was requested, roundoff errors caused the leading eigenvalues to no longer satisfy the sorting condition. See also -------- rsf2csf : Convert real Schur form to complex Schur form Examples -------- >>> from scipy.linalg import schur, eigvals >>> A = np.array([[0, 2, 2], [0, 1, 2], [1, 0, 1]]) >>> T, Z = schur(A) >>> T array([[ 2.65896708, 1.42440458, -1.92933439], [ 0. , -0.32948354, -0.49063704], [ 0. , 1.31178921, -0.32948354]]) >>> Z array([[0.72711591, -0.60156188, 0.33079564], [0.52839428, 0.79801892, 0.28976765], [0.43829436, 0.03590414, -0.89811411]]) >>> T2, Z2 = schur(A, output='complex') >>> T2 array([[ 2.65896708, -1.22839825+1.32378589j, 0.42590089+1.51937378j], [ 0. , -0.32948354+0.80225456j, -0.59877807+0.56192146j], [ 0. , 0. , -0.32948354-0.80225456j]]) >>> eigvals(T2) array([2.65896708, -0.32948354+0.80225456j, -0.32948354-0.80225456j]) An arbitrary custom eig-sorting condition, having positive imaginary part, which is satisfied by only one eigenvalue >>> T3, Z3, sdim = schur(A, output='complex', sort=lambda x: x.imag > 0) >>> sdim 1 """ if output not in ['real', 'complex', 'r', 'c']: raise ValueError("argument must be 'real', or 'complex'") if check_finite: a1 = asarray_chkfinite(a) else: a1 = asarray(a) if len(a1.shape) != 2 or (a1.shape[0] != a1.shape[1]): raise ValueError('expected square matrix') typ = a1.dtype.char if output in ['complex', 'c'] and typ not in ['F', 'D']: if typ in _double_precision: a1 = a1.astype('D') typ = 'D' else: a1 = a1.astype('F') typ = 'F' overwrite_a = overwrite_a or (_datacopied(a1, a)) gees, = get_lapack_funcs(('gees', ), (a1, )) if lwork is None or lwork == -1: # get optimal work array result = gees(lambda x: None, a1, lwork=-1) lwork = result[-2][0].real.astype(numpy.int) if sort is None: sort_t = 0 sfunction = lambda x: None else: sort_t = 1 if callable(sort): sfunction = sort elif sort == 'lhp': sfunction = lambda x: (x.real < 0.0) elif sort == 'rhp': sfunction = lambda x: (x.real >= 0.0) elif sort == 'iuc': sfunction = lambda x: (abs(x) <= 1.0) elif sort == 'ouc': sfunction = lambda x: (abs(x) > 1.0) else: raise ValueError("'sort' parameter must either be 'None', or a " "callable, or one of ('lhp','rhp','iuc','ouc')") result = gees(sfunction, a1, lwork=lwork, overwrite_a=overwrite_a, sort_t=sort_t) info = result[-1] if info < 0: raise ValueError('illegal value in {}-th argument of internal gees' ''.format(-info)) elif info == a1.shape[0] + 1: raise LinAlgError('Eigenvalues could not be separated for reordering.') elif info == a1.shape[0] + 2: raise LinAlgError('Leading eigenvalues do not satisfy sort condition.') elif info > 0: raise LinAlgError("Schur form not found. Possibly ill-conditioned.") if sort_t == 0: return result[0], result[-3] else: return result[0], result[-3], result[1]
def norm(x, ord=None): """Matrix or vector norm. Parameters ---------- x : array, shape (M,) or (M, N) ord : number, or {None, 1, -1, 2, -2, inf, -inf, 'fro'} Order of the norm: ===== ============================ ========================== ord norm for matrices norm for vectors ===== ============================ ========================== None Frobenius norm 2-norm 'fro' Frobenius norm -- inf max(sum(abs(x), axis=1)) max(abs(x)) -inf min(sum(abs(x), axis=1)) min(abs(x)) 1 max(sum(abs(x), axis=0)) as below -1 min(sum(abs(x), axis=0)) as below 2 2-norm (largest sing. value) as below -2 smallest singular value as below other -- sum(abs(x)**ord)**(1./ord) ===== ============================ ========================== Returns ------- n : float Norm of the matrix or vector Notes ----- For values ord < 0, the result is, strictly speaking, not a mathematical 'norm', but it may still be useful for numerical purposes. """ x = asarray_chkfinite(x) if ord is None: # check the default case first and handle it immediately return sqrt(add.reduce(real((conjugate(x) * x).ravel()))) nd = len(x.shape) Inf = numpy.Inf if nd == 1: if ord == Inf: return numpy.amax(abs(x)) elif ord == -Inf: return numpy.amin(abs(x)) elif ord == 1: return numpy.sum(abs(x), axis=0) # special case for speedup elif ord == 2: return sqrt(numpy.sum(real((conjugate(x) * x)), axis=0)) # special case for speedup else: return numpy.sum(abs(x)**ord, axis=0)**(1.0 / ord) elif nd == 2: if ord == 2: return numpy.amax(decomp.svd(x, compute_uv=0)) elif ord == -2: return numpy.amin(decomp.svd(x, compute_uv=0)) elif ord == 1: return numpy.amax(numpy.sum(abs(x), axis=0)) elif ord == Inf: return numpy.amax(numpy.sum(abs(x), axis=1)) elif ord == -1: return numpy.amin(numpy.sum(abs(x), axis=0)) elif ord == -Inf: return numpy.amin(numpy.sum(abs(x), axis=1)) elif ord in ['fro', 'f']: return sqrt(add.reduce(real((conjugate(x) * x).ravel()))) else: raise ValueError, "Invalid norm order for matrices." else: raise ValueError, "Improper number of dimensions to norm."
def timeshifted_split(inputs, lagtime: int, chunksize: int = 1000, stride: int = 1, n_splits: Optional[int] = None, shuffle: bool = False, random_state: Optional[np.random.RandomState] = None): r""" Utility function which splits input trajectories into pairs of timeshifted data :math:`(X_t, X_{t+\tau})`. In case multiple trajectories are provided, the timeshifted pairs are always within the same trajectory. Parameters ---------- inputs : (T, n) ndarray or list of (T_i, n) ndarrays Input trajectory or trajectories. In case multiple trajectories are provided, they must have the same dimension in the second axis but may be of variable length. lagtime : int The lag time :math:`\tau` used to produce timeshifted blocks. chunksize : int, default=1000 The chunk size, i.e., the maximal length of the blocks. stride: int, default=1 Optional stride which is applied *after* creating a tau-shifted version of the dataset. n_splits : int, optional, default=None Alternative to chunksize - this determines the number of timeshifted blocks that is drawn from each provided trajectory. Supersedes whatever was provided as chunksize. shuffle : bool, default=False Whether to shuffle the data prior to splitting it. random_state : np.random.RandomState, default=None When shuffling this can be used to set a specific random state. Returns ------- iterable : Generator A Python generator which can be iterated. Examples -------- Using chunksize: >>> data = np.array([0, 1, 2, 3, 4, 5, 6]) >>> for X, Y in timeshifted_split(data, lagtime=1, chunksize=4): ... print(X, Y) [0 1 2 3] [1 2 3 4] [4 5] [5 6] Using n_splits: >>> data = np.array([0, 1, 2, 3, 4, 5, 6]) >>> for X, Y in timeshifted_split(data, lagtime=1, n_splits=2): ... print(X, Y) [0 1 2] [1 2 3] [3 4 5] [4 5 6] """ if lagtime < 0: raise ValueError('lagtime has to be positive') if int(chunksize) < 0: raise ValueError('chunksize has to be positive') if shuffle and random_state is None: random_state = np.random.RandomState() if not isinstance(inputs, list): if isinstance(inputs, tuple): inputs = list(inputs) inputs = [inputs] if not all(len(data) > lagtime for data in inputs): too_short_inputs = [ i for i, x in enumerate(inputs) if len(x) < lagtime ] raise ValueError( f'Input contained to short (smaller than lagtime({lagtime}) at following ' f'indices: {too_short_inputs}') for data in inputs: data = np.asarray_chkfinite(data) data_lagged = data[lagtime:][::stride] if lagtime > 0: data = data[:-lagtime][::stride] else: data = data[ 0::stride] # otherwise data is empty as slice over `data[:-0]` ix = np.arange(len(data)) # iota range over data if shuffle: random_state.shuffle(ix) if n_splits is not None: assert n_splits >= 1 for ix_split in np.array_split(ix, n_splits): if len(ix_split) > 0: x = data[ix_split] if lagtime > 0: x_lagged = data_lagged[ix_split] yield x, x_lagged else: yield x else: break else: t = 0 while t < len(data): if t == len(data_lagged): break x = data[ix[t:min(t + chunksize, len(data))]] if lagtime > 0: x_lagged = data_lagged[ ix[t:min(t + chunksize, len(data_lagged))]] yield x, x_lagged else: yield x t += chunksize
def curve_fit(f, xdata, ydata, p0=None, sigma=None, absolute_sigma=False, check_finite=True, bounds=(-np.inf, np.inf), method=None, jac=None, **kwargs): """ Use non-linear least squares to fit a function, f, to data. Assumes ``ydata = f(xdata, *params) + eps`` Parameters ---------- f : callable The model function, f(x, ...). It must take the independent variable as the first argument and the parameters to fit as separate remaining arguments. xdata : An M-length sequence or an (k,M)-shaped array for functions with k predictors. The independent variable where the data is measured. ydata : M-length sequence The dependent data --- nominally f(xdata, ...) p0 : None, scalar, or N-length sequence, optional Initial guess for the parameters. If None, then the initial values will all be 1 (if the number of parameters for the function can be determined using introspection, otherwise a ValueError is raised). sigma : None or M-length sequence, optional If not None, the uncertainties in the ydata array. These are used as weights in the least-squares problem i.e. minimising ``np.sum( ((f(xdata, *popt) - ydata) / sigma)**2 )`` If None, the uncertainties are assumed to be 1. absolute_sigma : bool, optional If False, `sigma` denotes relative weights of the data points. The returned covariance matrix `pcov` is based on *estimated* errors in the data, and is not affected by the overall magnitude of the values in `sigma`. Only the relative magnitudes of the `sigma` values matter. If True, `sigma` describes one standard deviation errors of the input data points. The estimated covariance in `pcov` is based on these values. check_finite : bool, optional If True, check that the input arrays do not contain nans of infs, and raise a ValueError if they do. Setting this parameter to False may silently produce nonsensical results if the input arrays do contain nans. Default is True. bounds : 2-tuple of array_like, optional Lower and upper bounds on independent variables. Defaults to no bounds. Each element of the tuple must be either an array with the length equal to the number of parameters, or a scalar (in which case the bound is taken to be the same for all parameters.) Use ``np.inf`` with an appropriate sign to disable bounds on all or some parameters. .. versionadded:: 0.17 method : {'lm', 'trf', 'dogbox'}, optional Method to use for optimization. See `least_squares` for more details. Default is 'lm' for unconstrained problems and 'trf' if `bounds` are provided. The method 'lm' won't work when the number of observations is less than the number of variables, use 'trf' or 'dogbox' in this case. .. versionadded:: 0.17 jac : callable, string or None, optional Function with signature ``jac(x, ...)`` which computes the Jacobian matrix of the model function with respect to parameters as a dense array_like structure. It will be scaled according to provided `sigma`. If None (default), the Jacobian will be estimated numerically. String keywords for 'trf' and 'dogbox' methods can be used to select a finite difference scheme, see `least_squares`. .. versionadded:: 0.18 kwargs Keyword arguments passed to `leastsq` for ``method='lm'`` or `least_squares` otherwise. Returns ------- popt : array Optimal values for the parameters so that the sum of the squared error of ``f(xdata, *popt) - ydata`` is minimized pcov : 2d array The estimated covariance of popt. The diagonals provide the variance of the parameter estimate. To compute one standard deviation errors on the parameters use ``perr = np.sqrt(np.diag(pcov))``. How the `sigma` parameter affects the estimated covariance depends on `absolute_sigma` argument, as described above. If the Jacobian matrix at the solution doesn't have a full rank, then 'lm' method returns a matrix filled with ``np.inf``, on the other hand 'trf' and 'dogbox' methods use Moore-Penrose pseudoinverse to compute the covariance matrix. Raises ------ ValueError if either `ydata` or `xdata` contain NaNs, or if incompatible options are used. RuntimeError if the least-squares minimization fails. OptimizeWarning if covariance of the parameters can not be estimated. See Also -------- least_squares : Minimize the sum of squares of nonlinear functions. stats.linregress : Calculate a linear least squares regression for two sets of measurements. Notes ----- With ``method='lm'``, the algorithm uses the Levenberg-Marquardt algorithm through `leastsq`. Note that this algorithm can only deal with unconstrained problems. Box constraints can be handled by methods 'trf' and 'dogbox'. Refer to the docstring of `least_squares` for more information. Examples -------- >>> import numpy as np >>> from scipy.optimize import curve_fit >>> def func(x, a, b, c): ... return a * np.exp(-b * x) + c >>> xdata = np.linspace(0, 4, 50) >>> y = func(xdata, 2.5, 1.3, 0.5) >>> ydata = y + 0.2 * np.random.normal(size=len(xdata)) >>> popt, pcov = curve_fit(func, xdata, ydata) Constrain the optimization to the region of ``0 < a < 3``, ``0 < b < 2`` and ``0 < c < 1``: >>> popt, pcov = curve_fit(func, xdata, ydata, bounds=(0, [3., 2., 1.])) """ if p0 is None: # determine number of parameters by inspecting the function from scipy._lib._util import getargspec_no_self as _getargspec args, varargs, varkw, defaults = _getargspec(f) if len(args) < 2: raise ValueError("Unable to determine number of fit parameters.") n = len(args) - 1 else: p0 = np.atleast_1d(p0) n = p0.size lb, ub = prepare_bounds(bounds, n) if p0 is None: p0 = _initialize_feasible(lb, ub) bounded_problem = np.any((lb > -np.inf) | (ub < np.inf)) if method is None: if bounded_problem: method = 'trf' else: method = 'lm' if method == 'lm' and bounded_problem: raise ValueError("Method 'lm' only works for unconstrained problems. " "Use 'trf' or 'dogbox' instead.") # NaNs can not be handled if check_finite: ydata = np.asarray_chkfinite(ydata) else: ydata = np.asarray(ydata) if isinstance(xdata, (list, tuple, np.ndarray)): # `xdata` is passed straight to the user-defined `f`, so allow # non-array_like `xdata`. if check_finite: xdata = np.asarray_chkfinite(xdata) else: xdata = np.asarray(xdata) weights = 1.0 / asarray(sigma) if sigma is not None else None func = _wrap_func(f, xdata, ydata, weights) if callable(jac): jac = _wrap_jac(jac, xdata, weights) elif jac is None and method != 'lm': jac = '2-point' if method == 'lm': # Remove full_output from kwargs, otherwise we're passing it in twice. return_full = kwargs.pop('full_output', False) res = leastsq(func, p0, Dfun=jac, full_output=1, **kwargs) popt, pcov, infodict, errmsg, ier = res cost = np.sum(infodict['fvec'] ** 2) if ier not in [1, 2, 3, 4]: raise RuntimeError("Optimal parameters not found: " + errmsg) else: res = least_squares(func, p0, jac=jac, bounds=bounds, method=method, **kwargs) if not res.success: raise RuntimeError("Optimal parameters not found: " + res.message) cost = 2 * res.cost # res.cost is half sum of squares! popt = res.x # Do Moore-Penrose inverse discarding zero singular values. _, s, VT = svd(res.jac, full_matrices=False) threshold = np.finfo(float).eps * max(res.jac.shape) * s[0] s = s[s > threshold] VT = VT[:s.size] pcov = np.dot(VT.T / s**2, VT) return_full = False warn_cov = False if pcov is None: # indeterminate covariance pcov = zeros((len(popt), len(popt)), dtype=float) pcov.fill(inf) warn_cov = True elif not absolute_sigma: if ydata.size > p0.size: s_sq = cost / (ydata.size - p0.size) pcov = pcov * s_sq else: pcov.fill(inf) warn_cov = True if warn_cov: warnings.warn('Covariance of the parameters could not be estimated', category=OptimizeWarning) if return_full: return popt, pcov, infodict, errmsg, ier else: return popt, pcov
def trid(x): x = np.asarray_chkfinite(x) return sum((x - 1)**2) - sum(x[:-1] * x[1:])
def rq(a, overwrite_a=False, lwork=None, mode='full'): """Compute RQ decomposition of a square real matrix. Calculate the decomposition :lm:`A = R Q` where Q is unitary/orthogonal and R upper triangular. Parameters ---------- a : array, shape (M, M) Matrix to be decomposed overwrite_a : boolean Whether data in a is overwritten (may improve performance) lwork : integer Work array size, lwork >= a.shape[1]. If None or -1, an optimal size is computed. mode : {'full', 'r', 'economic'} Determines what information is to be returned: either both Q and R ('full', default), only R ('r') or both Q and R but computed in economy-size ('economic', see Notes). Returns ------- R : float array, shape (M, N) Q : float or complex array, shape (M, M) Raises LinAlgError if decomposition fails Examples -------- >>> from scipy import linalg >>> from numpy import random, dot, allclose >>> a = random.randn(6, 9) >>> r, q = linalg.rq(a) >>> allclose(a, dot(r, q)) True >>> r.shape, q.shape ((6, 9), (9, 9)) >>> r2 = linalg.rq(a, mode='r') >>> allclose(r, r2) True >>> r3, q3 = linalg.rq(a, mode='economic') >>> r3.shape, q3.shape ((6, 6), (6, 9)) """ if not mode in ['full', 'r', 'economic']: raise ValueError(\ "Mode argument should be one of ['full', 'r', 'economic']") a1 = numpy.asarray_chkfinite(a) if len(a1.shape) != 2: raise ValueError('expected matrix') M, N = a1.shape overwrite_a = overwrite_a or (_datacopied(a1, a)) gerqf, = get_lapack_funcs(('gerqf', ), (a1, )) if lwork is None or lwork == -1: # get optimal work array rq, tau, work, info = gerqf(a1, lwork=-1, overwrite_a=1) lwork = work[0].real.astype(numpy.int) rq, tau, work, info = gerqf(a1, lwork=lwork, overwrite_a=overwrite_a) if info < 0: raise ValueError('illegal value in %d-th argument of internal gerqf' % -info) if not mode == 'economic' or N < M: R = numpy.triu(rq, N - M) else: R = numpy.triu(rq[-M:, -M:]) if mode == 'r': return R if find_best_lapack_type((a1, ))[0] in ('s', 'd'): gor_un_grq, = get_lapack_funcs(('orgrq', ), (rq, )) else: gor_un_grq, = get_lapack_funcs(('ungrq', ), (rq, )) if N < M: # get optimal work array Q, work, info = gor_un_grq(rq[-N:], tau, lwork=-1, overwrite_a=1) lwork = work[0].real.astype(numpy.int) Q, work, info = gor_un_grq(rq[-N:], tau, lwork=lwork, overwrite_a=1) elif mode == 'economic': # get optimal work array Q, work, info = gor_un_grq(rq, tau, lwork=-1, overwrite_a=1) lwork = work[0].real.astype(numpy.int) Q, work, info = gor_un_grq(rq, tau, lwork=lwork, overwrite_a=1) else: rq1 = numpy.empty((N, N), dtype=rq.dtype) rq1[-M:] = rq # get optimal work array Q, work, info = gor_un_grq(rq1, tau, lwork=-1, overwrite_a=1) lwork = work[0].real.astype(numpy.int) Q, work, info = gor_un_grq(rq1, tau, lwork=lwork, overwrite_a=1) if info < 0: raise ValueError("illegal value in %d-th argument of internal orgrq" % -info) return R, Q
def lu_factor(a, overwrite_a=False, check_finite=True): """ Compute pivoted LU decomposition of a matrix. The decomposition is:: A = P L U where P is a permutation matrix, L lower triangular with unit diagonal elements, and U upper triangular. Parameters ---------- a : (M, M) array_like Matrix to decompose overwrite_a : bool, optional Whether to overwrite data in A (may increase performance) check_finite : bool, 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 ------- lu : (N, N) ndarray Matrix containing U in its upper triangle, and L in its lower triangle. The unit diagonal elements of L are not stored. piv : (N,) ndarray Pivot indices representing the permutation matrix P: row i of matrix was interchanged with row piv[i]. See also -------- lu_solve : solve an equation system using the LU factorization of a matrix Notes ----- This is a wrapper to the ``*GETRF`` routines from LAPACK. Examples -------- >>> from scipy.linalg import lu_factor >>> from numpy import tril, triu, allclose, zeros, eye >>> A = np.array([[2, 5, 8, 7], [5, 2, 2, 8], [7, 5, 6, 6], [5, 4, 4, 8]]) >>> lu, piv = lu_factor(A) >>> piv array([2, 2, 3, 3], dtype=int32) Convert LAPACK's ``piv`` array to NumPy index and test the permutation >>> piv_py = [2, 0, 3, 1] >>> L, U = np.tril(lu, k=-1) + np.eye(4), np.triu(lu) >>> np.allclose(A[piv_py] - L @ U, np.zeros((4, 4))) True """ if check_finite: a1 = asarray_chkfinite(a) else: a1 = 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)) getrf, = get_lapack_funcs(('getrf', ), (a1, )) lu, piv, info = getrf(a1, overwrite_a=overwrite_a) if info < 0: raise ValueError('illegal value in %d-th argument of ' 'internal getrf (lu_factor)' % -info) if info > 0: warn("Diagonal number %d is exactly zero. Singular matrix." % info, LinAlgWarning, stacklevel=2) return lu, piv
def eigh(a, b=None, lower=True, eigvals_only=False, overwrite_a=False, overwrite_b=False, turbo=True, eigvals=None, type=1): """Solve an ordinary or generalized eigenvalue problem for a complex Hermitian or real symmetric matrix. Find eigenvalues w and optionally eigenvectors v of matrix a, where b is positive definite:: a v[:,i] = w[i] b v[:,i] v[i,:].conj() a v[:,i] = w[i] v[i,:].conj() b v[:,i] = 1 Parameters ---------- a : array, shape (M, M) A complex Hermitian or real symmetric matrix whose eigenvalues and eigenvectors will be computed. b : array, shape (M, M) A complex Hermitian or real symmetric definite positive matrix in. If omitted, identity matrix is assumed. lower : boolean Whether the pertinent array data is taken from the lower or upper triangle of a. (Default: lower) eigvals_only : boolean Whether to calculate only eigenvalues and no eigenvectors. (Default: both are calculated) turbo : boolean Use divide and conquer algorithm (faster but expensive in memory, only for generalized eigenvalue problem and if eigvals=None) eigvals : tuple (lo, hi) Indexes of the smallest and largest (in ascending order) eigenvalues and corresponding eigenvectors to be returned: 0 <= lo < hi <= M-1. If omitted, all eigenvalues and eigenvectors are returned. type: integer Specifies the problem type to be solved: type = 1: a v[:,i] = w[i] b v[:,i] type = 2: a b v[:,i] = w[i] v[:,i] type = 3: b a v[:,i] = w[i] v[:,i] overwrite_a : boolean Whether to overwrite data in a (may improve performance) overwrite_b : boolean Whether to overwrite data in b (may improve performance) Returns ------- w : real array, shape (N,) The N (1<=N<=M) selected eigenvalues, in ascending order, each repeated according to its multiplicity. (if eigvals_only == False) v : complex array, shape (M, N) The normalized selected eigenvector corresponding to the eigenvalue w[i] is the column v[:,i]. Normalization: type 1 and 3: v.conj() a v = w type 2: inv(v).conj() a inv(v) = w type = 1 or 2: v.conj() b v = I type = 3 : v.conj() inv(b) v = I Raises LinAlgError if eigenvalue computation does not converge, an error occurred, or b matrix is not definite positive. Note that if input matrices are not symmetric or hermitian, no error is reported but results will be wrong. See Also -------- eig : eigenvalues and right eigenvectors for non-symmetric arrays """ 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)) if iscomplexobj(a1): cplx = True else: cplx = False if b is not None: b1 = asarray_chkfinite(b) overwrite_b = overwrite_b or _datacopied(b1, b) if len(b1.shape) != 2 or b1.shape[0] != b1.shape[1]: raise ValueError('expected square matrix') if b1.shape != a1.shape: raise ValueError("wrong b dimensions %s, should " "be %s" % (str(b1.shape), str(a1.shape))) if iscomplexobj(b1): cplx = True else: cplx = cplx or False else: b1 = None # Set job for fortran routines _job = (eigvals_only and 'N') or 'V' # port eigenvalue range from python to fortran convention if eigvals is not None: lo, hi = eigvals if lo < 0 or hi >= a1.shape[0]: raise ValueError('The eigenvalue range specified is not valid.\n' 'Valid range is [%s,%s]' % (0, a1.shape[0]-1)) lo += 1 hi += 1 eigvals = (lo, hi) # set lower if lower: uplo = 'L' else: uplo = 'U' # fix prefix for lapack routines if cplx: pfx = 'he' else: pfx = 'sy' # Standard Eigenvalue Problem # Use '*evr' routines # FIXME: implement calculation of optimal lwork # for all lapack routines if b1 is None: (evr,) = get_lapack_funcs((pfx+'evr',), (a1,)) if eigvals is None: w, v, info = evr(a1, uplo=uplo, jobz=_job, range="A", il=1, iu=a1.shape[0], overwrite_a=overwrite_a) else: (lo, hi)= eigvals w_tot, v, info = evr(a1, uplo=uplo, jobz=_job, range="I", il=lo, iu=hi, overwrite_a=overwrite_a) w = w_tot[0:hi-lo+1] # Generalized Eigenvalue Problem else: # Use '*gvx' routines if range is specified if eigvals is not None: (gvx,) = get_lapack_funcs((pfx+'gvx',), (a1,b1)) (lo, hi) = eigvals w_tot, v, ifail, info = gvx(a1, b1, uplo=uplo, iu=hi, itype=type,jobz=_job, il=lo, overwrite_a=overwrite_a, overwrite_b=overwrite_b) w = w_tot[0:hi-lo+1] # Use '*gvd' routine if turbo is on and no eigvals are specified elif turbo: (gvd,) = get_lapack_funcs((pfx+'gvd',), (a1,b1)) v, w, info = gvd(a1, b1, uplo=uplo, itype=type, jobz=_job, overwrite_a=overwrite_a, overwrite_b=overwrite_b) # Use '*gv' routine if turbo is off and no eigvals are specified else: (gv,) = get_lapack_funcs((pfx+'gv',), (a1,b1)) v, w, info = gv(a1, b1, uplo=uplo, itype= type, jobz=_job, overwrite_a=overwrite_a, overwrite_b=overwrite_b) # Check if we had a successful exit if info == 0: if eigvals_only: return w else: return w, v elif info < 0: raise LinAlgError("illegal value in %i-th argument of internal" " fortran routine." % (-info)) elif info > 0 and b1 is None: raise LinAlgError("unrecoverable internal error.") # The algorithm failed to converge. elif info > 0 and info <= b1.shape[0]: if eigvals is not None: raise LinAlgError("the eigenvectors %s failed to" " converge." % nonzero(ifail)-1) else: raise LinAlgError("internal fortran routine failed to converge: " "%i off-diagonal elements of an " "intermediate tridiagonal form did not converge" " to zero." % info) # This occurs when b is not positive definite else: raise LinAlgError("the leading minor of order %i" " of 'b' is not positive definite. The" " factorization of 'b' could not be completed" " and no eigenvalues or eigenvectors were" " computed." % (info-b1.shape[0]))
def lu_solve(lu_and_piv, b, trans=0, overwrite_b=False, check_finite=True): """Solve an equation system, a x = b, given the LU factorization of a Parameters ---------- (lu, piv) Factorization of the coefficient matrix a, as given by lu_factor b : array Right-hand side trans : {0, 1, 2}, optional Type of system to solve: ===== ========= trans system ===== ========= 0 a x = b 1 a^T x = b 2 a^H x = b ===== ========= overwrite_b : bool, optional Whether to overwrite data in b (may increase performance) check_finite : bool, optional Whether to check that the input matrices contain 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 ------- x : array Solution to the system See also -------- lu_factor : LU factorize a matrix Examples -------- >>> from scipy.linalg import lu_factor, lu_solve >>> A = np.array([[2, 5, 8, 7], [5, 2, 2, 8], [7, 5, 6, 6], [5, 4, 4, 8]]) >>> b = np.array([1, 1, 1, 1]) >>> lu, piv = lu_factor(A) >>> x = lu_solve((lu, piv), b) >>> np.allclose(A @ x - b, np.zeros((4,))) True """ (lu, piv) = lu_and_piv if check_finite: b1 = asarray_chkfinite(b) else: b1 = asarray(b) overwrite_b = overwrite_b or _datacopied(b1, b) if lu.shape[0] != b1.shape[0]: raise ValueError("incompatible dimensions.") getrs, = get_lapack_funcs(('getrs', ), (lu, b1)) x, info = getrs(lu, piv, b1, trans=trans, overwrite_b=overwrite_b) if info == 0: return x raise ValueError('illegal value in %d-th argument of internal gesv|posv' % -info)
def eig_banded(a_band, lower=False, eigvals_only=False, overwrite_a_band=False, select='a', select_range=None, max_ev = 0): """Solve real symmetric or complex hermitian band matrix eigenvalue problem. Find eigenvalues w and optionally right eigenvectors v of a:: a v[:,i] = w[i] v[:,i] v.H v = identity The matrix a is stored in ab either in lower diagonal or upper diagonal ordered form: ab[u + i - j, j] == a[i,j] (if upper form; i <= j) ab[ i - j, j] == a[i,j] (if lower form; i >= j) Example of ab (shape of a is (6,6), u=2):: upper form: * * a02 a13 a24 a35 * a01 a12 a23 a34 a45 a00 a11 a22 a33 a44 a55 lower form: a00 a11 a22 a33 a44 a55 a10 a21 a32 a43 a54 * a20 a31 a42 a53 * * Cells marked with * are not used. Parameters ---------- a_band : array, shape (M, u+1) Banded matrix whose eigenvalues to calculate lower : boolean Is the matrix in the lower form. (Default is upper form) eigvals_only : boolean Compute only the eigenvalues and no eigenvectors. (Default: calculate also eigenvectors) overwrite_a_band: Discard data in a_band (may enhance performance) select: {'a', 'v', 'i'} Which eigenvalues to calculate ====== ======================================== select calculated ====== ======================================== 'a' All eigenvalues 'v' Eigenvalues in the interval (min, max] 'i' Eigenvalues with indices min <= i <= max ====== ======================================== select_range : (min, max) Range of selected eigenvalues max_ev : integer For select=='v', maximum number of eigenvalues expected. For other values of select, has no meaning. In doubt, leave this parameter untouched. Returns ------- w : array, shape (M,) The eigenvalues, in ascending order, each repeated according to its multiplicity. v : double or complex double array, shape (M, M) The normalized eigenvector corresponding to the eigenvalue w[i] is the column v[:,i]. Raises LinAlgError if eigenvalue computation does not converge """ if eigvals_only or overwrite_a_band: a1 = asarray_chkfinite(a_band) overwrite_a_band = overwrite_a_band or (_datacopied(a1, a_band)) else: a1 = array(a_band) if issubclass(a1.dtype.type, inexact) and not isfinite(a1).all(): raise ValueError("array must not contain infs or NaNs") overwrite_a_band = 1 if len(a1.shape) != 2: raise ValueError('expected two-dimensional array') if select.lower() not in [0, 1, 2, 'a', 'v', 'i', 'all', 'value', 'index']: raise ValueError('invalid argument for select') if select.lower() in [0, 'a', 'all']: if a1.dtype.char in 'GFD': bevd, = get_lapack_funcs(('hbevd',), (a1,)) # FIXME: implement this somewhen, for now go with builtin values # FIXME: calc optimal lwork by calling ?hbevd(lwork=-1) # or by using calc_lwork.f ??? # lwork = calc_lwork.hbevd(bevd.prefix, a1.shape[0], lower) internal_name = 'hbevd' else: # a1.dtype.char in 'fd': bevd, = get_lapack_funcs(('sbevd',), (a1,)) # FIXME: implement this somewhen, for now go with builtin values # see above # lwork = calc_lwork.sbevd(bevd.prefix, a1.shape[0], lower) internal_name = 'sbevd' w,v,info = bevd(a1, compute_v=not eigvals_only, lower=lower, overwrite_ab=overwrite_a_band) if select.lower() in [1, 2, 'i', 'v', 'index', 'value']: # calculate certain range only if select.lower() in [2, 'i', 'index']: select = 2 vl, vu, il, iu = 0.0, 0.0, min(select_range), max(select_range) if min(il, iu) < 0 or max(il, iu) >= a1.shape[1]: raise ValueError('select_range out of bounds') max_ev = iu - il + 1 else: # 1, 'v', 'value' select = 1 vl, vu, il, iu = min(select_range), max(select_range), 0, 0 if max_ev == 0: max_ev = a_band.shape[1] if eigvals_only: max_ev = 1 # calculate optimal abstol for dsbevx (see manpage) if a1.dtype.char in 'fF': # single precision lamch, = get_lapack_funcs(('lamch',), (array(0, dtype='f'),)) else: lamch, = get_lapack_funcs(('lamch',), (array(0, dtype='d'),)) abstol = 2 * lamch('s') if a1.dtype.char in 'GFD': bevx, = get_lapack_funcs(('hbevx',), (a1,)) internal_name = 'hbevx' else: # a1.dtype.char in 'gfd' bevx, = get_lapack_funcs(('sbevx',), (a1,)) internal_name = 'sbevx' # il+1, iu+1: translate python indexing (0 ... N-1) into Fortran # indexing (1 ... N) w, v, m, ifail, info = bevx(a1, vl, vu, il+1, iu+1, compute_v=not eigvals_only, mmax=max_ev, range=select, lower=lower, overwrite_ab=overwrite_a_band, abstol=abstol) # crop off w and v w = w[:m] if not eigvals_only: v = v[:, :m] if info < 0: raise ValueError('illegal value in %d-th argument of internal %s' % (-info, internal_name)) if info > 0: raise LinAlgError("eig algorithm did not converge") if eigvals_only: return w return w, v
def _qz(A, B, output='real', lwork=None, sort=None, overwrite_a=False, overwrite_b=False, check_finite=True): if sort is not None: # Disabled due to segfaults on win32, see ticket 1717. raise ValueError("The 'sort' input of qz() has to be None and will be " "removed in a future release. Use ordqz instead.") if output not in ['real', 'complex', 'r', 'c']: raise ValueError("argument must be 'real', or 'complex'") if check_finite: a1 = asarray_chkfinite(A) b1 = asarray_chkfinite(B) else: a1 = np.asarray(A) b1 = np.asarray(B) a_m, a_n = a1.shape b_m, b_n = b1.shape if not (a_m == a_n == b_m == b_n): raise ValueError("Array dimensions must be square and agree") typa = a1.dtype.char if output in ['complex', 'c'] and typa not in ['F', 'D']: if typa in _double_precision: a1 = a1.astype('D') typa = 'D' else: a1 = a1.astype('F') typa = 'F' typb = b1.dtype.char if output in ['complex', 'c'] and typb not in ['F', 'D']: if typb in _double_precision: b1 = b1.astype('D') typb = 'D' else: b1 = b1.astype('F') typb = 'F' overwrite_a = overwrite_a or (_datacopied(a1, A)) overwrite_b = overwrite_b or (_datacopied(b1, B)) gges, = get_lapack_funcs(('gges', ), (a1, b1)) if lwork is None or lwork == -1: # get optimal work array size result = gges(lambda x: None, a1, b1, lwork=-1) lwork = result[-2][0].real.astype(np.int) sfunction = lambda x: None result = gges(sfunction, a1, b1, lwork=lwork, overwrite_a=overwrite_a, overwrite_b=overwrite_b, sort_t=0) info = result[-1] if info < 0: raise ValueError("Illegal value in argument {} of gges".format(-info)) elif info > 0 and info <= a_n: warnings.warn("The QZ iteration failed. (a,b) are not in Schur " "form, but ALPHAR(j), ALPHAI(j), and BETA(j) should be " "correct for J={},...,N".format(info - 1), LinAlgWarning, stacklevel=3) elif info == a_n + 1: raise LinAlgError("Something other than QZ iteration failed") elif info == a_n + 2: raise LinAlgError("After reordering, roundoff changed values of some " "complex eigenvalues so that leading eigenvalues " "in the Generalized Schur form no longer satisfy " "sort=True. This could also be due to scaling.") elif info == a_n + 3: raise LinAlgError("Reordering failed in <s,d,c,z>tgsen") return result, gges.typecode
def eig(a, b=None, left=False, right=True, overwrite_a=False, overwrite_b=False): """Solve an ordinary or generalized eigenvalue problem of a square matrix. Find eigenvalues w and right or left eigenvectors of a general matrix:: a vr[:,i] = w[i] b vr[:,i] a.H vl[:,i] = w[i].conj() b.H vl[:,i] where .H is the Hermitean conjugation. Parameters ---------- a : array, shape (M, M) A complex or real matrix whose eigenvalues and eigenvectors will be computed. b : array, shape (M, M) Right-hand side matrix in a generalized eigenvalue problem. If omitted, identity matrix is assumed. left : boolean Whether to calculate and return left eigenvectors right : boolean Whether to calculate and return right eigenvectors overwrite_a : boolean Whether to overwrite data in a (may improve performance) overwrite_b : boolean Whether to overwrite data in b (may improve performance) Returns ------- w : double or complex array, shape (M,) The eigenvalues, each repeated according to its multiplicity. (if left == True) vl : double or complex array, shape (M, M) The normalized left eigenvector corresponding to the eigenvalue w[i] is the column v[:,i]. (if right == True) vr : double or complex array, shape (M, M) The normalized right eigenvector corresponding to the eigenvalue w[i] is the column vr[:,i]. Raises LinAlgError if eigenvalue computation does not converge See Also -------- eigh : eigenvalues and right eigenvectors for symmetric/Hermitian arrays """ 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)) if b is not None: b = asarray_chkfinite(b) if b.shape != a1.shape: raise ValueError('a and b must have the same shape') return _geneig(a1, b, left, right, overwrite_a, overwrite_b) geev, = get_lapack_funcs(('geev',), (a1,)) compute_vl, compute_vr = left, right if geev.module_name[:7] == 'flapack': lwork = calc_lwork.geev(geev.prefix, a1.shape[0], compute_vl, compute_vr)[1] if geev.prefix in 'cz': w, vl, vr, info = geev(a1, lwork=lwork, compute_vl=compute_vl, compute_vr=compute_vr, overwrite_a=overwrite_a) else: wr, wi, vl, vr, info = geev(a1, lwork=lwork, compute_vl=compute_vl, compute_vr=compute_vr, overwrite_a=overwrite_a) t = {'f':'F','d':'D'}[wr.dtype.char] w = wr + _I * wi else: # 'clapack' if geev.prefix in 'cz': w, vl, vr, info = geev(a1, compute_vl=compute_vl, compute_vr=compute_vr, overwrite_a=overwrite_a) else: wr, wi, vl, vr, info = geev(a1, compute_vl=compute_vl, compute_vr=compute_vr, overwrite_a=overwrite_a) t = {'f':'F','d':'D'}[wr.dtype.char] w = wr + _I * wi if info < 0: raise ValueError('illegal value in %d-th argument of internal geev' % -info) if info > 0: raise LinAlgError("eig algorithm did not converge (only eigenvalues " "with order >= %d have converged)" % info) only_real = numpy.logical_and.reduce(numpy.equal(w.imag, 0.0)) if not (geev.prefix in 'cz' or only_real): t = w.dtype.char if left: vl = _make_complex_eigvecs(w, vl, t) if right: vr = _make_complex_eigvecs(w, vr, t) if not (left or right): return w if left: if right: return w, vl, vr return w, vl return w, vr
def curve_fit(f, xdata, ydata, p0=None, sigma=None, absolute_sigma=False, check_finite=True, **kw): """ Use non-linear least squares to fit a function, f, to data. Assumes ``ydata = f(xdata, *params) + eps`` Parameters ---------- f : callable The model function, f(x, ...). It must take the independent variable as the first argument and the parameters to fit as separate remaining arguments. xdata : An M-length sequence or an (k,M)-shaped array for functions with k predictors. The independent variable where the data is measured. ydata : M-length sequence The dependent data --- nominally f(xdata, ...) p0 : None, scalar, or N-length sequence, optional Initial guess for the parameters. If None, then the initial values will all be 1 (if the number of parameters for the function can be determined using introspection, otherwise a ValueError is raised). sigma : None or M-length sequence, optional If not None, the uncertainties in the ydata array. These are used as weights in the least-squares problem i.e. minimising ``np.sum( ((f(xdata, *popt) - ydata) / sigma)**2 )`` If None, the uncertainties are assumed to be 1. absolute_sigma : bool, optional If False, `sigma` denotes relative weights of the data points. The returned covariance matrix `pcov` is based on *estimated* errors in the data, and is not affected by the overall magnitude of the values in `sigma`. Only the relative magnitudes of the `sigma` values matter. If True, `sigma` describes one standard deviation errors of the input data points. The estimated covariance in `pcov` is based on these values. check_finite : bool, optional If True, check that the input arrays do not contain nans of infs, and raise a ValueError if they do. Setting this parameter to False may silently produce nonsensical results if the input arrays do contain nans. Default is True. Returns ------- popt : array Optimal values for the parameters so that the sum of the squared error of ``f(xdata, *popt) - ydata`` is minimized pcov : 2d array The estimated covariance of popt. The diagonals provide the variance of the parameter estimate. To compute one standard deviation errors on the parameters use ``perr = np.sqrt(np.diag(pcov))``. How the `sigma` parameter affects the estimated covariance depends on `absolute_sigma` argument, as described above. Raises ------ OptimizeWarning if covariance of the parameters can not be estimated. ValueError if ydata and xdata contain NaNs. See Also -------- leastsq Notes ----- The algorithm uses the Levenberg-Marquardt algorithm through `leastsq`. Additional keyword arguments are passed directly to that algorithm. Examples -------- >>> import numpy as np >>> from scipy.optimize import curve_fit >>> def func(x, a, b, c): ... return a * np.exp(-b * x) + c >>> xdata = np.linspace(0, 4, 50) >>> y = func(xdata, 2.5, 1.3, 0.5) >>> ydata = y + 0.2 * np.random.normal(size=len(xdata)) >>> popt, pcov = curve_fit(func, xdata, ydata) """ if p0 is None: # determine number of parameters by inspecting the function import inspect args, varargs, varkw, defaults = inspect.getargspec(f) if len(args) < 2: msg = "Unable to determine number of fit parameters." raise ValueError(msg) if 'self' in args: p0 = [1.0] * (len(args)-2) else: p0 = [1.0] * (len(args)-1) # Check input arguments if isscalar(p0): p0 = array([p0]) # NaNs can not be handled if check_finite: ydata = np.asarray_chkfinite(ydata) else: ydata = np.asarray(ydata) if isinstance(xdata, (list, tuple, np.ndarray)): # `xdata` is passed straight to the user-defined `f`, so allow # non-array_like `xdata`. if check_finite: xdata = np.asarray_chkfinite(xdata) else: xdata = np.asarray(xdata) args = (xdata, ydata, f) if sigma is None: func = _general_function else: func = _weighted_general_function args += (1.0 / asarray(sigma),) # Remove full_output from kw, otherwise we're passing it in twice. return_full = kw.pop('full_output', False) res = leastsq(func, p0, args=args, full_output=1, **kw) (popt, pcov, infodict, errmsg, ier) = res if ier not in [1, 2, 3, 4]: msg = "Optimal parameters not found: " + errmsg raise RuntimeError(msg) warn_cov = False if pcov is None: # indeterminate covariance pcov = zeros((len(popt), len(popt)), dtype=float) pcov.fill(inf) warn_cov = True elif not absolute_sigma: if len(ydata) > len(p0): s_sq = (asarray(func(popt, *args))**2).sum() / (len(ydata) - len(p0)) pcov = pcov * s_sq else: pcov.fill(inf) warn_cov = True if warn_cov: warnings.warn('Covariance of the parameters could not be estimated', category=OptimizeWarning) if return_full: return popt, pcov, infodict, errmsg, ier else: return popt, pcov
def lu(a, permute_l=False, overwrite_a=False, check_finite=True): """ Compute pivoted LU decomposition of a matrix. The decomposition is:: A = P L U where P is a permutation matrix, L lower triangular with unit diagonal elements, and U upper triangular. Parameters ---------- a : (M, N) array_like Array to decompose permute_l : bool Perform the multiplication P*L (Default: do not permute) overwrite_a : bool Whether to overwrite data in a (may improve performance) 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 ------- **(If permute_l == False)** p : (M, M) ndarray Permutation matrix l : (M, K) ndarray Lower triangular or trapezoidal matrix with unit diagonal. K = min(M, N) u : (K, N) ndarray Upper triangular or trapezoidal matrix **(If permute_l == True)** pl : (M, K) ndarray Permuted L matrix. K = min(M, N) u : (K, N) ndarray Upper triangular or trapezoidal matrix Notes ----- This is a LU factorization routine written for Scipy. """ if check_finite: a1 = asarray_chkfinite(a) else: a1 = asarray(a) if len(a1.shape) != 2: raise ValueError('expected matrix') overwrite_a = overwrite_a or (_datacopied(a1, a)) flu, = get_flinalg_funcs(('lu', ), (a1, )) p, l, u, info = flu(a1, permute_l=permute_l, overwrite_a=overwrite_a) if info < 0: raise ValueError('illegal value in %d-th argument of ' 'internal lu.getrf' % -info) if permute_l: return l, u return p, l, u
def qr_multiply(a, c, mode='right', pivoting=False, conjugate=False, overwrite_a=False, overwrite_c=False): """Calculate the QR decomposition and multiply Q with a matrix. Calculate the decomposition ``A = Q R`` where Q is unitary/orthogonal and R upper triangular. Multiply Q with a vector or a matrix c. .. versionadded:: 0.11 Parameters ---------- a : ndarray, shape (M, N) Matrix to be decomposed c : ndarray, one- or two-dimensional calculate the product of c and q, depending on the mode: mode : {'left', 'right'} ``dot(Q, c)`` is returned if mode is 'left', ``dot(c, Q)`` is returned if mode is 'right'. The shape of c must be appropriate for the matrix multiplications, if mode is 'left', ``min(a.shape) == c.shape[0]``, if mode is 'right', ``a.shape[0] == c.shape[1]``. pivoting : bool, optional Whether or not factorization should include pivoting for rank-revealing qr decomposition, see the documentation of qr. conjugate : bool, optional Whether Q should be complex-conjugated. This might be faster than explicit conjugation. overwrite_a : bool, optional Whether data in a is overwritten (may improve performance) overwrite_c : bool, optional Whether data in c is overwritten (may improve performance). If this is used, c must be big enough to keep the result, i.e. c.shape[0] = a.shape[0] if mode is 'left'. Returns ------- CQ : float or complex ndarray the product of Q and c, as defined in mode R : float or complex ndarray Of shape (K, N), ``K = min(M, N)``. P : ndarray of ints Of shape (N,) for ``pivoting=True``. Not returned if ``pivoting=False``. Raises ------ LinAlgError Raised if decomposition fails Notes ----- This is an interface to the LAPACK routines dgeqrf, zgeqrf, dormqr, zunmqr, dgeqp3, and zgeqp3. """ if not mode in ['left', 'right']: raise ValueError("Mode argument should be one of ['left', 'right']") c = numpy.asarray_chkfinite(c) onedim = c.ndim == 1 if onedim: c = c.reshape(1, len(c)) if mode == "left": c = c.T a = numpy.asarray(a) # chkfinite done in qr M, N = a.shape if not (mode == "left" and (not overwrite_c and min(M, N) == c.shape[0] or overwrite_c and M == c.shape[0]) or mode == "right" and M == c.shape[1]): raise ValueError("objects are not aligned") raw = qr(a, overwrite_a, None, "raw", pivoting) Q, tau = raw[0] if find_best_lapack_type((Q, ))[0] in ('s', 'd'): gor_un_mqr, = get_lapack_funcs(('ormqr', ), (Q, )) trans = "T" else: gor_un_mqr, = get_lapack_funcs(('unmqr', ), (Q, )) trans = "C" Q = Q[:, :min(M, N)] if M > N and mode == "left" and not overwrite_c: if conjugate: cc = numpy.zeros((c.shape[1], M), dtype=c.dtype, order="F") cc[:, :N] = c.T else: cc = numpy.zeros((M, c.shape[1]), dtype=c.dtype, order="F") cc[:N, :] = c trans = "N" if conjugate: lr = "R" else: lr = "L" overwrite_c = True elif c.flags["C_CONTIGUOUS"] and trans == "T" or conjugate: cc = c.T if mode == "left": lr = "R" else: lr = "L" else: trans = "N" cc = c if mode == "left": lr = "L" else: lr = "R" cQ, = safecall(gor_un_mqr, "gormqr/gunmqr", lr, trans, Q, tau, cc, overwrite_c=overwrite_c) if trans != "N": cQ = cQ.T if mode == "right": cQ = cQ[:, :min(M, N)] if onedim: cQ = cQ.ravel() return (cQ, ) + raw[1:]
def qr(a, overwrite_a=False, lwork=None, mode='full', pivoting=False): """ Compute QR decomposition of a matrix. Calculate the decomposition ``A = Q R`` where Q is unitary/orthogonal and R upper triangular. Parameters ---------- a : array, shape (M, N) Matrix to be decomposed overwrite_a : bool, optional Whether data in a is overwritten (may improve performance) lwork : int, optional Work array size, lwork >= a.shape[1]. If None or -1, an optimal size is computed. mode : {'full', 'r', 'economic', 'raw'} Determines what information is to be returned: either both Q and R ('full', default), only R ('r') or both Q and R but computed in economy-size ('economic', see Notes). The final option 'raw' (added in Scipy 0.11) makes the function return two matrixes (Q, TAU) in the internal format used by LAPACK. pivoting : bool, optional Whether or not factorization should include pivoting for rank-revealing qr decomposition. If pivoting, compute the decomposition ``A P = Q R`` as above, but where P is chosen such that the diagonal of R is non-increasing. Returns ------- Q : float or complex ndarray Of shape (M, M), or (M, K) for ``mode='economic'``. Not returned if ``mode='r'``. R : float or complex ndarray Of shape (M, N), or (K, N) for ``mode='economic'``. ``K = min(M, N)``. P : integer ndarray Of shape (N,) for ``pivoting=True``. Not returned if ``pivoting=False``. Raises ------ LinAlgError Raised if decomposition fails Notes ----- This is an interface to the LAPACK routines dgeqrf, zgeqrf, dorgqr, zungqr, dgeqp3, and zgeqp3. If ``mode=economic``, the shapes of Q and R are (M, K) and (K, N) instead of (M,M) and (M,N), with ``K=min(M,N)``. Examples -------- >>> from scipy import random, linalg, dot, diag, all, allclose >>> a = random.randn(9, 6) >>> q, r = linalg.qr(a) >>> allclose(a, np.dot(q, r)) True >>> q.shape, r.shape ((9, 9), (9, 6)) >>> r2 = linalg.qr(a, mode='r') >>> allclose(r, r2) True >>> q3, r3 = linalg.qr(a, mode='economic') >>> q3.shape, r3.shape ((9, 6), (6, 6)) >>> q4, r4, p4 = linalg.qr(a, pivoting=True) >>> d = abs(diag(r4)) >>> all(d[1:] <= d[:-1]) True >>> allclose(a[:, p4], dot(q4, r4)) True >>> q4.shape, r4.shape, p4.shape ((9, 9), (9, 6), (6,)) >>> q5, r5, p5 = linalg.qr(a, mode='economic', pivoting=True) >>> q5.shape, r5.shape, p5.shape ((9, 6), (6, 6), (6,)) """ # 'qr' was the old default, equivalent to 'full'. Neither 'full' nor # 'qr' are used below. # 'raw' is used internally by qr_multiply if mode not in ['full', 'qr', 'r', 'economic', 'raw']: raise ValueError( "Mode argument should be one of ['full', 'r', 'economic', 'raw']") a1 = numpy.asarray_chkfinite(a) if len(a1.shape) != 2: raise ValueError("expected 2D array") M, N = a1.shape overwrite_a = overwrite_a or (_datacopied(a1, a)) if pivoting: geqp3, = get_lapack_funcs(('geqp3', ), (a1, )) qr, jpvt, tau = safecall(geqp3, "geqp3", a1, overwrite_a=overwrite_a) jpvt -= 1 # geqp3 returns a 1-based index array, so subtract 1 else: geqrf, = get_lapack_funcs(('geqrf', ), (a1, )) qr, tau = safecall(geqrf, "geqrf", a1, lwork=lwork, overwrite_a=overwrite_a) if mode not in ['economic', 'raw'] or M < N: R = numpy.triu(qr) else: R = numpy.triu(qr[:N, :]) if pivoting: Rj = R, jpvt else: Rj = R, if mode == 'r': return Rj elif mode == 'raw': return ((qr, tau), ) + Rj if find_best_lapack_type((a1, ))[0] in ('s', 'd'): gor_un_gqr, = get_lapack_funcs(('orgqr', ), (qr, )) else: gor_un_gqr, = get_lapack_funcs(('ungqr', ), (qr, )) if M < N: Q, = safecall(gor_un_gqr, "gorgqr/gungqr", qr[:, :M], tau, lwork=lwork, overwrite_a=1) elif mode == 'economic': Q, = safecall(gor_un_gqr, "gorgqr/gungqr", qr, tau, lwork=lwork, overwrite_a=1) else: t = qr.dtype.char qqr = numpy.empty((M, M), dtype=t) qqr[:, :N] = qr Q, = safecall(gor_un_gqr, "gorgqr/gungqr", qqr, tau, lwork=lwork, overwrite_a=1) return (Q, ) + Rj
0 a x = b 1 a^T x = b 2 a^H x = b ===== ========= Returns ------- x : array Solution to the system See also -------- lu_factor : LU factorize a matrix """ b1 = asarray_chkfinite(b) overwrite_b = overwrite_b or (b1 is not b and not hasattr(b, '__array__')) if lu.shape[0] != b1.shape[0]: raise ValueError, "incompatible dimensions." getrs, = get_lapack_funcs(('getrs', ), (lu, b1)) x, info = getrs(lu, piv, b1, trans=trans, overwrite_b=overwrite_b) if info == 0: return x raise ValueError,\ 'illegal value in %-th argument of internal gesv|posv'%(-info) def cho_solve((c, lower), b, overwrite_b=0): """Solve an equation system, a x = b, given the Cholesky factorization of a Parameters
def sphere(x): x = np.asarray_chkfinite(x) return sum(x**2)