def test_coefficient_vector(self): mesh = (np.arange(3), np.arange(10, 12)) G = Grid.Grid(mesh, initializer=lambda *x: 0.0) # print G F = FD.FiniteDifferenceEngineADI(G, coefficients={ (0, 1): lambda t, *x: 1 }) op = self.F.operators[(0, 1)] op.D.data[op.D.data != 0] = op.D.data[op.D.data != 0]**0 op.D = todia(op.D) # diamat = op.D # densemat = diamat.todense() # f0 = lambda t, *x: x[0] # f1 = lambda t, *x: x[1] f = lambda t, *x: x vec = F.coefficient_vector(f, 0, 0) ref = np.tile(mesh[0], G.shape[1]), np.repeat(mesh[1], G.shape[0]) npt.assert_array_equal(ref, vec, "Failed when focused on dim: %i", 0) vec = F.coefficient_vector(f, 0, 1) ref = np.repeat(mesh[0], G.shape[1]), np.tile(mesh[1], G.shape[0]) npt.assert_array_equal(ref, vec, "Failed when focused on dim: %i", 1)
def setUp(self): # print "Setting up Params for CPP tests" shape = (5,4) self.v1 = np.arange(shape[0]*shape[1], dtype=float)**2 self.v2 = self.v1.copy() self.v2.resize(shape) coeffs = {(0,) : lambda t, *x: x[0]*x[1], (0,0): lambda t, *x: x[0]*x[1], (1,) : lambda t, *x: x[0]*x[1], (1,1): lambda t, *x: x[0]*x[1], (0,1): lambda t, *x: x[0]*x[1], } bounds = { (0,) : ((0, lambda *args: 0), (1, lambda *args: 1)), (0,0) : ((0, lambda *args: 0), (None, lambda *args: 1)), (1,) : ((None, lambda *args: None), (None, lambda *args: None)), (1,1) : ((1, lambda *args: 0.0), (None, lambda *args: None)), } schemes = {} self.G = Grid.Grid([np.arange(shape[0], dtype=float)**3, np.arange(shape[1], dtype=float)**3], lambda x, y: (x*shape[1]+y)**2) self.F = FD.FiniteDifferenceEngineADI(self.G, coefficients=coeffs, boundaries=bounds, schemes=schemes, force_bandwidth=None) # print "Setting up FDE for CPP tests" self.F.init() self.F.operators[0].R = np.arange(self.G.size, dtype=float) self.F.operators[1].R = np.arange(self.G.size, dtype=float)
def setUp(self): spot_max = 1500.0 var_max = 13.0 nspots = 50 nvols = 30 spotdensity = 7.0 # infinity is linear? varexp = 4 self.strike = spot_max / 4.0 self.spots = utils.sinh_space(self.strike, spot_max, spotdensity, nspots) self.vars = utils.exponential_space(0.00, 0.04, var_max, varexp, nvols) self.Grid = Grid.Grid((self.spots, self.vars), initializer=lambda x0,x1: np.maximum(x0-self.strike,0))
def setUp(self): s1_enable = 1 s2_enable = 1 v1_enable = 1 v2_enable = 1 r_enable = 1 dirichlet_s = 1 dirichlet_v = 1 kappa = 1 r = 0.06 theta = 0.04 sigma = 0.4 rho = 0.6 spot_max = 1500.0 var_max = 13.0 nspots = 5 nvols = 5 spotdensity = 7.0 # infinity is linear? varexp = 5 up_or_down_spot = 'up' up_or_down_var = 'down' flip_idx_spot = nspots // 2 flip_idx_var = nvols // 2 k = spot_max / 4.0 # spots = np.linspace(0, spot_max, nspots) # vars = np.linspace(0, var_max, nvols) spots = utils.sinh_space(k, spot_max, spotdensity, nspots) vars = utils.exponential_space(0.00, 0.04, var_max, varexp, nvols) def mu_s(t, *dim): return r * dim[0] * s1_enable def gamma2_s(t, *dim): return 0.5 * dim[1] * dim[0]**2 * s2_enable def mu_v(t, *dim): return kappa * (theta - dim[1]) * v1_enable def gamma2_v(t, *dim): return 0.5 * sigma**2 * dim[1] * v2_enable coeffs = { (): lambda t: -r * r_enable, (0, ): mu_s, (0, 0): gamma2_s, (1, ): mu_v, (1, 1): gamma2_v, (0, 1): lambda t, *dim: dim[0] * dim[1] * rho * sigma } coeffs = {k: lambda *x: 1 for k in coeffs} bounds = { (0, ): ((0, lambda *args: 0), (1, lambda *args: 1)), (0, 0): ((0, lambda *args: 0), (None, lambda *args: 1)), (1, ): ((None, lambda *args: None), (None, lambda *args: None)), (1, 1): ((1, lambda *args: 0.0), (None, lambda *args: None)), } schemes = {} # G = Grid.Grid((spots, vars), initializer=lambda x0,x1: np.maximum(x0-k,0)) self.G = Grid.Grid((spots, vars), initializer=lambda x0, x1: x0 * x1) # print G self.F = FD.FiniteDifferenceEngineADI(self.G, coefficients=coeffs, boundaries=bounds, schemes=schemes, force_bandwidth=None) self.F.init() # self.F.operators[1].diagonalize() self.FG = FDG.FiniteDifferenceEngineADI() self.FG.from_host_FiniteDifferenceEngine(self.F)
def test_dirichlet_boundary(self): spots = np.arange(5.) vars = np.arange(4.) def rndgrid(x0, x1): return np.random.random((x0.shape[0], x1.shape[1])) G = Grid.Grid((spots, vars), initializer=rndgrid) npt.assert_array_equal(G.shape, tuple(map(len, G.mesh))) coeffs = bounds = {} coeffs = { (0, ): lambda t, *dim: 1, # (0,0): lambda t, *dim: 0, ( 1, ): lambda t, *dim: 0, # (1,1): lambda t, *dim: 0, # (0,1): lambda t, *dim: 0 } bounds = { (0, ): ((0, lambda t, *x: 1), (0, lambda t, *x: 1)), # (0,0): ((None, lambda *x: 1), (0, lambda *x: 1)), ( 1, ): ((0, lambda *x: 1), (0, lambda *x: 1)), # (1,1): ((0, lambda *x: 1), (0, lambda *x: 1)), } F = FD.FiniteDifferenceEngineADI(G, coefficients=coeffs, boundaries=bounds, force_bandwidth=None) F.init() for d, o in F.simple_operators.items(): l = [[1] * F.grid.shape[(o.axis + 1) % 2]] * 2 npt.assert_array_equal( o.dirichlet, l, err_msg="Dim: %s, dirichlet: %s, expected: %s" % (d, o.dirichlet, l)) for d, o in F.simple_operators.items(): l = [[1] * F.grid.shape[(o.axis + 1) % 2]] * 2 npt.assert_array_equal( o.dirichlet, l, err_msg="Dim: %s, dirichlet: %s, expected: %s" % (d, o.dirichlet, l)) for d in bounds.keys(): B = F.simple_operators[d] # print "Derivative", d, "Dirichlets", B.dirichlet g = (B + 1).solve(F.grid.domain[-1]) if B.axis == 1: g = g.T if B.dirichlet[0] is not None: npt.assert_array_equal(g[0, :], 1) if B.dirichlet[1] is not None: npt.assert_array_equal(g[-1, :], 1) for d in bounds.keys(): B = F.simple_operators[d] # print "Derivative", d, "Dirichlets", B.dirichlet # print B.dirichlet g = B.apply(F.grid.domain[-1]) if B.axis == 1: g = g.T if B.dirichlet[0] is not None: npt.assert_array_equal(g[0, :], 1) if B.dirichlet[1] is not None: npt.assert_array_equal(g[-1, :], 1) for d in bounds.keys(): B = F.simple_operators[d] # print "Derivative", d, "Dirichlets", B.dirichlet # fp(B.data) g = (B + 1).solve(F.grid.domain[-1]) # fp(g) if B.axis == 1: g = g.T if B.dirichlet[0] is not None: npt.assert_array_equal(g[0, :], 1) if B.dirichlet[1] is not None: npt.assert_array_equal(g[-1, :], 1)
def test_numpy_vs_operators(self): spots = np.linspace(0, 1, 4) vars = np.linspace(0, 10, 4) # spots = self.G.mesh[0] # vars = self.G.mesh[1] G = Grid.Grid((spots, vars), initializer=lambda x0, x1: x1 * 1) coeffs = { (): lambda t: 0, (0, ): lambda t, *dim: dim[0], (0, 0): lambda t, *dim: dim[0], (1, ): lambda t, *dim: 0 * dim[1], (1, 1): lambda t, *dim: dim[1], (0, 1): lambda t, *dim: dim[0] * dim[1] } bounds = { (0, ): ((None, lambda *x: None), (None, lambda *x: 3)), (0, 0): ((None, lambda *x: None), (None, lambda *x: 3)), (1, ): ((None, lambda *x: None), (None, lambda *x: 1)), (1, 1): ((None, lambda *x: None), (None, lambda *x: 1)), } F = FD.FiniteDifferenceEngineADI(G, coefficients=coeffs, boundaries=bounds, force_bandwidth=None) F.init() cb = utils.clear_boundary g = F.grid.domain[-1] op_ = {'delta': {}, 'grid_delta': {}, 'derivative': {}} np_ = {'delta': {}, 'grid_delta': {}, 'derivative': {}} dims = coeffs.keys() dims.remove(()) for dim in dims: op_['grid_delta'][dim] = F.simple_operators[dim].copy() op_['grid_delta'][dim].R = None op_['delta'][(0, )] = op_['grid_delta'][(0, )].deltas[:, np.newaxis] op_['delta'][(1, )] = op_['grid_delta'][(1, )].deltas x = F.grid.mesh[0] y = F.grid.mesh[1] np_['delta'][(0, )] = np.gradient(x)[:, np.newaxis] np_['delta'][(1, )] = np.gradient(y) np_['delta'][(0, )][0, 0] = np.nan np_['delta'][(1, )][0] = np.nan for f in (op_, np_): f['delta'][(0, 0)] = f['delta'][(0, )]**2 f['delta'][(1, 1)] = f['delta'][(1, )]**2 f['delta'][(0, 1)] = f['delta'][(1, )] * f['delta'][(0, )] f['delta'][(1, 0)] = f['delta'][(1, )] * f['delta'][(0, )] np_['grid_delta'][(0, )], np_['grid_delta'][(1, )] = np.gradient(g) for fst in [0, 1]: np_['grid_delta'][(fst, 0)], np_['grid_delta'][(fst, 1)] = np.gradient( np_['grid_delta'][(fst, )]) Y, X = np.meshgrid(y, x) for dim in dims: op_['derivative'][dim] = cb(op_['grid_delta'][dim].apply(g), inplace=True) npt.assert_(op_['derivative'][dim].shape == g.shape) np_['derivative'][dim] = cb(np_['grid_delta'][dim] / np_['delta'][dim], inplace=True) np_['derivative'][dim] *= F.coefficients[dim](0, X, Y) op_['derivative'][dim] *= F.coefficients[dim](0, X, Y) np_['derivative'][(1, 0)] = cb(np_['grid_delta'][(1, 0)] / np_['delta'][(1, 0)], inplace=True) np_['derivative'][(1, 0)] *= F.coefficients[(0, 1)](0, X, Y) for dim in dims: for x in ('delta', 'derivative'): msg = "Comparing %s in dimension %s" % (x, dim) try: npt.assert_array_almost_equal(op_[x][dim], np_[x][dim], decimal=7, err_msg=msg) except AssertionError: print msg, op_['grid_delta'][dim].axis fp((op_['grid_delta'][dim]).D.data) fp((op_[x][dim]), fmt='f') fp((np_[x][dim]), fmt='f') fp((op_[x][dim] - np_[x][dim]), fmt='f') # npt.assert_allclose(op_[x][dim], np_[x][dim], err_msg=msg) npt.assert_array_almost_equal(op_[x][dim], np_[x][dim], decimal=7, err_msg=msg) npt.assert_array_almost_equal(np_['derivative'][(0, 1)], np_['derivative'][(1, 0)], err_msg=msg)
def setUp(self): s1_enable = 1 s2_enable = 1 v1_enable = 1 v2_enable = 1 r_enable = 1 dirichlet_s = 1 dirichlet_v = 1 kappa = 1 r = 0.06 theta = 0.04 sigma = 0.4 rho = 0.6 spot_max = 1500.0 var_max = 13.0 nspots = 5 nvols = 5 spotdensity = 7.0 # infinity is linear? varexp = 5 # TODO:!!!!XXX TODO XXX # var_max = nvols-1 # spot_max = nspots-1 up_or_down_spot = 'up' up_or_down_var = 'down' flip_idx_spot = nspots // 2 flip_idx_var = nvols // 2 k = spot_max / 4.0 # spots = np.linspace(0, spot_max, nspots) # vars = np.linspace(0, var_max, nvols) spots = utils.sinh_space(k, spot_max, spotdensity, nspots) vars = utils.exponential_space(0.00, 0.04, var_max, varexp, nvols) def mu_s(t, *dim): return r * dim[0] * s1_enable def gamma2_s(t, *dim): return 0.5 * dim[1] * dim[0]**2 * s2_enable def mu_v(t, *dim): return kappa * (theta - dim[1]) * v1_enable def gamma2_v(t, *dim): return 0.5 * sigma**2 * dim[1] * v2_enable coeffs = { (): lambda t: -r * r_enable, (0, ): mu_s, (0, 0): gamma2_s, (1, ): mu_v, (1, 1): gamma2_v, (0, 1): lambda t, *dim: dim[0] * dim[1] * rho * sigma } bounds = { # D: U = 0 VN: dU/dS = 1 ( 0, ): ((0 if dirichlet_s else 1, lambda *args: 0.0), (1, lambda *args: 1.0)), # D: U = 0 Free boundary (0, 0): ((0 if dirichlet_s else 1, lambda *args: 0.0), (None, lambda *x: 1.0)), # Free boundary at low variance ( 1, ): ( (None, lambda *x: None), # (0.0, lambda t, *dim: 0), # D intrinsic value at high variance # (None, lambda *x: None) (0 if dirichlet_v else 1, lambda t, *dim: np.maximum(0.0, dim[0] - k))), # # Free boundary (1, 1): ( (1, lambda *x: 0), # D intrinsic value at high variance # (None, lambda *x: None) (0 if dirichlet_v else 1, lambda t, *dim: np.maximum(0.0, dim[0] - k))) } schemes = {} schemes[(0, )] = ({ "scheme": "center" }, { "scheme": up_or_down_spot, "from": flip_idx_spot }) schemes[(1, )] = ({ "scheme": "center" }, { "scheme": up_or_down_var, "from": flip_idx_var }) dss = np.hstack((np.nan, np.diff(spots))) dvs = np.hstack((np.nan, np.diff(vars))) As_ = utils.nonuniform_complete_coefficients( dss, up_or_down=up_or_down_spot, flip_idx=flip_idx_spot)[0] Ass_ = utils.nonuniform_complete_coefficients(dss)[1] L1_ = [] R1_ = [] # As_, Ass_ = utils.nonuniform_forward_coefficients(dss) assert (not np.isnan(As_.data).any()) assert (not np.isnan(Ass_.data).any()) for j, v in enumerate(vars): # Be careful not to overwrite operators As, Ass = As_.copy(), Ass_.copy() m = 2 mu_s = r * spots * s1_enable gamma2_s = 0.5 * v * spots**2 * s2_enable for i, z in enumerate(mu_s): # print z, coeffs[0,](0, spots[i]) assert z == coeffs[0, ](0, spots[i]) for i, z in enumerate(gamma2_s): # print z, coeffs[0,0](0, spots[i], v) assert z == coeffs[0, 0](0, spots[i], v) Rs = np.zeros(nspots) Rs[-1] = 1 As.data[m - 2, 2:] *= mu_s[:-2] As.data[m - 1, 1:] *= mu_s[:-1] As.data[m, :] *= mu_s As.data[m + 1, :-1] *= mu_s[1:] As.data[m + 2, :-2] *= mu_s[2:] Rs *= mu_s Rss = np.zeros(nspots) Rss[-1] = 2 * dss[-1] / dss[-1]**2 Ass.data[m + 1, -2] = 2 / dss[-1]**2 Ass.data[m, -1] = -2 / dss[-1]**2 Ass.data[m - 2, 2:] *= gamma2_s[:-2] Ass.data[m - 1, 1:] *= gamma2_s[:-1] Ass.data[m, :] *= gamma2_s Ass.data[m + 1, :-1] *= gamma2_s[1:] Ass.data[m + 2, :-2] *= gamma2_s[2:] Rss *= gamma2_s L1_.append(As.copy()) L1_[j].data += Ass.data L1_[j].data[m, :] -= 0.5 * r * r_enable L1_[j].data[m, 0] = 1 * dirichlet_s R1_.append((Rs + Rss).copy()) R1_[j][0] = 0 L2_ = [] R2_ = [] Av_ = utils.nonuniform_complete_coefficients(dvs, up_or_down=up_or_down_var, flip_idx=flip_idx_var)[0] Avv_ = utils.nonuniform_complete_coefficients(dvs)[1] assert (not np.isnan(Av_.data).any()) assert (not np.isnan(Avv_.data).any()) for i, s in enumerate(spots): mu_v = kappa * (theta - vars) * v1_enable gamma2_v = 0.5 * sigma**2 * vars * v2_enable # for j, z in enumerate(mu_v): # assert z == coeffs[1,](0, 0, vars[j]) # for j, z in enumerate(gamma2_v): # assert z == coeffs[1,1](0, 0, vars[j]) # Be careful not to overwrite our operators Av, Avv = Av_.copy(), Avv_.copy() m = 2 Av.data[m - 2, 2] = -dvs[1] / (dvs[2] * (dvs[1] + dvs[2])) Av.data[m - 1, 1] = (dvs[1] + dvs[2]) / (dvs[1] * dvs[2]) Av.data[m, 0] = (-2 * dvs[1] - dvs[2]) / (dvs[1] * (dvs[1] + dvs[2])) Av.data[m - 2, 2:] *= mu_v[:-2] Av.data[m - 1, 1:] *= mu_v[:-1] Av.data[m, :] *= mu_v Av.data[m + 1, :-1] *= mu_v[1:] Av.data[m + 2, :-2] *= mu_v[2:] Rv = np.zeros(nvols) Rv *= mu_v Avv.data[m - 1, 1] = 2 / dvs[1]**2 Avv.data[m, 0] = -2 / dvs[1]**2 Avv.data[m - 2, 2:] *= gamma2_v[:-2] Avv.data[m - 1, 1:] *= gamma2_v[:-1] Avv.data[m, :] *= gamma2_v Avv.data[m + 1, :-1] *= gamma2_v[1:] Avv.data[m + 2, :-2] *= gamma2_v[2:] Rvv = np.zeros(nvols) Rvv[0] = 2 * dvs[1] / dvs[1]**2 Rvv *= gamma2_v L2_.append(Av.copy()) L2_[i].data += Avv.data L2_[i].data[m, :] -= 0.5 * r * r_enable L2_[i].data[ m, -1] = 1 * dirichlet_v # This is to cancel out the previous value so we can # set the dirichlet boundary condition using R. # Then we have U_i + -U_i + R R2_.append(Rv + Rvv) R2_[i][-1] = 0 # np.maximum(0, s - k) def flatten_tensor(mats): diags = np.hstack([x.data for x in mats]) flatmat = scipy.sparse.dia_matrix( (diags, mats[0].offsets), shape=(diags.shape[1], diags.shape[1])) return flatmat L1 = flatten_tensor(L1_) L2 = flatten_tensor(L2_) R1 = np.array(R1_).T R2 = np.array(R2_) self.As_ = As_ self.Ass_ = Ass_ self.L1_ = L1 self.R1_ = R1 self.L2_ = L2 self.R2_ = R2 # G = Grid.Grid((spots, vars), initializer=lambda x0,x1: np.maximum(x0-k,0)) self.G = Grid.Grid((spots, vars), initializer=lambda x0, x1: x0 * x1) # print G self.F = FD.FiniteDifferenceEngineADI(self.G, coefficients=coeffs, boundaries=bounds, schemes=schemes, force_bandwidth=None) self.F.init()