def _assertRotationMatrix(matrix): """ Check if a matrix is a rotation matrix. Parameters ---------- matrix : array_like The matrix to check. Raises ------ LinAlgError If the supplied matrix is not a rotation matrix. """ if matrix.ndim != 2: raise LinAlgError('%d-dimensional array given. Array must be ' 'two-dimensional' % matrix.ndim) m, n = matrix.shape if m != n: raise LinAlgError('Array must be square') if not numpy.allclose(numpy.dot(matrix.T, matrix), numpy.eye(n)): raise LinAlgError('Matrix is not orthogonal') if not numpy.allclose(numpy.linalg.det(matrix), 1.0): raise LinAlgError('Matrix is not a proper rotation matrix')
def tri_mult_imp_1D(a_and_lower, x, overwrite_x=False, check_finite=True): (a, lower) = a_and_lower # Squareness check if (a.ndim != 2) or (a.shape[0] != a.shape[1]): raise LinAlgError("The triangular matrix a is not square.") # Dimension check if a.shape[1] != x.shape[0]: raise LinAlgError("a and x have incompatible dimensions.") # Check that arrays are finite if check_finite: _check_finite_array(a) _check_finite_array(x) # float and fortran conversions if to_float64: # need to upcast these. if already float64 should be a no-copy. # otherwise, copies to C order, so do this before as_fortranarray a1 = np.asarray(a, dtype=np.float64) x1 = np.asarray(x, dtype=np.float64) else: a1 = a x1 = x # convert to fortran order, avoiding copy whenever possible. a1 = _asfortranarray(a1, overwrite_a=True) x1 = _asfortranarray(x1, overwrite_x) # determine order uplo = LO if lower else UP # wrap everything into something with ctypes n = np.array(a.shape[0], dtype=np.int32) lda = n # call fortran via cython_blas _trmv(uplo.ctypes, trans.ctypes, diag.ctypes, n.ctypes, a1.ctypes, lda.ctypes, x1.ctypes, incx.ctypes) return x1
def __call__(self, a): import scipy.linalg a = astensor(a) if a.ndim != 2: raise LinAlgError('{0}-dimensional array given. ' 'Tensor must be two-dimensional'.format(a.ndim)) if a.shape[0] != a.shape[1]: raise LinAlgError('Input must be square') tiny_p, tiny_l, tiny_u = scipy.linalg.lu( np.array([[1, 2], [2, 5]], dtype=a.dtype)) p, l, u = self.new_tensors([a], (a.shape, a.shape, a.shape), kws=[ { 'side': 'p', 'dtype': tiny_p.dtype }, { 'side': 'l', 'dtype': tiny_l.dtype }, { 'side': 'u', 'dtype': tiny_u.dtype }, ]) return ExecutableTuple([p, l, u])
def _assert_is_rotation_matrix(matrix: numpy.ndarray) -> None: """ Check if a matrix is a rotation matrix. Parameters ---------- matrix : ndarray The matrix to check. Raises ------ LinAlgError If the supplied matrix is not a rotation matrix. """ if matrix.ndim != 2: raise LinAlgError( "%d-dimensional array given. Array must be two-dimensional" % matrix.ndim ) m, n = matrix.shape if m != n: raise LinAlgError("Array must be square") if not numpy.allclose(numpy.dot(matrix.T, matrix), numpy.eye(n)): raise LinAlgError("Matrix is not orthogonal") if not numpy.allclose(numpy.linalg.det(matrix), 1.0): raise LinAlgError("Matrix is not a proper rotation matrix")
def __init__(self, individuals, label, variance=None, incidence_matrix=None, covariance_matrix=None, levels=None): """ Create the random effect. :param individuals: Individuals included :param label: name of the effect :param variance: variance associated with the effect :param incidence_matrix: incidence matrix for random effect :param covariance_matrix: covariance matrix for random effect :param levels: levels of random effect :type individuals: iterable :type label: string :type variance: float :type incidence_matrix: matrix :type covariance_matrix: matrix """ nobs = len(individuals) self.label = label self.variance_component = variance if isinstance(incidence_matrix, str) and incidence_matrix == 'eye': self.incidence_matrix = sparseeye(nobs, nobs) elif incidence_matrix is None: self.incidence_matrix = make_incidence_matrix( individuals, self.label) else: self.incidence_matrix = incidence_matrix if covariance_matrix is None: # Number of levels of random effects is the number of # columns in the incidence matrix nlevel = self.incidence_matrix.shape[1] self.covariance_matrix = sparseeye(nlevel, nlevel) else: # Covariance matrices are square if covariance_matrix.shape[0] != covariance_matrix.shape[1]: raise LinAlgError('Covariance matrix not square') if covariance_matrix.shape[0] != self.incidence_matrix.shape[1]: raise LinAlgError('Incidence and covariance matrix ' 'not conformable') self.covariance_matrix = covariance_matrix if not levels: self.levels = [ 'L{}'.format(i) for i in range(self.incidence_matrix.shape[1]) ] else: if len(levels) != incidence_matrix.shape[1]: raise ValueError('Number of levels not correct') self.levels = levels self.V_i = self.Z * self.G * self.Z.T
def solve_triangular(a, b, lower=False, sparse=None): """ Solve the equation `a x = b` for `x`, assuming a is a triangular matrix. Parameters ---------- a : (M, M) array_like A triangular matrix b : (M,) or (M, N) array_like Right-hand side matrix in `a x = b` lower : bool, optional Use only data contained in the lower triangle of `a`. Default is to use upper triangle. sparse: bool, optional Return sparse value or not. Returns ------- x : (M,) or (M, N) ndarray Solution to the system `a x = b`. Shape of return matches `b`. Examples -------- Solve the lower triangular system a x = b, where:: [3 0 0 0] [4] a = [2 1 0 0] b = [2] [1 0 1 0] [4] [1 1 1 1] [2] >>> import mars.tensor as mt >>> a = mt.array([[3, 0, 0, 0], [2, 1, 0, 0], [1, 0, 1, 0], [1, 1, 1, 1]]) >>> b = mt.array([4, 2, 4, 2]) >>> x = mt.linalg.solve_triangular(a, b, lower=True) >>> x.execute() array([ 1.33333333, -0.66666667, 2.66666667, -1.33333333]) >>> a.dot(x).execute() # Check the result array([ 4., 2., 4., 2.]) """ import scipy.linalg a = astensor(a) b = astensor(b) if a.ndim != 2: raise LinAlgError('a must be 2 dimensional') if b.ndim <= 2: if a.shape[1] != b.shape[0]: raise LinAlgError('a.shape[1] and b.shape[0] must be equal') else: raise LinAlgError('b must be 1 or 2 dimensional') tiny_x = scipy.linalg.solve_triangular( np.array([[2, 0], [2, 1]], dtype=a.dtype), np.array([[2], [3]], dtype=b.dtype)) sparse = sparse if sparse is not None else a.issparse() op = TensorSolveTriangular(lower=lower, dtype=tiny_x.dtype, sparse=sparse) return op(a, b)
def getAdjFwdEig(A, numModes=None): """ Compute adjoint and foward fission source moments, and eigenvalues Parameters ---------- A : scipy.sparse.spmatrix Double precision square fission matrix. Shape should be ``NxN`` numModes : int, optional Number of modes to be extracted. If given, must be less than ``N-1`` Returns ------- adj : numpy.ndarray Adjoint moments from of the fission source fwd : numpy.ndarray Forward moments from of the fission source eig : numpy.ndarray $k$-eigenvalues of the fission matrix Raises ------ numpy.linalg.LinAlgError QR algorithm for the eigensolver failed and no eigenvectors were computed """ if not issparse(A): A = csr_matrix(A) if not A.ndim == 2: raise ValueError(f"A must be 2D square matrix, not {A.shape}") (nr, nc) = A.shape if nr != nc: raise ValueError(f"A must be 2D square matrix, not {A.shape}") if numModes is None: numModes = nr - 2 elif not isinstance(numModes, Integral): raise TypeError( f"Number of modes k must be positive integer, not {numModes}") elif numModes <= 0: raise ValueError( f"Number of modes k must be positive integer, not {numModes}") try: fwdMoments, fwdKEigs = _eigWrapper(A, numModes) except Exception as ee: raise LinAlgError("Failed to obtain forward moments") from ee try: adjMoments, _adjKEigs = _eigWrapper(A.T, numModes) except Exception as ee: raise LinAlgError("Failed to obtain adjoint moments") from ee return adjMoments, fwdMoments, fwdKEigs
def inv(a, sparse=None): """ Compute the (multiplicative) inverse of a matrix. Given a square matrix `a`, return the matrix `ainv` satisfying ``dot(a, ainv) = dot(ainv, a) = eye(a.shape[0])``. Parameters ---------- a : (..., M, M) array_like Matrix to be inverted. sparse: bool, optional Return sparse value or not. Returns ------- ainv : (..., M, M) ndarray or matrix (Multiplicative) inverse of the matrix `a`. Raises ------ LinAlgError If `a` is not square or inversion fails. Examples -------- >>> import mars.tensor as mt >>> a = np.array([[1., 2.], [3., 4.]]) >>> ainv = mt.linalg.inv(a) >>> mt.allclose(mt.dot(a, ainv), mt.eye(2)).execute() True >>> mt.allclose(mt.dot(ainv, a), mt.eye(2)).execute() True >>> ainv.execute() array([[ -2. , 1. ], [ 1.5, -0.5]]) """ # TODO: using some parallel algorithm for matrix inversion. a = astensor(a) if a.ndim != 2: raise LinAlgError(f'{a.ndim}-dimensional array given. ' 'Tensor must be two-dimensional') if a.shape[0] != a.shape[1]: raise LinAlgError('Input must be square') tiny_inv = np.linalg.inv(np.array([[1, 2], [2, 5]], dtype=a.dtype)) sparse = sparse if sparse is not None else a.issparse() op = TensorInv(dtype=tiny_inv.dtype, sparse=sparse) return op(a)
def do_kcsd_evd(pot, ele_pos, xmin, xmax, ymin, ymax, n_src_init=1000, R_init=30): k = KCSD2D(ele_pos, pot, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, h=1, sigma=1, n_src_init=n_src_init, gdx=4, gdy=4, R_init=R_init) try: eigenvalue, eigenvector = np.linalg.eigh(k.k_pot + k.lambd * np.identity(k.k_pot.shape[0])) except LinAlgError: raise LinAlgError('EVD is failing - try moving the electrodes' 'slightly') idx = eigenvalue.argsort()[::-1] eigenvalues = eigenvalue[idx] eigenvectors = eigenvector[:, idx] return k, eigenvalues, eigenvectors
def make_incidence_matrix(individuals, effect_name): if effect_name.lower() == 'residual': incidence_matrix = sparseeye(len(individuals)) elif is_genetic_effect(effect_name): incidence_matrix = sparseeye(len(individuals)) else: levels = sorted({ind.phenotypes[effect_name] for ind in individuals}) # Missing values are not a valid level levels = [x for x in levels if x is not None] nlevels = len(levels) # Calculate which individual has which level gen = (ind.phenotypes[effect_name] == level for ind, level in product(individuals, levels)) Z = np.fromiter(gen, dtype=np.uint8) # Shout out to scipy for both not documenting reshape on any of their # sparse matrix objects and also not making them take the same number # of arguments Z = Z.reshape(-1, nlevels) # Check for missing values and complain about them! # Kind of hard to read but heres how it goes: # Check if any of the rows are all zero. if (Z == 0).all(axis=1).any(): raise LinAlgError('Missing values in random effect') incidence_matrix = csc_matrix(Z) return incidence_matrix
def _assert_square(*arrays): for a in arrays: m, n = a.shape[-2:] if m != n: raise LinAlgError('Last 2 dimensions of the array must be square' '. Found an array with shape: {}x{}'.format( m, n))
def compute_cverror(self, lambd, index_generator): """Useful for Cross validation error calculations Parameters ---------- lambd : float index_generator : list Returns ------- err : float the sum of the error computed. """ err = 0 for idx_train, idx_test in index_generator: B_train = self.k_pot[np.ix_(idx_train, idx_train)] V_train = self.pots[idx_train] V_test = self.pots[idx_test] I_matrix = np.identity(len(idx_train)) B_new = np.matrix(B_train) + (lambd * I_matrix) try: beta_new = np.dot(np.matrix(B_new).I, np.matrix(V_train)) B_test = self.k_pot[np.ix_(idx_test, idx_train)] V_est = np.zeros((len(idx_test), self.pots.shape[1])) for ii in range(len(idx_train)): for tt in range(self.pots.shape[1]): V_est[:, tt] += beta_new[ii, tt] * B_test[:, ii] err += np.linalg.norm(V_est - V_test) except LinAlgError: raise LinAlgError( 'Encoutered Singular Matrix Error: try changing ele_pos slightly' ) return err
def fit(self, signal) -> "CostRank": """Set parameters of the instance. Args: signal (array): signal. Shape (n_samples,) or (n_samples, n_features) Returns: self """ if signal.ndim == 1: signal = signal.reshape(-1, 1) obs, vars = signal.shape # Convert signal data into ranks in the range [1, n] ranks = rankdata(signal, axis=0) # Center the ranks into the range [-(n+1)/2, (n+1)/2] centered_ranks = ranks - ((obs + 1) / 2) # Sigma is the covariance of these ranks. # If it's a scalar, reshape it into a 1x1 matrix cov = np.cov(centered_ranks, rowvar=False, bias=True).reshape(vars, vars) # Use the pseudoinverse to handle linear dependencies # see Lung-Yut-Fong, A., Lévy-Leduc, C., & Cappé, O. (2015) try: self.inv_cov = pinv(cov) except LinAlgError as e: raise LinAlgError( "The covariance matrix of the rank signal is not invertible and the " "pseudo-inverse computation did not converge.") from e self.ranks = centered_ranks return self
def transformation_matrix(self, matrix): R, S = qrp(matrix) s = numpy.diag(S) if not numpy.allclose(S, numpy.diag(s)): raise LinAlgError('Array must be diagonal') self.rotation_matrix = R self.scale = s
def __call__(self, a): a = astensor(a) if a.ndim != 2: raise LinAlgError('{0}-dimensional tensor given. ' 'Tensor must be two-dimensional'.format(a.ndim)) tiny_U, tiny_s, tiny_V = np.linalg.svd(np.ones((1, 1), dtype=a.dtype)) # if a's shape is (6, 18), U's shape is (6, 6), s's shape is (6,), V's shape is (6, 18) # if a's shape is (18, 6), U's shape is (18, 6), s's shape is (6,), V's shape is (6, 6) x, y = a.shape if x > y: U_shape = (x, y) s_shape = (y, ) V_shape = (y, y) else: U_shape = (x, x) s_shape = (x, ) V_shape = (x, y) U, s, V = self.new_tensors([a], (U_shape, s_shape, V_shape), kws=[{ 'side': 'U', 'dtype': tiny_U.dtype }, { 'side': 's', 'dtype': tiny_s.dtype }, { 'side': 'V', 'dtype': tiny_V.dtype }]) return ExecutableTuple([U, s, V])
def get_nadir_point(extreme_points, ideal_point, worst_point, worst_of_front, worst_of_population): try: # find the intercepts using gaussian elimination M = extreme_points - ideal_point b = np.ones(extreme_points.shape[1]) plane = np.linalg.solve(M, b) warnings.simplefilter("ignore") intercepts = 1 / plane nadir_point = ideal_point + intercepts # check if the hyperplane makes sense if not np.allclose(np.dot(M, plane), b) or np.any(intercepts <= 1e-6): raise LinAlgError() # if the nadir point should be larger than any value discovered so far set it to that value # NOTE: different to the proposed version in the paper b = nadir_point > worst_point nadir_point[b] = worst_point[b] except LinAlgError: # fall back to worst of front otherwise nadir_point = worst_of_front # if the range is too small set it to worst of population b = nadir_point - ideal_point <= 1e-6 nadir_point[b] = worst_of_population[b] return nadir_point
def __call__(self, a): a = astensor(a) if a.ndim != 2: raise LinAlgError('{0}-dimensional tensor given. ' 'Tensor must be two-dimensional'.format(a.ndim)) tiny_U, tiny_s, tiny_V = np.linalg.svd(np.ones((1, 1), dtype=a.dtype)) # if a's shape is (6, 18), U's shape is (6, 6), s's shape is (6,), V's shape is (6, 18) # if a's shape is (18, 6), U's shape is (18, 6), s's shape is (6,), V's shape is (6, 6) U_shape, s_shape, V_shape = calc_svd_shapes(a) U, s, V = self.new_tensors([a], order=TensorOrder.C_ORDER, kws=[{ 'side': 'U', 'dtype': tiny_U.dtype, 'shape': U_shape }, { 'side': 's', 'dtype': tiny_s.dtype, 'shape': s_shape }, { 'side': 'V', 'dtype': tiny_V.dtype, 'shape': V_shape }]) return ExecutableTuple([U, s, V])
def solve_sylvester(a, b, q): """Computes a solution (X) to the Sylvester equation (AX + XB = Q). .. versionadded:: 0.11.0 Parameters ---------- a : array, shape (M, M) Leading matrix of the Sylvester equation b : array, shape (N, N) Trailing matrix of the Sylvester equation q : array, shape (M, N) Right-hand side Returns ------- x : array, shape (M, N) The solution to the Sylvester equation. Raises ------ LinAlgError If solution was not found Notes ----- Computes a solution to the Sylvester matrix equation via the Bartels- Stewart algorithm. The A and B matrices first undergo Schur decompositions. The resulting matrices are used to construct an alternative Sylvester equation (``RY + YS^T = F``) where the R and S matrices are in quasi-triangular form (or, when R, S or F are complex, triangular form). The simplified equation is then solved using ``*TRSYL`` from LAPACK directly. """ # Compute the Schur decomp form of a r, u = schur(a, output='real') # Compute the Schur decomp of b s, v = schur(b.conj().transpose(), output='real') # Construct f = u'*q*v f = np.dot(np.dot(u.conj().transpose(), q), v) # Call the Sylvester equation solver trsyl, = get_lapack_funcs(('trsyl', ), (r, s, f)) if trsyl == None: raise RuntimeError( 'LAPACK implementation does not contain a proper Sylvester equation solver (TRSYL)' ) y, scale, info = trsyl(r, s, f, tranb='C') y = scale * y if info < 0: raise LinAlgError("Illegal value encountered in the %d term" % (-info, )) return np.dot(np.dot(u, y), v.conj().transpose())
def __call__(self, a): a = astensor(a) if a.ndim != 2: raise LinAlgError(f"{a.ndim}-dimensional tensor given. " "Tensor must be two-dimensional") tiny_q, tiny_r = np.linalg.qr(np.ones((1, 1), dtype=a.dtype)) x, y = a.shape q_shape, r_shape = (a.shape, (y, y)) if x > y else ((x, x), a.shape) q, r = self.new_tensors( [a], kws=[ { "side": "q", "dtype": tiny_q.dtype, "shape": q_shape, "order": TensorOrder.C_ORDER, }, { "side": "r", "dtype": tiny_r.dtype, "shape": r_shape, "order": TensorOrder.C_ORDER, }, ], ) return ExecutableTuple([q, r])
def __call__(self, a): import scipy.linalg a = astensor(a) if a.ndim != 2: raise LinAlgError('{0}-dimensional array given. ' 'Tensor must be two-dimensional'.format(a.ndim)) if a.shape[0] > a.shape[1]: p_shape = (a.shape[0],) * 2 l_shape = a.shape u_shape = (a.shape[1],) * 2 elif a.shape[0] < a.shape[1]: p_shape = (a.shape[0],) * 2 l_shape = (a.shape[0],) * 2 u_shape = a.shape else: p_shape, l_shape, u_shape = (a.shape,) * 3 tiny_p, tiny_l, tiny_u = scipy.linalg.lu(np.array([[1, 2], [2, 5]], dtype=a.dtype)) order = a.order p, l, u = self.new_tensors([a], kws=[ {'side': 'p', 'dtype': tiny_p.dtype, 'shape': p_shape, 'order': order}, {'side': 'l', 'dtype': tiny_l.dtype, 'shape': l_shape, 'order': order}, {'side': 'u', 'dtype': tiny_u.dtype, 'shape': u_shape, 'order': order}, ]) return ExecutableTuple([p, l, u])
def _undiscretize(T, dt, method, prewarp_at, q): m, n = T.NumberOfInputs, T.NumberOfStates if method == 'zoh': M = np.r_[np.c_[T.a, T.b], np.c_[np.zeros((m, n)), np.eye(m)]] eM = logm(M)*(1/dt) Ac, Bc, Cc, Dc = eM[:n, :n], eM[:n, n:], T.c, T.d elif method in ('bilinear', 'tustin', 'trapezoidal'): if prewarp_at == 0.: q = np.array([[-2/dt, 2/np.sqrt(dt)], [2/np.sqrt(dt), -1]]) else: if 1/(2*dt) <= prewarp_at: raise ValueError('Prewarping frequency is beyond the Nyquist' ' rate. It has to satisfy 0 < w < 1/(2*Δt)' ' and Δt being the sampling period in ' 'seconds. Δt={0} is given, hence the maximum' ' allowed is {1} Hz.'.format(dt, 1/(2*dt))) prew_rps = 2 * np.pi * prewarp_at sq2tan = np.sqrt(2*np.tan(prew_rps * dt / 2)/prew_rps) q = np.array([[-2/sq2tan**2, 1/sq2tan], [1/sq2tan, -1]]) Ac, Bc, Cc, Dc = _simple_lft_connect(q, T.a, T.b, T.c, T.d) elif method in ('forward euler', 'forward difference', 'forward rectangular', '>>'): q = np.array([[-1/dt, 1/np.sqrt(dt)], [1/np.sqrt(dt), 0]]) Ac, Bc, Cc, Dc = _simple_lft_connect(q, T.a, T.b, T.c, T.d) elif method in ('backward euler', 'backward difference', 'backward rectangular', '<<'): # nonproper via lft, compute explicitly. with catch_warnings(): simplefilter('error') try: iAd = inv(T.a) except RuntimeWarning: warn('The state matrix has eigenvalues too close to imaginary' ' axis. This conversion method might give inaccurate ' 'results', RuntimeWarning, stacklevel=2) except LinAlgError: raise LinAlgError('The state matrix has eigenvalues at zero' 'and this conversion method can\'t be used.') Ac = np.eye(n) - iAd Ac /= dt Bc = 1/np.sqrt(dt)*iAd @ T.b Cc = 1/np.sqrt(dt) * T.c @ iAd Dc = T.d - dt*Cc @ iAd @ Bc elif method == 'lft': if q is None: raise ValueError('"lft" method requires a 2x2 interconnection ' 'matrix "q" between s and z indeterminates.') Ac, Bc, Cc, Dc = _simple_lft_connect(q, T.a, T.b, T.c, T.d) return Ac, Bc, Cc, Dc
def _check_finite_array(a): """ check whether array is finite (copied from numba.linalg._check_finite_matrix) """ for v in np.nditer(a): # for v in np.ravel(a): if not np.isfinite(v.item()): raise LinAlgError("Array must not contain infs or NaNs.")
def stability_M(n_src, total_ele, ele_pos, pots, R_init=0.23): """ Investigates stability of reconstruction for different number of basis sources Parameters ---------- n_src: int Number of basis sources. total_ele: int Number of electrodes. ele_pos: numpy array Electrodes positions. pots: numpy array Values of potentials at ele_pos. R_init: float Initial value of R parameter - width of basis source Default: 0.23. Returns ------- obj_all: class object eigenvalues: numpy array Eigenvalues of k_pot matrix. eigenvectors: numpy array Eigen vectors of k_pot matrix. """ obj_all = [] eigenvectors = np.zeros((len(n_src), total_ele, total_ele)) eigenvalues = np.zeros((len(n_src), total_ele)) for i, value in enumerate(n_src): pots = pots.reshape((len(ele_pos), 1)) obj = KCSD2D(ele_pos, pots, src_type='gauss', sigma=1., h=50., gdx=0.01, gdy=0.01, n_src_init=n_src[i], xmin=0, xmax=1, ymax=1, ymin=0, R_init=R_init) try: eigenvalue, eigenvector = np.linalg.eigh( obj.k_pot + obj.lambd * np.identity(obj.k_pot.shape[0])) except LinAlgError: raise LinAlgError('EVD is failing - try moving the electrodes' 'slightly') idx = eigenvalue.argsort()[::-1] eigenvalues[i] = eigenvalue[idx] eigenvectors[i] = eigenvector[:, idx] obj_all.append(obj) return obj_all, eigenvalues, eigenvectors
def cho_solve_imp(c_and_lower, b, overwrite_b=False, check_finite=True): (c, lower) = c_and_lower # Squareness check if (c.shape[0] != c.shape[1]): raise LinAlgError("The factored matrix c is not square.") # Dimension check if c.shape[1] != b.shape[0]: raise LinAlgError("c and b have incompatible dimensions.") # Check that arrays are finite if check_finite: _check_finite_array(c) _check_finite_array(b) if to_float64: # need to upcast these. if already float64 should be a no-copy. # otherwise, copies to C order, so do this before as_fortranarray c1 = np.asarray(c, dtype=np.float64) b1 = np.asarray(b, dtype=np.float64) else: c1 = c b1 = b # convert to fortran order, avoiding copy whenever possible. # c is assumed to come from cho_factor, so already in fortran order. # if it was already float64, _asfortranarray does nothing # if it needed to be changed to float64, a copy was already made, # so _asfortranarray is not overwriting the original c. c1 = _asfortranarray(c1, overwrite_a=True) b1 = _asfortranarray(b1, overwrite_b) # determine order uplo = LO if lower else UP # wrap everything into something with ctypes n = np.array(c.shape[0], dtype=np.int32) # nrhs = np.array(b.shape[1], dtype=np.int32) nrhs = np.array(b.size / b.shape[0], dtype=np.int32) lda = n ldb = n info = np.empty(1, dtype=np.int32) # call fortran via cython_lapack _potrs(uplo.ctypes, n.ctypes, nrhs.ctypes, c1.ctypes, lda.ctypes, b1.ctypes, ldb.ctypes, info.ctypes) # check return if info[0] != 0: raise ValueError('Illegal value in internal "POTRS".') return b1
def _eval_metric(self): """ Evaluate MICE criterion on all candidate points and select new design point This internal method computes the MICE criterion on all candidate points and returns the index of the point with the maximum value. It does so by first fitting a base GP to all points in the current design, and then fitting a dummy GP to all candidate design points using the parameter values determined from the base GP fit. The MICE criterion does not depend on the target values, since the parameters are determined via the base GP and the MICE criterion only depends on the uncertainty of the candidate GP (which is independent of the target values). These fit GPs are then used to compute the MICE criterion for each candidate point, and the method returns the index of the point that had the maximum value of the MICE criterion. :returns: Index of the candidate with the maximum MICE score (integer with ``0 <= index < n_cand``) :rtype: int """ numtries = 10 for i in range(numtries): try: self.gp = GaussianProcess(self.inputs, self.targets, nugget=self.nugget) self.gp = fit_GP_MAP(self.gp) self.gp_fast = MICEFastGP(self.candidates, np.ones(self.n_cand), nugget=np.exp(self.gp.theta[-2]) * self.nugget_s) self.gp_fast.theta = self.gp.theta break except FloatingPointError: if i < numtries - 1: continue else: raise FloatingPointError( "Unable to find parameters suitable for both GPs") except LinAlgError: if i < numtries - 1: continue else: raise LinAlgError( "Unable to find parameters suitable for both GPs") results = [] for point in range(self.n_cand): results.append(self._MICE_criterion(point)) return np.argmax(results)
def _rotation_matrix_to_angle(matrix): """ Returns the angle for a given 2x2 rotation matrix. Parameters ---------- matrix : 2x2 array Rotation matrix. Returns ------ angle : float Rotation angle in radians. Raises ------ LinAlgError If the supplied matrix is not a rotation matrix. NotImplementedError If the supplied matrix is not of size 2x2. Examples -------- >>> matrix = numpy.array([(0., -1.), (1., 0.)]) >>> Transform._rotation_matrix_to_angle(matrix) 1.5707963267948966 """ if len(matrix.shape) != 2: raise LinAlgError('%d-dimensional array given. Array must be ' 'two-dimensional' % len(matrix.shape)) if max(matrix.shape) != min(matrix.shape): raise LinAlgError('Array must be square') if matrix.shape != (2, 2): raise NotImplementedError('Can only handle 2x2 matrices') if not numpy.allclose(numpy.dot(matrix.T, matrix), numpy.eye(2)): raise LinAlgError('Matrix is not orthogonal') if not numpy.allclose(numpy.linalg.det(matrix), 1.0): raise LinAlgError('Matrix is not a proper rotation matrix') return numpy.arctan2(matrix[1, 0], matrix[0, 0])
def inv(a): global getrf, getri lu, piv, info = getrf(a, overwrite_a=True) if info == 0: lwork = calc_lwork.getri(getri.typecode, a.shape[0]) lwork = lwork[1] lwork = int(1.01 * lwork) inv_a, info = getri(lu, piv, lwork=lwork, overwrite_lu=1) if info > 0: raise LinAlgError("singular matrix") if info < 0: raise ValueError('illegal value in %d-th argument of internal ' 'getrf|getri' % -info) return inv_a
def set_invcovariance(self,xmask,invertcovariance=[],scalecovariance=None): del self.params['xmask'] xmaskall = scipy.concatenate(xmask) if self.scale_data_covariance is not None: self.logger.info('Scaling covariance by {:.4f}.'.format(scalecovariance)) self.covariance *= scalecovariance self.stddev = scipy.diag(self.covariance[scipy.ix_(xmaskall,xmaskall)]) error_message = 'The covariance matrix is ill-conditionned. You may want to try the option sliced.' if 'sliced' in self.invert_covariance: self.logger.info('Slicing covariance.') self.covariance = self.covariance[scipy.ix_(xmaskall,xmaskall)] error_message = 'The covariance matrix is ill-conditionned. You may want to try the option block.' self.covariance = self.covariance.astype(scipy.float64) #make sure we have enough precision if 'diagonal' in self.invert_covariance: self.logger.info('Inverting diagonal matrix/blocks.') def inv(A): return scipy.diag(1./scipy.diag(A)) elif 'cholesky' in self.invert_covariance: self.logger.info('Inverting using Choleskys decomposition.') def inv(A): c = linalg.inv(linalg.cholesky(A)) #using Cholesky's decomposition return scipy.dot(c.T,c) else: self.logger.info('Inverting using linalg inversion.') def inv(A): return linalg.inv(A) if 'block' in self.invert_covariance: self.logger.info('Inverting by block.') if 'sliced' in self.invert_covariance: blocksize = scipy.cumsum([0] + map(scipy.sum,xmask)) else: blocksize = scipy.cumsum([0] + map(len,xmask)) blocks = [[self.covariance[i1:i2,j1:j2] for j1,j2 in zip(blocksize[:-1],blocksize[1:])] for i1,i2 in zip(blocksize[:-1],blocksize[1:])] self.invcovariance = utils.blockinv(blocks,inv=inv) error_message = 'The covariance matrix is ill-conditionned. You have to provide a better estimate.' else: self.invcovariance = inv(self.covariance) diff = self.covariance.dot(self.invcovariance)-scipy.eye(self.covariance.shape[0]) diff = scipy.absolute(diff).max() self.logger.info('Inversion computed to absolute precision {:.4g}.'.format(diff)) if diff > 1.: raise LinAlgError(error_message) if 'sliced' not in self.invert_covariance: self.logger.info('Slicing covariance.') self.invcovariance = self.invcovariance[scipy.ix_(xmaskall,xmaskall)]
def covar(self, target="residuals"): """ Estimates the covariance matrix of the Objective. Parameters ---------- target : {"residuals", "nll", "nlpost"} Specifies what approach should be used to estimate covariance. Returns ------- covar : np.ndarray Covariance matrix Notes ----- For most purposes the Jacobian of the `'residuals'` should be used to calculate the covariance matrix, estimated as J.T x J. If an Objective cannot calculate residuals then the covariance matrix can be estimated by inverting a Hessian matrix created from either the `'nll'` or `'nlpost'` methods. The default `'residuals'` approach falls back to `'nll'` if a problem is experienced. The default `'residuals'` setting is preferred as the other settings can sometimes experience instabilities during Hessian estimation with numerical differentiation. """ if target == "residuals": try: covar = self._covar_from_residuals() except Exception: # fallback to "nll" target = "nll" if target in ["nll", "nlpost"]: covar = super(Objective, self).covar(target) pvar = np.diagonal(covar).copy() psingular = np.where(pvar == 0)[0] if len(psingular) > 0: var_params = self.varying_parameters() singular_params = [var_params[ps] for ps in psingular] raise LinAlgError("The following Parameters have no effect on" " Objective.residuals, please consider fixing" " them.\n" + repr(singular_params)) return covar
def cho_factor_imp(a, lower=False, overwrite_a=False, check_finite=True): # Reject ndarrays with unsupported dimensionality if a.shape[0] != a.shape[1]: raise LinAlgError('Input array needs to be a square matrix.') # Quick return for square empty array if a.size == 0: return a.copy(), lower # Check that matrix is finite if check_finite: _check_finite_array(a) # this should be a no-copy if array is already in fortran order # and overwrite_a = True a1 = _asfortranarray(a, overwrite_a) # determine order uplo = LO if lower else UP # wrap everything into something with ctypes n = np.array(a.shape[0], dtype=np.int32) lda = n info = np.empty(1, dtype=np.int32) # uplo = np.array([uplo], dtype=np.int32) # call fortran via cython_lapack _potrf(uplo.ctypes, n.ctypes, a1.ctypes, lda.ctypes, info.ctypes) # check return if info[0] > 0: # raise np.linalg.LinAlgError( # "%d-th leading minor of the array is not positive " # "definite." % info[0]) raise LinAlgError("Input matrix is not positive definite.") if info[0] < 0: # info[0] = -info[0] # raise ValueError( # 'LAPACK reported an illegal value in %d-th argument' # 'on entry to "POTRF".' % info[0]) raise ValueError( 'LAPACK reported an illegal value on entry to "POTRF".') return a1, lower