def prep_simple(simple_type, dtype): """Given a ctypes simple type, construct and attach an __array_interface__ property to it if it does not yet have one. """ try: simple_type.__array_interface__ except AttributeError: pass else: return typestr = _dtype(dtype).str _typecodes[typestr] = simple_type def __array_interface__(self): return { "descr": [("", typestr)], "__ref": self, "strides": None, "shape": (), "version": 3, "typestr": typestr, "data": (ct.addressof(self), False), } simple_type.__array_interface__ = property(__array_interface__)
def op_t_pz(opstr,indx,J,dtype,pauli,N,m,basis,L,**blocks): a=blocks.get("a") kblock=blocks.get("kblock") pzblock=blocks.get("pzblock") char = _dtype(dtype).char compiled_op = basis_ops.__dict__[char+"_t_pz_op"] col,ME,error = compiled_op(N,m,basis,opstr,indx,J,L,pzblock,kblock,a) if error != 0: raise OpstrError(_basis_op_errors[error]) row=_np.arange(len(basis),dtype=_index_type) row=_np.concatenate((row,row)) mask = col >= 0 row = row[ mask ] col = col[ mask ] ME = ME[ mask ] # print col,ME if not pauli: Nop = len(opstr.replace("I","")) ME /= 2.0**(Nop) return ME,row,col
def as_ctypes_type(dtype): """ Convert a dtype into a ctypes type. Parameters ---------- dtype : dtype The dtype to convert Returns ------- ctypes A ctype scalar, union, array, or struct Raises ------ NotImplementedError If the conversion is not possible Notes ----- This function does not losslessly round-trip in either direction. ``np.dtype(as_ctypes_type(dt))`` will: - insert padding fields - reorder fields to be sorted by offset - discard field titles ``as_ctypes_type(np.dtype(ctype))`` will: - discard the class names of ``Structure``s and ``Union``s - convert single-element ``Union``s into single-element ``Structure``s - insert padding fields """ return _ctype_from_dtype(_dtype(dtype))
def op_t_p_z(opstr,indx,J,dtype,N,m,basis,L,**blocks): a=blocks.get("a") kblock=blocks.get("kblock") pblock=blocks.get("pblock") zblock=blocks.get("zblock") pauli=blocks.get("pauli") char = _dtype(dtype).char compiled_op = basis_ops.__dict__[char+"_t_p_z_op"] row,ME,error = compiled_op(N,m,basis,opstr,indx,J,L,pblock,zblock,kblock,a) if error != 0: raise OpstrError(_basis_op_errors[error]) col = _np.arange(len(basis),dtype=_index_type) col=_np.concatenate((col,col)) mask = row >= 0 col = col[ mask ] row = row[ mask ] ME = ME[ mask ] if not pauli: Nop = len(opstr.replace("I","")) ME /= 2.0**(Nop) return ME,row,col
def op(opstr,indx,J,dtype,basis,**blocks): char = _dtype(dtype).char compiled_op = basis_ops.__dict__[char+"_spinop"] pauli = blocks.get('pauli') # row: resilting basis states; -1: state is thrown out (cf FindZState) # ME: array of dtype with matrix elements # error: see line 11 above row,ME,error = compiled_op(basis,opstr,indx,J) if error != 0: raise OpstrError(_basis_op_errors[error]) col = _np.arange(len(basis),dtype=_index_type) mask = row >= 0 col = col[ mask ] row = row[ mask ] ME = ME[ mask ] if not pauli: Nop = len(opstr.replace("I","")) ME /= 2.0**(Nop) return ME,row,col
def contents(self): """ Get an ndarray viewing the data pointed to by this pointer. This mirrors the `contents` attribute of a normal ctypes pointer """ full_dtype = _dtype((self._dtype_, self._shape_)) full_ctype = ctypes.c_char * full_dtype.itemsize buffer = ctypes.cast(self, ctypes.POINTER(full_ctype)).contents return frombuffer(buffer, dtype=full_dtype).squeeze(axis=0)
def _get_typecodes(): """ Return a dictionary mapping __array_interface__ formats to ctypes types """ ct = ctypes simple_types = [ ct.c_byte, ct.c_short, ct.c_int, ct.c_long, ct.c_longlong, ct.c_ubyte, ct.c_ushort, ct.c_uint, ct.c_ulong, ct.c_ulonglong, ct.c_float, ct.c_double, ] return {_dtype(ctype).str: ctype for ctype in simple_types}
def _get_scalar_type_map(): """ Return a dictionary mapping native endian scalar dtype to ctypes types """ ct = ctypes simple_types = [ ct.c_byte, ct.c_short, ct.c_int, ct.c_long, ct.c_longlong, ct.c_ubyte, ct.c_ushort, ct.c_uint, ct.c_ulong, ct.c_ulonglong, ct.c_float, ct.c_double, ct.c_bool, ] return {_dtype(ctype): ctype for ctype in simple_types}
def as_ctypes(obj): """Create and return a ctypes object from a numpy array. Actually anything that exposes the __array_interface__ is accepted.""" ai = obj.__array_interface__ if ai["strides"]: raise TypeError("strided arrays not supported") if ai["version"] != 3: raise TypeError("only __array_interface__ version 3 supported") addr, readonly = ai["data"] if readonly: raise TypeError("readonly arrays unsupported") dtype = _dtype((ai["typestr"], ai["shape"])) result = as_ctypes_type(dtype).from_address(addr) result.__keep = obj return result
def prep_pointer(pointer_obj, shape): """Given a ctypes pointer object, construct and attach an __array_interface__ property to it if it does not yet have one. """ try: pointer_obj.__array_interface__ except AttributeError: pass else: return contents = pointer_obj.contents dtype = _dtype(type(contents)) inter = {'version': 3, 'typestr': dtype.str, 'data': (ct.addressof(contents), False), 'shape': shape} pointer_obj.__array_interface__ = inter
def op_m(opstr,indx,J,dtype,pauli,basis,**blocks): char = _dtype(dtype).char compiled_op = basis_ops.__dict__[char+"_m_op"] col,ME,error = compiled_op(basis,opstr,indx,J) if error != 0: raise OpstrError(_basis_op_errors[error]) row=_np.arange(len(basis),dtype=_index_type) mask = col >= 0 row = row[ mask ] col = col[ mask ] ME = ME[ mask ] if not pauli: Nop = len(opstr.replace("I","")) ME /= 2.0**(Nop) return ME,row,col
def prep_simple(simple_type, dtype): """Given a ctypes simple type, construct and attach an __array_interface__ property to it if it does not yet have one. """ try: simple_type.__array_interface__ except AttributeError: pass else: return typestr = _dtype(dtype).str _typecodes[typestr] = simple_type def __array_interface__(self): return {'descr': [('', typestr)], '__ref': self, 'strides': None, 'shape': (), 'version': 3, 'typestr': typestr, 'data': (ct.addressof(self), False), } simple_type.__array_interface__ = property(__array_interface__)
def op_pz(opstr,indx,J,dtype,N,basis,L,**blocks): pzblock=blocks.get("pzblock") pauli=blocks.get("pauli") char = _dtype(dtype).char compiled_op = basis_ops.__dict__[char+"_pz_op"] row,ME,error = compiled_op(N,basis,opstr,indx,J,L,pzblock) if error != 0: raise OpstrError(_basis_op_errors[error]) col = _np.arange(len(basis),dtype=_index_type) mask = row >= 0 col = col[ mask ] row = row[ mask ] ME = ME[ mask ] if not pauli: Nop = len(opstr.replace("I","")) ME /= 2.0**(Nop) return ME,row,col
def ndpointer(dtype=None, ndim=None, shape=None, flags=None): """ Array-checking restype/argtypes. An ndpointer instance is used to describe an ndarray in restypes and argtypes specifications. This approach is more flexible than using, for example, ``POINTER(c_double)``, since several restrictions can be specified, which are verified upon calling the ctypes function. These include data type, number of dimensions, shape and flags. If a given array does not satisfy the specified restrictions, a ``TypeError`` is raised. Parameters ---------- dtype : data-type, optional Array data-type. ndim : int, optional Number of array dimensions. shape : tuple of ints, optional Array shape. flags : str or tuple of str Array flags; may be one or more of: - C_CONTIGUOUS / C / CONTIGUOUS - F_CONTIGUOUS / F / FORTRAN - OWNDATA / O - WRITEABLE / W - ALIGNED / A - UPDATEIFCOPY / U Returns ------- klass : ndpointer type object A type object, which is an ``_ndtpr`` instance containing dtype, ndim, shape and flags information. Raises ------ TypeError If a given array does not satisfy the specified restrictions. Examples -------- >>> clib.somefunc.argtypes = [np.ctypeslib.ndpointer(dtype=np.float64, ... ndim=1, ... flags='C_CONTIGUOUS')] >>> clib.somefunc(np.array([1, 2, 3], dtype=np.float64)) """ if dtype is not None: dtype = _dtype(dtype) num = None if flags is not None: if isinstance(flags, str): flags = flags.split(',') elif isinstance(flags, (int, integer)): num = flags flags = _flags_fromnum(num) elif isinstance(flags, flagsobj): num = flags.num flags = _flags_fromnum(num) if num is None: try: flags = [x.strip().upper() for x in flags] except: raise TypeError, "invalid flags specification" num = _num_fromflags(flags) try: return _pointer_type_cache[(dtype, ndim, shape, num)] except KeyError: pass if dtype is None: name = 'any' elif dtype.names: name = str(id(dtype)) else: name = dtype.str if ndim is not None: name += "_%dd" % ndim if shape is not None: try: strshape = [str(x) for x in shape] except TypeError: strshape = [str(shape)] shape = (shape,) shape = tuple(shape) name += "_"+"x".join(strshape) if flags is not None: name += "_"+"_".join(flags) else: flags = [] klass = type("ndpointer_%s"%name, (_ndptr,), {"_dtype_": dtype, "_shape_" : shape, "_ndim_" : ndim, "_flags_" : num}) _pointer_type_cache[dtype] = klass return klass
def ndpointer(dtype=None, ndim=None, shape=None, flags=None): """Array-checking restype/argtypes. An ndpointer instance is used to describe an ndarray in restypes and argtypes specifications. This approach is more flexible than using, for example, POINTER(c_double) since several restrictions can be specified, which are verified upon calling the ctypes function. These include data type (dtype), number of dimensions (ndim), shape and flags (e.g. 'C_CONTIGUOUS' or 'F_CONTIGUOUS'). If a given array does not satisfy the specified restrictions, a TypeError is raised. Example: clib.somefunc.argtypes = [ndpointer(dtype=float64, ndim=1, flags='C_CONTIGUOUS')] clib.somefunc(array([1,2,3],dtype=float64)) """ if dtype is not None: dtype = _dtype(dtype) num = None if flags is not None: if isinstance(flags, str): flags = flags.split(',') elif isinstance(flags, (int, integer)): num = flags flags = _flags_fromnum(num) elif isinstance(flags, flagsobj): num = flags.num flags = _flags_fromnum(num) if num is None: try: flags = [x.strip().upper() for x in flags] except: raise TypeError, "invalid flags specification" num = _num_fromflags(flags) try: return _pointer_type_cache[(dtype, ndim, shape, num)] except KeyError: pass if dtype is None: name = 'any' elif dtype.names: name = str(id(dtype)) else: name = dtype.str if ndim is not None: name += "_%dd" % ndim if shape is not None: try: strshape = [str(x) for x in shape] except TypeError: strshape = [str(shape)] shape = (shape,) shape = tuple(shape) name += "_"+"x".join(strshape) if flags is not None: name += "_"+"_".join(flags) else: flags = [] klass = type("ndpointer_%s"%name, (_ndptr,), {"_dtype_": dtype, "_shape_" : shape, "_ndim_" : ndim, "_flags_" : num}) _pointer_type_cache[dtype] = klass return klass
def ndpointer(dtype=None, ndim=None, shape=None, flags=None): """ Array-checking restype/argtypes. An ndpointer instance is used to describe an ndarray in restypes and argtypes specifications. This approach is more flexible than using, for example, ``POINTER(c_double)``, since several restrictions can be specified, which are verified upon calling the ctypes function. These include data type, number of dimensions, shape and flags. If a given array does not satisfy the specified restrictions, a ``TypeError`` is raised. Parameters ---------- dtype : data-type, optional Array data-type. ndim : int, optional Number of array dimensions. shape : tuple of ints, optional Array shape. flags : str or tuple of str Array flags; may be one or more of: - C_CONTIGUOUS / C / CONTIGUOUS - F_CONTIGUOUS / F / FORTRAN - OWNDATA / O - WRITEABLE / W - ALIGNED / A - WRITEBACKIFCOPY / X - UPDATEIFCOPY / U Returns ------- klass : ndpointer type object A type object, which is an ``_ndtpr`` instance containing dtype, ndim, shape and flags information. Raises ------ TypeError If a given array does not satisfy the specified restrictions. Examples -------- >>> clib.somefunc.argtypes = [np.ctypeslib.ndpointer(dtype=np.float64, ... ndim=1, ... flags='C_CONTIGUOUS')] ... #doctest: +SKIP >>> clib.somefunc(np.array([1, 2, 3], dtype=np.float64)) ... #doctest: +SKIP """ # normalize dtype to an Optional[dtype] if dtype is not None: dtype = _dtype(dtype) # normalize flags to an Optional[int] num = None if flags is not None: if isinstance(flags, str): flags = flags.split(',') elif isinstance(flags, (int, integer)): num = flags flags = _flags_fromnum(num) elif isinstance(flags, flagsobj): num = flags.num flags = _flags_fromnum(num) if num is None: try: flags = [x.strip().upper() for x in flags] except Exception: raise TypeError("invalid flags specification") num = _num_fromflags(flags) # normalize shape to an Optional[tuple] if shape is not None: try: shape = tuple(shape) except TypeError: # single integer -> 1-tuple shape = (shape, ) cache_key = (dtype, ndim, shape, num) try: return _pointer_type_cache[cache_key] except KeyError: pass # produce a name for the new type if dtype is None: name = 'any' elif dtype.names is not None: name = str(id(dtype)) else: name = dtype.str if ndim is not None: name += "_%dd" % ndim if shape is not None: name += "_" + "x".join(str(x) for x in shape) if flags is not None: name += "_" + "_".join(flags) if dtype is not None and shape is not None: base = _concrete_ndptr else: base = _ndptr klass = type("ndpointer_%s" % name, (base, ), { "_dtype_": dtype, "_shape_": shape, "_ndim_": ndim, "_flags_": num }) _pointer_type_cache[cache_key] = klass return klass
def ndpointer(dtype=None, ndim=None, shape=None, flags=None): """ Array-checking restype/argtypes. An ndpointer instance is used to describe an ndarray in restypes and argtypes specifications. This approach is more flexible than using, for example, ``POINTER(c_double)``, since several restrictions can be specified, which are verified upon calling the ctypes function. These include data type, number of dimensions, shape and flags. If a given array does not satisfy the specified restrictions, a ``TypeError`` is raised. Parameters ---------- dtype : data-type, optional Array data-type. ndim : int, optional Number of array dimensions. shape : tuple of ints, optional Array shape. flags : string or tuple of strings Array flags; may be one or more of: - C_CONTIGUOUS / C / CONTIGUOUS - F_CONTIGUOUS / F / FORTRAN - OWNDATA / O - WRITEABLE / W - ALIGNED / A - UPDATEIFCOPY / U Examples -------- >>> clib.somefunc.argtypes = [np.ctypeslib.ndpointer(dtype=float64, ... ndim=1, ... flags='C_CONTIGUOUS')] >>> clib.somefunc(np.array([1, 2, 3], dtype=np.float64)) """ if dtype is not None: dtype = _dtype(dtype) num = None if flags is not None: if isinstance(flags, str): flags = flags.split(',') elif isinstance(flags, (int, integer)): num = flags flags = _flags_fromnum(num) elif isinstance(flags, flagsobj): num = flags.num flags = _flags_fromnum(num) if num is None: try: flags = [x.strip().upper() for x in flags] except: raise TypeError, "invalid flags specification" num = _num_fromflags(flags) try: return _pointer_type_cache[(dtype, ndim, shape, num)] except KeyError: pass if dtype is None: name = 'any' elif dtype.names: name = str(id(dtype)) else: name = dtype.str if ndim is not None: name += "_%dd" % ndim if shape is not None: try: strshape = [str(x) for x in shape] except TypeError: strshape = [str(shape)] shape = (shape, ) shape = tuple(shape) name += "_" + "x".join(strshape) if flags is not None: name += "_" + "_".join(flags) else: flags = [] klass = type("ndpointer_%s" % name, (_ndptr, ), { "_dtype_": dtype, "_shape_": shape, "_ndim_": ndim, "_flags_": num }) _pointer_type_cache[dtype] = klass return klass