You are on page 1of 8

Question 1:

import numpy as np
import matplotlib.pyplot as plt
from numpy.linalg import norm

# Divide interval [0,0.4] into subinterval of length h


a = 0 #starting time
b = 0.4 #ending time
h = 0.1 #step size
n = int((b-a)/h+1) #number of point in the interval
x = np.linspace(a,b,n)#partition of interval
y_Euler=np.zeros(n) #initialize an array to store values of
approximation of y(t)

#######################################################
#slope of the solution from the given differential equation
def f(x,y):
return 7 * np.exp(4*x) - 3 * y

########################################################
#true solution
def true_sol(x):
return np.exp(4*x) + np.exp(-3*x)
y_true =true_sol(x) #true value of y(x)

#######################################################
#Use Euler's method to find a numerical solution

y_Euler[0] = 2 # initial condition


for i in range(n-1):
slope = f(x[i],y_Euler[i])
y_Euler[i+1] = y_Euler[i]+ h*slope #update approximate value of y in
the next step

error_Euler = np.abs(y_Euler-y_true) #evaluate error

#######################################################
#plotting
#compare true and approximate value
plt.figure()
plt.plot(x,y_true,linewidth=5, color = "yellow")
plt.plot(x,y_Euler, 'b--')
plt.xlabel('x')
plt.legend(["'approximation solution with Euler method'", "exact
solution"], loc="lower left")
plt.title(f"Comparison the true solution and approximation solution
with h = {h}")

#display error
plt.figure()

plt.plot(x, error_Euler, label = "error")


plt.title("Error in approximation")
plt.xlabel('x')

plt.show()

#######################################################
#compute global relative error
ErrorG_Euler = norm(error_Euler)/norm(y_true)
print("h = ", h)
print("ErrorG_Euler = ", ErrorG_Euler )

Question 2:
import numpy as np
import matplotlib.pyplot as plt
from numpy.linalg import norm

def f(t, y): # Slope of the solution from the given differential
equation
return 7 * np.exp(4 * t) - 3 * y

def true_sol(t):
return np.exp(4 * t) + np.exp(-3 * t)

# Parameters
a = 0 # Starting time
b = 0.4 # Ending time
h = 0.1 # Step size
n = int((b - a) / h) + 1 # Number of points in the interval
t = np.linspace(a, b, n) # Partition of the interval
y_true = true_sol(t) # True value of y(t)
# Modified Euler's method
y_mEuler = np.zeros(n) # Initialize an array to store values of
approximation of y(t)
y_mEuler[0] = 2 # Initial condition

for i in range(n - 1):


slope = f(t[i], y_mEuler[i])
if i == 0:
k = f(t[i], y_mEuler[i])
else:
k = f(t[i + 1], y_mEuler[i] + h * slope) # Slope at the next
point
y_mEuler[i + 1] = y_mEuler[i] + 1 * h * k # Update approximate
value of y in the next step

# Evaluate error
error_mEuler = np.abs(y_mEuler - y_true)

# Plotting
plt.figure()
plt.plot(t, y_true, linewidth=5, color="yellow")
plt.plot(t, y_mEuler, 'b--')
plt.xlabel('t')
plt.legend(["Approximation solution with Modified Euler method", "Exact
solution"], loc="best")
plt.title(f"Comparison of the true solution and approximation solution
with h = {h}")

plt.figure()
plt.plot(t, error_mEuler)
plt.title("Error in approximation using Modified Euler method")
plt.xlabel('t')
plt.show()

# Compute global relative error


ErrorG_mEuler = norm(error_mEuler) / norm(y_true)
print("h = ", h)
print("ErrorG_mEuler = ", ErrorG_mEuler )

Question 3:

########################################################
#Slope function and true solution
def f(x,y): #slope of the solution from the given differential equation
return 7 * np.exp(4*x) - 3 * y
def true_sol(x):
return np.exp(4*x) + np.exp(-3*x)
y_true =true_sol(x) #true value of y(x)

# Improved Euler Method


def improved_euler(x0, y0, h, xmax):
x_values = [x0]
y_values = [y0]
while x_values[-1] < xmax:
x = x_values[-1]
y = y_values[-1]
k1 = f(x, y)
k2 = f(x + h, y + h * k1)
y_new = y + 0.5 * h * (k1 + k2)
x_values.append(x + h)
y_values.append(y_new)
return x_values, y_values

########################################################

#Use Euler's method to find a numerical solution


y_iEuler=np.zeros(n) #initialize an array to store values of
approximation of y(t)
y_iEuler[0] = 2 # initial condition

for i in range(n-1):
k1 = f(x[i],y_iEuler[i]) #slope at the beginning of the period
y_temp = y_iEuler[i] + h*k1 #temporary value of y at the end of the
period
k2 = f(x[i+1],y_temp) #temporary value of y' at the end of the period
y_iEuler[i+1] = y_iEuler[i]+ 0.5*h*(k1+k2)#update approximate value
of y in the next step

########################################################

#Evaluate error
error_iEuler = np.abs(y_iEuler-y_true) #evaluate error

########################################################
#plotting
#compare true and approximation solution
plt.figure()
plt.plot(x,y_true,linewidth=5, color = "yellow")
plt.plot(x,y_iEuler, 'b--')
plt.xlabel('x')
plt.legend(["'approximation solution with modifiedEuler method'",
"exact solution"], loc="lower left")
plt.title(f"Comparison the true solution and approximation solution
with h = {h}")

#display error
plt.figure()
plt.plot(x, error_iEuler)
plt.plot(x, error_mEuler)
plt.plot(x, error_Euler)

plt.legend(["Improved Euler method ","Modified Euler method ", " Euler


method"], loc="best")
plt.title("Error in approximation")
plt.xlabel('x')

plt.show()

########################################################
#compute global relative error
ErrorG_iEuler = norm(error_iEuler)/norm(y_true)
print("h = ", h)
print("ErrorG_iEuler = ", ErrorG_iEuler )

Question 4:

import numpy as np

def RK4(f, a, b, y_initial, h):


# Calculate the number of steps
n = int((b - a) / h)
# Initialize time and y arrays
t = np.linspace(a, b, n + 1)
y = np.zeros(n + 1)
y[0] = y_initial

# Runge-Kutta 4th order method


for i in range(n):
k1 = h * f(t[i], y[i])
k2 = h * f(t[i] + h/2, y[i] + k1/2)
k3 = h * f(t[i] + h/2, y[i] + k2/2)
k4 = h * f(t[i] + h, y[i] + k3)
y[i + 1] = y[i] + (k1 + 2 * k2 + 2 * k3 + k4) / 6

return t, y

def func(t, y):


return -3 * t**2 * y

def true_solution(t):
return np.exp(-t**3)
def euler_method(f, a, b, y_initial, h):
n = int((b - a) / h)
t = np.linspace(a, b, n + 1)
y = np.zeros(n + 1)
y[0] = y_initial

for i in range(n):
y[i + 1] = y[i] + h * f(t[i], y[i])

return t, y
def modified_euler_method(f, a, b, y_initial, h):
n = int((b - a) / h)
t = np.linspace(a, b, n + 1)
y = np.zeros(n + 1)
y[0] = y_initial

for i in range(n):
k1 = f(t[i], y[i])
k2 = f(t[i] + h, y[i] + h * k1)
y[i + 1] = y[i] + h * (k1 + k2) / 2
return t, y

def improved_euler_method(f, a, b, y_initial, h):


n = int((b - a) / h)
t = np.linspace(a, b, n + 1)
y = np.zeros(n + 1)
y[0] = y_initial

for i in range(n):
k1 = f(t[i], y[i])
k2 = f(t[i] + h, y[i] + h * k1)
y[i + 1] = y[i] + h * (k1 + k2) / 2

return t, y

# Define step sizes


step_sizes = [0.1, 0.01, 0.001]

# Evaluate errors for each step size


for h in step_sizes:
# RK4 method
t_rk4, y_rk4 = RK4(func, 0, 0.4, 1, h)
rk4_approx = y_rk4[-1] # Last value is the approximation at t=0.4
rk4_true = true_solution(0.4)
rk4_absolute_error = np.abs(rk4_approx - rk4_true)
rk4_relative_error = rk4_absolute_error / rk4_true

# Euler's method
t_euler, y_euler = euler_method(func, 0, 0.4, 1, h)
euler_approx = y_euler[-1]
euler_absolute_error = np.abs(euler_approx - rk4_true)
euler_relative_error = euler_absolute_error / rk4_true

# Modified Euler's method


t_modified_euler, y_modified_euler = modified_euler_method(func, 0,
0.4, 1, h)
modified_euler_approx = y_modified_euler[-1]
modified_euler_absolute_error = np.abs(modified_euler_approx -
rk4_true)
modified_euler_relative_error = modified_euler_absolute_error /
rk4_true

# Improved Euler's method


t_improved_euler, y_improved_euler = improved_euler_method(func, 0,
0.4, 1, h)
improved_euler_approx = y_improved_euler[-1]
improved_euler_absolute_error = np.abs(improved_euler_approx -
rk4_true)
improved_euler_relative_error = improved_euler_absolute_error /
rk4_true

print(f"Step size: {h}")


print(f"RK4 Absolute Error: {rk4_absolute_error:.10f}")
print(f"RK4 Relative Error: {rk4_relative_error:.10f}")
print(f"Euler Absolute Error: {euler_absolute_error:.10f}")
print(f"Euler Relative Error: {euler_relative_error:.10f}")
print(f"Modified Euler Absolute Error:
{modified_euler_absolute_error:.10f}")
print(f"Modified Euler Relative Error:
{modified_euler_relative_error:.10f}")
print(f"Improved Euler Absolute Error:
{improved_euler_absolute_error:.10f}")
print(f"Improved Euler Relative Error:
{improved_euler_relative_error:.10f}")
print()

You might also like