Пример #1
0
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')
Пример #2
0
 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
Пример #3
0
Файл: lu.py Проект: ic/mars
    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])
Пример #4
0
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")
Пример #5
0
    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
Пример #6
0
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)
Пример #7
0
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
Пример #8
0
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)
Пример #9
0
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
Пример #10
0
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
Пример #11
0
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))
Пример #12
0
 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
Пример #13
0
    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
Пример #14
0
 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
Пример #15
0
    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])
Пример #16
0
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
Пример #17
0
    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])
Пример #18
0
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())
Пример #19
0
    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])
Пример #20
0
    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])
Пример #21
0
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
Пример #22
0
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
Пример #24
0
 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
Пример #25
0
    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)
Пример #26
0
    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])
Пример #27
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
Пример #28
0
	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)]
Пример #29
0
    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
Пример #30
0
 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