284 lines
8.1 KiB
Cython
284 lines
8.1 KiB
Cython
#cython: language_level=3
|
|
#cython: c_string_type=str
|
|
#cython: c_string_encoding=ascii
|
|
#cython: boundscheck=False
|
|
#cython: wrapparound=False
|
|
#cython: cdivision=True
|
|
#cython: embedsignature=True
|
|
|
|
from libcpp.memory cimport shared_ptr, make_shared, dynamic_pointer_cast
|
|
from libcpp.string cimport string
|
|
from libcpp cimport bool
|
|
from cython.operator cimport dereference as deref
|
|
from range cimport cpp_RangeBase
|
|
from range_factory cimport cpp_RangeFactoryBase, cpp_CRangeFactory
|
|
from array cimport cpp_CArrayBase, cpp_MArray, cpp_AIndex
|
|
from index cimport cpp_DIndex
|
|
from cereal cimport cpp_writeJSONFile, cpp_writeBINARYFile, cpp_readJSONFile, cpp_readBINARYFile
|
|
|
|
|
|
## ============
|
|
## Range
|
|
## ============
|
|
|
|
cdef class Range:
|
|
cdef shared_ptr[cpp_RangeBase] cpp_range
|
|
|
|
def size(self):
|
|
return self.cpp_range.get().size()
|
|
|
|
def dim(self):
|
|
return self.cpp_range.get().dim()
|
|
|
|
def sub(self):
|
|
return getSubRange(self)
|
|
|
|
def index(self):
|
|
return getRangeIndex(self)
|
|
|
|
|
|
cdef class RangeFactory:
|
|
cdef shared_ptr[cpp_RangeFactoryBase] cpp_rfactory
|
|
|
|
def __cinit__(self,rangetype,**kvargs):
|
|
cdef size_t size = 0
|
|
if rangetype == 'C':
|
|
size = kvargs['size']
|
|
self.cpp_rfactory = dynamic_pointer_cast[cpp_RangeFactoryBase,cpp_CRangeFactory](
|
|
make_shared[cpp_CRangeFactory](size))
|
|
else:
|
|
raise Exception('unknown range type:'+ rangetype)
|
|
|
|
def create(self):
|
|
r = Range()
|
|
r.cpp_range = self.cpp_rfactory.get().create()
|
|
return r
|
|
|
|
|
|
## ===========
|
|
## Index
|
|
## ===========
|
|
|
|
cdef class Index:
|
|
|
|
def __iter__(self):
|
|
return self
|
|
|
|
def __next__(self):
|
|
return self
|
|
|
|
def lex(self):
|
|
return 0
|
|
|
|
def dim(self):
|
|
return 0
|
|
|
|
def stringMeta(self):
|
|
return ''
|
|
|
|
|
|
cdef class DIndex (Index):
|
|
cdef shared_ptr[cpp_DIndex] cpp_index
|
|
cdef bool itercall
|
|
|
|
def __cinit__(self,_range,_lexpos=0):
|
|
cdef Range r = _range
|
|
cdef size_t l = _lexpos
|
|
self.cpp_index = make_shared[cpp_DIndex] (r.cpp_range,l)
|
|
self.itercall = False
|
|
|
|
def __iter__(self):
|
|
self.cpp_index.get().setlpos(0)
|
|
self.itercall = True # otherwise first (i.e. zeroth) will be excluded
|
|
return self
|
|
|
|
def __next__(self):
|
|
cdef DIndex ret = self
|
|
if self.itercall:
|
|
ret.itercall = False
|
|
return ret
|
|
if self.lex() < self.cpp_index.get().range().get().size()-1:
|
|
ret.cpp_index = make_shared[cpp_DIndex] (self.cpp_index.get().plus(1))
|
|
return ret
|
|
else:
|
|
raise StopIteration
|
|
|
|
def lex(self):
|
|
return self.cpp_index.get().lex()
|
|
|
|
def dim(self):
|
|
return self.cpp_index.get().dim()
|
|
|
|
def stringMeta(self):
|
|
return self.cpp_index.get().stringMeta()
|
|
|
|
def getRangeIndex(_range):
|
|
return DIndex(_range)
|
|
|
|
|
|
## ===========
|
|
## Array
|
|
## ===========
|
|
|
|
cdef class Array:
|
|
|
|
def size(self):
|
|
return 0
|
|
|
|
def range(self):
|
|
cdef Range r = Range()
|
|
return r
|
|
|
|
|
|
cdef class Array_Double (Array):
|
|
cdef shared_ptr[cpp_CArrayBase[double]] cpp_array
|
|
|
|
def __cinit__(self,_range=None):
|
|
cdef Range r
|
|
if not _range is None:
|
|
r = _range
|
|
self.cpp_array = dynamic_pointer_cast[cpp_CArrayBase[double],cpp_MArray[double]] (make_shared[cpp_MArray[double]] (r.cpp_range) )
|
|
|
|
def size(self):
|
|
return self.cpp_array.get().size()
|
|
|
|
def range(self):
|
|
cdef Range r = Range()
|
|
r.cpp_range = self.cpp_array.get().range()
|
|
return r
|
|
|
|
def index(self):
|
|
return AIndex_Double(self)
|
|
|
|
cdef class Array_Range (Array):
|
|
cdef shared_ptr[cpp_CArrayBase[shared_ptr[cpp_RangeBase]]] cpp_array
|
|
|
|
def __cinit__(self,_range=None):
|
|
cdef Range r
|
|
if not _range is None:
|
|
r = _range
|
|
self.cpp_array = dynamic_pointer_cast[cpp_CArrayBase[shared_ptr[cpp_RangeBase]],cpp_MArray[shared_ptr[cpp_RangeBase]]] (make_shared[cpp_MArray[shared_ptr[cpp_RangeBase]]] (r.cpp_range) )
|
|
|
|
def size(self):
|
|
return self.cpp_array.get().size()
|
|
|
|
def range(self):
|
|
cdef Range r = Range()
|
|
r.cpp_range = self.cpp_array.get().range()
|
|
return r
|
|
|
|
def index(self):
|
|
return AIndex_Range(self)
|
|
|
|
|
|
def getSubRange(_range):
|
|
cdef Range r = _range
|
|
cdef Array_Range a = Array_Range()
|
|
a.cpp_array = dynamic_pointer_cast[cpp_CArrayBase[shared_ptr[cpp_RangeBase]],cpp_MArray[shared_ptr[cpp_RangeBase]]] (make_shared[cpp_MArray[shared_ptr[cpp_RangeBase]]] (r.cpp_range.get().sub()) )
|
|
return a
|
|
|
|
def writeFile(_fname,_array,_format):
|
|
cdef Array_Double a = _array
|
|
cdef shared_ptr[cpp_MArray[double]] ap = dynamic_pointer_cast[cpp_MArray[double],cpp_CArrayBase[double]](a.cpp_array)
|
|
if _format.upper() == "JSON":
|
|
cpp_writeJSONFile[double](_fname, deref(ap.get()))
|
|
elif _format.upper() == "BINARY":
|
|
cpp_writeBINARYFile[double](_fname, deref(ap.get()))
|
|
else:
|
|
raise Exception("unknown array file format '{}'".format(_format))
|
|
|
|
def readFile(_fname,_format):
|
|
cdef Array_Double a = Array_Double()
|
|
cdef shared_ptr[cpp_MArray[double]] ap = make_shared[cpp_MArray[double]]()
|
|
a.cpp_array = dynamic_pointer_cast[cpp_CArrayBase[double],cpp_MArray[double]](ap)
|
|
if _format.upper() == "JSON":
|
|
cpp_readJSONFile[double](_fname, deref(ap.get()))
|
|
elif _format.upper() == "BINARY":
|
|
cpp_readBINARYFile[double](_fname, deref(ap.get()))
|
|
else:
|
|
raise Exception("unknown array file format '{}'".format(_format))
|
|
return a
|
|
|
|
|
|
cdef class AIndex_Double (Index):
|
|
cdef shared_ptr[cpp_CArrayBase[double]] cpp_array # keep the instance alive
|
|
cdef shared_ptr[cpp_AIndex[double]] cpp_index
|
|
cdef bool itercall
|
|
|
|
def __cinit__(self,_array,_lexpos=0):
|
|
cdef size_t l = _lexpos
|
|
cdef Array_Double a = _array
|
|
self.cpp_array = a.cpp_array
|
|
self.cpp_index = make_shared[cpp_AIndex[double]] (a.cpp_array.get().begin().A_plus(l))
|
|
self.itercall = False
|
|
|
|
def __iter__(self):
|
|
self.cpp_index.get().setlpos(0)
|
|
self.itercall = True # otherwise first (i.e. zeroth) will be excluded
|
|
return self
|
|
|
|
def __next__(self):
|
|
cdef AIndex_Double ret = self
|
|
if self.itercall:
|
|
ret.itercall = False
|
|
return ret
|
|
if self.lex() < self.cpp_index.get().range().get().size()-1:
|
|
ret.cpp_index = make_shared[cpp_AIndex[double]] (self.cpp_index.get().A_plus(1))
|
|
return ret
|
|
else:
|
|
raise StopIteration
|
|
|
|
def lex(self):
|
|
return self.cpp_index.get().lex()
|
|
|
|
def dim(self):
|
|
return self.cpp_index.get().dim()
|
|
|
|
def stringMeta(self):
|
|
return self.cpp_index.get().stringMeta()
|
|
|
|
def get(self):
|
|
return self.cpp_index.get().A_get()
|
|
|
|
|
|
cdef class AIndex_Range (Index):
|
|
cdef shared_ptr[cpp_CArrayBase[shared_ptr[cpp_RangeBase]]] cpp_array # keep the instance alive
|
|
cdef shared_ptr[cpp_AIndex[shared_ptr[cpp_RangeBase]]] cpp_index
|
|
cdef bool itercall
|
|
|
|
def __cinit__(self,_array,_lexpos=0):
|
|
cdef size_t l = _lexpos
|
|
cdef Array_Range a = _array
|
|
self.cpp_array = a.cpp_array
|
|
self.cpp_index = make_shared[cpp_AIndex[shared_ptr[cpp_RangeBase]]] (a.cpp_array.get().begin().A_plus(l))
|
|
self.itercall = False
|
|
|
|
def __iter__(self):
|
|
self.cpp_index.get().setlpos(0)
|
|
self.itercall = True # otherwise first (i.e. zeroth) will be excluded
|
|
return self
|
|
|
|
def __next__(self):
|
|
cdef AIndex_Range ret = self
|
|
if self.itercall:
|
|
ret.itercall = False
|
|
return ret
|
|
if self.lex() < self.cpp_index.get().range().get().size()-1:
|
|
ret.cpp_index = make_shared[cpp_AIndex[shared_ptr[cpp_RangeBase]]] (self.cpp_index.get().A_plus(1))
|
|
return ret
|
|
else:
|
|
raise StopIteration
|
|
|
|
def lex(self):
|
|
return self.cpp_index.get().lex()
|
|
|
|
def dim(self):
|
|
return self.cpp_index.get().dim()
|
|
|
|
def stringMeta(self):
|
|
return self.cpp_index.get().stringMeta()
|
|
|
|
def get(self):
|
|
cdef Range r = Range()
|
|
r.cpp_range = self.cpp_index.get().A_get()
|
|
return r
|