def _correlate_kernel(Array, Filter, mode): # Anything to do? if Array.size <= 0: return Array.copy() # Complex correlate includes a conjugation if numpy.iscomplexobj(Filter): Filter = numpy.conj(Filter) # Get sizes as arrays for easier manipulation ArrSize = numpy.array(Array.shape, dtype=numpy.int32) FilterSize = numpy.array(Filter.shape, dtype=numpy.int32) # Check that mode='valid' is allowed given the array sizes if mode == 'valid': diffSize = ArrSize[:FilterSize.size] - FilterSize nSmaller = summations.sum(diffSize < 0) if nSmaller > 0: raise ValueError( "correlateNd: For 'valid' mode, one must be at least as large as the other in every dimension") # Use numpy convention for result dype dtype = numpy.result_type(Array, Filter) # Add zeros along relevant dimensions Padded = _addZerosNd(Array, FilterSize, dtype) PaddedSize = numpy.array(Padded.shape, dtype=numpy.int32) # Get positions of first view IndiVec = _findIndices(PaddedSize, FilterSize) CenterPos = tuple((FilterSize - 1) // 2) IndiMat = IndiVec.reshape(FilterSize, order='F') nPre = IndiMat[CenterPos] # Required zeros before Array for correct alignment nPost = IndiVec[Filter.size - 1] - nPre n = Padded.size nTot = n + nPre + nPost # Total size after pre/post padding V = array_create.empty([nTot], dtype=dtype, bohrium=bhary.check(Array)) V[nPre:n + nPre] = Padded.flatten(order='F') V[:nPre] = 0 V[n + nPre:] = 0 A = Filter.flatten(order='F') # Actual correlation calculation Correlated = V[IndiVec[0]:n + IndiVec[0]] * A[0] for i in range(1, Filter.size): Correlated += V[IndiVec[i]:n + IndiVec[i]] * A[i] # TODO: we need this flush because of very slow fusion if bhary.check(V): _bh.flush() Full = Correlated.reshape(PaddedSize, order='F') if mode == 'full': return Full elif mode == 'same': return _findSame(Full, FilterSize) elif mode == 'valid': return _findValid(Full, FilterSize) else: raise ValueError("correlateNd: invalid mode '%s'" % mode)
def _addZerosNd(Array, FilterSize, dtype): # Introduces zero padding for Column major flattening PaddedSize = numpy.array(Array.shape, dtype=numpy.int32) N = FilterSize.shape[0] PaddedSize[0:N] += FilterSize - 1 cut = '[' for i in range(PaddedSize.shape[0]): if i < N: minpos = int(FilterSize[i] / 2) maxpos = Array.shape[i] + int(FilterSize[i] / 2) else: minpos = 0 maxpos = Array.shape[i] cut += str(minpos) + ':' + str(maxpos) + ',' cut = cut[:-1] + ']' Padded = array_create.zeros(PaddedSize, dtype=dtype, bohrium=bhary.check(Array)) exec ('Padded' + cut + '=Array') return Padded
def _addZerosNd(Array, FilterSize, dtype): # Introduces zero padding for Column major flattening PaddedSize = numpy.array(Array.shape, dtype=numpy.int32) N = FilterSize.shape[0] PaddedSize[0:N] += FilterSize - 1 cut = '[' for i in range(PaddedSize.shape[0]): if i < N: minpos = int(FilterSize[i] / 2) maxpos = Array.shape[i] + int(FilterSize[i] / 2) else: minpos = 0 maxpos = Array.shape[i] cut += str(minpos) + ':' + str(maxpos) + ',' cut = cut[:-1] + ']' Padded = array_create.zeros(PaddedSize, dtype=dtype, bohrium=bhary.check(Array)) exec('Padded' + cut + '=Array') return Padded
def array(obj, dtype=None, copy=False, order=None, subok=False, ndmin=0, bohrium=True): """ Create an array -- Bohrium or NumPy ndarray. Parameters ---------- obj : array_like An array, any object exposing the array interface, an object whose __array__ method returns an array, or any (nested) sequence. dtype : data-type, optional The desired data-type for the array. If not given, then the type will be determined as the minimum type required to hold the objects in the sequence. This argument can only be used to 'upcast' the array. For downcasting, use the .astype(t) method. copy : bool, optional If true, then the object is copied. Otherwise, a copy will only be made if __array__ returns a copy, if obj is a nested sequence, or if a copy is needed to satisfy any of the other requirements (`dtype`, `order`, etc.). order : {'C', 'F', 'A'}, optional Specify the order of the array. If order is 'C' (default), then the array will be in C-contiguous order (last-index varies the fastest). If order is 'F', then the returned array will be in Fortran-contiguous order (first-index varies the fastest). If order is 'A', then the returned array may be in any order (either C-, Fortran-contiguous, or even discontiguous). subok : bool, optional If True, then sub-classes will be passed-through, otherwise the returned array will be forced to be a base-class array (default). ndmin : int, optional Specifies the minimum number of dimensions that the resulting array should have. Ones will be pre-pended to the shape as needed to meet this requirement. bohrium : boolean, optional Determines whether it is a Bohrium array (bohrium.ndarray) or a regular NumPy array (numpy.ndarray) Returns ------- out : ndarray An array object satisfying the specified requirements. See Also -------- empty, empty_like, zeros, zeros_like, ones, ones_like, fill Examples -------- >>> np.array([1, 2, 3]) array([1, 2, 3]) Upcasting: >>> np.array([1, 2, 3.0]) array([ 1., 2., 3.]) More than one dimension: >>> np.array([[1, 2], [3, 4]]) array([[1, 2], [3, 4]]) Minimum dimensions 2: >>> np.array([1, 2, 3], ndmin=2) array([[1, 2, 3]]) Type provided: >>> np.array([1, 2, 3], dtype=complex) array([ 1.+0.j, 2.+0.j, 3.+0.j]) Data-type consisting of more than one element: >>> x = np.array([(1,2),(3,4)],dtype=[('a','<i4'),('b','<i4')]) >>> x['a'] array([1, 3]) Creating an array from sub-classes: >>> np.array(np.mat('1 2; 3 4')) array([[1, 2], [3, 4]]) >>> np.array(np.mat('1 2; 3 4'), subok=True) matrix([[1, 2], [3, 4]]) """ ary = obj if bohrium: if bhary.check(ary): if order == 'F': raise ValueError("Cannot convert a Bohrium array to column-major ('F') memory representation") elif order == 'C' and not ary.flags['C_CONTIGUOUS']: copy = True # We need to copy in order to make the returned array contiguous if copy: t = empty_like(ary) t[...] = ary ary = t if dtype is not None and not dtype_equal(dtype, ary.dtype): t = empty_like(ary, dtype=dtype) t[...] = ary ary = t for i in range(ary.ndim, ndmin): ary = numpy.expand_dims(ary, i) return ary else: # Let's convert the array using regular NumPy. # When `ary` is not a regular NumPy array, we make sure that `ary` contains no Bohrium arrays if isinstance(ary, collections.Sequence) and \ not (isinstance(ary, numpy.ndarray) and ary.dtype.isbuiltin == 1): ary = list(ary) # Let's make sure that `ary` is mutable for i in range(len(ary)): # Converting 1-element Bohrium arrays to NumPy scalars if bhary.check(ary[i]): ary[i] = ary[i].copy2numpy() ary = numpy.array(ary, dtype=dtype, copy=copy, order=order, subok=subok, ndmin=ndmin, fix_biclass=False) # In any case, the array must meet some requirements ary = numpy.require(ary, requirements=['C_CONTIGUOUS', 'ALIGNED', 'OWNDATA']) if bohrium and not dtype_support(ary.dtype): _warn_dtype(ary.dtype, 3) return ary ret = empty(ary.shape, dtype=ary.dtype) if ret.size > 0: ret._data_fill(ary) return ret else: if bhary.check(ary): ret = ary.copy2numpy() return numpy.array(ret, dtype=dtype, copy=copy, order=order, subok=subok, ndmin=ndmin, fix_biclass=False) else: return numpy.array(ary, dtype=dtype, copy=copy, order=order, subok=subok, ndmin=ndmin, fix_biclass=False)
def _correlate_kernel(Array, Filter, mode): # Anything to do? if Array.size <= 0: return Array.copy() # Complex correlate includes a conjugation if numpy.iscomplexobj(Filter): Filter = numpy.conj(Filter) # Get sizes as arrays for easier manipulation ArrSize = numpy.array(Array.shape, dtype=numpy.int32) FilterSize = numpy.array(Filter.shape, dtype=numpy.int32) # Check that mode='valid' is allowed given the array sizes if mode == 'valid': diffSize = ArrSize[:FilterSize.size] - FilterSize nSmaller = summations.sum(diffSize < 0) if nSmaller > 0: raise ValueError( "correlateNd: For 'valid' mode, one must be at least as large as the other in every dimension" ) # Use numpy convention for result dype dtype = numpy.result_type(Array, Filter) # Add zeros along relevant dimensions Padded = _addZerosNd(Array, FilterSize, dtype) PaddedSize = numpy.array(Padded.shape, dtype=numpy.int32) # Get positions of first view IndiVec = _findIndices(PaddedSize, FilterSize) CenterPos = tuple((FilterSize - 1) // 2) IndiMat = IndiVec.reshape(FilterSize, order='F') nPre = IndiMat[ CenterPos] # Required zeros before Array for correct alignment nPost = IndiVec[Filter.size - 1] - nPre n = Padded.size nTot = n + nPre + nPost # Total size after pre/post padding V = array_create.empty([nTot], dtype=dtype, bohrium=bhary.check(Array)) V[nPre:n + nPre] = Padded.flatten(order='F') V[:nPre] = 0 V[n + nPre:] = 0 A = Filter.flatten(order='F') # Actual correlation calculation Correlated = V[IndiVec[0]:n + IndiVec[0]] * A[0] for i in range(1, Filter.size): Correlated += V[IndiVec[i]:n + IndiVec[i]] * A[i] # TODO: we need this flush because of very slow fusion if bhary.check(V): _util.flush() Full = Correlated.reshape(PaddedSize, order='F') if mode == 'full': return Full elif mode == 'same': return _findSame(Full, FilterSize) elif mode == 'valid': return _findValid(Full, FilterSize) else: raise ValueError("correlateNd: invalid mode '%s'" % mode)
def as_strided(x, shape=None, strides=None, subok=True, writeable=True): """ Create a view into the array with the given shape and strides. .. warning:: This function has to be used with extreme care, see notes. Parameters ---------- x : ndarray Array to create a new. shape : sequence of int, optional The shape of the new array. Defaults to ``x.shape``. strides : sequence of int, optional The strides of the new array. Defaults to ``x.strides``. subok : bool, optional .. versionadded:: 1.10 If True, subclasses are preserved. writeable : bool, optional .. versionadded:: 1.12 If set to False, the returned array will always be readonly. Otherwise it will be writable if the original array was. It is advisable to set this to False if possible (see Notes). Returns ------- view : ndarray See also -------- broadcast_to: broadcast an array to a given shape. reshape : reshape an array. Notes ----- ``as_strided`` creates a view into the array given the exact strides and shape. This means it manipulates the internal data structure of ndarray and, if done incorrectly, the array elements can point to invalid memory and can corrupt results or crash your program. It is advisable to always use the original ``x.strides`` when calculating new strides to avoid reliance on a contiguous memory layout. Furthermore, arrays created with this function often contain self overlapping memory, so that two elements are identical. Vectorized write operations on such arrays will typically be unpredictable. They may even give different results for small, large, or transposed arrays. Since writing to these arrays has to be tested and done with great care, you may want to use ``writeable=False`` to avoid accidental write operations. For these reasons it is advisable to avoid ``as_strided`` when possible. """ class DummyArray(object): """Dummy object that just exists to hang __array_interface__ dictionaries and possibly keep alive a reference to a base array. """ def __init__(self, interface, base=None): self.__array_interface__ = interface self.base = base def _maybe_view_as_subclass(original_array, new_array): if type(original_array) is not type(new_array): # if input was an ndarray subclass and subclasses were OK, # then view the result as that subclass. new_array = new_array.view(type=type(original_array)) # Since we have done something akin to a view from original_array, we # should let the subclass finalize (if it has it implemented, i.e., is # not None). if new_array.__array_finalize__: new_array.__array_finalize__(original_array) return new_array # first convert input to array, possibly keeping subclass x = numpy.array(x, copy=False, subok=subok) interface = dict(x.__array_interface__) if shape is not None: interface['shape'] = tuple(shape) if strides is not None: interface['strides'] = tuple(strides) array = numpy.asarray(DummyArray(interface, base=x)) # The route via `__interface__` does not preserve structured # dtypes. Since dtype should remain unchanged, we set it explicitly. array.dtype = x.dtype view = _maybe_view_as_subclass(x, array) if view.flags.writeable and not writeable: view.flags.writeable = False return view