Вы должны попытаться векторизовать суммы и обращения к процедуре интерполяции.Например, вот так:
import numpy as np
class Bond(object):
def __init__(self, years, cpn):
self.years = years
self.coupon = cpn
self.cashflows = np.zeros((self.years + 1, 2))
self.cashflows[:,0] = np.arange(self.years + 1)
self.cashflows[:,1] = self.coupon
self.cashflows[0,:] = 0, -1
self.cashflows[-1,:] = self.years, 1.0 + self.coupon
def pv(self, market):
return (self.cashflows[:,1] * market.df(self.cashflows[:,0])).sum()
, что, похоже, дает ~ 10-кратное ускорение.Вы также можете заменить списки knots
и dfs
в Market
массивами аналогичным образом.
Причина, по которой повторная калибровка занимает много времени, заключается в том, что leastsq
должен еще раз проверить, чтоэто действительно сидит на местном минимуме.Это требует численного дифференцирования целевой функции, что требует времени, так как у вас есть много свободных переменных.Задача оптимизации довольно проста, поэтому она сходится за несколько шагов, что означает, что проверка минимума занимает почти столько же времени, сколько и решение проблемы.