diff options
| -rw-r--r-- | pyisda/credit_index.pxd | 4 | ||||
| -rw-r--r-- | pyisda/curve.pxd | 6 | ||||
| -rw-r--r-- | pyisda/curve.pyx | 41 |
3 files changed, 37 insertions, 14 deletions
diff --git a/pyisda/credit_index.pxd b/pyisda/credit_index.pxd index e52a33d..961130d 100644 --- a/pyisda/credit_index.pxd +++ b/pyisda/credit_index.pxd @@ -1,6 +1,6 @@ from legs cimport TContingentLeg, TFeeLeg from date cimport TDate -from curve cimport TCurve, TRatePt, shared_ptr +from curve cimport TCurve, TRatePt, shared_ptr, Carray from libcpp.vector cimport vector from libcpp.unordered_map cimport unordered_map from libcpp.string cimport string @@ -11,7 +11,7 @@ cdef class CurveList: cdef vector[double] T cdef vector[shared_ptr[TCurve]] curves cdef unordered_map[string, size_t] tickers - cdef vector[double[:]] recovery_rates + cdef vector[Carray] recovery_rates cdef class CreditIndex(CurveList): cdef TDate start_date diff --git a/pyisda/curve.pxd b/pyisda/curve.pxd index 49b1c1b..6432d40 100644 --- a/pyisda/curve.pxd +++ b/pyisda/curve.pxd @@ -197,9 +197,13 @@ cdef class Curve: cdef class YieldCurve(Curve): cdef vector[TDate] dates +ctypedef struct Carray: + shared_ptr[double] data + size_t size + cdef class SpreadCurve(Curve): cdef string ticker - cdef double[:] recovery_rates + cdef Carray recovery_rates cdef fArray_to_list(TRatePt* fArray, int fNumItems) diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx index 260ac4f..26b3c79 100644 --- a/pyisda/curve.pyx +++ b/pyisda/curve.pyx @@ -21,8 +21,6 @@ from numpy cimport npy_intp cdef extern from "Python.h": int PyMemoryView_Check(object) Py_buffer *PyMemoryView_GET_BUFFER(object) - object PyMemoryView_FromMemory(char* mem, Py_ssize_t data, int flags) - cdef int PyBUF_WRITE cdef extern from "numpy/arrayobject.h": void PyArray_ENABLEFLAGS(np.ndarray arr, int flags) @@ -41,6 +39,9 @@ cpdef public enum BadDay: cdef inline shared_ptr[TCurve] make_shared(TCurve* ptr) nogil: return shared_ptr[TCurve](ptr, JpmcdsFreeTCurve) +cdef inline void double_free(double* ptr) nogil: + free(ptr) + cdef class Curve(object): def __getstate__(self): @@ -480,6 +481,7 @@ cdef class SpreadCurve(Curve): cdef unsigned int includes = 0 cdef size_t i cdef bint freeup = False + if cash_settle_date_c < yc._thisptr.get().fBaseDate: raise ValueError("cash_settle_date: {0} is anterior to yc's base_date: {1}". format(cash_settle_date, yc.base_date)) @@ -528,7 +530,10 @@ cdef class SpreadCurve(Curve): raise ValueError("Didn't init the survival curve properly") else: self._thisptr = make_shared(curve) - self.recovery_rates = recovery_rates + self.recovery_rates.size = recovery_rates.shape[0] * sizeof(double) + self.recovery_rates.data = shared_ptr[double](<double*>malloc(self.recovery_rates.size), + double_free) + memcpy(<void*>self.recovery_rates.data.get(), &recovery_rates[0], self.recovery_rates.size) if ticker: self.ticker = ticker.encode() @@ -541,7 +546,7 @@ cdef class SpreadCurve(Curve): TCurve* curve = self._thisptr.get() size_t size = TCurve_size(curve.fNumItems) size_t buf_size = size + sizeof(size_t) + self.ticker.length() + \ - sizeof(size_t) + sizeof(double) * self.recovery_rates.shape[0] + sizeof(size_t) + self.recovery_rates.size unsigned char* buf = <unsigned char*>malloc(buf_size) unsigned char* cursor = buf + size serialize(curve, buf) @@ -549,10 +554,10 @@ cdef class SpreadCurve(Curve): memcpy(cursor, &size, sizeof(size_t)) cursor += sizeof(size_t) cursor += self.ticker.copy(<char*>cursor, size, 0) - size = self.recovery_rates.shape[0] + size = self.recovery_rates.size memcpy(cursor, &size, sizeof(size_t)) cursor += sizeof(size_t) - memcpy(cursor, &self.recovery_rates[0], sizeof(double) * self.recovery_rates.shape[0]) + memcpy(cursor, self.recovery_rates.data.get(), self.recovery_rates.size) return <bytes>buf[:buf_size] @cython.initializedcheck(False) @@ -571,15 +576,20 @@ cdef class SpreadCurve(Curve): self.ticker = string(<char*>cursor, ticker_length) cursor += ticker_length memcpy(&size, cursor, sizeof(size_t)) - temp = <double*>malloc(size * sizeof(char)) + self.recovery_rates.size = size + self.recovery_rates.data = shared_ptr[double](<double*>malloc(self.recovery_rates.size), + double_free) cursor += sizeof(size_t) - memcpy(temp, cursor, size) - self.recovery_rates = <double[:size/sizeof(double)]>(temp) + memcpy(self.recovery_rates.data.get(), cursor, size) def __deepcopy__(self, dict memo): cdef SpreadCurve sc = SpreadCurve.__new__(SpreadCurve) sc._thisptr = make_shared(JpmcdsCopyCurve(self._thisptr.get())) sc.ticker = self.ticker + sc.recovery_rates.data = shared_ptr[double](<double*>malloc(self.recovery_rates.size), + double_free) + memcpy(sc.recovery_rates.data.get(), self.recovery_rates.data.get(), self.recovery_rates.size) + sc.recovery_rates.size = self.recovery_rates.size memo[id(self)] = sc return sc @@ -589,7 +599,7 @@ cdef class SpreadCurve(Curve): SpreadCurve instance = SpreadCurve.__new__(SpreadCurve) unsigned char* cursor TCurve* curve = <TCurve*>malloc(sizeof(TCurve)) - size_t ticker_length + size_t ticker_length, size Py_buffer* py_buf if PyMemoryView_Check(state): @@ -603,6 +613,11 @@ cdef class SpreadCurve(Curve): memcpy(&ticker_length, cursor, sizeof(size_t)) cursor += sizeof(size_t) instance.ticker = string(<char*>cursor, ticker_length) + memcpy(&size, cursor, sizeof(size_t)) + instance.recovery_rates.size = size + instance.recovery_rates.data = shared_ptr[double](<double*>malloc(size), double_free) + cursor += sizeof(size_t) + memcpy(instance.recovery_rates.data.get(), cursor, size) return instance def __hash__(self): @@ -743,7 +758,11 @@ cdef class SpreadCurve(Curve): @property def recovery_rates(self): - return np.asarray(self.recovery_rates) + cdef np.npy_intp* shape = <np.npy_intp*>&self.recovery_rates.size + cdef np.ndarray[np.float64_t] out = \ + np.PyArray_SimpleNewFromData(1, shape, np.NPY_DOUBLE, + self.recovery_rates.data.get()) + return out @cython.boundscheck(False) @cython.wraparound(False) |
