I am creating a function to create an approximate solution for differential equations using Euler's method. I can get the code to work, but ran into trouble when trying to convert this into a function. Namely, I am having difficulty getting my function to correctly call the formula.
This original code worked well:
#define your inital values
y = 1
x = 0
#h represents step size (incremental shift over the directional field)
h = 0.1
solutions = []
x_values = []
#generates a list of 10 solutions, increase the number in the range to get more solutions
for s in range (0, 10):
#enter your differential equation
diff_eq = x+y
#Euler's method to approximate the solutions
s = y + h*(diff_eq)
solutions.append(s)
#replace initial values with the new values
y = s
x = x + h
#create a list of the x values
x_values.append(x)
#creating a dataframe from the solutions
Euler_values = pd.DataFrame(list(zip(x_values, solutions)), columns = ['xₙ', 'yₙ'])
#create an index for the dataframe starting at one and increasing by one
Euler_values.index = Euler_values.index + 1
Euler_values.rename_axis('n', inplace = True)
Euler_values
This is the start of turning the above code into a function:
#eulers method to approximate the solutions function
def eulers_method(x, y, diff_eq, h, n):
#empty solution and x_value lists to be used in the euler function
solutions = []
x_values = []
for s in range (0, n):
# eq = diff_eq <-- this does not work
# if I call the equation here it does work, but I want it to be entered into the function
eq = x + y
s = y + h*(eq)
#replace initial values with the new values and adds them to the solution and x_value lists
y = s
solutions.append(s)
x = x + h
x_values.append(x)
#creates a dataframe from the solutions
Euler_values = pd.DataFrame(list(zip(x_values, solutions)), columns = ['xₙ', 'yₙ'])
#creates an index for the dataframe starting at one and increasing by one
Euler_values.index = Euler_values.index + 1
Euler_values.rename_axis('n', inplace = True)
return Euler_values
#enter an initial x value, initial y value, the differential equation, the step size, and the number of solutions to generate
# the diff_eq entry is giving me trouble
eulers_method(0,1, x+y, 0.1, 10)
There are a couple of ways of dealing with your problem. The first (and IMO preferable) solution is just to pass a function to your eulers_method
function i.e.
def eulers_method(x, y, diff_eq, h, n):
#empty solution and x_value lists to be used in the euler function
solutions = []
x_values = []
for s in range (0, n):
# compute the function
eq = diff_eq(x, y)
s = y + h*(eq)
#replace initial values with the new values and adds them to the solution and x_value lists
y = s
solutions.append(s)
x = x + h
x_values.append(x)
#creates a dataframe from the solutions
Euler_values = pd.DataFrame(list(zip(x_values, solutions)), columns = ['xₙ', 'yₙ'])
#creates an index for the dataframe starting at one and increasing by one
Euler_values.index = Euler_values.index + 1
Euler_values.rename_axis('n', inplace = True)
return Euler_values
#enter an initial x value, initial y value, the differential equation, the step size, and the number of solutions to generate
eulers_method(0, 1, lambda x, y:x+y, 0.1, 10)
Output:
xₙ yₙ
n
1 0.1 1.100000
2 0.2 1.220000
3 0.3 1.362000
4 0.4 1.528200
5 0.5 1.721020
6 0.6 1.943122
7 0.7 2.197434
8 0.8 2.487178
9 0.9 2.815895
10 1.0 3.187485
The second, and not really desirable method is to pass a string version of the function, and eval
it in the eulers_method
function:
def eulers_method(x, y, diff_eq, h, n):
#empty solution and x_value lists to be used in the euler function
solutions = []
x_values = []
for s in range (0, n):
# compute the function
eq = eval(diff_eq)
s = y + h*(eq)
#replace initial values with the new values and adds them to the solution and x_value lists
y = s
solutions.append(s)
x = x + h
x_values.append(x)
#creates a dataframe from the solutions
Euler_values = pd.DataFrame(list(zip(x_values, solutions)), columns = ['xₙ', 'yₙ'])
#creates an index for the dataframe starting at one and increasing by one
Euler_values.index = Euler_values.index + 1
Euler_values.rename_axis('n', inplace = True)
return Euler_values
#enter an initial x value, initial y value, the differential equation, the step size, and the number of solutions to generate
eulers_method(0, 1, 'x+y', 0.1, 10)
The output is the same.