def exact_solution_KP4459(): """Exactly solvable test system from Kloeden & Platen ch 4.4 eqn (4.59)""" h = 0.0004 tspan = np.arange(0.0, 5.0, h) N = len(tspan) y0 = np.array([1.0]) a = -0.02 b1 = 1.0 b2 = 2.0 # Ito version: def f(y, t): return np.array([a * y[0]]) def G(y, t): return np.array([[b1 * y[0], b2 * y[0]]]) # Stratonovich version of the same equation: def f_strat(y, t): return np.array([(a - (b1**2 + b2**2) / 2.0) * y[0]]) # Generate Wiener increments and repeated integrals for one sample path: dW = sdeint.deltaW(N - 1, 2, h) __, I = sdeint.Iwik(dW, h) J = I + 0.5 * h * np.eye(2).reshape((1, 2, 2)) # since m==2 # compute exact solution y for that sample path: y = np.zeros(N) y[0] = y0 Wn = np.array([0.0, 0.0]) for n in range(1, N): tn = tspan[n] Wn += dW[n - 1, :] y[n] = y0 * np.exp((a - (b1**2 + b2**2) / 2.0) * tn + b1 * Wn[0] + b2 * Wn[1]) return (dW, I, J, f, f_strat, G, y0, tspan, y)
def exact_solution_KP4446(): """Exactly solvable test system from Kloeden & Platen ch 4.4 eqn (4.46) By making this a fixture, the exact solution can be re-used in several tests without re-calculating it. """ h = 0.0004 tspan = np.arange(0.0, 10.0, h) N = len(tspan) y0 = 0.1 a = 1.0 b = 0.80 # Ito version: def f(y, t): return -(a + y*b**2)*(1 - y**2) def G(y, t): return b*(1 - y**2) # Stratonovich version of the same equation: def f_strat(y, t): return -a*(1 - y**2) # Generate Wiener increments and repeated integrals for one sample path: dW = sdeint.deltaW(N-1, 1, h) __, I = sdeint.Iwik(dW, h) # Ito repeated integrals J = I + 0.5*h # Stratonovich repeated integrals (m==1) # Compute exact solution y for that sample path: y = np.zeros(N) y[0] = y0 Wn = 0.0 for n in range(1, N): tn = tspan[n] Wn += dW[n-1] y[n] = (((1 + y0)*np.exp(-2.0*a*tn + 2.0*b*Wn) + y0 - 1.0)/ ((1 + y0)*np.exp(-2.0*a*tn + 2.0*b*Wn) + 1.0 - y0)) return (dW, I, J, f, f_strat, G, y0, tspan, y)
def exact_solution_KP4459(): """Exactly solvable test system from Kloeden & Platen ch 4.4 eqn (4.59)""" h = 0.0004 tspan = np.arange(0.0, 5.0, h) N = len(tspan) y0 = np.array([1.0]) a = -0.02 b1 = 1.0 b2 = 2.0 # Ito version: def f(y, t): return np.array([a*y[0]]) def G(y, t): return np.array([[b1*y[0], b2*y[0]]]) # Stratonovich version of the same equation: def f_strat(y, t): return np.array([(a - (b1**2 + b2**2)/2.0)*y[0]]) # Generate Wiener increments and repeated integrals for one sample path: dW = sdeint.deltaW(N-1, 2, h) __, I = sdeint.Iwik(dW, h) J = I + 0.5*h*np.eye(2).reshape((1, 2, 2)) # since m==2 # compute exact solution y for that sample path: y = np.zeros(N) y[0] = y0 Wn = np.array([0.0, 0.0]) for n in range(1, N): tn = tspan[n] Wn += dW[n-1,:] y[n] = y0*np.exp((a - (b1**2 + b2**2)/2.0)*tn + b1*Wn[0] + b2*Wn[1]) return (dW, I, J, f, f_strat, G, y0, tspan, y)
def exact_solution_R74(): """exactly solvable test system from Roessler2010 eqn (7.4)""" d = 5 m = 4 h = 0.0004 tspan = np.arange(0.0, 10.0, h) N = len(tspan) A = np.ones((d, d)) * 0.05 B0 = np.ones((d, d)) * 0.01 for i in range(0, d): A[i, i] = -1.5 B0[i, i] = 0.2 B = np.vstack([B0[np.newaxis, ...]] * m) y0 = np.ones(d) # Ito version: def f(y, t): return np.dot(A, y) def G(y, t): return np.dot(B, y).T G_separate = [lambda y, t: np.dot(B0, y)] * m # Stratonovich version of the same equation: S = np.ones((d, d)) * -0.0086 for i in range(0, d): S[i, i] = -0.0808 def f_strat(y, t): return np.dot(A + S, y) # Generate Wiener increments and repeated integrals for one sample path: dW = sdeint.deltaW(N - 1, m, h) # shape (N-1, m) __, I = sdeint.Iwik(dW, h) J = I + 0.5 * h * np.eye(m).reshape((1, m, m)) # compute exact solution y for that sample path: y = np.zeros((N, d)) y[0] = y0 Wn = np.zeros(m) term1 = A - 0.5 * np.einsum('kij,kjl', B, B) for n in range(1, N): tn = tspan[n] Wn += dW[n - 1] term2 = np.einsum('kij,k', B, Wn) y[n] = linalg.expm(term1 * tn + term2).dot(y0) return (dW, I, J, f, f_strat, G, G_separate, y0, tspan, y)
def exact_solution_R74(): """exactly solvable test system from Roessler2010 eqn (7.4)""" d = 5 m = 4 h = 0.0004 tspan = np.arange(0.0, 10.0, h) N = len(tspan) A = np.ones((d, d))*0.05 B0 = np.ones((d, d))*0.01 for i in range(0, d): A[i, i] = -1.5 B0[i, i] = 0.2 B = np.vstack([B0[np.newaxis,...]]*m) y0 = np.ones(d) # Ito version: def f(y, t): return np.dot(A, y) def G(y, t): return np.dot(B, y).T G_separate = [lambda y, t: np.dot(B0, y)] * m # Stratonovich version of the same equation: S = np.ones((d, d))*-0.0086 for i in range(0, d): S[i, i] = -0.0808 def f_strat(y, t): return np.dot(A + S, y) # Generate Wiener increments and repeated integrals for one sample path: dW = sdeint.deltaW(N-1, m, h) # shape (N-1, m) __, I = sdeint.Iwik(dW, h) J = I + 0.5*h*np.eye(m).reshape((1, m, m)) # compute exact solution y for that sample path: y = np.zeros((N, d)) y[0] = y0 Wn = np.zeros(m) term1 = A - 0.5*np.einsum('kij,kjl', B, B) for n in range(1, N): tn = tspan[n] Wn += dW[n-1] term2 = np.einsum('kij,k', B, Wn) y[n] = linalg.expm(term1*tn + term2).dot(y0) return (dW, I, J, f, f_strat, G, G_separate, y0, tspan, y)
def exact_solution_KP4446(): """Exactly solvable test system from Kloeden & Platen ch 4.4 eqn (4.46) By making this a fixture, the exact solution can be re-used in several tests without re-calculating it. """ h = 0.0004 tspan = np.arange(0.0, 10.0, h) N = len(tspan) y0 = 0.1 a = 1.0 b = 0.80 # Ito version: def f(y, t): return -(a + y * b**2) * (1 - y**2) def G(y, t): return b * (1 - y**2) # Stratonovich version of the same equation: def f_strat(y, t): return -a * (1 - y**2) # Generate Wiener increments and repeated integrals for one sample path: dW = sdeint.deltaW(N - 1, 1, h) __, I = sdeint.Iwik(dW, h) # Ito repeated integrals J = I + 0.5 * h # Stratonovich repeated integrals (m==1) # Compute exact solution y for that sample path: y = np.zeros(N) y[0] = y0 Wn = 0.0 for n in range(1, N): tn = tspan[n] Wn += dW[n - 1] y[n] = (((1 + y0) * np.exp(-2.0 * a * tn + 2.0 * b * Wn) + y0 - 1.0) / ((1 + y0) * np.exp(-2.0 * a * tn + 2.0 * b * Wn) + 1.0 - y0)) return (dW, I, J, f, f_strat, G, y0, tspan, y)