summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuillaume Horel <guillaume.horel@gmail.com>2023-01-25 21:47:39 -0500
committerGuillaume Horel <guillaume.horel@gmail.com>2023-01-25 22:41:01 -0500
commit846daaf8a1f3090965a2606a7933ad0e6f71aa6e (patch)
treefe8b2407a0f518b145e4b929d37dfe121dbac3be
parenteb1fc3f3c30a7fad72d577cc22171fb1d7865d95 (diff)
downloadpyisda-846daaf8a1f3090965a2606a7933ad0e6f71aa6e.tar.gz
faster deepcopy
-rw-r--r--pyisda/credit_index.pxd5
-rw-r--r--pyisda/credit_index.pyx121
-rw-r--r--pyisda/curve.pyx2
-rw-r--r--pyisda/legs.pxd3
-rw-r--r--pyisda/legs.pyx19
5 files changed, 80 insertions, 70 deletions
diff --git a/pyisda/credit_index.pxd b/pyisda/credit_index.pxd
index 2be66ff..1a07a6f 100644
--- a/pyisda/credit_index.pxd
+++ b/pyisda/credit_index.pxd
@@ -20,4 +20,7 @@ cdef class CreditIndex(CurveList):
cdef vector[TDate] _maturities
cdef TContingentLeg** contingent_legs
cdef TFeeLeg** fee_legs
- cdef readonly char* cal_file
+ cdef readonly char[30] cal_file
+
+
+cdef copy(CurveList orig, CurveList copy)
diff --git a/pyisda/credit_index.pyx b/pyisda/credit_index.pyx
index 2bbfe96..57cd48c 100644
--- a/pyisda/credit_index.pyx
+++ b/pyisda/credit_index.pyx
@@ -10,7 +10,8 @@ from cython.parallel cimport prange, parallel
cimport cython
from .legs cimport (JpmcdsCdsContingentLegMake, JpmcdsCdsFeeLegMake,
- JpmcdsContingentLegPV, JpmcdsFeeLegPV, FeeLegAI, JpmcdsFeeLegFree)
+ JpmcdsContingentLegPV, JpmcdsFeeLegPV, FeeLegAI, JpmcdsFeeLegFree,
+ fee_leg_copy)
from .curve cimport (SpreadCurve, JpmcdsCopyCurve, tweak_curve, YieldCurve,
JpmcdsFreeTCurve, survival_prob, Hash64WithSeed,
Hash64, uint64_t, CurveName,
@@ -28,18 +29,6 @@ cimport cython
ctypedef TFeeLeg* TFeeLeg_ptr
ctypedef TContingentLeg* TContingentLeg_ptr
-cdef TFeeLeg* copyFeeLeg(TFeeLeg* leg) nogil:
- cdef TFeeLeg* new_leg = <TFeeLeg*>malloc(sizeof(TFeeLeg))
- cdef size_t size = leg.nbDates * sizeof(TDate)
- memcpy(new_leg, leg, sizeof(TFeeLeg))
- new_leg.accStartDates = <TDate*>malloc(size)
- new_leg.accEndDates = <TDate*>malloc(size)
- new_leg.payDates = <TDate*>malloc(size)
- memcpy(new_leg.accStartDates, leg.accStartDates, size)
- memcpy(new_leg.accEndDates, leg.accEndDates, size)
- memcpy(new_leg.payDates, leg.payDates, size)
- return new_leg
-
cdef TContingentLeg* copyContingentLeg(TContingentLeg* leg) nogil:
cdef TContingentLeg* new_leg = <TContingentLeg*>malloc(sizeof(TContingentLeg))
memcpy(new_leg, leg, sizeof(TContingentLeg))
@@ -48,6 +37,31 @@ cdef TContingentLeg* copyContingentLeg(TContingentLeg* leg) nogil:
cdef inline void char_free(char* ptr) nogil:
free(ptr)
+cdef copy(CurveList orig, CurveList copy):
+ cdef:
+ char* buf
+ char* new_buf
+ TCurve* curve
+ int size
+ CurveName cn
+ uint16_t offset
+ copy.base_date = orig.base_date
+ copy._weights = orig._weights
+ copy._curves.resize(orig._curves.size())
+ copy.defaulted = orig.defaulted
+ copy.offset_recovery_rates = orig.offset_recovery_rates
+ for p in orig.names:
+ buf = orig._curves[p.second].get()
+ offset = p.first.name - buf
+ size = offset + p.first.size()
+ new_buf = <char*>malloc(size)
+ memcpy(new_buf, buf, size)
+ curve = <TCurve*>new_buf
+ curve.fArray = <TRatePt*>(new_buf + sizeof(TCurve))
+ cn = CurveName(new_buf + offset)
+ copy._curves[p.second] = shared_ptr[char](new_buf, char_free)
+ copy.names[cn] = p.second
+
@cython.auto_pickle(False)
cdef class CurveList:
@@ -220,32 +234,9 @@ cdef class CurveList:
CurveList.__init__(self, l)
self.base_date = temp
- # def __deepcopy__(self, memo):
- # cdef:
- # CurveList copy = CurveList.__new__(CurveList)
- # char* buf
- # char* new_buf
- # TCurve* curve
- # int size
- # CurveName cn
- # uint16_t offset
- # copy.base_date = self.base_date
- # copy._weights = self._weights
- # copy._curves.resize(self._curves.size())
- # copy.defaulted = self.defaulted
- # copy.offset_recovery_rates = self.offset_recovery_rates
- # for p in self.names:
- # buf = self._curves[p.second].get()
- # offset = p.first.name - buf
- # size = offset + p.first.size()
- # new_buf = <char*>malloc(size)
- # memcpy(new_buf, buf, size)
- # curve = <TCurve*>new_buf
- # curve.fArray = <TRatePt*>(new_buf + sizeof(TCurve))
- # cn = CurveName(new_buf + offset)
- # copy._curves[p.second] = shared_ptr[char](new_buf, char_free)
- # copy.names[cn] = p.second
- # return copy
+ def __deepcopy__(self, memo):
+ cdef CurveList copy = CurveList.__new__(CurveList)
+ copy(self, copy)
def __reduce__(self):
return (self.__class__, (self.curves, TDate_to_pydate(self.base_date)))
@@ -286,34 +277,32 @@ cdef class CreditIndex(CurveList):
for i in range(self._maturities.size()):
JpmcdsFeeLegFree(self.fee_legs[i])
- # def __deepcopy__(self, memo):
- # cdef:
- # shared_ptr[TCurve] sc
- # double* temp
- # size_t i = 0
- # TCurve* copy_sc
- # CreditIndex copy = CreditIndex.__new__(CreditIndex)
- # copy._weights = self._weights
- # copy.T = self.T
- # copy.base_date = self.base_date
- # copy.start_date = self.start_date
- # copy._maturities = self._maturities
- # for sc in self._curves:
- # copy_sc = sc.get()
- # copy._curves.push_back(make_shared(JpmcdsCopyCurve(copy_sc)))
- # temp = <double*>malloc(copy_sc.fNumItems * sizeof(double))
- # if temp != NULL:
- # memcpy(<void*>temp, self.recovery_rates[i].get(),
- # copy_sc.fNumItems * sizeof(double))
- # copy.recovery_rates.push_back(shared_ptr[double](temp, double_free))
+ def __deepcopy__(self, memo):
+ cdef:
+ CreditIndex copy = CreditIndex.__new__(CreditIndex)
+ size_t i
+ int n
+ TContingentLeg* cl
+ TFeeLeg* fl
+ copy(self, copy)
+ copy._start_date = self._start_date
+ copy._maturities = self._maturities
+ n = self._maturities.size()
+ copy.contingent_legs = <TContingentLeg**>malloc(n * sizeof(TContingentLeg*))
+ copy.fee_legs = <TFeeLeg**>malloc(n * sizeof(TFeeLeg*))
+ for i in range(n):
+ cl = self.contingent_legs[i]
+ fl = self.fee_legs[i]
+ copy.contingent_legs[i] = JpmcdsCdsContingentLegMake(cl.startDate,
+ cl.endDate,
+ cl.notional,
+ cl.protectStart)
+ copy.fee_legs[i] = <TFeeLeg*>malloc(sizeof(TFeeLeg))
+ fee_leg_copy(fl, copy.fee_legs[i])
- # copy.tickers = self.tickers
- # copy.contingent_legs = <TContingentLeg**>malloc(sizeof(TContingentLeg*) * self._maturities.size())
- # copy.fee_legs = <TFeeLeg**>malloc(sizeof(TFeeLeg*) * self._maturities.size())
- # for i in range(self._maturities.size()):
- # copy.fee_legs[i] = copyFeeLeg(self.fee_legs[i])
- # copy.contingent_legs[i] = copyContingentLeg(self.contingent_legs[i])
- # return copy
+ strcpy(copy.cal_file, self.cal_file)
+ memo[id(self)] = copy
+ return copy
def __reduce__(self):
return (self.__class__,
diff --git a/pyisda/curve.pyx b/pyisda/curve.pyx
index 6e3b452..a3821c2 100644
--- a/pyisda/curve.pyx
+++ b/pyisda/curve.pyx
@@ -811,8 +811,6 @@ cdef class SpreadCurve(Curve):
return JpmcdsForwardZeroPrice(curve, pydate_to_TDate(d1),
pydate_to_TDate(d2))
-
-
def __setstate__(self, bytes state):
super().__setstate__(state)
cdef char* cursor = self.buf.get()
diff --git a/pyisda/legs.pxd b/pyisda/legs.pxd
index a9e1ad7..bd35530 100644
--- a/pyisda/legs.pxd
+++ b/pyisda/legs.pxd
@@ -110,3 +110,6 @@ cdef class ContingentLeg:
cdef class FeeLeg:
cdef TFeeLeg* _thisptr
+
+
+cdef void fee_leg_copy(TFeeLeg* orig, TFeeLeg* copy) nogil
diff --git a/pyisda/legs.pyx b/pyisda/legs.pyx
index 12c8bff..a7f6ab2 100644
--- a/pyisda/legs.pyx
+++ b/pyisda/legs.pyx
@@ -1,4 +1,5 @@
-from libc.stdlib cimport free
+from libc.stdlib cimport free, malloc
+from libc.string cimport memcpy
from .date cimport (pydate_to_TDate, TDate_to_pydate, dcc,
JpmcdsStringToStubMethod, MODIFIED)
from .date import dcc_tostring
@@ -211,3 +212,19 @@ cdef class FeeLeg:
def __dealloc__(self):
if self._thisptr is not NULL:
JpmcdsFeeLegFree(self._thisptr)
+
+
+cdef void fee_leg_copy(const TFeeLeg* orig, TFeeLeg* copy) nogil:
+ cdef int n = orig.nbDates
+ copy.nbDates = n
+ copy.notional = orig.notional
+ copy.couponRate = orig.couponRate
+ copy.dcc = orig.dcc
+ copy.accrualPayConv = orig.accrualPayConv
+ copy.obsStartOfDay = orig.obsStartOfDay
+ copy.accStartDates = <TDate*>malloc(n * sizeof(TDate))
+ copy.accEndDates = <TDate*>malloc(n * sizeof(TDate))
+ copy.payDates = <TDate*>malloc(n * sizeof(TDate))
+ memcpy(copy.accStartDates, orig.accStartDates, n * sizeof(TDate))
+ memcpy(copy.accEndDates, orig.accEndDates, n * sizeof(TDate))
+ memcpy(copy.payDates, orig.payDates, n * sizeof(TDate))