Exemplo n.º 1
0
def _get_outer_edges(a, range):
    """
    Determine the outer bin edges to use, from either the data or the range
    argument
    """
    if range is not None:
        first_edge, last_edge = range
        if first_edge > last_edge:
            raise ValueError("max must be larger than min in range parameter.")
        if not (numpy.isfinite(first_edge) and numpy.isfinite(last_edge)):
            raise ValueError("supplied range of [{}, {}] is not finite".format(
                first_edge, last_edge))
    elif a.size == 0:
        first_edge = 0.0
        last_edge = 1.0
    else:
        first_edge = float(a.min())
        last_edge = float(a.max())
        if not (cupy.isfinite(first_edge) and cupy.isfinite(last_edge)):
            raise ValueError(
                "autodetected range of [{}, {}] is not finite".format(
                    first_edge, last_edge))

    # expand empty range to avoid divide by zero
    if first_edge == last_edge:
        first_edge = first_edge - 0.5
        last_edge = last_edge + 0.5

    return first_edge, last_edge
Exemplo n.º 2
0
 def step(self, state, momentum, rng, **args):
     q = state.copy()
     p = self.draw_momentum(rng)
     q_new = deepcopy(q)
     p_new = deepcopy(p)
     positions, momentums = [cp.asnumpy(q)], [cp.asnumpy(p)]
     epsilon = self.step_size
     path_length = cp.ceil(2 * cp.random.rand() * self.path_length /
                           epsilon)
     grad_q = self.model.grad(q, **args)
     # leapfrog step
     for _ in cp.arange(path_length - 1):
         for var in self.start.keys():
             p_new[var] -= (0.5 * epsilon) * grad_q[var]
             q_new[var] += epsilon * p_new[var]
             grad_q = self.model.grad(q_new, **args)
             p_new[var] -= epsilon * grad_q[var]
         #positions.append(deepcopy(q_new))
         #momentums.append(deepcopy(p_new))
     # negate momentum
     for var in self.start.keys():
         p_new[var] = -p_new[var]
     acceptprob = self.accept(q, q_new, p, p_new, **args)
     if cp.isfinite(acceptprob) and (cp.random.rand() < acceptprob):
         q = q_new.copy()
         p = p_new.copy()
     return q, p, positions, momentums, acceptprob
Exemplo n.º 3
0
def check_finite(array, force_all_finite=True):
    """Checks that the input is finite if necessary

    Parameters
    ----------
    array : object
        Input object to check / convert.
    force_all_finite : boolean or 'allow-nan', (default=True)
        Whether to raise an error on np.inf, np.nan, pd.NA in array. The
        possibilities are:
        - True: Force all values of array to be finite.
        - False: accepts np.inf, np.nan, pd.NA in array.
        - 'allow-nan': accepts only np.nan and pd.NA values in array. Values
          cannot be infinite.
           ``force_all_finite`` accepts the string ``'allow-nan'``.

    Returns
    -------
    None or raise error
    """
    if force_all_finite is True:
        if not cp.all(cp.isfinite(array)):
            raise ValueError("Non-finite value encountered in array")
    elif force_all_finite == 'allow-nan':
        if cp.any(cp.isinf(array)):
            raise ValueError("Non-finite value encountered in array")
Exemplo n.º 4
0
def isfinite(x: Array, /) -> Array:
    """
    Array API compatible wrapper for :py:func:`np.isfinite <numpy.isfinite>`.

    See its docstring for more information.
    """
    if x.dtype not in _numeric_dtypes:
        raise TypeError("Only numeric dtypes are allowed in isfinite")
    return Array._new(np.isfinite(x._array))
Exemplo n.º 5
0
def _lu_factor(a, overwrite_a=False, check_finite=True):
    a = cupy.asarray(a)
    _util._assert_2d(a)

    dtype = a.dtype

    if dtype.char == 'f':
        getrf = cusolver.sgetrf
        getrf_bufferSize = cusolver.sgetrf_bufferSize
    elif dtype.char == 'd':
        getrf = cusolver.dgetrf
        getrf_bufferSize = cusolver.dgetrf_bufferSize
    elif dtype.char == 'F':
        getrf = cusolver.cgetrf
        getrf_bufferSize = cusolver.cgetrf_bufferSize
    elif dtype.char == 'D':
        getrf = cusolver.zgetrf
        getrf_bufferSize = cusolver.zgetrf_bufferSize
    else:
        msg = 'Only float32, float64, complex64 and complex128 are supported.'
        raise NotImplementedError(msg)

    a = a.astype(dtype, order='F', copy=(not overwrite_a))

    if check_finite:
        if a.dtype.kind == 'f' and not cupy.isfinite(a).all():
            raise ValueError('array must not contain infs or NaNs')

    cusolver_handle = device.get_cusolver_handle()
    dev_info = cupy.empty(1, dtype=numpy.int32)

    m, n = a.shape

    ipiv = cupy.empty((min(m, n), ), dtype=numpy.intc)

    buffersize = getrf_bufferSize(cusolver_handle, m, n, a.data.ptr, m)
    workspace = cupy.empty(buffersize, dtype=dtype)

    # LU factorization
    getrf(cusolver_handle, m, n, a.data.ptr, m, workspace.data.ptr,
          ipiv.data.ptr, dev_info.data.ptr)

    if not runtime.is_hip and dev_info[0] < 0:
        # rocSOLVER does not inform us this info
        raise ValueError('illegal value in %d-th argument of '
                         'internal getrf (lu_factor)' % -dev_info[0])
    elif dev_info[0] > 0:
        warn('Diagonal number %d is exactly zero. Singular matrix.' %
             dev_info[0],
             RuntimeWarning,
             stacklevel=2)

    # cuSolver uses 1-origin while SciPy uses 0-origin
    ipiv -= 1

    return (a, ipiv)
Exemplo n.º 6
0
def test_li_pathological_arrays():
    # See https://github.com/scikit-image/scikit-image/issues/4140
    a = cp.asarray([0, 0, 1, 0, 0, 1, 0, 1])
    b = cp.asarray([0, 0, 0.1, 0, 0, 0.1, 0, 0.1])
    c = cp.asarray([0, 0, 0.1, 0, 0, 0.1, 0.01, 0.1])
    d = cp.asarray([0, 0, 1, 0, 0, 1, 0.5, 1])
    e = cp.asarray([1, 1])
    f = cp.asarray([1, 2])
    arrays = [a, b, c, d, e, f]
    thresholds = cp.asarray([float(threshold_li(arr)) for arr in arrays])
    assert cp.all(cp.isfinite(thresholds))
Exemplo n.º 7
0
def test_li_pathological_arrays():
    # See https://github.com/scikit-image/scikit-image/issues/4140
    a = cp.array([0, 0, 1, 0, 0, 1, 0, 1])
    b = cp.array([0, 0, 0.1, 0, 0, 0.1, 0, 0.1])
    c = cp.array([0, 0, 0.1, 0, 0, 0.1, 0.01, 0.1])
    d = cp.array([0, 0, 1, 0, 0, 1, 0.5, 1])
    e = cp.array([1, 1])
    f = cp.asarray([1, 2])
    arrays = [a, b, c, d, e, f]
    with np.errstate(divide='ignore'):
        # ignoring "divide by zero encountered in log" error from np.log(0)
        thresholds = cp.array([float(threshold_li(arr)) for arr in arrays])
    assert cp.all(cp.isfinite(thresholds))
Exemplo n.º 8
0
def test_blank_image_nans():
    """Some of the corner detectors had a weakness in terms of returning
    NaN when presented with regions of constant intensity. This should
    be fixed by now. We test whether each detector returns something
    finite in the case of constant input"""

    #    detectors = [corner_moravec, corner_harris, corner_shi_tomasi,
    #                 corner_kitchen_rosenfeld]
    detectors = [
        corner_harris,
        corner_shi_tomasi,
        corner_kitchen_rosenfeld,
    ]
    constant_image = cp.zeros((20, 20))

    for det in detectors:
        response = det(constant_image)
        assert cp.all(cp.isfinite(response))

    w, q = corner_foerstner(constant_image)
    assert cp.all(cp.isfinite(w))
    assert cp.all(cp.isfinite(q))
Exemplo n.º 9
0
def log_softmax(x, axis=None):
    """Compute logarithm of softmax function

    Parameters
    ----------
    x : array-like
        Input array
    axis : int or tuple of ints, optional
        Axis to compute values along. Default is None and softmax
        will be  computed over the entire array `x`

    Returns
    -------
    s : cupy.ndarry
        An array with the same shape as `x`. Exponential of the
        result will sum to 1 along the specified axis. If `x` is a
        scalar, a scalar is returned

    """

    x_max = cp.amax(x, axis=axis, keepdims=True)

    if x_max.ndim > 0:
        x_max[~cp.isfinite(x_max)] = 0
    elif not cp.isfinite(x_max):
        x_max = 0

    tmp = x - x_max

    if tmp.dtype.kind in 'iu':
        for out_dtype in [cp.float16, cp.float32, cp.float64]:
            if cp.can_cast(tmp.dtype, out_dtype):
                tmp = tmp.astype(out_dtype)
                break

    out = _log_softmax_kernel(tmp, axis=axis, keepdims=True)

    out = tmp - out
    return out
Exemplo n.º 10
0
def fhtcoeff(n, dln, mu, offset=0.0, bias=0.0):
    '''Compute the coefficient array for a fast Hankel transform.
    '''

    lnkr, q = offset, bias

    # Hankel transform coefficients
    # u_m = (kr)^{-i 2m pi/(n dlnr)} U_mu(q + i 2m pi/(n dlnr))
    # with U_mu(x) = 2^x Gamma((mu+1+x)/2)/Gamma((mu+1-x)/2)
    xp = (mu + 1 + q)/2
    xm = (mu + 1 - q)/2
    y = cupy.linspace(0, math.pi * (n // 2) / (n * dln), n // 2 + 1)
    u = cupy.empty(n // 2 + 1, dtype=complex)
    v = cupy.empty(n // 2 + 1, dtype=complex)
    u.imag[:] = y
    u.real[:] = xm
    loggamma(u, out=v)
    u.real[:] = xp
    loggamma(u, out=u)
    y *= 2 * (LN_2 - lnkr)
    u.real -= v.real
    u.real += LN_2 * q
    u.imag += v.imag
    u.imag += y
    cupy.exp(u, out=u)

    # fix last coefficient to be real
    u.imag[-1] = 0

    # deal with special cases
    if not cupy.isfinite(u[0]):
        # write u_0 = 2^q Gamma(xp)/Gamma(xm) = 2^q poch(xm, xp-xm)
        # poch() handles special cases for negative integers correctly
        u[0] = 2**q * poch(xm, xp - xm)
        # the coefficient may be inf or 0, meaning the transform or the
        # inverse transform, respectively, is singular

    return u
Exemplo n.º 11
0
 def step(self, state, momentum, rng, **args):
     q = state.copy()
     p = self.draw_momentum(rng)
     q_new = deepcopy(q)
     p_new = deepcopy(p)
     epsilon = self.step_size
     path_length = cp.ceil(2 * cp.random.rand() * self.path_length /
                           epsilon)
     grad_q = self.model.grad(q, **args)
     # SG-HMC leapfrog step
     for _ in cp.arange(path_length - 1):
         for var in self.start.keys():
             dim = (cp.array(q_new[var])).size
             rvar = rng.normal(0, 2 * epsilon, dim).reshape(q[var].shape)
             q_new[var] += epsilon * p_new[var]
             grad_q = self.model.grad(q_new, **args)
             p_new[var] = (
                 1 - epsilon) * p_new[var] + epsilon * grad_q[var] + rvar
     acceptprob = self.accept(q, q_new, p, p_new, **args)
     if cp.isfinite(acceptprob) and (cp.random.rand() < acceptprob):
         q = q_new.copy()
         p = p_new.copy()
     return q, p, acceptprob
Exemplo n.º 12
0
def asarray_chkfinite(a, dtype=None, order=None):
    """Converts the given input to an array,
    and raises an error if the input contains NaNs or Infs.

    Args:
        a: array like.
        dtype: data type, optional
        order: {'C', 'F', 'A', 'K'}, optional

    Returns:
        cupy.ndarray: An array on the current device.

    .. note::
        This function performs device synchronization.

    .. seealso:: :func:`numpy.asarray_chkfinite`

    """

    a = cupy.asarray(a, dtype=dtype, order=order)
    if not cupy.isfinite(a).all():
        raise ValueError("array must not contain Infs or NaNs")
    return a
Exemplo n.º 13
0
def lstsq_grad(
    op, comm,
    data, probe, scan, psi,
    recover_psi=True, recover_probe=False, recover_positions=False,
    cg_iter=4,
    cost=None,
    eigen_probe=None,
    eigen_weights=None,
):  # yapf: disable
    """Solve the ptychography problem using Odstrcil et al's approach.

    The near- and farfield- ptychography problems are solved separately using
    gradient descent in the farfield and linear-least-squares in the nearfield.

    Parameters
    ----------
    op : tike.operators.Ptycho
        A ptychography operator.
    comm : tike.communicators.Comm
        An object which manages communications between GPUs and nodes.

    References
    ----------
    Michal Odstrcil, Andreas Menzel, and Manuel Guizar-Sicaros. Iterative
    least-squares solver for generalized maximum-likelihood ptychography.
    Optics Express. 2018.

    """
    data_ = data[0]
    probe = probe[0]
    scan_ = scan[0]
    psi = psi[0]
    if eigen_probe is not None:
        eigen_weights = eigen_weights[0]
        eigen_probe = eigen_probe[0]

    # -------------------------------------------------------------------------

    common_probe = probe
    unique_probe = get_varying_probe(
        probe,
        eigen_probe=eigen_probe,
        weights=eigen_weights,
    )

    farplane, cost = _update_wavefront(op, data_, unique_probe, scan_, psi)

    pad, end = op.diffraction.pad, op.diffraction.end

    # Solve the nearplane problem ---------------------------------------------

    for m in range(probe.shape[-3]):

        nearplane = farplane[..., m:m + 1, pad:end, pad:end]

        cprobe = common_probe[..., m:m + 1, :, :]
        uprobe = unique_probe[..., m:m + 1, :, :]

        patches = op.diffraction._patch(
            patches=cp.zeros(nearplane.shape, dtype='complex64'),
            psi=psi,
            scan=scan_,
            fwd=True,
        )

        # χ (diff) is the target for the nearplane problem; the difference
        # between the desired nearplane and the current nearplane that we wish
        # to minimize.
        diff = nearplane - uprobe * patches

        logger.info('%10s cost is %+12.5e', 'nearplane', norm(diff))

        if recover_psi:
            grad_psi = cp.conj(uprobe) * diff

            # (25b) Common object gradient. Use a weighted (normalized) sum
            # instead of division as described in publication to improve
            # numerical stability.
            common_grad_psi = op.diffraction._patch(
                patches=grad_psi,
                psi=cp.zeros(psi.shape, dtype='complex64'),
                scan=scan_,
                fwd=False,
            )

            dOP = op.diffraction._patch(
                patches=cp.zeros(patches.shape, dtype='complex64'),
                psi=common_grad_psi,
                scan=scan_,
                fwd=True,
            ) * uprobe
            A1 = cp.sum((dOP * dOP.conj()).real + 0.5, axis=(-2, -1))
            A1 += 0.5 * cp.mean(A1, axis=-3, keepdims=True)
            b1 = cp.sum((dOP.conj() * diff).real, axis=(-2, -1))

        if recover_probe:
            grad_probe = cp.conj(patches) * diff

            # (25a) Common probe gradient. Use simple average instead of
            # division as described in publication because that's what
            # ptychoshelves does
            common_grad_probe = cp.mean(
                grad_probe,
                axis=-5,
                keepdims=True,
            )

            dPO = common_grad_probe * patches
            A4 = cp.sum((dPO * dPO.conj()).real + 0.5, axis=(-2, -1))
            A4 += 0.5 * cp.mean(A4, axis=-3, keepdims=True)
            b2 = cp.sum((dPO.conj() * diff).real, axis=(-2, -1))

        if recover_probe and eigen_probe is not None:
            logger.info('Updating eigen probes')
            # (30) residual probe updates
            R = grad_probe - cp.mean(grad_probe, axis=-5, keepdims=True)

            for c in range(eigen_probe.shape[-4]):

                eigen_probe[..., c:c + 1, m:m + 1, :, :] = update_eigen_probe(
                    R,
                    eigen_probe[..., c:c + 1, m:m + 1, :, :],
                    eigen_weights[..., c, m],
                    β=0.01,  # TODO: Adjust according to mini-batch size
                )

                # Determine new eigen_weights for the updated eigen probe
                phi = patches * eigen_probe[..., c:c + 1, m:m + 1, :, :]
                n = cp.mean(
                    cp.real(diff * phi.conj()),
                    axis=(-1, -2),
                    keepdims=True,
                )
                norm_phi = cp.square(cp.abs(phi))
                d = cp.mean(norm_phi, axis=(-1, -2), keepdims=True)
                d += 0.1 * cp.mean(d, axis=-5, keepdims=True)
                weight_update = (n / d).reshape(*eigen_weights[..., 0, 0].shape)
                assert cp.all(cp.isfinite(weight_update))

                # (33) The sum of all previous steps constrained to zero-mean
                eigen_weights[..., c, m] += weight_update
                eigen_weights[..., c, m] -= cp.mean(
                    eigen_weights[..., c, m],
                    axis=-1,
                    keepdims=True,
                )

                if eigen_probe.shape[-4] <= c + 1:
                    # Subtract projection of R onto new probe from R
                    R -= projection(
                        R,
                        eigen_probe[..., c:c + 1, m:m + 1, :, :],
                        axis=(-2, -1),
                    )

        # (22) Use least-squares to find the optimal step sizes simultaneously
        if recover_psi and recover_probe:
            A2 = cp.sum((dOP * dPO.conj()), axis=(-2, -1))
            A3 = A2.conj()
            determinant = A1 * A4 - A2 * A3
            x1 = -cp.conj(A2 * b2 - A4 * b1) / determinant
            x2 = cp.conj(A1 * b2 - A3 * b1) / determinant
        elif recover_psi:
            x1 = b1 / A1
        elif recover_probe:
            x2 = b2 / A4

        # Update each direction
        if recover_psi:
            step = x1[..., None, None]

            # (27b) Object update
            weighted_step = cp.mean(step, keepdims=True, axis=-5)[..., 0, 0, 0]

            psi += weighted_step * common_grad_psi

        if recover_probe:
            step = x2[..., None, None]

            # (27a) Probe update
            cprobe += common_grad_probe * cp.mean(
                step,
                axis=-5,
                keepdims=True,
            )

        if __debug__:
            patches = op.diffraction._patch(
                patches=cp.zeros(nearplane.shape, dtype='complex64'),
                psi=psi,
                scan=scan_,
                fwd=True,
            )
            logger.info('%10s cost is %+12.5e', 'nearplane',
                        norm(cprobe * patches - nearplane))

    result = {
        'psi': [psi],
        'probe': [probe],
        'cost': cost,
        'scan': scan,
    }
    if eigen_probe is not None:
        result['eigen_probe'] = [eigen_probe]
        result['eigen_weights'] = [eigen_weights]
    return result
Exemplo n.º 14
0
 def test_standard_logistic_isfinite(self):
     x = self.generate(size=10**7)
     self.assertTrue(cupy.isfinite(x).all())
Exemplo n.º 15
0
 def test_standard_exponential_isfinite(self):
     x = self.generate(size=10**7)
     assert cupy.isfinite(x).all()
Exemplo n.º 16
0
Arquivo: _util.py Projeto: zhaohb/cupy
def _check_cval(mode, cval, integer_output):
    if mode == 'constant' and integer_output and not cupy.isfinite(cval):
        raise NotImplementedError("Non-finite cval is not supported for "
                                  "outputs with integer dtype.")
Exemplo n.º 17
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``

    Args:
        lu_and_piv (tuple): LU factorization of matrix ``a`` (``(M, M)``)
            together with pivot indices.
        b (cupy.ndarray): The matrix with dimension ``(M,)`` or
            ``(M, N)``.
        trans ({0, 1, 2}): Type of system to solve:

            ========  =========
            trans     system
            ========  =========
            0         a x  = b
            1         a^T x = b
            2         a^H x = b
            ========  =========
        overwrite_b (bool): Allow overwriting data in b (may enhance
            performance)
        check_finite (bool): 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:
        cupy.ndarray:
            The matrix with dimension ``(M,)`` or ``(M, N)``.

    .. seealso:: :func:`scipy.linalg.lu_solve`
    """

    (lu, ipiv) = lu_and_piv

    util._assert_cupy_array(lu)
    util._assert_rank2(lu)
    util._assert_nd_squareness(lu)

    m = lu.shape[0]
    if m != b.shape[0]:
        raise ValueError('incompatible dimensions.')

    dtype = lu.dtype
    if dtype.char == 'f':
        getrs = cusolver.sgetrs
    elif dtype.char == 'd':
        getrs = cusolver.dgetrs
    else:
        raise NotImplementedError('Only float32 and float64 are supported.')

    if trans == 0:
        trans = cublas.CUBLAS_OP_N
    elif trans == 1:
        trans = cublas.CUBLAS_OP_T
    elif trans == 2:
        trans = cublas.CUBLAS_OP_C
    else:
        raise ValueError('unknown trans')

    lu = lu.astype(dtype, order='F', copy=False)
    ipiv = ipiv.astype(ipiv.dtype, order='F', copy=True)
    # cuSolver uses 1-origin while SciPy uses 0-origin
    ipiv += 1
    b = b.astype(dtype, order='F', copy=(not overwrite_b))

    if check_finite:
        if lu.dtype.kind == 'f' and not cupy.isfinite(lu).all():
            raise ValueError(
                'array must not contain infs or NaNs.\n'
                'Note that when a singular matrix is given, unlike '
                'scipy.linalg.lu_factor, cupyx.scipy.linalg.lu_factor '
                'returns an array containing NaN.')
        if b.dtype.kind == 'f' and not cupy.isfinite(b).all():
            raise ValueError('array must not contain infs or NaNs')

    n = 1 if b.ndim == 1 else b.shape[1]
    cusolver_handle = device.get_cusolver_handle()
    dev_info = cupy.empty(1, dtype=numpy.int32)

    # solve for the inverse
    getrs(cusolver_handle, trans, m, n, lu.data.ptr, m, ipiv.data.ptr,
          b.data.ptr, m, dev_info.data.ptr)

    if dev_info[0] < 0:
        raise ValueError('illegal value in %d-th argument of '
                         'internal getrs (lu_solve)' % -dev_info[0])

    return b
Exemplo n.º 18
0
def lu_factor(a, overwrite_a=False, check_finite=True):
    """LU decomposition.

    Decompose a given two-dimensional square matrix into ``P * L * U``,
    where ``P`` is a permutation matrix,  ``L`` lower-triangular with
    unit diagonal elements, and ``U`` upper-triangular matrix.
    Note that in the current implementation ``a`` must be
    a real matrix, and only :class:`numpy.float32` and :class:`numpy.float64`
    are supported.

    Args:
        a (cupy.ndarray): The input matrix with dimension ``(M, N)``
        overwrite_a (bool): Allow overwriting data in ``a`` (may enhance
            performance)
        check_finite (bool): 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:
        tuple:
            ``(lu, piv)`` where ``lu`` is a :class:`cupy.ndarray`
            storing ``U`` in its upper triangle, and ``L`` without
            unit diagonal elements in its lower triangle, and ``piv`` is
            a :class:`cupy.ndarray` storing pivot indices representing
            permutation matrix ``P``. For ``0 <= i < min(M,N)``, row
            ``i`` of the matrix was interchanged with row ``piv[i]``

    .. seealso:: :func:`scipy.linalg.lu_factor`

    .. note::

        Current implementation returns result different from SciPy when the
        matrix singular. SciPy returns an array containing ``0.`` while the
        current implementation returns an array containing ``nan``.

        >>> import numpy as np
        >>> import scipy.linalg
        >>> scipy.linalg.lu_factor(np.array([[0, 1], [0, 0]], \
dtype=np.float32))
        (array([[0., 1.],
               [0., 0.]], dtype=float32), array([0, 1], dtype=int32))

        >>> import cupy as cp
        >>> import cupyx.scipy.linalg
        >>> cupyx.scipy.linalg.lu_factor(cp.array([[0, 1], [0, 0]], \
dtype=cp.float32))
        (array([[ 0.,  1.],
               [nan, nan]], dtype=float32), array([0, 1], dtype=int32))
    """

    a = cupy.asarray(a)
    util._assert_rank2(a)

    dtype = a.dtype

    if dtype.char == 'f':
        getrf = cusolver.sgetrf
        getrf_bufferSize = cusolver.sgetrf_bufferSize
    elif dtype.char == 'd':
        getrf = cusolver.dgetrf
        getrf_bufferSize = cusolver.dgetrf_bufferSize
    else:
        raise NotImplementedError('Only float32 and float64 are supported.')

    a = a.astype(dtype, order='F', copy=(not overwrite_a))

    if check_finite:
        if a.dtype.kind == 'f' and not cupy.isfinite(a).all():
            raise ValueError('array must not contain infs or NaNs')

    cusolver_handle = device.get_cusolver_handle()
    dev_info = cupy.empty(1, dtype=numpy.int32)

    m, n = a.shape

    ipiv = cupy.empty((min(m, n), ), dtype=numpy.intc)

    buffersize = getrf_bufferSize(cusolver_handle, m, n, a.data.ptr, m)
    workspace = cupy.empty(buffersize, dtype=dtype)

    # LU factorization
    getrf(cusolver_handle, m, n, a.data.ptr, m, workspace.data.ptr,
          ipiv.data.ptr, dev_info.data.ptr)

    if dev_info[0] < 0:
        raise ValueError('illegal value in %d-th argument of '
                         'internal getrf (lu_factor)' % -dev_info[0])
    elif dev_info[0] > 0:
        warn('Diagonal number %d is exactly zero. Singular matrix.' %
             dev_info[0],
             RuntimeWarning,
             stacklevel=2)

    # cuSolver uses 1-origin while SciPy uses 0-origin
    ipiv -= 1

    return (a, ipiv)
Exemplo n.º 19
0
 def test_standard_exponential_isfinite(self):
     for _ in range(10):
         x = self.generate(size=10**7)
         self.assertTrue(cupy.isfinite(x).all())
Exemplo n.º 20
0
def solve_triangular(a,
                     b,
                     trans=0,
                     lower=False,
                     unit_diagonal=False,
                     overwrite_b=False,
                     check_finite=False):
    """Solve the equation a x = b for x, assuming a is a triangular matrix.

    Args:
        a (cupy.ndarray): The matrix with dimension ``(M, M)``.
        b (cupy.ndarray): The matrix with dimension ``(M,)`` or
            ``(M, N)``.
        lower (bool): Use only data contained in the lower triangle of ``a``.
            Default is to use upper triangle.
        trans (0, 1, 2, 'N', 'T' or 'C'): Type of system to solve:

            - *'0'* or *'N'* -- :math:`a x  = b`
            - *'1'* or *'T'* -- :math:`a^T x = b`
            - *'2'* or *'C'* -- :math:`a^H x = b`

        unit_diagonal (bool): If ``True``, diagonal elements of ``a`` are
            assumed to be 1 and will not be referenced.
        overwrite_b (bool): Allow overwriting data in b (may enhance
            performance)
        check_finite (bool): 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:
        cupy.ndarray:
            The matrix with dimension ``(M,)`` or ``(M, N)``.

    .. seealso:: :func:`scipy.linalg.solve_triangular`
    """

    _util._assert_cupy_array(a, b)

    if len(a.shape) != 2 or a.shape[0] != a.shape[1]:
        raise ValueError('expected square matrix')
    if len(a) != len(b):
        raise ValueError('incompatible dimensions')

    # Cast to float32 or float64
    if a.dtype.char in 'fd':
        dtype = a.dtype
    else:
        dtype = numpy.promote_types(a.dtype.char, 'f')

    a = cupy.array(a, dtype=dtype, order='F', copy=False)
    b = cupy.array(b, dtype=dtype, order='F', copy=(not overwrite_b))

    if check_finite:
        if a.dtype.kind == 'f' and not cupy.isfinite(a).all():
            raise ValueError('array must not contain infs or NaNs')
        if b.dtype.kind == 'f' and not cupy.isfinite(b).all():
            raise ValueError('array must not contain infs or NaNs')

    m, n = (b.size, 1) if b.ndim == 1 else b.shape
    cublas_handle = device.get_cublas_handle()

    if dtype == 'f':
        trsm = cublas.strsm
    elif dtype == 'd':
        trsm = cublas.dtrsm
    elif dtype == 'F':
        trsm = cublas.ctrsm
    else:  # dtype == 'D'
        trsm = cublas.ztrsm
    one = numpy.array(1, dtype=dtype)

    if lower:
        uplo = cublas.CUBLAS_FILL_MODE_LOWER
    else:
        uplo = cublas.CUBLAS_FILL_MODE_UPPER

    if trans == 'N':
        trans = cublas.CUBLAS_OP_N
    elif trans == 'T':
        trans = cublas.CUBLAS_OP_T
    elif trans == 'C':
        trans = cublas.CUBLAS_OP_C

    if unit_diagonal:
        diag = cublas.CUBLAS_DIAG_UNIT
    else:
        diag = cublas.CUBLAS_DIAG_NON_UNIT

    trsm(cublas_handle, cublas.CUBLAS_SIDE_LEFT, uplo, trans, diag, m, n,
         one.ctypes.data, a.data.ptr, m, b.data.ptr, m)
    return b
Exemplo n.º 21
0
def threshold_li(image,
                 *,
                 tolerance=None,
                 initial_guess=None,
                 iter_callback=None):
    """Compute threshold value by Li's iterative Minimum Cross Entropy method.

    Parameters
    ----------
    image : ndarray
        Input image.

    tolerance : float, optional
        Finish the computation when the change in the threshold in an iteration
        is less than this value. By default, this is half the smallest
        difference between intensity values in ``image``.

    initial_guess : float or Callable[[array[float]], float], optional
        Li's iterative method uses gradient descent to find the optimal
        threshold. If the image intensity histogram contains more than two
        modes (peaks), the gradient descent could get stuck in a local optimum.
        An initial guess for the iteration can help the algorithm find the
        globally-optimal threshold. A float value defines a specific start
        point, while a callable should take in an array of image intensities
        and return a float value. Example valid callables include
        ``numpy.mean`` (default), ``lambda arr: numpy.quantile(arr, 0.95)``,
        or even :func:`skimage.filters.threshold_otsu`.

    iter_callback : Callable[[float], Any], optional
        A function that will be called on the threshold at every iteration of
        the algorithm.

    Returns
    -------
    threshold : float
        Upper threshold value. All pixels with an intensity higher than
        this value are assumed to be foreground.

    References
    ----------
    .. [1] Li C.H. and Lee C.K. (1993) "Minimum Cross Entropy Thresholding"
           Pattern Recognition, 26(4): 617-625
           :DOI:`10.1016/0031-3203(93)90115-D`
    .. [2] Li C.H. and Tam P.K.S. (1998) "An Iterative Algorithm for Minimum
           Cross Entropy Thresholding" Pattern Recognition Letters, 18(8): 771-776
           :DOI:`10.1016/S0167-8655(98)00057-9`
    .. [3] Sezgin M. and Sankur B. (2004) "Survey over Image Thresholding
           Techniques and Quantitative Performance Evaluation" Journal of
           Electronic Imaging, 13(1): 146-165
           :DOI:`10.1117/1.1631315`
    .. [4] ImageJ AutoThresholder code, http://fiji.sc/wiki/index.php/Auto_Threshold

    Examples
    --------
    >>> from skimage.data import camera
    >>> image = camera()
    >>> thresh = threshold_li(image)
    >>> binary = image > thresh
    """  # noqa
    # Remove nan:
    image = image[~cp.isnan(image)]
    if image.size == 0:
        return cp.nan

    # Make sure image has more than one value; otherwise, return that value
    # This works even for cp.inf
    val0 = image.ravel()[0]
    if cp.all(image == val0):  # device synchronize!
        return val0

    # At this point, the image only contains cp.inf, -cp.inf, or valid numbers
    image = image[cp.isfinite(image)]
    # if there are no finite values in the image, return 0. This is because
    # at this point we *know* that there are *both* inf and -inf values,
    # because inf == inf evaluates to True. We might as well separate them.
    if image.size == 0:
        return 0.0

    # Li's algorithm requires positive image (because of log(mean))
    image_min = cp.min(image)
    image -= image_min
    tolerance = tolerance or cp.min(cp.diff(cp.unique(image))) / 2

    # Initial estimate for iteration. See "initial_guess" in the parameter list
    if initial_guess is None:
        t_next = cp.mean(image)
    elif callable(initial_guess):
        t_next = initial_guess(image)
    elif cp.isscalar(initial_guess):  # convert to new, positive image range
        t_next = initial_guess - image_min
        image_max = cp.max(image) + image_min
        if not 0 < t_next < cp.max(image):
            msg = ('The initial guess for threshold_li must be within the '
                   'range of the image. Got {} for image min {} and max {} '.
                   format(initial_guess, image_min, image_max))
            raise ValueError(msg)
    else:
        raise TypeError('Incorrect type for `initial_guess`; should be '
                        'a floating point value, or a function mapping an '
                        'array to a floating point value.')

    # initial value for t_curr must be different from t_next by at
    # least the tolerance. Since the image is positive, we ensure this
    # by setting to a large-enough negative number
    t_curr = -2 * tolerance

    # Callback on initial iterations
    if iter_callback is not None:
        iter_callback(t_next + image_min)

    # Stop the iterations when the difference between the
    # new and old threshold values is less than the tolerance
    while abs(t_next - t_curr) > tolerance:
        t_curr = t_next
        foreground = image > t_curr
        mean_fore = cp.mean(image[foreground])
        mean_back = cp.mean(image[~foreground])

        t_next = ((mean_back - mean_fore) /
                  (cp.log(mean_back) - cp.log(mean_fore)))

        if iter_callback is not None:
            iter_callback(t_next + image_min)

    threshold = t_next + image_min
    return threshold
Exemplo n.º 22
0
 def test_standard_cauchy_isfinite(self):
     x = self.generate(size=10**7)
     assert cupy.isfinite(x).all()
 #print(i)
 if i == 5000:
     P3 = cp.cov(Thetasim[0:i], rowvar=False)
 while go_on == 0:
     Thetac = cp.random.multivariate_normal(Thetasim[i, :], (c) * P3)
     try:
         G1, impact, RC, A, B, C, E, DD, R, V_s = REE_gen1(
             cp.asnumpy(Thetac))
     except:
         RC = cp.zeros([2, 1])
     go_on = param_checks(Thetac, RC)
 prioc = NK_priors(cp.asnumpy(Thetac))
 likic, dropoutc = PFLIKE(Thetac, EPS, S, RR, randphi)
 objc = cp.float(NK_priors(cp.asnumpy(Thetac))) + cp.float(likic)
 #print(objc)
 if cp.isfinite(objc) == False:
     alpha = -1
     u = 0
 else:
     u = cp.log(cp.random.uniform(0, 1, 1))
     alpha = objc - obj
 if alpha - u >= 0:
     Thetasim[i + 1, :] = Thetac
     accept = accept + 1
     DROP[i + 1] = dropoutc
     logpost[i + 1] = objc
     LIK[i + 1] = likic
     obj = objc
     likij = likic
     dropoutj = dropoutc
     #print('accepted')