Example #1
0
def da_sub(daa, dab):
    """
    subtract 2 DataArrays as cleverly as possible:
      * keep the metadata of the first DA in the result
      * ensures the result has the right type so that no underflows happen
    returns (DataArray): the result of daa - dab
    """
    rt = numpy.result_type(daa, dab) # dtype of result of daa-dab

    dt = None # default is to let numpy decide
    if rt.kind == "f":
        # float should always be fine
        pass
    elif rt.kind in "iub":
        # underflow can happen (especially if unsigned)

        # find the worse case value (could be improved, but would be longer)
        worse_val = int(daa.min()) - int(dab.max())
        dt = numpy.result_type(rt, numpy.min_scalar_type(worse_val))
    else:
        # subtracting such a data is suspicious, but try anyway
        logging.warning("Subtraction on data of type %s unsupported", rt.name)

    res = numpy.subtract(daa, dab, dtype=dt) # metadata is copied from daa
    logging.debug("type = %s, %s", res.dtype.name, daa.dtype.name)
    return res
Example #2
0
    def accum (self, key1, key2, value, weight=1):
        index1 = self._key1map[key1]
        index2 = self._key2map[key2]

        if self._m0 is None:
            self._m0 = np.zeros ((self.chunk0size, self.chunk0size), dtype=np.result_type (weight))
            self._m1 = np.zeros ((self.chunk0size, self.chunk0size), dtype=np.result_type (value, weight))
            self._m2 = np.zeros_like (self._m1)

        if index1 >= self._m0.shape[0]:
            self._m0 = np.concatenate ((self._m0, np.zeros_like (self._m0)), axis=0)
            self._m1 = np.concatenate ((self._m1, np.zeros_like (self._m1)), axis=0)
            self._m2 = np.concatenate ((self._m2, np.zeros_like (self._m2)), axis=0)

        if index2 >= self._m0.shape[1]:
            self._m0 = np.concatenate ((self._m0, np.zeros_like (self._m0)), axis=1)
            self._m1 = np.concatenate ((self._m1, np.zeros_like (self._m1)), axis=1)
            self._m2 = np.concatenate ((self._m2, np.zeros_like (self._m2)), axis=1)

        self._m0[index1,index2] += weight
        q = weight * value
        self._m1[index1,index2] += q
        q *= value
        self._m2[index1,index2] += q
        return self
Example #3
0
    def ShiftConvNumbaFFT(h, N, M, xdtype=np.complex_, powerof2=True):
        # implements Doppler filter:
        # y[n, p] = SUM_k (exp(2*pi*j*n*(k - (L-1))/N) * h[k]) * x[p - k]
        #         = SUM_k (exp(-2*pi*j*n*k/N) * s*[k]) * x[p - (L-1) + k]
        L = len(h)
        outlen = M + L - 1
        nfft = outlen
        if powerof2:
            nfft = pow2(nfft)

        dopplermat = np.exp(2*np.pi*1j*np.arange(N)[:, np.newaxis]*(np.arange(L) - (L - 1))/N)
        dopplermat.astype(np.result_type(h.dtype, np.complex64)) # cast to complex type with precision of h
        hbank = h*dopplermat
        # speed not critical here, just use numpy fft
        hbankpad = zero_pad(hbank, nfft)
        H = np.fft.fft(hbankpad) / nfft # divide by nfft b/c FFTW's ifft does not do this

        xcdtype = np.result_type(xdtype, np.complex64) # cast to complex type with precision of x
        xpad = pyfftw.n_byte_align(np.zeros(nfft, xcdtype), 16)
        X = pyfftw.n_byte_align(np.zeros(nfft, xcdtype), 16)
        xfft = pyfftw.FFTW(xpad, X, threads=_THREADS)

        ydtype = np.result_type(H.dtype, xcdtype)
        Y = pyfftw.n_byte_align_empty(H.shape, 16, ydtype)
        y = pyfftw.n_byte_align_empty(H.shape, 16, ydtype)
        ifft = pyfftw.FFTW(Y, y, direction='FFTW_BACKWARD', threads=_THREADS)

        xtype = numba.__getattribute__(str(np.dtype(xdtype)))

        #htype = numba.__getattribute__(str(H.dtype))
        #xctype = numba.__getattribute__(str(X.dtype))
        #ytype = numba.__getattribute__(str(Y.dtype))
        #@jit(argtypes=[htype[:, ::1], xctype[::1], ytype[:, ::1], xtype[::1]])
        #def fun(H, X, Y, x):
            #xpad[:M] = x
            #xfft.execute() # input is xpad, output is X
            #Y[:, :] = H*X # need expression optimized by numba but that writes into Y
            #ifft.execute() # input is Y, output is y

            #yc = np.array(y)[:, :outlen] # need a copy, which np.array provides
            #return yc

        #@dopplerbank_dec(h, N, M, nfft=nfft, H=H)
        #def shiftconv_numba_fft(x):
            #return fun(H, X, Y, x)

        #@jit(argtypes=[xtype[::1]])
        @jit
        def shiftconv_numba_fft(x):
            xpad[:M] = x
            xfft.execute() # input is xpad, output is X
            Y[:, :] = X*H # need expression optimized by numba but that writes into Y
            ifft.execute() # input is Y, output is y

            yc = np.array(y[:, :outlen]) # need a copy, which np.array provides
            return yc

        shiftconv_numba_fft = dopplerbank_dec(h, N, M, nfft=nfft, H=H)(shiftconv_numba_fft)

        return shiftconv_numba_fft
Example #4
0
    def _take_with_fill(self, indices, fill_value=None):
        if fill_value is None:
            fill_value = self.dtype.na_value

        if indices.min() < -1:
            raise ValueError("Invalid value in 'indices'. Must be between -1 "
                             "and the length of the array.")

        if indices.max() >= len(self):
            raise IndexError("out of bounds value in 'indices'.")

        if len(self) == 0:
            # Empty... Allow taking only if all empty
            if (indices == -1).all():
                dtype = np.result_type(self.sp_values, fill_value)
                taken = np.empty_like(indices, dtype=dtype)
                taken.fill(fill_value)
                return taken
            else:
                raise IndexError('cannot do a non-empty take from an empty '
                                 'axes.')

        sp_indexer = self.sp_index.lookup_array(indices)

        if self.sp_index.npoints == 0:
            # Avoid taking from the empty self.sp_values
            taken = np.full(sp_indexer.shape, fill_value=fill_value,
                            dtype=np.result_type(fill_value))
        else:
            taken = self.sp_values.take(sp_indexer)

            # sp_indexer may be -1 for two reasons
            # 1.) we took for an index of -1 (new)
            # 2.) we took a value that was self.fill_value (old)
            new_fill_indices = indices == -1
            old_fill_indices = (sp_indexer == -1) & ~new_fill_indices

            # Fill in two steps.
            # Old fill values
            # New fill values
            # potentially coercing to a new dtype at each stage.

            m0 = sp_indexer[old_fill_indices] < 0
            m1 = sp_indexer[new_fill_indices] < 0

            result_type = taken.dtype

            if m0.any():
                result_type = np.result_type(result_type, self.fill_value)
                taken = taken.astype(result_type)
                taken[old_fill_indices] = self.fill_value

            if m1.any():
                result_type = np.result_type(result_type, fill_value)
                taken = taken.astype(result_type)
                taken[new_fill_indices] = fill_value

        return taken
Example #5
0
    def NumbaFFTW(h, M, xdtype=np.complex_, powerof2=True):
        L = len(h)
        outlen = M + L - 1
        nfft = outlen
        if powerof2:
            nfft = pow2(nfft)

        outdtype = np.result_type(h.dtype, xdtype)
        fftdtype = np.result_type(outdtype, np.complex64) # output is always complex, promote using smallest

        # speed not critical here, just use numpy fft
        # cast to outdtype so we use same type of fft as when transforming x
        hpad = zero_pad(h, nfft).astype(outdtype)
        if np.iscomplexobj(hpad):
            H = np.fft.fft(hpad)
        else:
            H = np.fft.rfft(hpad)
        H = (H / nfft).astype(fftdtype) # divide by nfft b/c FFTW's ifft does not do this

        xpad = pyfftw.n_byte_align(np.zeros(nfft, outdtype), 16) # outdtype so same type fft as h->H
        X = pyfftw.n_byte_align(np.zeros(len(H), fftdtype), 16) # len(H) b/c rfft may be used
        xfft = pyfftw.FFTW(xpad, X, threads=_THREADS)

        y = pyfftw.n_byte_align_empty(nfft, 16, outdtype)
        ifft = pyfftw.FFTW(X, y, direction='FFTW_BACKWARD', threads=_THREADS)

        xtype = numba.__getattribute__(str(np.dtype(xdtype)))
        outtype = numba.__getattribute__(str(outdtype))
        ffttype = numba.__getattribute__(str(fftdtype))

        #@jit(restype=outtype[::1],
            #argtypes=[outtype[::1], ffttype[::1], ffttype[::1], outtype[::1], xtype[::1]])
        #def filt(xpad, X, H, y, x):
            #xpad[:M] = x
            #xfft.execute() # input in xpad, result in X
            #X[:] = H*X
            #ifft.execute() # input in X, result in y
            #yc = y[:outlen].copy()
            #return yc

        #@filter_dec(h, M, nfft=nfft, H=H)
        #def numba_fftw(x):
            #return filt(xpad, X, H, y, x)

        #@jit(argtypes=[xtype[::1]])
        @jit
        def numba_fftw(x):
            xpad[:M] = x
            xfft.execute() # input in xpad, result in X
            X[:] = H*X # want expression that is optimized by numba but writes into X
            ifft.execute() # input in X, result in y
            yc = y[:outlen].copy()
            return yc

        numba_fftw = filter_dec(h, M, nfft=nfft, H=H)(numba_fftw)

        return numba_fftw
Example #6
0
    def test_result_type(self):
        self.check_promotion_cases(np.result_type)

        f64 = float64(0)
        c64 = complex64(0)
        ## Scalars do not coerce to complex if the value is real
        #assert_equal(np.result_type(c64,array([f64])), np.dtype(float64))
        # But they do if the value is complex
        assert_equal(np.result_type(complex64(3j),array([f64])),
                                                    np.dtype(complex128))

        # Scalars do coerce to complex even if the value is real
        # This is so "a+0j" can be reliably used to make something complex.
        assert_equal(np.result_type(c64,array([f64])), np.dtype(complex128))
Example #7
0
File: _linear.py Project: ckmo/iris
    def _interpolated_dtype(self, dtype):
        """
        Determine the minimum base dtype required by the
        underlying interpolator.

        """
        return np.result_type(_DEFAULT_DTYPE, dtype)
Example #8
0
def build_supergather(step, width, bins, dataset):
	sutype = np.result_type(dataset)
	cdps = np.unique(dataset['cdp'])
	dataset['offset'] = np.abs(dataset['offset'])
	supergather_centres = range(min(cdps)+width, max(cdps)-width, step)
	supergather_slices = [cdps[a-width:a+width] for a in supergather_centres]
	for index, inds in enumerate(supergather_slices):
		for cdpn, cdp in enumerate(dataset['cdp']):
			if cdp in inds:
				dataset['ns1'][cdpn] = index
				
	dataset = dataset[dataset['ns1'] != 0]
	output = np.empty(0, dtype=sutype)
	for ind in np.unique(dataset['ns1']):
		sg = dataset[dataset['ns1'] == ind]
		hist = np.digitize(sg['offset'], bins)
		sg['ep'] = hist
		vals = np.unique(sg['ep'])
		holder = np.zeros(len(vals), dtype=sutype)
		for v in vals:
			traces = sg[sg['ep'] == v]
			header = traces[0].copy()
			header['trace'].fill(0.0)
			fold = traces.size
			header['trace'] += np.sum(traces['trace'], axis=-2)/np.float(fold)
			holder[v-1] = header
		#~ display(holder)		
		output = np.concatenate([output, holder])
		
	return output
	
Example #9
0
def promote(*operands):
    """
    Take an arbitrary number of graph nodes and produce the promoted
    dtype by discarding all shape information and just looking at the
    measures.

    ::

        5, 5,  | int   |
        2, 5,  | int   |
        1, 3,  | float |

    >>> promote(IntNode(1), Op(IntNode(2))
    int
    >>> promote(FloatNode(1), Op(IntNode(2))
    float
    """

    # Looks something like this...

    # (ArrayNode, IntNode...) -> (dshape('2, int'), dshape('int'))
    # (dshape('2, int', dshape('int')) -> (dshape('int', dshape('int'))
    # (dshape('2, int', dshape('int')) -> (dtype('int', dtype('int'))

    types    = (op.simple_type() for op in operands if op is not None)
    measures = (extract_measure(t) for t in types)
    dtypes   = (to_numpy(m) for m in measures)

    promoted = np.result_type(*dtypes)
    datashape = CType.from_dtype(promoted)
    return datashape
Example #10
0
def _contract_plain(mydf, mos, coulG, phase, max_memory):
    cell = mydf.cell
    moiT, mojT, mokT, molT = mos
    nmoi, nmoj, nmok, nmol = [x.shape[0] for x in mos]
    ngrids = moiT.shape[1]
    wcoulG = coulG * (cell.vol/ngrids)
    dtype = numpy.result_type(phase, *mos)
    eri = numpy.empty((nmoi*nmoj,nmok*nmol), dtype=dtype)

    blksize = int(min(max(nmoi,nmok), (max_memory*1e6/16 - eri.size)/2/ngrids/max(nmoj,nmol)+1))
    assert blksize > 0
    buf0 = numpy.empty((blksize,max(nmoj,nmol),ngrids), dtype=dtype)
    buf1 = numpy.ndarray((blksize,nmoj,ngrids), dtype=dtype, buffer=buf0)
    buf2 = numpy.ndarray((blksize,nmol,ngrids), dtype=dtype, buffer=buf0)
    for p0, p1 in lib.prange(0, nmoi, blksize):
        mo_pairs = numpy.einsum('ig,jg->ijg', moiT[p0:p1].conj()*phase,
                                mojT, out=buf1[:p1-p0])
        mo_pairs_G = tools.fft(mo_pairs.reshape(-1,ngrids), mydf.mesh)
        mo_pairs = None
        mo_pairs_G*= wcoulG
        v = tools.ifft(mo_pairs_G, mydf.mesh)
        mo_pairs_G = None
        v *= phase.conj()
        if dtype == numpy.double:
            v = numpy.asarray(v.real, order='C')
        for q0, q1 in lib.prange(0, nmok, blksize):
            mo_pairs = numpy.einsum('ig,jg->ijg', mokT[q0:q1].conj(),
                                    molT, out=buf2[:q1-q0])
            eri[p0*nmoj:p1*nmoj,q0*nmol:q1*nmol] = lib.dot(v, mo_pairs.reshape(-1,ngrids).T)
        v = None
    return eri
Example #11
0
 def test_dtypes(self):
     for dtypes in get_dtypes():
         dtype_op, dtype_in = dtypes
         dtype_out = np.result_type(dtype_op, dtype_in)
         A = lo.ZeroOperator(3, 3, dtype=dtype_op)
         x = np.array([1, 1, 1]).astype(dtype_in)
         assert_((A * x).dtype == dtype_out)
Example #12
0
    def _convert_list(self, value):
        """Convert a string into a typed numpy array.

        If it is not possible it returns a numpy string.
        """
        try:
            numpy_values = []
            values = value.split(" ")
            types = set([])
            for string_value in values:
                v = self._convert_scalar_value(string_value)
                numpy_values.append(v)
                types.add(v.dtype.type)

            result_type = numpy.result_type(*types)

            if issubclass(result_type.type, (numpy.string_, six.binary_type)):
                # use the raw data to create the result
                return numpy.string_(value)
            elif issubclass(result_type.type, (numpy.unicode_, six.text_type)):
                # use the raw data to create the result
                return numpy.unicode_(value)
            else:
                return numpy.array(numpy_values, dtype=result_type)
        except ValueError:
            return numpy.string_(value)
Example #13
0
    def _inequality(self, other, op, op_name, bad_scalar_msg):
        # Scalar other.
        if isscalarlike(other):
            if 0 == other and op_name in ('_le_', '_ge_'):
                raise NotImplementedError(" >= and <= don't work with 0.")
            elif op(0, other):
                warn(bad_scalar_msg, SparseEfficiencyWarning)
                other_arr = np.empty(self.shape, dtype=np.result_type(other))
                other_arr.fill(other)
                other_arr = self.__class__(other_arr)
                return self._binopt(other_arr, op_name)
            else:
                return self._scalar_binopt(other, op)
        # Dense other.
        elif isdense(other):
            return op(self.todense(), other)
        # Sparse other.
        elif isspmatrix(other):
            #TODO sparse broadcasting
            if self.shape != other.shape:
                raise ValueError("inconsistent shapes")
            elif self.format != other.format:
                other = other.asformat(self.format)
            if op_name not in ('_ge_', '_le_'):
                return self._binopt(other, op_name)

            warn("Comparing sparse matrices using >= and <= is inefficient, "
                 "using <, >, or !=, instead.", SparseEfficiencyWarning)
            all_true = self.__class__(np.ones(self.shape))
            res = self._binopt(other, '_gt_' if op_name == '_le_' else '_lt_')
            return all_true - res
        else:
            raise ValueError("Operands could not be compared.")
Example #14
0
 def _valid_input(self, value, dtype=None):
     if not misc.is_valid_param_value(value):
         msg = 'The value must be either a tensorflow variable, an array or a scalar.'
         raise ValueError(msg)
     cast = not (dtype is None)
     is_built = False
     shape = None
     if hasattr(self, '_value'): # The parameter has not initialized yet.
         is_built = self.is_built_coherence() == Build.YES
         shape = self.shape
         inner_dtype = self.dtype
         if dtype is not None and inner_dtype != dtype:
             msg = 'Overriding parameter\'s type "{0}" with "{1}" is not possible.'
             raise ValueError(msg.format(inner_dtype, dtype))
         elif isinstance(value, np.ndarray) and inner_dtype != value.dtype:
             msg = 'The value has different data type "{0}". Parameter type is "{1}".'
             raise ValueError(msg.format(value.dtype, inner_dtype))
         cast = False
         dtype = inner_dtype
     if misc.is_number(value):
         value_type = np.result_type(value).type
         num_type = misc.normalize_num_type(value_type)
         dtype = num_type if dtype is None else dtype
         value = np.array(value, dtype=dtype)
     elif misc.is_list(value):
         dtype = settings.float_type if dtype is None else dtype
         value = np.array(value, dtype=dtype)
     elif cast:
         value = value.astype(dtype)
     if shape is not None and self.fixed_shape and is_built and shape != value.shape:
         msg = 'Value has different shape. Parameter shape {0}, value shape {1}.'
         raise ValueError(msg.format(shape, value.shape))
     return value
Example #15
0
def test_upcast():
    a0 = csr_matrix([[np.pi, np.pi*1j], [3, 4]], dtype=complex)
    b0 = np.array([256+1j, 2**32], dtype=complex)

    for a_dtype in supported_dtypes:
        for b_dtype in supported_dtypes:
            msg = "(%r, %r)" % (a_dtype, b_dtype)

            if np.issubdtype(a_dtype, np.complexfloating):
                a = a0.copy().astype(a_dtype)
            else:
                a = a0.real.copy().astype(a_dtype)

            if np.issubdtype(b_dtype, np.complexfloating):
                b = b0.copy().astype(b_dtype)
            else:
                b = b0.real.copy().astype(b_dtype)

            if not (a_dtype == np.bool_ and b_dtype == np.bool_):
                c = np.zeros((2,), dtype=np.bool_)
                assert_raises(ValueError, _sparsetools.csr_matvec,
                              2, 2, a.indptr, a.indices, a.data, b, c)

            if ((np.issubdtype(a_dtype, np.complexfloating) and
                 not np.issubdtype(b_dtype, np.complexfloating)) or
                (not np.issubdtype(a_dtype, np.complexfloating) and
                 np.issubdtype(b_dtype, np.complexfloating))):
                c = np.zeros((2,), dtype=np.float64)
                assert_raises(ValueError, _sparsetools.csr_matvec,
                              2, 2, a.indptr, a.indices, a.data, b, c)

            c = np.zeros((2,), dtype=np.result_type(a_dtype, b_dtype))
            _sparsetools.csr_matvec(2, 2, a.indptr, a.indices, a.data, b, c)
            assert_allclose(c, np.dot(a.toarray(), b), err_msg=msg)
Example #16
0
 def _normalize_vector_type(self, dtype):
     """Normalize the """
     if self.__at_least_32bits:
         if numpy.issubdtype(dtype, numpy.signedinteger):
             dtype = numpy.result_type(dtype, numpy.uint32)
         if numpy.issubdtype(dtype, numpy.unsignedinteger):
             dtype = numpy.result_type(dtype, numpy.uint32)
         elif numpy.issubdtype(dtype, numpy.floating):
             dtype = numpy.result_type(dtype, numpy.float32)
         elif numpy.issubdtype(dtype, numpy.complexfloating):
             dtype = numpy.result_type(dtype, numpy.complex64)
     if self.__signed_type:
         if numpy.issubdtype(dtype, numpy.unsignedinteger):
             signed = numpy.dtype("%s%i" % ('i', dtype.itemsize))
             dtype = numpy.result_type(dtype, signed)
     return dtype
Example #17
0
def promote(lhs, rhs):
    """Promote two scalar dshapes to a possibly larger, but compatible type.

    Examples
    --------
    >>> from datashape import int32, int64, Option
    >>> x = Option(int32)
    >>> y = int64
    >>> promote(x, y)
    ?int64
    >>> promote(int64, int64)
    ctype("int64")

    Notes
    ----
    This uses ``numpy.result_type`` for type promotion logic.  See the numpy
    documentation at
    http://docs.scipy.org/doc/numpy/reference/generated/numpy.result_type.html
    """
    if lhs == rhs:
        return lhs
    else:
        left, right = getattr(lhs, "ty", lhs), getattr(rhs, "ty", rhs)
        dtype = np.result_type(datashape.to_numpy_dtype(left), datashape.to_numpy_dtype(right))
        return optionify(lhs, rhs, datashape.CType.from_numpy_dtype(dtype))
Example #18
0
def rfft(a):
	n = a.shape[-1]
	b = a.reshape(np.prod(a.shape[:-1]),n)
	fb = np.empty((b.shape[0],b.shape[1]/2+1),dtype=np.result_type(a,0j))
	for i in range(b.shape[0]):
		fb[i] = myfft.rfft(b[i])*n**-0.5
	return np.reshape(fb, list(a.shape[:-1]) + [fb.shape[-1]])
Example #19
0
        def blk_matvec(x, blks):
            nargins = [[blk.shape[-1] for blk in blkrow] for blkrow in blks]
            nargouts = [[blk.shape[0] for blk in blkrow] for blkrow in blks]
            nargin = sum(nargins[0])
            nargout = sum([out[0] for out in nargouts])
            nx = len(x)
            self.logger.debug('Multiplying with a vector of size %d' % nx)
            self.logger.debug('nargin=%d, nargout=%d' % (nargin, nargout))
            if nx != nargin:
                raise ShapeError('Multiplying with vector of wrong shape.')

            result_type = np.result_type(self.dtype, x.dtype)
            y = np.zeros(nargout, dtype=result_type)

            nblk_row = len(blks)
            nblk_col = len(blks[0])

            row_start = col_start = 0
            for row in range(nblk_row):
                row_end = row_start + nargouts[row][0]
                yout = y[row_start:row_end]
                for col in range(nblk_col):
                    col_end = col_start + nargins[0][col]
                    xin = x[col_start:col_end]
                    B = blks[row][col]
                    yout[:] += B * xin
                    col_start = col_end
                row_start = row_end
                col_start = 0

            return y
Example #20
0
        def blk_matvec(x, blks):
            nx = len(x)
            nargins = [blk.shape[-1] for blk in blocks]
            nargin = sum(nargins)
            nargouts = [blk.shape[0] for blk in blocks]
            nargout = sum(nargouts)
            self.logger.debug('Multiplying with a vector of size %d' % nx)
            self.logger.debug('nargin=%d, nargout=%d' % (nargin, nargout))
            if nx != nargin:
                raise ShapeError('Multiplying with vector of wrong shape.')

            result_type = np.result_type(self.dtype, x.dtype)
            y = np.empty(nargout, dtype=result_type)

            nblks = len(blks)

            row_start = col_start = 0
            for blk in range(nblks):
                row_end = row_start + nargouts[blk]
                yout = y[row_start:row_end]

                col_end = col_start + nargins[blk]
                xin = x[col_start:col_end]

                B = blks[blk]
                yout[:] = B * xin

                col_start = col_end
                row_start = row_end

            return y
Example #21
0
    def call(self, args, axis=0, out=None, chunksize=1024 * 1024, **kwargs):
        """ axis is the axis to chop it off.
            if self.altreduce is set, the results will
            be reduced with altreduce and returned
            otherwise will be saved to out, then return out.
        """
        if self.altreduce is not None:
            ret = [None]
        else:
            if out is None :
                if self.outdtype is not None:
                    dtype = self.outdtype
                else:
                    try:
                        dtype = numpy.result_type(*[args[i] for i in self.ins] * 2)
                    except:
                        dtype = None
                out = sharedmem.empty(
                        numpy.broadcast(*[args[i] for i in self.ins] * 2).shape,
                        dtype=dtype)
        if axis != 0:
            for i in self.ins:
                args[i] = numpy.rollaxis(args[i], axis)
            out = numpy.rollaxis(out, axis)
        size = numpy.max([len(args[i]) for i in self.ins])
        with sharedmem.MapReduce() as pool:
            def work(i):
                sl = slice(i, i+chunksize)
                myargs = args[:]
                for j in self.ins:
                    try: 
                        tmp = myargs[j][sl]
                        a, b, c = sl.indices(len(args[j]))
                        myargs[j] = tmp
                    except Exception as e:
                        print tmp
                        print j, e
                        pass
                if b == a: return None
                rt = self.ufunc(*myargs, **kwargs)
                if self.altreduce is not None:
                    return rt
                else:
                    out[sl] = rt
            def reduce(rt):
                if self.altreduce is None:
                    return
                if ret[0] is None:
                    ret[0] = rt
                elif rt is not None:
                    ret[0] = self.altreduce(ret[0], rt)

            pool.map(work, range(0, size, chunksize), reduce=reduce)

        if self.altreduce is None:
            if axis != 0:
                out = numpy.rollaxis(out, 0, axis + 1)
            return out                
        else:
            return ret[0]
Example #22
0
    def __new__(cls, *arrays):
        """Create combined array with views to separate arrays.

        The provided arrays are flattened and concatenated in the order
        given to make the combined array. The array views accessible with the
        `parts` attribute and through iteration provide views into the
        combined array that correspond to the location of the original arrays.


        Parameters
        ----------

        arrays : iterable
            Individual arrays to combine.

        """
        dtype = np.result_type(*arrays)
        sizes = [arr.size for arr in arrays]
        size = np.sum(sizes)

        self = np.ndarray.__new__(cls, size, dtype=dtype)

        idxs = [0] + list(np.cumsum(sizes))
        self._slices = tuple(slice(idxs[k], idxs[k + 1])
                             for k in xrange(len(idxs) - 1))
        self._shapes = tuple(arr.shape for arr in arrays)

        # copy original arrays into corresponding views of the combined array
        for view, arr in zip(iter(self), arrays):
            view[...] = arr

        return self
Example #23
0
def covariance(m, ddof=1.5):
    """
    A simplified version of numpy's 'cov' which allows ddof=1.5 and assumes
    variables to be in columns (rowvar=0).
    """
    # Handles complex arrays too
    m = np.asarray(m)
    dtype = np.result_type(m, np.float64)
    
    X = np.array(m, ndmin=2, dtype=dtype)
    if X.shape[0] != 1:
        X = X.T
    if X.shape[0] == 0:
        return np.array([]).reshape(0, 0)
    
    avg = np.mean(X, axis=1)

    # Determine the normalization
    fact = float(X.shape[1] - ddof)
    if fact <= 0:
        warn("Degrees of freedom <= 0 for slice", RuntimeWarning)
        fact = 0.0

    X -= avg[:, None]
    X_T = X.T
    return (np.dot(X, X_T.conj())/fact).squeeze()
Example #24
0
def cast(arrays, dtype=None, order='c'):
    """
    Cast a list of arrays into a same data type.

    Parameters
    ----------
    arrays : sequence of array-like or None
        The list of arrays to be cast.
    dtype : numpy.dtype
        If specified, all arrays will be cast to this data type. Otherwise,
        the data types is inferred from the arrays.

    Example
    -------
    >>> cast([[1., 2.], None, np.array(2j)])
    (array([ 1.+0.j,  2.+0.j]), None, array(2j))

    """
    arrays = tuple(arrays)
    if dtype is None:
        arrays_ = [np.array(a, copy=False) for a in arrays if a is not None]
        dtype = np.result_type(*arrays_)
    result = (np.array(a, dtype=dtype, order=order, copy=False)
              if a is not None else None for a in arrays)
    return tuple(result)
Example #25
0
def use_hmm(observations, state_count, symbol_count, maxit=1000, accuracy=-1, retries=10, dtype=numpy.float32):
    curr_A, curr_B, curr_pi = None, None, None
    curr_eps = None
#    try:
#        importlib.import_module('spscicomp.hmm.kernel.opencl')
#        kernel = spscicomp.hmm.kernel.opencl
#        LOG.debug('OpenCL-Kernel used')
#    except:
#        LOG.debug('OpenCL-Kernel not available')
    try:
        importlib.import_module('spscicomp.hmm.kernel.c')
        kernel = spscicomp.hmm.kernel.c
        if numpy.result_type(observations) != numpy.int16:
            LOG.debug('Observations data type was not int16, thus casting it for c-extension.')
            observations = numpy.array(observations, dtype=numpy.int16)
        LOG.debug('C-Kernel used')
    except:
        LOG.debug('C-Kernel not available')
        kernel = spscicomp.hmm.kernel.python
        LOG.debug('Python-Kernel used')

    for _ in range(0, retries):
        A = spscicomp.hmm.utility.generate_random_matrice(state_count, state_count)
        B = spscicomp.hmm.utility.generate_random_matrice(state_count, symbol_count)
        pi = spscicomp.hmm.utility.generate_random_array(state_count)

        A, B, pi, eps, it = spscicomp.hmm.algorithms.baum_welch_multiple(obs=observations, A=A, B=B, pi=pi,
                                                                         kernel=kernel,
                                                                         dtype=dtype, maxit=maxit, accuracy=accuracy)

        if curr_eps is None or curr_eps < eps:
            curr_A, curr_B, curr_pi, curr_eps = A, B, pi, eps

    return curr_A, curr_B, curr_pi
Example #26
0
def _coo_matmul_gradsp(a, b, c_row, c_col, c_shape, transa, transb, transc,
                       dtype):
    if dtype is None:
        dtype = numpy.result_type(a.dtype, b.dtype)

    if transa:
        A = a.swapaxes(-1, -2)
    else:
        A = a
    if transb:
        B = b.swapaxes(-1, -2)
    else:
        B = b
    if transc:
        C_row = c_col
        C_col = c_row
    else:
        C_row = c_row
        C_col = c_col

    xp = cuda.get_array_module(A, B)
    if xp is numpy:
        return _coo_matmul_gradsp_cpu(A, B, C_row, C_col, dtype)
    else:
        return _coo_matmul_gradsp_gpu(A, B, C_row, C_col, dtype)
Example #27
0
 def matvec_transp(x):
     if x.shape != (nargout,):
         msg = 'Input has shape ' + str(x.shape)
         msg += ' instead of (%d,)' % self.nargout
         raise ValueError(msg)
     result_type = np.result_type(self.dtype, x.dtype)
     return np.zeros(nargin, dtype=result_type)
Example #28
0
 def test_dtypes(self):
     for dtype_op in allowed_types:
         for dtype_in in allowed_types:
             dtype_out = np.result_type(dtype_op, dtype_in)
             A = lo.IdentityOperator(3, dtype=dtype_op)
             x = np.array([1, 1, 1]).astype(dtype_in)
             assert_((A * x).dtype == dtype_out)
Example #29
0
def _coo_matmul(sp_data, sp_row, sp_col, sp_shape, dn, transa, transb, transc,
                dtype=None):
    if dtype is None:
        dtype = numpy.result_type(sp_data.dtype, dn.dtype)

    A_data = sp_data
    if transa:
        A_row = sp_col
        A_col = sp_row
        A_shape = (sp_shape[1], sp_shape[0])
    else:
        A_row = sp_row
        A_col = sp_col
        A_shape = sp_shape
    if transb:
        B = dn.swapaxes(-1, -2)
    else:
        B = dn

    xp = cuda.get_array_module(A_data, B)
    if xp is numpy:
        C = _coo_matmul_cpu(A_data, A_row, A_col, A_shape, B, dtype)
    else:
        C = _coo_matmul_gpu(A_data, A_row, A_col, A_shape, B, dtype)

    if transc:
        C = C.swapaxes(-1, -2)
    return C
Example #30
0
def trisolve(dl, d, du, b, inplace=False):
    """
    The tridiagonal matrix (Thomas) algorithm for solving tridiagonal systems
    of equations:

        a_{i}x_{i-1} + b_{i}x_{i} + c_{i}x_{i+1} = y_{i}

    in matrix form:
        Mx = b

    TDMA is O(n), whereas standard Gaussian elimination is O(n^3).

    Arguments:
    -----------
        dl: (n - 1,) vector
            the lower diagonal of M
        d: (n,) vector
            the main diagonal of M
        du: (n - 1,) vector
            the upper diagonal of M
        b: (n,) vector
            the result of Mx
        inplace:
            if True, and if d and b are both float64 vectors, they will be
            modified in place (may be faster)

    Returns:
    -----------
        x: (n,) vector
            the solution to Mx = b

    References:
    -----------
    http://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm
    http://www.netlib.org/lapack/explore-html/d1/db3/dgtsv_8f.html
    """

    if (dl.shape[0] != du.shape[0] or (d.shape[0] != dl.shape[0] + 1)
            or d.shape[0] != b.shape[0]):
        raise ValueError('Invalid diagonal shapes')

    bshape_in = b.shape
    rtype = np.result_type(dl, d, du, b)

    if not inplace:
        # force a copy
        dl = np.array(dl, dtype=rtype, copy=True, order='F')
        d = np.array(d, dtype=rtype, copy=True, order='F')
        du = np.array(du, dtype=rtype, copy=True, order='F')
        b = np.array(b, dtype=rtype, copy=True, order='F')

    # this may also force copies if arrays have inconsistent types / incorrect
    # order
    dl, d, du, b = (np.array(v, dtype=rtype, copy=False, order='F')
                    for v in (dl, d, du, b))

    # use the LAPACK implementation
    _lapack_trisolve(dl, d, du, b, rtype)

    return b.reshape(bshape_in)
Example #31
0
def get_k_e1_kpts(mydf,
                  dm_kpts,
                  kpts=np.zeros((1, 3)),
                  kpts_band=None,
                  exxdiv=None):

    cell = mydf.cell
    mesh = mydf.mesh
    coords = cell.gen_uniform_grids(mesh)
    ngrids = coords.shape[0]

    if getattr(dm_kpts, 'mo_coeff', None) is not None:
        mo_coeff = dm_kpts.mo_coeff
        mo_occ = dm_kpts.mo_occ
    else:
        mo_coeff = None

    kpts = np.asarray(kpts)
    dm_kpts = lib.asarray(dm_kpts, order='C')
    dms = _format_dms(dm_kpts, kpts)
    nset, nkpts, nao = dms.shape[:3]

    weight = 1. / nkpts * (cell.vol / ngrids)

    kpts_band, input_band = _format_kpts_band(kpts_band, kpts), kpts_band
    nband = len(kpts_band)

    if gamma_point(kpts_band) and gamma_point(kpts):
        vk_kpts = np.zeros((3, nset, nband, nao, nao), dtype=dms.dtype)
    else:
        vk_kpts = np.zeros((3, nset, nband, nao, nao), dtype=np.complex128)

    coords = mydf.grids.coords

    if input_band is None:
        ao2_kpts = [
            np.asarray(ao.transpose(0, 2, 1), order='C')
            for ao in mydf._numint.eval_ao(cell, coords, kpts=kpts, deriv=1)
        ]
        ao1_kpts = ao2_kpts
        ao2_kpts = [ao2_kpt[0] for ao2_kpt in ao2_kpts]
    else:
        ao2_kpts = [
            np.asarray(ao.T, order='C')
            for ao in mydf._numint.eval_ao(cell, coords, kpts=kpts)
        ]
        ao1_kpts = [
            np.asarray(ao.transpose(0, 2, 1), order='C') for ao in
            mydf._numint.eval_ao(cell, coords, kpts=kpts_band, deriv=1)
        ]

    if mo_coeff is not None and nset == 1:
        mo_coeff = [
            mo_coeff[k][:, occ > 0] * np.sqrt(occ[occ > 0])
            for k, occ in enumerate(mo_occ)
        ]
        ao2_kpts = [np.dot(mo_coeff[k].T, ao) for k, ao in enumerate(ao2_kpts)]

    mem_now = lib.current_memory()[0]
    max_memory = mydf.max_memory - mem_now
    blksize = int(
        min(nao,
            max(1, (max_memory - mem_now) * 1e6 / 16 / 4 / 3 / ngrids / nao)))
    lib.logger.debug1(mydf, 'fft_jk: get_k_kpts max_memory %s  blksize %d',
                      max_memory, blksize)
    ao1_dtype = np.result_type(*ao1_kpts)
    ao2_dtype = np.result_type(*ao2_kpts)
    vR_dm = np.empty((3, nset, nao, ngrids), dtype=vk_kpts.dtype)

    t1 = (time.clock(), time.time())
    for k2, ao2T in enumerate(ao2_kpts):
        if ao2T.size == 0:
            continue

        kpt2 = kpts[k2]
        naoj = ao2T.shape[0]
        if mo_coeff is None or nset > 1:
            ao_dms = [lib.dot(dms[i, k2], ao2T.conj()) for i in range(nset)]
        else:
            ao_dms = [ao2T.conj()]

        for k1, ao1T in enumerate(ao1_kpts):
            kpt1 = kpts_band[k1]

            # If we have an ewald exxdiv, we add the G=0 correction near the
            # end of the function to bypass any discretization errors
            # that arise from the FFT.
            mydf.exxdiv = exxdiv
            if exxdiv == 'ewald' or exxdiv is None:
                coulG = tools.get_coulG(cell, kpt2 - kpt1, False, mydf, mesh)
            else:
                coulG = tools.get_coulG(cell, kpt2 - kpt1, True, mydf, mesh)
            if is_zero(kpt1 - kpt2):
                expmikr = np.array(1.)
            else:
                expmikr = np.exp(-1j * np.dot(coords, kpt2 - kpt1))

            for p0, p1 in lib.prange(0, nao, blksize):
                rho1 = np.einsum('aig,jg->aijg',
                                 ao1T[1:, p0:p1].conj() * expmikr, ao2T)
                vG = tools.fft(rho1.reshape(-1, ngrids), mesh)
                rho1 = None
                vG *= coulG
                vR = tools.ifft(vG, mesh).reshape(3, p1 - p0, naoj, ngrids)
                vG = None
                if vR_dm.dtype == np.double:
                    vR = vR.real
                for i in range(nset):
                    np.einsum('aijg,jg->aig',
                              vR,
                              ao_dms[i],
                              out=vR_dm[:, i, p0:p1])
                vR = None
            vR_dm *= expmikr.conj()

            for i in range(nset):
                vk_kpts[:, i, k1] -= weight * np.einsum(
                    'aig,jg->aij', vR_dm[:, i], ao1T[0])
        t1 = lib.logger.timer_debug1(mydf, 'get_k_kpts: make_kpt (%d,*)' % k2,
                                     *t1)

    # Ewald correction has no contribution to nuclear gradient unless range separted Coulomb is used
    # The gradient correction part is not added in the vk matrix
    if exxdiv == 'ewald' and cell.omega != 0:
        raise NotImplementedError("Range Separated Coulomb")
        # when cell.omega !=0: madelung constant will have a non-zero derivative
    vk_kpts = np.asarray(
        [_format_jks(vk, dm_kpts, input_band, kpts) for vk in vk_kpts])
    return vk_kpts
Example #32
0
def _dtype(x):
    return canonicalize_dtype(onp.result_type(x))
Example #33
0
    def _tile_dataframe(cls, op):
        from ...tensor.merge.stack import TensorStack

        df = op.outputs[0]
        if df.ndim == 1:
            if op.axis == 0:
                ts = []
                for name in df.index_value.to_pandas():
                    a = tensor_from_series(op.input[name])
                    t = tensor_quantile(a,
                                        op.q,
                                        interpolation=op.interpolation,
                                        handle_non_numeric=not op.numeric_only)
                    ts.append(t)
                try:
                    dtype = np.result_type(*[it.dtype for it in ts])
                except TypeError:
                    dtype = np.dtype(object)
                stack_op = TensorStack(axis=0, dtype=dtype)
                tr = stack_op(ts)
                r = series_from_tensor(tr,
                                       index=df.index_value.to_pandas(),
                                       name=np.asscalar(ts[0].op.q))
            else:
                assert op.axis == 1
                empty_df = build_empty_df(op.input.dtypes)
                fields = empty_df._get_numeric_data().columns.tolist()
                t = tensor_from_dataframe(op.input[fields])
                tr = tensor_quantile(t,
                                     op.q,
                                     axis=1,
                                     interpolation=op.interpolation,
                                     handle_non_numeric=not op.numeric_only)
                r = series_from_tensor(tr, name=np.asscalar(tr.op.q))
                r._index_value = op.input.index_value
        else:
            assert df.ndim == 2
            if op.axis == 0:
                d = OrderedDict()
                for name in df.dtypes.index:
                    a = tensor_from_series(op.input[name])
                    t = tensor_quantile(a,
                                        op.q,
                                        interpolation=op.interpolation,
                                        handle_non_numeric=not op.numeric_only)
                    d[name] = t
                r = create_df(d, index=op.q)
            else:
                assert op.axis == 1
                empty_df = build_empty_df(op.input.dtypes)
                fields = empty_df._get_numeric_data().columns.tolist()
                t = tensor_from_dataframe(op.input[fields])
                tr = tensor_quantile(t,
                                     op.q,
                                     axis=1,
                                     interpolation=op.interpolation,
                                     handle_non_numeric=not op.numeric_only)
                if not op.input.index_value.has_value():
                    raise NotImplementedError
                # TODO(xuye.qin): use index=op.input.index when we support DataFrame.index
                r = dataframe_from_tensor(
                    tr, index=op.q, columns=op.input.index_value.to_pandas())

        return (yield from recursive_tile(r))
Example #34
0
def average(a, axis=None, weights=None, returned=False):
    """Returns the weighted average along an axis.

    Args:
        a (cupy.ndarray): Array to compute average.
        axis (int): Along which axis to compute average. The flattened array
            is used by default.
        weights (cupy.ndarray): Array of weights where each element
            corresponds to the value in ``a``. If ``None``, all the values
            in ``a`` have a weight equal to one.
        returned (bool): If ``True``, a tuple of the average and the sum
            of weights is returned, otherwise only the average is returned.

    Returns:
        cupy.ndarray or tuple of cupy.ndarray: The average of the input array
            along the axis and the sum of weights.

    .. seealso:: :func:`numpy.average`
    """
    a = cupy.asarray(a)

    if weights is None:
        avg = a.mean(axis)
        scl = avg.dtype.type(a.size / avg.size)
    else:
        wgt = cupy.asarray(weights)

        if issubclass(a.dtype.type, (numpy.integer, numpy.bool_)):
            result_dtype = numpy.result_type(a.dtype, wgt.dtype, 'f8')
        else:
            result_dtype = numpy.result_type(a.dtype, wgt.dtype)

        # Sanity checks
        if a.shape != wgt.shape:
            if axis is None:
                raise TypeError(
                    'Axis must be specified when shapes of a and weights '
                    'differ.')
            if wgt.ndim != 1:
                raise TypeError(
                    '1D weights expected when shapes of a and weights differ.')
            if wgt.shape[0] != a.shape[axis]:
                raise ValueError(
                    'Length of weights not compatible with specified axis.')

            # setup wgt to broadcast along axis
            wgt = cupy.broadcast_to(wgt, (a.ndim - 1) * (1,) + wgt.shape)
            wgt = wgt.swapaxes(-1, axis)

        scl = wgt.sum(axis=axis, dtype=result_dtype)
        if cupy.any(scl == 0.0):
            raise ZeroDivisionError(
                'Weights sum to zero, can\'t be normalized')

        avg = cupy.multiply(a, wgt, dtype=result_dtype).sum(axis) / scl

    if returned:
        if scl.shape != avg.shape:
            scl = cupy.broadcast_to(cupy.array(scl), avg.shape).copy()
        return avg, scl
    else:
        return avg
Example #35
0
 def pv_like(x):
     aval = ShapedArray(onp.shape(x), onp.result_type(x))
     return pe.PartialVal((aval, unit))
Example #36
0
def make_shaped_array(x):
  dtype = xla_bridge.canonicalize_dtype(onp.result_type(x))
  return ShapedArray(onp.shape(x), dtype)
Example #37
0
 def __init__(self, val):
   self.val = val
   self.shape = onp.shape(val)
   # canonicalized self.dtype doesn't necessarily match self.val
   self.dtype = onp.dtype(xla_bridge.canonicalize_dtype(onp.result_type(val)))
   assert self.dtype != onp.dtype('O')
Example #38
0
def _multiply_no_nan(x, y, name=None):  # pylint: disable=unused-argument
    dtype = np.result_type(x, y)
    # TODO(b/146385087): The gradient should be
    # `lambda dz: [multiply_no_nan(dz, y), multiply_no_nan(x, dz)]`.
    return np.where(np.equal(y, 0.), np.zeros((), dtype=dtype),
                    np.multiply(x, y))
Example #39
0
def _divide_no_nan(x, y, name=None):  # pylint: disable=unused-argument
    dtype = np.result_type(x, y)
    y_is_zero = np.equal(y, 0.)
    div = np.divide(x, np.where(y_is_zero, np.ones((), dtype=dtype), y))
    return np.where(y_is_zero, np.zeros((), dtype=dtype), div)
Example #40
0
    def __init__(
        self,
        arr_shape,
        order="F",
        arr_dtype=np.float32,
        use_fft_shifts=True,
        sample_mask=None,
        ortho=False,
        coil_sensitivities=None,
        force_real_image=False,
        debug=False,
        preplan_pyfftw=True,
        pyfftw_threads=None,
        fft_axes=None,
        fftshift_axes=None,
        planner_effort="FFTW_ESTIMATE",
        loop_over_coils=False,
        preserve_memory=False,
        disable_warnings=False,
        im_mask=None,
        pixel_basis="dirac",
        rel_fov=None,
        **kwargs,
    ):
        """Cartesian MRI Operator  (with partial FFT and coil maps).

        Parameters
        ----------
        arr_shape : int
            shape of the array
        order : {'C','F'}, optional
            array ordering that will be assumed if inputs/outputs need to be
            reshaped
        arr_dtype : numpy.dtype, optional
            dtype for the array
        sample_mask : array_like, optional
            boolean mask of which FFT coefficients to keep
        coil_sensitivities : array, optional
            Array of coil sensitivities.
        ortho : bool, optional
            if True, change the normalizeation to the orthogonal case
        preplan_pyfftw : bool, optional
            if True, precompute the pyFFTW plan upon object creation
        pyfftw_threads : int, optional
            number of threads to be used by pyFFTW.  defaults to
            multiprocessing.cpu_count() // 2.
        use_fft_shifts : bool, optional
            If False, do not apply any FFT shifts
        fft_axes : tuple or None, optional
            Specify a subset of the axes to transform.  The default is to
            transform all axes.
        fftshift_axes : tuple or None, optional
            Specify a subset of the axes to fftshift.  The default is to
            shift all axes.
        im_mask : ndarray or None, optional
            Image domain mask
        force_real_image : bool, optional
        loop_over_coils : bool, optional
            If True, memory required is lower, but speed will be slower.
        preserve_memory : bool, optional
            If False, conjugate copy of coils won't be precomputed
        debug : bool, optional

        Additional Parameters
        ---------------------
        nd_input : bool, optional
        nd_output : bool, optional

        """
        if isinstance(arr_shape, (np.ndarray, list)):
            # retrieve shape from array
            arr_shape = tuple(arr_shape)
        if not isinstance(arr_shape, tuple):
            raise ValueError("expected array_shape to be a tuple or list")

        self.arr_shape = arr_shape
        self.ndim = len(arr_shape)
        self.order = order
        self.use_fft_shifts = use_fft_shifts
        self.disable_warnings = disable_warnings

        if "loc_in" in kwargs and kwargs["loc_in"] == "gpu":
            xp = cupy
            on_gpu = True
        else:
            xp = np
            on_gpu = False
        self._on_gpu = on_gpu

        if sample_mask is not None:
            # masking faster if continguity of mask matches
            if self.order == "F":
                sample_mask = xp.asfortranarray(sample_mask)
            elif self.order == "C":
                sample_mask = xp.ascontiguousarray(sample_mask)
            else:
                raise ValueError("order must be C or F")
        self.sample_mask = sample_mask

        self.force_real_image = force_real_image
        self.debug = debug
        if self.sample_mask is not None:
            if sample_mask.shape != arr_shape:
                raise ValueError("sample mask shape must match arr_shape")
            # make sure it is boolean
            self.sample_mask = self.sample_mask > 0
            # # prestore raveled mask indices to save time later during masking
            # self.sample_mask_idx = xp.where(
            #     self.sample_mask.ravel(order=self.order)
            # )

        self.preserve_memory = preserve_memory
        self.loop_over_coils = loop_over_coils

        # can specify a subset of the axes to perform the FFT/FFTshifts over
        self.fft_axes = fft_axes
        if self.fft_axes is None:
            if self.order == "C":
                # last ndim axes
                self.fft_axes = tuple([-ax for ax in range(self.ndim, 0, -1)])
            else:
                # first ndim axes
                self.fft_axes = tuple(range(self.ndim))

        if fftshift_axes is None:
            self.fftshift_axes = self.fft_axes
        else:
            self.fftshift_axes = fftshift_axes

        # configure scaling  (e.g. unitary operator or not)
        self.ortho = ortho
        if self.fft_axes is None:
            Ntrans = prod(self.arr_shape)
        else:
            Ntrans = prod(
                np.asarray(self.arr_shape)[np.asarray(self.fft_axes)])
        if self.ortho:
            # sqrt of product of shape along axes where FFT is performed
            self.scale_ortho = sqrt(Ntrans)
            self.gpu_scale_inverse = 1  # self.scale_ortho / Ntrans
            # self.gpu_scale_forward = self.scale_ortho
        else:
            self.scale_ortho = None
            self.gpu_scale_inverse = 1 / Ntrans

        if "mask_out" in kwargs:
            raise ValueError("This operator specifies `mask_out` via the "
                             "parameter `sample_mask")

        if ("mask_in" in kwargs) or ("mask_out" in kwargs):
            raise ValueError("This operator specifies `mask_in` via the "
                             "parameter `im_mask")

        if coil_sensitivities is not None:
            if coil_sensitivities.ndim == self.ndim + 1:
                # self.arr_shape + (Ncoils, )
                if self.order == "C":
                    Ncoils = coil_sensitivities.shape[0]
                else:
                    Ncoils = coil_sensitivities.shape[-1]
                Nmaps = 1
            elif coil_sensitivities.ndim == self.ndim + 2:
                # case with multiple maps (e.g. ESPIRIT soft-SENSE)
                # self.arr_shape + (Ncoils, Nmaps)
                if self.order == "C":
                    Ncoils = coil_sensitivities.shape[1]
                    Nmaps = coil_sensitivities.shape[0]
                else:
                    Ncoils = coil_sensitivities.shape[-2]
                    Nmaps = coil_sensitivities.shape[-1]
            else:
                # determine based on size
                Ncoils = coil_sensitivities.size / prod(self.arr_shape)
            if (Ncoils % 1) != 0:
                raise ValueError("sensitivity map size mismatch")
            self.Ncoils = int(Ncoils)
            self.Nmaps = Nmaps
            if self.order == "C":
                cmap_shape = (self.Nmaps, self.Ncoils) + self.arr_shape
                if not coil_sensitivities.flags.c_contiguous:
                    msg = (
                        "Converting coil_sensitivities to be C contiguous"
                        " (requires a copy).  To avoid the copy, convert to "
                        "Fortran contiguous order prior to calling "
                        "MRI_Cartesian (see np.ascontiguousarray)")
                    if not self.disable_warnings:
                        warnings.warn(msg)
                    coil_sensitivities = xp.ascontiguousarray(
                        coil_sensitivities)
            else:
                cmap_shape = self.arr_shape + (self.Ncoils, self.Nmaps)
                if not coil_sensitivities.flags.f_contiguous:
                    msg = (
                        "Converting coil_sensitivities to be Fortan contiguous"
                        " (requires a copy).  To avoid the copy, convert to "
                        "Fortran contiguous order prior to calling "
                        "MRI_Cartesian (see np.asfortranarray)")
                    if not self.disable_warnings:
                        warnings.warn(msg)
                    coil_sensitivities = xp.asfortranarray(coil_sensitivities)
            if tuple(coil_sensitivities.shape) != tuple(cmap_shape):
                coil_sensitivities = coil_sensitivities.reshape(
                    cmap_shape, order=self.order)
            if not self.preserve_memory:
                self.coil_sensitivities_conj = xp.conj(coil_sensitivities)
        else:
            self.Ncoils = 1
            self.Nmaps = 1

        if self.Ncoils == 1:
            # TODO: currently has a shape bug if Ncoils == 1
            #       and loop_over_coils = False.
            self.loop_over_coils = True

        self.coil_sensitivities = coil_sensitivities

        if im_mask is not None:
            if im_mask.shape != arr_shape:
                raise ValueError("im_mask shape mismatch")
            if order != "F":
                raise ValueError("only order='F' supported for im_mask case")
            nargin = xp.count_nonzero(im_mask)
            self.im_mask = im_mask
        else:
            nargin = prod(arr_shape)
            self.im_mask = None
        nargin *= self.Nmaps

        # nargout = # of k-space samples
        if sample_mask is not None:
            nargout = xp.count_nonzero(sample_mask) * self.Ncoils
        else:
            nargout = nargin // self.Nmaps * self.Ncoils
        nargout = int(nargout)

        self.idx_orig = None
        self.idx_conj = None
        self.sample_mask_conj = None

        # output of FFTs will be complex, regardless of input type
        self.result_dtype = np.result_type(arr_dtype, np.complex64)

        matvec_allows_repetitions = kwargs.pop("matvec_allows_repetitions",
                                               True)
        squeeze_reps = kwargs.pop("squeeze_reps", True)
        nd_input = kwargs.pop("nd_input", False)
        nd_output = kwargs.pop("nd_output", False)

        if (self.sample_mask is not None) and nd_output:
            raise ValueError("cannot have both nd_output and sample_mask")
        if nd_output:
            if self.Ncoils == 1:
                shape_out = self.arr_shape
            else:
                if Nmaps == 1:
                    if self.order == "C":
                        shape_out = (self.Ncoils, ) + self.arr_shape
                    else:
                        shape_out = self.arr_shape + (self.Ncoils, )
                else:
                    if self.order == "C":
                        shape_out = (self.Nmaps, self.Ncoils) + self.arr_shape
                    else:
                        shape_out = self.arr_shape + (self.Ncoils, self.Nmaps)
        else:
            shape_out = (nargout, 1)

        if self.Nmaps == 1:
            shape_in = self.arr_shape
        else:
            if self.order == "C":
                shape_in = (self.Nmaps, ) + self.arr_shape
            else:
                shape_in = self.arr_shape + (self.Nmaps, )
        if self.order == "C":
            self.shape_inM = (self.Nmaps, ) + self.arr_shape
        else:
            self.shape_inM = self.arr_shape + (self.Nmaps, )
        self.shape_in1 = self.arr_shape
        self.have_pyfftw = config.have_pyfftw

        if self.on_gpu:
            self.preplan_pyfftw = False
        else:
            self.preplan_pyfftw = preplan_pyfftw if self.have_pyfftw else False

            if self.preplan_pyfftw:
                self._preplan_fft(pyfftw_threads, planner_effort)
                # raise ValueError("Implementation Incomplete")

        if self.on_gpu:
            self.fftn = partial(fftn, xp=cupy)
            self.ifftn = partial(ifftn, xp=cupy)
        else:
            if self.preplan_pyfftw:
                self._preplan_fft(pyfftw_threads, planner_effort)
            else:
                self.fftn = partial(fftn, xp=np)
                self.ifftn = partial(ifftn, xp=np)
        self.fftshift = xp.fft.fftshift
        self.ifftshift = xp.fft.ifftshift

        self.rel_fov = rel_fov

        self.mask = None  # TODO: implement or remove (expected by CUDA code)

        matvec = self.forward
        matvec_adj = self.adjoint
        self.norm_available = False
        self.norm = self._norm

        super(MRI_Cartesian, self).__init__(
            nargin=nargin,
            nargout=nargout,
            matvec=matvec,
            matvec_transp=matvec_adj,
            matvec_adj=matvec_adj,
            nd_input=nd_input or (im_mask is not None),
            nd_output=nd_output,
            shape_in=shape_in,
            shape_out=shape_out,
            order=self.order,
            matvec_allows_repetitions=matvec_allows_repetitions,
            squeeze_reps=squeeze_reps,
            mask_in=im_mask,
            mask_out=None,  # mask_out,
            symmetric=False,  # TODO: set properly
            hermetian=False,  # TODO: set properly
            dtype=self.result_dtype,
            **kwargs,
        )

        self._init_pixel_basis(pixel_basis=pixel_basis)
Example #41
0
def einsum(*operands, **kwargs):
    casting = kwargs.pop('casting', 'safe')
    dtype = kwargs.pop('dtype', None)
    optimize = kwargs.pop('optimize', False)
    order = kwargs.pop('order', 'K')
    split_every = kwargs.pop('split_every', None)
    if kwargs:
        raise TypeError("einsum() got unexpected keyword "
                        "argument(s) %s" % ",".join(kwargs))

    einsum_dtype = dtype

    inputs, outputs, ops = parse_einsum_input(operands)
    subscripts = '->'.join((inputs, outputs))

    # Infer the output dtype from operands
    if dtype is None:
        dtype = np.result_type(*[o.dtype for o in ops])

    if einsum_can_optimize:
        if optimize is not False:
            # Avoid computation of dask arrays within np.einsum_path
            # by passing in small numpy arrays broadcasted
            # up to the right shape
            fake_ops = [
                np.broadcast_to(o.dtype.type(0), shape=o.shape) for o in ops
            ]
            optimize, _ = np.einsum_path(subscripts,
                                         *fake_ops,
                                         optimize=optimize)
        kwargs = {'optimize': optimize}
    else:
        kwargs = {}

    inputs = [tuple(i) for i in inputs.split(",")]

    # Set of all indices
    all_inds = set(a for i in inputs for a in i)

    # Which indices are contracted?
    contract_inds = all_inds - set(outputs)
    ncontract_inds = len(contract_inds)

    # Introduce the contracted indices into the blockwise product
    # so that we get numpy arrays, not lists
    result = blockwise(
        chunk.einsum,
        tuple(outputs) + tuple(contract_inds),
        *(a for ap in zip(ops, inputs) for a in ap),
        # blockwise parameters
        adjust_chunks={ind: 1
                       for ind in contract_inds},
        dtype=dtype,
        # np.einsum parameters
        subscripts=subscripts,
        kernel_dtype=einsum_dtype,
        ncontract_inds=ncontract_inds,
        order=order,
        casting=casting,
        **kwargs)

    # Now reduce over any extra contraction dimensions
    if ncontract_inds > 0:
        size = len(outputs)
        return result.sum(axis=list(range(size, size + ncontract_inds)),
                          split_every=split_every)

    return result
Example #42
0
def check_output(output, unit, inputs, function=None):
    """Check that function output can be stored in the output array given.

    Parameters
    ----------
    output : array or `~astropy.units.Quantity` or tuple
        Array that should hold the function output (or tuple of such arrays).
    unit : `~astropy.units.Unit` or None, or tuple
        Unit that the output will have, or `None` for pure numbers (should be
        tuple of same if output is a tuple of outputs).
    inputs : tuple
        Any input arguments.  These should be castable to the output.
    function : callable
        The function that will be producing the output.  If given, used to
        give a more informative error message.

    Returns
    -------
    arrays : `~numpy.ndarray` view of ``output`` (or tuple of such views).

    Raises
    ------
    UnitTypeError : If ``unit`` is inconsistent with the class of ``output``

    TypeError : If the ``inputs`` cannot be cast safely to ``output``.
    """
    if isinstance(output, tuple):
        return tuple(
            check_output(output_, unit_, inputs, function)
            for output_, unit_ in zip(output, unit))

    # ``None`` indicates no actual array is needed.  This can happen, e.g.,
    # with np.modf(a, out=(None, b)).
    if output is None:
        return None

    if hasattr(output, '__quantity_subclass__'):
        # Check that we're not trying to store a plain Numpy array or a
        # Quantity with an inconsistent unit (e.g., not angular for Angle).
        if unit is None:
            raise TypeError("Cannot store non-quantity output{0} in {1} "
                            "instance".format(
                                (" from {0} function".format(function.__name__)
                                 if function is not None else ""),
                                type(output)))

        if output.__quantity_subclass__(unit)[0] is not type(output):
            raise UnitTypeError(
                "Cannot store output with unit '{0}'{1} "
                "in {2} instance.  Use {3} instance instead.".format(
                    unit, (" from {0} function".format(function.__name__)
                           if function is not None else ""), type(output),
                    output.__quantity_subclass__(unit)[0]))

        # Turn into ndarray, so we do not loop into array_wrap/array_ufunc
        # if the output is used to store results of a function.
        output = output.view(np.ndarray)
    else:
        # output is not a Quantity, so cannot obtain a unit.
        if not (unit is None or unit is dimensionless_unscaled):
            raise UnitTypeError(
                "Cannot store quantity with dimension "
                "{0}in a non-Quantity instance.".format(
                    "" if function is None else "resulting from {0} function ".
                    format(function.__name__)))

    # check we can handle the dtype (e.g., that we are not int
    # when float is required).
    if not np.can_cast(
            np.result_type(*inputs), output.dtype, casting='same_kind'):
        raise TypeError("Arguments cannot be cast safely to inplace "
                        "output with dtype={0}".format(output.dtype))
    return output
Example #43
0
def numeric_normalize_types(*args):
    """Cast all args to a common type using numpy promotion logic
    """
    dtype = np.result_type(*[a.dtype for a in args])
    return [a.astype(dtype) for a in args]
Example #44
0
def get_k_kpts(mydf,
               dm_kpts,
               hermi=1,
               kpts=np.zeros((1, 3)),
               kpts_band=None,
               exxdiv=None):
    '''Get the Coulomb (J) and exchange (K) AO matrices at sampled k-points.

    Args:
        dm_kpts : (nkpts, nao, nao) ndarray
            Density matrix at each k-point
        kpts : (nkpts, 3) ndarray

    Kwargs:
        hermi : int
            Whether K matrix is hermitian

            | 0 : not hermitian and not symmetric
            | 1 : hermitian

        kpts_band : (3,) ndarray or (*,3) ndarray
            A list of arbitrary "band" k-points at which to evalute the matrix.

    Returns:
        vj : (nkpts, nao, nao) ndarray
        vk : (nkpts, nao, nao) ndarray
        or list of vj and vk if the input dm_kpts is a list of DMs
    '''
    cell = mydf.cell
    mesh = mydf.mesh
    coords = cell.gen_uniform_grids(mesh)
    ngrids = coords.shape[0]

    if getattr(dm_kpts, 'mo_coeff', None) is not None:
        mo_coeff = dm_kpts.mo_coeff
        mo_occ = dm_kpts.mo_occ
    else:
        mo_coeff = None

    kpts = np.asarray(kpts)
    dm_kpts = lib.asarray(dm_kpts, order='C')
    dms = _format_dms(dm_kpts, kpts)
    nset, nkpts, nao = dms.shape[:3]

    weight = 1. / nkpts * (cell.vol / ngrids)

    kpts_band, input_band = _format_kpts_band(kpts_band, kpts), kpts_band
    nband = len(kpts_band)

    if gamma_point(kpts_band) and gamma_point(kpts):
        vk_kpts = np.zeros((nset, nband, nao, nao), dtype=dms.dtype)
    else:
        vk_kpts = np.zeros((nset, nband, nao, nao), dtype=np.complex128)

    coords = mydf.grids.coords
    ao2_kpts = [
        np.asarray(ao.T, order='C')
        for ao in mydf._numint.eval_ao(cell, coords, kpts=kpts)
    ]
    if input_band is None:
        ao1_kpts = ao2_kpts
    else:
        ao1_kpts = [
            np.asarray(ao.T, order='C')
            for ao in mydf._numint.eval_ao(cell, coords, kpts=kpts_band)
        ]
    if mo_coeff is not None and nset == 1:
        mo_coeff = [
            mo_coeff[k][:, occ > 0] * np.sqrt(occ[occ > 0])
            for k, occ in enumerate(mo_occ)
        ]
        ao2_kpts = [np.dot(mo_coeff[k].T, ao) for k, ao in enumerate(ao2_kpts)]

    mem_now = lib.current_memory()[0]
    max_memory = mydf.max_memory - mem_now
    blksize = int(
        min(nao, max(1, (max_memory - mem_now) * 1e6 / 16 / 4 / ngrids / nao)))
    lib.logger.debug1(mydf, 'fft_jk: get_k_kpts max_memory %s  blksize %d',
                      max_memory, blksize)
    ao1_dtype = np.result_type(*ao1_kpts)
    ao2_dtype = np.result_type(*ao2_kpts)
    vR_dm = np.empty((nset, nao, ngrids), dtype=vk_kpts.dtype)

    t1 = (time.clock(), time.time())
    for k2, ao2T in enumerate(ao2_kpts):
        if ao2T.size == 0:
            continue

        kpt2 = kpts[k2]
        naoj = ao2T.shape[0]
        if mo_coeff is None or nset > 1:
            ao_dms = [lib.dot(dms[i, k2], ao2T.conj()) for i in range(nset)]
        else:
            ao_dms = [ao2T.conj()]

        for k1, ao1T in enumerate(ao1_kpts):
            kpt1 = kpts_band[k1]

            # If we have an ewald exxdiv, we add the G=0 correction near the
            # end of the function to bypass any discretization errors
            # that arise from the FFT.
            mydf.exxdiv = exxdiv
            if exxdiv == 'ewald' or exxdiv is None:
                coulG = tools.get_coulG(cell, kpt2 - kpt1, False, mydf, mesh)
            else:
                coulG = tools.get_coulG(cell, kpt2 - kpt1, True, mydf, mesh)
            if is_zero(kpt1 - kpt2):
                expmikr = np.array(1.)
            else:
                expmikr = np.exp(-1j * np.dot(coords, kpt2 - kpt1))

            for p0, p1 in lib.prange(0, nao, blksize):
                rho1 = np.einsum('ig,jg->ijg', ao1T[p0:p1].conj() * expmikr,
                                 ao2T)
                vG = tools.fft(rho1.reshape(-1, ngrids), mesh)
                rho1 = None
                vG *= coulG
                vR = tools.ifft(vG, mesh).reshape(p1 - p0, naoj, ngrids)
                vG = None
                if vR_dm.dtype == np.double:
                    vR = vR.real
                for i in range(nset):
                    np.einsum('ijg,jg->ig', vR, ao_dms[i], out=vR_dm[i, p0:p1])
                vR = None
            vR_dm *= expmikr.conj()

            for i in range(nset):
                vk_kpts[i, k1] += weight * lib.dot(vR_dm[i], ao1T.T)
        t1 = lib.logger.timer_debug1(mydf, 'get_k_kpts: make_kpt (%d,*)' % k2,
                                     *t1)

    # Function _ewald_exxdiv_for_G0 to add back in the G=0 component to vk_kpts
    # Note in the _ewald_exxdiv_for_G0 implementation, the G=0 treatments are
    # different for 1D/2D and 3D systems.  The special treatments for 1D and 2D
    # can only be used with AFTDF/GDF/MDF method.  In the FFTDF method, 1D, 2D
    # and 3D should use the ewald probe charge correction.
    if exxdiv == 'ewald':
        _ewald_exxdiv_for_G0(cell, kpts, dms, vk_kpts, kpts_band=kpts_band)

    return _format_jks(vk_kpts, dm_kpts, input_band, kpts)
Example #45
0
def asfcarray(a):
    a = np.asarray(a)
    return np.asarray(a, np.result_type(a, 0.0))
Example #46
0
def _result_type(*arrays_and_dtypes):
    dtype = np.result_type(*arrays_and_dtypes)
    return canonicalize_dtype(dtype)
Example #47
0
def where(condition, x=None, y=None):
    """
    Return elements, either from `x` or `y`, depending on `condition`.

    If only `condition` is given, return ``condition.nonzero()``.

    Parameters
    ----------
    condition : array_like, bool
        When True, yield `x`, otherwise yield `y`.
    x, y : array_like, optional
        Values from which to choose. `x`, `y` and `condition` need to be
        broadcastable to some shape.

    Returns
    -------
    out : Tensor or tuple of Tensors
        If both `x` and `y` are specified, the output tensor contains
        elements of `x` where `condition` is True, and elements from
        `y` elsewhere.

        If only `condition` is given, return the tuple
        ``condition.nonzero()``, the indices where `condition` is True.

    See Also
    --------
    nonzero, choose

    Notes
    -----
    If `x` and `y` are given and input arrays are 1-D, `where` is
    equivalent to::

        [xv if c else yv for (c,xv,yv) in zip(condition,x,y)]

    Examples
    --------
    >>> import mars.tensor as mt

    >>> mt.where([[True, False], [True, True]],
    ...          [[1, 2], [3, 4]],
    ...          [[9, 8], [7, 6]]).execute()
    array([[1, 8],
           [3, 4]])

    >>> mt.where([[0, 1], [1, 0]]).execute()
    (array([0, 1]), array([1, 0]))

    >>> x = mt.arange(9.).reshape(3, 3)
    >>> mt.where( x > 5 ).execute()
    (array([2, 2, 2]), array([0, 1, 2]))
    >>> mt.where(x < 5, x, -1).execute()               # Note: broadcasting.
    array([[ 0.,  1.,  2.],
           [ 3.,  4., -1.],
           [-1., -1., -1.]])

    Find the indices of elements of `x` that are in `goodvalues`.

    >>> goodvalues = [3, 4, 7]
    >>> ix = mt.isin(x, goodvalues)
    >>> ix.execute()
    array([[False, False, False],
           [ True,  True, False],
           [False,  True, False]])
    >>> mt.where(ix).execute()
    (array([1, 1, 2]), array([0, 1, 1]))
    """
    if (x is None) != (y is None):
        raise ValueError('either both or neither of x and y should be given')

    if x is None and y is None:
        return astensor(condition).nonzero()

    x, y = astensor(x), astensor(y)
    dtype = np.result_type(x.dtype, y.dtype)
    shape = broadcast_shape(x.shape, y.shape)

    if np.isscalar(condition):
        return broadcast_to(x if condition else y, shape).astype(dtype)
    else:
        condition = astensor(condition)
        op = TensorWhere(dtype=dtype)
        return op(condition, x, y, shape=shape)
Example #48
0
def linspace(start,
             stop,
             num=50,
             endpoint=True,
             retstep=False,
             dtype=None,
             axis=0):
    """Implements a simplified linspace function as of numpy verion >= 1.16.

    As of numpy 1.16, the arguments start and stop can be array-like and
    there is an optional argument `axis`.
    For simplicity, we only allow 1d array-like to be passed to start and stop.
    See: https://github.com/numpy/numpy/pull/12388 and numpy 1.16 release
    notes about start and stop arrays for linspace logspace and geomspace.

    Returns
    -------
    out : ndarray of shape (num, n_start) or (num,)
        The output array with `n_start=start.shape[0]` columns.
    """
    if np_version < parse_version('1.16'):
        start = np.asanyarray(start) * 1.0
        stop = np.asanyarray(stop) * 1.0
        dt = np.result_type(start, stop, float(num))
        if dtype is None:
            dtype = dt

        if start.ndim == 0 == stop.ndim:
            return np.linspace(start=start,
                               stop=stop,
                               num=num,
                               endpoint=endpoint,
                               retstep=retstep,
                               dtype=dtype)

        if start.ndim != 1 or stop.ndim != 1 or start.shape != stop.shape:
            raise ValueError("start and stop must be 1d array-like of same"
                             " shape.")
        n_start = start.shape[0]
        out = np.empty((num, n_start), dtype=dtype)
        step = np.empty(n_start, dtype=np.float)
        for i in range(n_start):
            out[:, i], step[i] = np.linspace(start=start[i],
                                             stop=stop[i],
                                             num=num,
                                             endpoint=endpoint,
                                             retstep=True,
                                             dtype=dtype)
        if axis != 0:
            out = np.moveaxis(out, 0, axis)

        if retstep:
            return out, step
        else:
            return out
    else:
        return np.linspace(start=start,
                           stop=stop,
                           num=num,
                           endpoint=endpoint,
                           retstep=retstep,
                           dtype=dtype,
                           axis=axis)
Example #49
0
def check_array(
    array,
    accept_sparse=False,
    accept_large_sparse=True,
    dtype="numeric",
    order=None,
    copy=False,
    force_all_finite=True,
    ensure_2d=True,
    allow_nd=False,
    ensure_min_samples=1,
    ensure_min_features=1,
    warn_on_dtype=None,
    estimator=None,
):

    """Input validation on an array, list, sparse matrix or similar.
    By default, the input is checked to be a non-empty 2D array containing
    only finite values. If the dtype of the array is object, attempt
    converting to float, raising on failure.
    Parameters
    ----------
    array : object
        Input object to check / convert.
    accept_sparse : string, boolean or list/tuple of strings (default=False)
        String[s] representing allowed sparse matrix formats, such as 'csc',
        'csr', etc. If the input is sparse but not in the allowed format,
        it will be converted to the first listed format. True allows the input
        to be any format. False means that a sparse matrix input will
        raise an error.
    accept_large_sparse : bool (default=True)
        If a CSR, CSC, COO or BSR sparse matrix is supplied and accepted by
        accept_sparse, accept_large_sparse=False will cause it to be accepted
        only if its indices are stored with a 32-bit dtype.
        .. versionadded:: 0.20
    dtype : string, type, list of types or None (default="numeric")
        Data type of result. If None, the dtype of the input is preserved.
        If "numeric", dtype is preserved unless array.dtype is object.
        If dtype is a list of types, conversion on the first type is only
        performed if the dtype of the input is not in the list.
    order : 'F', 'C' or None (default=None)
        Whether an array will be forced to be fortran or c-style.
        When order is None (default), then if copy=False, nothing is ensured
        about the memory layout of the output array; otherwise (copy=True)
        the memory layout of the returned array is kept as close as possible
        to the original array.
    copy : boolean (default=False)
        Whether a forced copy will be triggered. If copy=False, a copy might
        be triggered by a conversion.
    force_all_finite : boolean or 'allow-nan', (default=True)
        Whether to raise an error on np.inf and np.nan in array. The
        possibilities are:
        - True: Force all values of array to be finite.
        - False: accept both np.inf and np.nan in array.
        - 'allow-nan': accept only np.nan values in array. Values cannot
          be infinite.
        For object dtyped data, only np.nan is checked and not np.inf.
        .. versionadded:: 0.20
           ``force_all_finite`` accepts the string ``'allow-nan'``.
    ensure_2d : boolean (default=True)
        Whether to raise a value error if array is not 2D.
    allow_nd : boolean (default=False)
        Whether to allow array.ndim > 2.
    ensure_min_samples : int (default=1)
        Make sure that the array has a minimum number of samples in its first
        axis (rows for a 2D array). Setting to 0 disables this check.
    ensure_min_features : int (default=1)
        Make sure that the 2D array has some minimum number of features
        (columns). The default value of 1 rejects empty datasets.
        This check is only enforced when the input data has effectively 2
        dimensions or is originally 1D and ``ensure_2d`` is True. Setting to 0
        disables this check.
    warn_on_dtype : boolean or None, optional (default=None)
        Raise DataConversionWarning if the dtype of the input data structure
        does not match the requested dtype, causing a memory copy.
        .. deprecated:: 0.21
            ``warn_on_dtype`` is deprecated in version 0.21 and will be
            removed in 0.23.
    estimator : str or estimator instance (default=None)
        If passed, include the name of the estimator in warning messages.
    Returns
    -------
    array_converted : object
        The converted and validated array.
    """
    # warn_on_dtype deprecation
    if warn_on_dtype is not None:
        warnings.warn(
            "'warn_on_dtype' is deprecated in version 0.21 and will be "
            "removed in 0.23. Don't set `warn_on_dtype` to remove this "
            "warning.",
            FutureWarning,
            stacklevel=2,
        )

    # store reference to original array to check if copy is needed when
    # function returns
    array_orig = array

    # store whether originally we wanted numeric dtype
    dtype_numeric = isinstance(dtype, str) and dtype == "numeric"

    dtype_orig = getattr(array, "dtype", None)
    if not hasattr(dtype_orig, "kind"):
        # not a data type (e.g. a column named dtype in a pandas DataFrame)
        dtype_orig = None

    # check if the object contains several dtypes (typically a pandas
    # DataFrame), and store them. If not, store None.
    dtypes_orig = None
    if hasattr(array, "dtypes") and hasattr(array.dtypes, "__array__"):
        dtypes_orig = np.array(array.dtypes)
        if all(isinstance(dtype, np.dtype) for dtype in dtypes_orig):
            dtype_orig = np.result_type(*array.dtypes)

    if dtype_numeric:
        if dtype_orig is not None and dtype_orig.kind == "O":
            # if input is object, convert to float.
            dtype = np.float64
        else:
            dtype = None

    if isinstance(dtype, (list, tuple)):
        if dtype_orig is not None and dtype_orig in dtype:
            # no dtype conversion required
            dtype = None
        else:
            # dtype conversion required. Let's select the first element of the
            # list of accepted types.
            dtype = dtype[0]

    if force_all_finite not in (True, False, "allow-nan"):
        raise ValueError(
            'force_all_finite should be a bool or "allow-nan"'
            ". Got {!r} instead".format(force_all_finite)
        )

    if estimator is not None:
        if isinstance(estimator, str):
            estimator_name = estimator
        else:
            estimator_name = estimator.__class__.__name__
    else:
        estimator_name = "Estimator"
    context = " by %s" % estimator_name if estimator is not None else ""

    if sp.issparse(array):
        _ensure_no_complex_data(array)
        array = _ensure_sparse_format(
            array,
            accept_sparse=accept_sparse,
            dtype=dtype,
            copy=copy,
            force_all_finite=force_all_finite,
            accept_large_sparse=accept_large_sparse,
        )
    else:
        # If np.array(..) gives ComplexWarning, then we convert the warning
        # to an error. This is needed because specifying a non complex
        # dtype to the function converts complex to real dtype,
        # thereby passing the test made in the lines following the scope
        # of warnings context manager.
        with warnings.catch_warnings():
            try:
                warnings.simplefilter("error", ComplexWarning)
                if dtype is not None and np.dtype(dtype).kind in "iu":
                    # Conversion float -> int should not contain NaN or
                    # inf (numpy#14412). We cannot use casting='safe' because
                    # then conversion float -> int would be disallowed.
                    array = np.asarray(array, order=order)
                    if array.dtype.kind == "f":
                        _assert_all_finite(array, allow_nan=False, msg_dtype=dtype)
                    array = array.astype(dtype, casting="unsafe", copy=False)
                else:
                    array = np.asarray(array, order=order, dtype=dtype)
            except ComplexWarning:
                raise ValueError("Complex data not supported\n" "{}\n".format(array))

        # It is possible that the np.array(..) gave no warning. This happens
        # when no dtype conversion happened, for example dtype = None. The
        # result is that np.array(..) produces an array of complex dtype
        # and we need to catch and raise exception for such cases.
        _ensure_no_complex_data(array)

        if ensure_2d:
            # If input is scalar raise error
            if array.ndim == 0:
                raise ValueError(
                    "Expected 2D array, got scalar array instead:\narray={}.\n"
                    "Reshape your data either using array.reshape(-1, 1) if "
                    "your data has a single feature or array.reshape(1, -1) "
                    "if it contains a single sample.".format(array)
                )
            # If input is 1D raise error
            if array.ndim == 1:
                raise ValueError(
                    "Expected 2D array, got 1D array instead:\narray={}.\n"
                    "Reshape your data either using array.reshape(-1, 1) if "
                    "your data has a single feature or array.reshape(1, -1) "
                    "if it contains a single sample.".format(array)
                )

        # in the future np.flexible dtypes will be handled like object dtypes
        if dtype_numeric and np.issubdtype(array.dtype, np.flexible):
            warnings.warn(
                "Beginning in version 0.22, arrays of bytes/strings will be "
                "converted to decimal numbers if dtype='numeric'. "
                "It is recommended that you convert the array to "
                "a float dtype before using it in scikit-learn, "
                "for example by using "
                "your_array = your_array.astype(np.float64).",
                FutureWarning,
                stacklevel=2,
            )

        # make sure we actually converted to numeric:
        if dtype_numeric and array.dtype.kind == "O":
            array = array.astype(np.float64)
        if not allow_nd and array.ndim >= 3:
            raise ValueError(
                "Found array with dim %d. %s expected <= 2."
                % (array.ndim, estimator_name)
            )

        if force_all_finite:
            _assert_all_finite(array, allow_nan=force_all_finite == "allow-nan")

    if ensure_min_samples > 0:
        n_samples = _num_samples(array)
        if n_samples < ensure_min_samples:
            raise ValueError(
                "Found array with %d sample(s) (shape=%s) while a"
                " minimum of %d is required%s."
                % (n_samples, array.shape, ensure_min_samples, context)
            )

    if ensure_min_features > 0 and array.ndim == 2:
        n_features = array.shape[1]
        if n_features < ensure_min_features:
            raise ValueError(
                "Found array with %d feature(s) (shape=%s) while"
                " a minimum of %d is required%s."
                % (n_features, array.shape, ensure_min_features, context)
            )

    if warn_on_dtype and dtype_orig is not None and array.dtype != dtype_orig:
        msg = "Data with input dtype %s was converted to %s%s." % (
            dtype_orig,
            array.dtype,
            context,
        )
        warnings.warn(msg, DataConversionWarning, stacklevel=2)

    if copy and np.may_share_memory(array, array_orig):
        array = np.array(array, dtype=dtype, order=order)

    if warn_on_dtype and dtypes_orig is not None and {array.dtype} != set(dtypes_orig):
        # if there was at the beginning some other types than the final one
        # (for instance in a DataFrame that can contain several dtypes) then
        # some data must have been converted
        msg = "Data with input dtype %s were all converted to %s%s." % (
            ", ".join(map(str, sorted(set(dtypes_orig)))),
            array.dtype,
            context,
        )
        warnings.warn(msg, DataConversionWarning, stacklevel=3)

    return array
Example #50
0
File: xla.py Project: zudehuang/jax
def canonicalize_ndarray_dtype(x):
    return onp.asarray(x, xb.canonicalize_dtype(onp.result_type(x)))
def _expm_multiply_interval(A,
                            B,
                            start=None,
                            stop=None,
                            num=None,
                            endpoint=None,
                            balance=False,
                            status_only=False):
    """
    Compute the action of the matrix exponential at multiple time points.

    Parameters
    ----------
    A : transposable linear operator
        The operator whose exponential is of interest.
    B : ndarray
        The matrix to be multiplied by the matrix exponential of A.
    start : scalar, optional
        The starting time point of the sequence.
    stop : scalar, optional
        The end time point of the sequence, unless `endpoint` is set to False.
        In that case, the sequence consists of all but the last of ``num + 1``
        evenly spaced time points, so that `stop` is excluded.
        Note that the step size changes when `endpoint` is False.
    num : int, optional
        Number of time points to use.
    endpoint : bool, optional
        If True, `stop` is the last time point.  Otherwise, it is not included.
    balance : bool
        Indicates whether or not to apply balancing.
    status_only : bool
        A flag that is set to True for some debugging and testing operations.

    Returns
    -------
    F : ndarray
        :math:`e^{t_k A} B`
    status : int
        An integer status for testing and debugging.

    Notes
    -----
    This is algorithm (5.2) in Al-Mohy and Higham (2011).

    There seems to be a typo, where line 15 of the algorithm should be
    moved to line 6.5 (between lines 6 and 7).

    """
    if balance:
        raise NotImplementedError
    if len(A.shape) != 2 or A.shape[0] != A.shape[1]:
        raise ValueError('expected A to be like a square matrix')
    if A.shape[1] != B.shape[0]:
        raise ValueError('the matrices A and B have incompatible shapes')
    ident = _ident_like(A)
    n = A.shape[0]
    if len(B.shape) == 1:
        n0 = 1
    elif len(B.shape) == 2:
        n0 = B.shape[1]
    else:
        raise ValueError('expected B to be like a matrix or a vector')
    u_d = 2**-53
    tol = u_d
    mu = _trace(A) / float(n)

    # Get the linspace samples, attempting to preserve the linspace defaults.
    linspace_kwargs = {'retstep': True}
    if num is not None:
        linspace_kwargs['num'] = num
    if endpoint is not None:
        linspace_kwargs['endpoint'] = endpoint
    samples, step = np.linspace(start, stop, **linspace_kwargs)

    # Convert the linspace output to the notation used by the publication.
    nsamples = len(samples)
    if nsamples < 2:
        raise ValueError('at least two time points are required')
    q = nsamples - 1
    h = step
    t_0 = samples[0]
    t_q = samples[q]

    # Define the output ndarray.
    # Use an ndim=3 shape, such that the last two indices
    # are the ones that may be involved in level 3 BLAS operations.
    X_shape = (nsamples, ) + B.shape
    X = np.empty(X_shape, dtype=np.result_type(A.dtype, B.dtype, float))
    t = t_q - t_0
    A = A - mu * ident
    A_1_norm = _exact_1_norm(A)
    if t * A_1_norm == 0:
        m_star, s = 0, 1
    else:
        ell = 2
        norm_info = LazyOperatorNormInfo(t * A, A_1_norm=t * A_1_norm, ell=ell)
        m_star, s = _fragment_3_1(norm_info, n0, tol, ell=ell)

    # Compute the expm action up to the initial time point.
    X[0] = _expm_multiply_simple_core(A, B, t_0, mu, m_star, s)

    # Compute the expm action at the rest of the time points.
    if q <= s:
        if status_only:
            return 0
        else:
            return _expm_multiply_interval_core_0(A, X, h, mu, m_star, s, q)
    elif q > s and not (q % s):
        if status_only:
            return 1
        else:
            return _expm_multiply_interval_core_1(A, X, h, mu, m_star, s, q,
                                                  tol)
    elif q > s and (q % s):
        if status_only:
            return 2
        else:
            return _expm_multiply_interval_core_2(A, X, h, mu, m_star, s, q,
                                                  tol)
    else:
        raise Exception('internal error')
Example #52
0
def stack(tensors, axis=0):
    """
    Join a sequence of tensors along a new axis.

    The `axis` parameter specifies the index of the new axis in the dimensions
    of the result. For example, if ``axis=0`` it will be the first dimension
    and if ``axis=-1`` it will be the last dimension.

    Parameters
    ----------
    tensors : sequence of array_like
        Each tensor must have the same shape.
    axis : int, optional
        The axis in the result tensor along which the input tensors are stacked.
    out : Tensor, optional
        If provided, the destination to place the result. The shape must be
        correct, matching that of what stack would have returned if no
        out argument were specified.

    Returns
    -------
    stacked : Tensor
        The stacked tensor has one more dimension than the input tensors.

    See Also
    --------
    concatenate : Join a sequence of tensors along an existing axis.
    split : Split tensor into a list of multiple sub-tensors of equal size.
    block : Assemble tensors from blocks.

    Examples
    --------
    >>> import mars.tensor as mt

    >>> arrays = [mt.random.randn(3, 4) for _ in range(10)]
    >>> mt.stack(arrays, axis=0).shape
    (10, 3, 4)

    >>> mt.stack(arrays, axis=1).shape
    (3, 10, 4)

    >>> mt.stack(arrays, axis=2).shape
    (3, 4, 10)

    >>> a = mt.array([1, 2, 3])
    >>> b = mt.array([2, 3, 4])
    >>> mt.stack((a, b)).execute()
    array([[1, 2, 3],
           [2, 3, 4]])

    >>> mt.stack((a, b), axis=-1).execute()
    array([[1, 2],
           [2, 3],
           [3, 4]])

    """
    tensors = [astensor(t) for t in tensors]

    if len(set(t.shape for t in tensors)) != 1:
        raise ValueError('all input tensors must have the same shape')

    ndim = len(tensors[0].shape)
    raw_axis = axis
    if axis < 0:
        axis = ndim + axis + 1
    if axis > ndim or axis < 0:
        raise np.AxisError('axis {0} is out of bounds for tensor '
                           'of dimension {1}'.format(raw_axis, ndim))

    dtype = np.result_type(*[t.dtype for t in tensors])
    sparse = all(t.issparse() for t in tensors)

    op = TensorStack(axis=axis, dtype=dtype, sparse=sparse)
    return op(tensors)
Example #53
0
def rand_map(shape,
             wcs,
             ps_lensinput,
             lmax=None,
             maplmax=None,
             dtype=np.float64,
             seed=None,
             oversample=2.0,
             spin=2,
             output="l",
             geodesic=True,
             verbose=False,
             delta_theta=None,
             phi_seed=None,
             separate_phi_from_cmb=False):
    import curvedsky, sharp
    ctype = np.result_type(dtype, 0j)
    # Restrict to target number of components
    oshape = shape[-3:]
    if len(oshape) == 2: shape = (1, ) + tuple(shape)

    #van Engelen added this:

    # First draw a random lensing field, and use it to compute the undeflected positions
    if not separate_phi_from_cmb:

        #AVE - this was the default option.
        if verbose: print("Generating alms")
        alm, ainfo = curvedsky.rand_alm(ps_lensinput,
                                        lmax=lmax,
                                        seed=seed,
                                        dtype=ctype,
                                        return_ainfo=True)
        phi_alm, cmb_alm = alm[0], alm[1:1 + shape[-3]]
        del alm
    else:
        if verbose: print("Generating alms, separating phi from cmb")
        phi_alm, phi_ainfo = curvedsky.rand_alm(ps_lensinput[0, 0, :],
                                                lmax=lmax,
                                                seed=phi_seed,
                                                dtype=ctype,
                                                return_ainfo=True)
        cmb_alm, cmb_ainfo = curvedsky.rand_alm(ps_lensinput[1:, 1:, :],
                                                lmax=lmax,
                                                seed=seed,
                                                dtype=ctype,
                                                return_ainfo=True)
    # Truncate alm if we want a smoother map. In taylens, it was necessary to truncate
    # to a lower lmax for the map than for phi, to avoid aliasing. The appropriate lmax
    # for the cmb was the one that fits the resolution. FIXME: Can't slice alm this way.
    #if maplmax: cmb_alm = cmb_alm[:,:maplmax]
    if delta_theta is None: bsize = shape[-2]
    else:
        bsize = utils.nint(abs(delta_theta / utils.degree / wcs.wcs.cdelt[1]))
        # Adjust bsize so we don't get any tiny blocks at the end
        nblock = shape[-2] // bsize
        bsize = int(shape[-2] / (nblock + 0.5))
    # Allocate output maps
    if "p" in output: phi_map = enmap.empty(shape[-2:], wcs, dtype=dtype)
    if "k" in output:
        kappa_map = enmap.empty(shape[-2:], wcs, dtype=dtype)
        l = np.arange(ainfo.lmax + 1.0)
        kappa_alm = ainfo.lmul(phi_alm, l * (l + 1) / 2)
        for i1 in range(0, shape[-2], bsize):
            curvedsky.alm2map(kappa_alm, kappa_map[..., i1:i1 + bize, :])
        del kappa_alm
    if "a" in output:
        grad_map = enmap.empty((2, ) + shape[-2:], wcs, dtype=dtype)
    if "u" in output: cmb_raw = enmap.empty(shape, wcs, dtype=dtype)
    if "l" in output: cmb_obs = enmap.empty(shape, wcs, dtype=dtype)
    # Then loop over dec bands
    for i1 in range(0, shape[-2], bsize):
        i2 = min(i1 + bsize, shape[-2])
        lshape, lwcs = enmap.slice_geometry(shape, wcs,
                                            (slice(i1, i2), slice(None)))
        if "p" in output:
            if verbose: print("Computing phi map")
            curvedsky.alm2map(phi_alm, phi_map[..., i1:i2, :])
        if verbose: print("Computing grad map")
        if "a" in output: grad = grad_map[..., i1:i2, :]
        else: grad = enmap.zeros((2, ) + lshape[-2:], lwcs, dtype=dtype)
        curvedsky.alm2map(phi_alm, grad, deriv=True)
        if "l" not in output: continue
        if verbose: print("Computing observed coordinates")
        obs_pos = enmap.posmap(lshape, lwcs)
        if verbose: print("Computing alpha map")
        raw_pos = enmap.samewcs(
            offset_by_grad(obs_pos, grad, pol=shape[-3] > 1,
                           geodesic=geodesic), obs_pos)
        del obs_pos, grad
        if "u" in output:
            if verbose: print("Computing unlensed map")
            curvedsky.alm2map(cmb_alm, cmb_raw[..., i1:i2, :], spin=spin)
        if verbose: print("Computing lensed map")
        cmb_obs[..., i1:i2, :] = curvedsky.alm2map_pos(cmb_alm,
                                                       raw_pos[:2],
                                                       oversample=oversample,
                                                       spin=spin)
        if raw_pos.shape[0] > 2 and np.any(raw_pos[2]):
            if verbose: print("Rotating polarization")
            cmb_obs[..., i1:i2, :] = enmap.rotate_pol(cmb_obs[..., i1:i2, :],
                                                      raw_pos[2])
        del raw_pos
    del cmb_alm, phi_alm
    # Output in same order as specified in output argument
    res = []
    for c in output:
        if c == "l": res.append(cmb_obs.reshape(oshape))
        elif c == "u": res.append(cmb_raw.reshape(oshape))
        elif c == "p": res.append(phi_map)
        elif c == "k": res.append(kappa_map)
        elif c == "a": res.append(grad_map)
    return tuple(res)
Example #54
0
def _get_bin_edges(op, a, bins, range, weights):
    # parse the overloaded bins argument
    n_equal_bins = None
    bin_edges = None
    first_edge = None
    last_edge = None

    if isinstance(bins, str):
        # when `bins` is str, x.min() and x.max()
        # will be calculated in advance
        bin_name = bins
        if a.size > 0:
            assert range is not None

        raw_range = range
        first_edge, last_edge = _get_outer_edges(a, range)

        if a.size == 0:
            n_equal_bins = 1
        else:
            # Do not call selectors on empty arrays
            selector = _hist_bin_selectors[bin_name](op, a,
                                                     (first_edge, last_edge),
                                                     raw_range)
            selector.check()
            width = selector.get_result()
            if width:
                n_equal_bins = int(
                    np.ceil(_unsigned_subtract(last_edge, first_edge) / width))
            else:
                # Width can be zero for some estimators, e.g. FD when
                # the IQR of the data is zero.
                n_equal_bins = 1

    elif mt.ndim(bins) == 0:
        first_edge, last_edge = _get_outer_edges(a, range)
        n_equal_bins = bins

    else:
        # cannot be Tensor, must be calculated first
        assert mt.ndim(bins) == 1 and not isinstance(bins, TENSOR_TYPE)
        bin_edges = np.asarray(bins)
        if not is_asc_sorted(bin_edges):
            raise ValueError(
                '`bins` must increase monotonically, when an array')

    if n_equal_bins is not None:
        # numpy gh-10322 means that type resolution rules are dependent on array
        # shapes. To avoid this causing problems, we pick a type now and stick
        # with it throughout.
        bin_type = np.result_type(first_edge, last_edge, a)
        if np.issubdtype(bin_type, np.integer):
            bin_type = np.result_type(bin_type, float)

        # bin edges must be computed
        bin_edges = mt.linspace(first_edge,
                                last_edge,
                                n_equal_bins + 1,
                                endpoint=True,
                                dtype=bin_type,
                                gpu=op.gpu)
        return bin_edges, (first_edge, last_edge, n_equal_bins)
    else:
        return mt.tensor(bin_edges), None
Example #55
0
    def einsum(idx_str, *tensors, **kwargs):
        '''Perform a more efficient einsum via reshaping to a matrix multiply.

        Current differences compared to numpy.einsum:
        This assumes that each repeated index is actually summed (i.e. no 'i,i->i')
        and appears only twice (i.e. no 'ij,ik,il->jkl'). The output indices must
        be explicitly specified (i.e. 'ij,j->i' and not 'ij,j').
        '''

        DEBUG = kwargs.get('DEBUG', False)

        idx_str = idx_str.replace(' ', '')
        indices = "".join(re.split(',|->', idx_str))
        if '->' not in idx_str or any(
                indices.count(x) > 2 for x in set(indices)):
            return numpy.einsum(idx_str, *tensors)

        if idx_str.count(',') > 1:
            indices = re.split(',|->', idx_str)
            indices_in = indices[:-1]
            idx_final = indices[-1]
            n_shared_max = 0
            for i in range(len(indices_in)):
                for j in range(i):
                    tmp = list(set(indices_in[i]).intersection(indices_in[j]))
                    n_shared_indices = len(tmp)
                    if n_shared_indices > n_shared_max:
                        n_shared_max = n_shared_indices
                        shared_indices = tmp
                        [a, b] = [i, j]
            tensors = list(tensors)
            A, B = tensors[a], tensors[b]
            idxA, idxB = indices[a], indices[b]
            idx_out = list(idxA + idxB)
            idx_out = "".join([x for x in idx_out if x not in shared_indices])
            C = einsum(idxA + "," + idxB + "->" + idx_out, A, B)
            indices_in.pop(a)
            indices_in.pop(b)
            indices_in.append(idx_out)
            tensors.pop(a)
            tensors.pop(b)
            tensors.append(C)
            return einsum(",".join(indices_in) + "->" + idx_final, *tensors)

        A, B = tensors
        # Call numpy.asarray because A or B may be HDF5 Datasets
        A = numpy.asarray(A, order='A')
        B = numpy.asarray(B, order='A')
        if A.size < 2000 or B.size < 2000:
            return numpy.einsum(idx_str, *tensors)

        # Split the strings into a list of idx char's
        idxA, idxBC = idx_str.split(',')
        idxB, idxC = idxBC.split('->')
        idxA, idxB, idxC = [list(x) for x in [idxA, idxB, idxC]]
        assert (len(idxA) == A.ndim)
        assert (len(idxB) == B.ndim)

        if DEBUG:
            print("*** Einsum for", idx_str)
            print(" idxA =", idxA)
            print(" idxB =", idxB)
            print(" idxC =", idxC)

        # Get the range for each index and put it in a dictionary
        rangeA = dict()
        rangeB = dict()
        #rangeC = dict()
        for idx, rnge in zip(idxA, A.shape):
            rangeA[idx] = rnge
        for idx, rnge in zip(idxB, B.shape):
            rangeB[idx] = rnge
        #for idx,rnge in zip(idxC,C.shape):
        #    rangeC[idx] = rnge

        if DEBUG:
            print("rangeA =", rangeA)
            print("rangeB =", rangeB)

        # Find the shared indices being summed over
        shared_idxAB = list(set(idxA).intersection(idxB))
        #if len(shared_idxAB) == 0:
        #    return np.einsum(idx_str,A,B)
        idxAt = list(idxA)
        idxBt = list(idxB)
        inner_shape = 1
        insert_B_loc = 0
        for n in shared_idxAB:
            if rangeA[n] != rangeB[n]:
                err = ('ERROR: In index string %s, the range of index %s is '
                       'different in A (%d) and B (%d)' %
                       (idx_str, n, rangeA[n], rangeB[n]))
                raise RuntimeError(err)

            # Bring idx all the way to the right for A
            # and to the left (but preserve order) for B
            idxA_n = idxAt.index(n)
            idxAt.insert(len(idxAt) - 1, idxAt.pop(idxA_n))

            idxB_n = idxBt.index(n)
            idxBt.insert(insert_B_loc, idxBt.pop(idxB_n))
            insert_B_loc += 1

            inner_shape *= rangeA[n]

        if DEBUG:
            print("shared_idxAB =", shared_idxAB)
            print("inner_shape =", inner_shape)

        # Transpose the tensors into the proper order and reshape into matrices
        new_orderA = [idxA.index(idx) for idx in idxAt]
        new_orderB = [idxB.index(idx) for idx in idxBt]

        if DEBUG:
            print("Transposing A as", new_orderA)
            print("Transposing B as", new_orderB)
            print("Reshaping A as (-1,", inner_shape, ")")
            print("Reshaping B as (", inner_shape, ",-1)")

        shapeCt = list()
        idxCt = list()
        for idx in idxAt:
            if idx in shared_idxAB:
                break
            shapeCt.append(rangeA[idx])
            idxCt.append(idx)
        for idx in idxBt:
            if idx in shared_idxAB:
                continue
            shapeCt.append(rangeB[idx])
            idxCt.append(idx)
        new_orderCt = [idxCt.index(idx) for idx in idxC]

        if A.size == 0 or B.size == 0:
            shapeCt = [shapeCt[i] for i in new_orderCt]
            return numpy.zeros(shapeCt, dtype=numpy.result_type(A, B))

        At = A.transpose(new_orderA)
        Bt = B.transpose(new_orderB)

        if At.flags.f_contiguous:
            At = numpy.asarray(At.reshape(-1, inner_shape), order='F')
        else:
            At = numpy.asarray(At.reshape(-1, inner_shape), order='C')
        if Bt.flags.f_contiguous:
            Bt = numpy.asarray(Bt.reshape(inner_shape, -1), order='F')
        else:
            Bt = numpy.asarray(Bt.reshape(inner_shape, -1), order='C')

        return dot(At, Bt).reshape(shapeCt, order='A').transpose(new_orderCt)
Example #56
0
def get_dtypes(*args):
    return [canonicalize_dtype(onp.result_type(arg)) for arg in args]
Example #57
0
def result_type(*args):
    args = [a if is_scalar_for_elemwise(a) else a.dtype for a in args]
    return np.result_type(*args)
Example #58
0
    def dot(self, v, work_array=None, overwrite_v=False, tol=None):
        """Calculates the action of :math:`\\mathrm{e}^{aA}` on a vector :math:`v`. 

        Examples
        --------

        .. literalinclude:: ../../doc_examples/expm_multiply_parallel-example.py
            :linenos:
            :language: python
            :lines: 37-

        Parameters
        -----------
        v : contiguous numpy.ndarray, 1d or 2d array
            array to apply :math:`\\mathrm{e}^{aA}` on.
        work_array : contiguous numpy.ndarray, optional
            array can be any shape but must contain 2*v.size contiguous elements. 
            This array is used as temporary memory space for the underlying c-code. This saves extra memory allocation for function operations.
        overwrite_v : bool, optoinal
            if set to `True`, the data in `v` is overwritten by the function. This saves extra memory allocation for the results.
        tol: float, optoinal
            tolerance value used to truncate Taylor expansion of matrix exponential. 

        Returns
        --------
        numpy.ndarray
            result of :math:`\\mathrm{e}^{aA}v`. 

            If `overwrite_v = True` the dunction returns `v` with the data overwritten, otherwise the result is stored in a new array.  

        """
        v = _np.asarray(v)

        if v.ndim > 2:
            raise ValueError("array must have ndim <= 2.")

        if v.shape[0] != self._A.shape[1]:
            raise ValueError("dimension mismatch {}, {}".format(
                self._A.shape, v.shape))

        v_dtype = _np.result_type(self._dtype, v.dtype)

        if overwrite_v:
            if v_dtype != v.dtype:
                raise ValueError(
                    "if overwrite_v is True, the input array must match correct output dtype for matrix multiplication."
                )

            if not v.flags["CARRAY"]:
                raise TypeError("input array must a contiguous and writable.")

        else:
            v = v.astype(v_dtype, order="C", copy=True)

        if work_array is None:
            if v.ndim == 1:
                work_array = _np.zeros((2 * self._A.shape[0], ), dtype=v.dtype)
            else:
                work_array = _np.zeros((2 * self._A.shape[0], v.shape[1]),
                                       dtype=v.dtype)
        else:
            work_array = work_array.ravel(order="A")

            if work_array.size != 2 * v.size:
                raise ValueError(
                    "work_array must have twice the number of elements as in v."
                )

            if work_array.dtype != v_dtype:
                raise ValueError(
                    "work_array must be array of dtype which matches the result of the matrix-vector multiplication."
                )

        a = _np.array(self._a, dtype=v_dtype)
        mu = _np.array(self._mu, dtype=v_dtype)
        if tol is not None:
            tol = _np.array(tol, dtype=mu.real.dtype)
        else:
            tol = _np.array(self._tol, dtype=mu.real.dtype)
        if v.ndim == 1:
            _wrapper_expm_multiply(self._A.indptr, self._A.indices,
                                   self._A.data, self._s, self._m_star, a, tol,
                                   mu, v, work_array.ravel())
        else:
            work_array = work_array.reshape((-1, v.shape[1]))
            _wrapper_expm_multiply_batch(self._A.indptr, self._A.indices,
                                         self._A.data, self._s, self._m_star,
                                         a, tol, mu, v, work_array)

        return v
Example #59
0
def zeros_like_array(x):
  dtype = xla_bridge.canonicalize_dtype(onp.result_type(x))
  return onp.broadcast_to(onp.array(0, dtype), onp.shape(x))
Example #60
0
def _spectral_helper(x, y, fs=1.0, window='hann', nperseg=None, noverlap=None,
                     nfft=None, detrend='constant', return_onesided=True,
                     scaling='spectrum', axis=-1, mode='psd', boundary=None,
                     padded=False):
    """ Calculate various forms of windowed FFTs for PSD, CSD, etc.  """
    if mode not in ['psd', 'stft']:
        raise ValueError("Unknown value for mode %s, must be one of: "
                         "{'psd', 'stft'}" % mode)
    




    boundary_funcs = {'even': even_ext,
                      'odd': odd_ext,
                      'constant': const_ext,
                      'zeros': zero_ext,
                      None: None}

    if boundary not in boundary_funcs:
        raise ValueError("Unknown boundary option '{0}', must be one of: {1}"
                          .format(boundary, list(boundary_funcs.keys())))

    # If x and y are the same object we can save ourselves some computation.
    same_data = y is x

    if not same_data and mode != 'psd':
        raise ValueError("x and y must be equal if mode is 'stft'")

    axis = int(axis)

    # Ensure we have np.arrays, get outdtype
    x = np.asarray(x)
    if not same_data:
        y = np.asarray(y)
        outdtype = np.result_type(x, y, np.complex64)
    else:
        outdtype = np.result_type(x, np.complex64)

    if not same_data:
        # Check if we can broadcast the outer axes together
        xouter = list(x.shape)
        youter = list(y.shape)
        xouter.pop(axis)
        youter.pop(axis)
        try:
            outershape = np.broadcast(np.empty(xouter), np.empty(youter)).shape
        except ValueError:
            raise ValueError('x and y cannot be broadcast together.')

    if same_data:
        if x.size == 0:
            return np.empty(x.shape), np.empty(x.shape), np.empty(x.shape)
    else:
        if x.size == 0 or y.size == 0:
            outshape = outershape + (min([x.shape[axis], y.shape[axis]]),)
            emptyout = np.rollaxis(np.empty(outshape), -1, axis)
            return emptyout, emptyout, emptyout

    if x.ndim > 1:
        if axis != -1:
            x = np.rollaxis(x, axis, len(x.shape))
            if not same_data and y.ndim > 1:
                y = np.rollaxis(y, axis, len(y.shape))

    # Check if x and y are the same length, zero-pad if necessary
    if not same_data:
        if x.shape[-1] != y.shape[-1]:
            if x.shape[-1] < y.shape[-1]:
                pad_shape = list(x.shape)
                pad_shape[-1] = y.shape[-1] - x.shape[-1]
                x = np.concatenate((x, np.zeros(pad_shape)), -1)
            else:
                pad_shape = list(y.shape)
                pad_shape[-1] = x.shape[-1] - y.shape[-1]
                y = np.concatenate((y, np.zeros(pad_shape)), -1)

    if nperseg is not None:  # if specified by user
        nperseg = int(nperseg)
        if nperseg < 1:
            raise ValueError('nperseg must be a positive integer')

    # parse window; if array like, then set nperseg = win.shape
    win, nperseg = _triage_segments(window, nperseg,input_length=x.shape[-1])

    if nfft is None:
        nfft = nperseg
    elif nfft < nperseg:
        raise ValueError('nfft must be greater than or equal to nperseg.')
    else:
        nfft = int(nfft)

    if noverlap is None:
        noverlap = nperseg//2
    else:
        noverlap = int(noverlap)
    if noverlap >= nperseg:
        raise ValueError('noverlap must be less than nperseg.')
    nstep = nperseg - noverlap

    # Padding occurs after boundary extension, so that the extended signal ends
    # in zeros, instead of introducing an impulse at the end.
    # I.e. if x = [..., 3, 2]
    # extend then pad -> [..., 3, 2, 2, 3, 0, 0, 0]
    # pad then extend -> [..., 3, 2, 0, 0, 0, 2, 3]

    if boundary is not None:
        ext_func = boundary_funcs[boundary]
        x = ext_func(x, nperseg//2, axis=-1)
        if not same_data:
            y = ext_func(y, nperseg//2, axis=-1)

    if padded:
        # Pad to integer number of windowed segments
        # I.e make x.shape[-1] = nperseg + (nseg-1)*nstep, with integer nseg
        nadd = (-(x.shape[-1]-nperseg) % nstep) % nperseg
        zeros_shape = list(x.shape[:-1]) + [nadd]
        x = np.concatenate((x, np.zeros(zeros_shape)), axis=-1)
        if not same_data:
            zeros_shape = list(y.shape[:-1]) + [nadd]
            y = np.concatenate((y, np.zeros(zeros_shape)), axis=-1)

    # Handle detrending and window functions
    if not detrend:
        def detrend_func(d):
            return d
    elif not hasattr(detrend, '__call__'):
        def detrend_func(d):
            return signaltools_detrend(d, type=detrend, axis=-1)
    elif axis != -1:
        # Wrap this function so that it receives a shape that it could
        # reasonably expect to receive.
        def detrend_func(d):
            d = np.rollaxis(d, -1, axis)
            d = detrend(d)
            return np.rollaxis(d, axis, len(d.shape))
    else:
        detrend_func = detrend

    if np.result_type(win,np.complex64) != outdtype:
        win = win.astype(outdtype)

    if scaling == 'density':
        scale = 1.0 / (fs * (win*win).sum())
    elif scaling == 'spectrum':
        scale = 1.0 / win.sum()**2
    else:
        raise ValueError('Unknown scaling: %r' % scaling)

    if mode == 'stft':
        scale = np.sqrt(scale)

    if return_onesided:
        if np.iscomplexobj(x):
            sides = 'twosided'
            #warnings.warn('Input data is complex, switching to ' 'return_onesided=False')
        else:
            sides = 'onesided'
            if not same_data:
                if np.iscomplexobj(y):
                    sides = 'twosided'
                    #warnings.warn('Input data is complex, switching to return_onesided=False')
    else:
        sides = 'twosided'

    if sides == 'twosided':
        raise Exception('NOT IMPLEMENTED')
         #freqs = fftpack.fftfreq(nfft, 1/fs)
    elif sides == 'onesided':
        freqs = np.fft.rfftfreq(nfft, 1/fs)

    # Perform the windowed FFTs
    result = _fft_helper(x, win, detrend_func, nperseg, noverlap, nfft, sides)

    if not same_data:
        # All the same operations on the y data
        result_y = _fft_helper(y, win, detrend_func, nperseg, noverlap, nfft,
                               sides)
        result = np.conjugate(result) * result_y
    elif mode == 'psd':
        result = np.conjugate(result) * result

    result *= scale
    if sides == 'onesided' and mode == 'psd':
        if nfft % 2:
            result[..., 1:] *= 2
        else:
            # Last point is unpaired Nyquist freq point, don't double
            result[..., 1:-1] *= 2

    time = np.arange(nperseg/2, x.shape[-1] - nperseg/2 + 1,
                     nperseg - noverlap)/float(fs)
    if boundary is not None:
        time -= (nperseg/2) / fs

    result = result.astype(outdtype)

    # All imaginary parts are zero anyways
    if same_data and mode != 'stft':
        result = result.real

    # Output is going to have new last axis for time/window index, so a
    # negative axis index shifts down one
    if axis < 0:
        axis -= 1

    # Roll frequency axis back to axis where the data came from
    result = np.rollaxis(result, -1, axis)

    # TODO
    class InfoClass():
        pass
    Info = InfoClass();
    Info.df=freqs[1]-freqs[0]
    Info.fMax=freqs[-1]
    Info.LFreq=len(freqs)
    Info.LSeg=nperseg
    Info.LWin=len(win)
    Info.LOvlp=noverlap
    Info.nFFT=nfft
    Info.nseg=-1
    #print('df:{:.3f} - fm:{:.2f} - nseg:{} - Lf:{:5d} - Lseg:{:5d} - Lwin:{:5d} - Lovlp:{:5d} - Nfft:{:5d} - Lsig:{}'.format(freqs[1]-freqs[0],freqs[-1],-1,len(freqs),nperseg,len(win),noverlap,nfft,x.shape[-1]))
    return freqs, time, result, Info