pythonfunctioncalculus

Getting a function to call an equation


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)

Solution

  • 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.