Search code examples
pythonpython-3.xfunctionglobal-variableslocal-variables

How to change a global variable dependent of other global variables inside the Python function


My task is to implement Euler's method in Python with five arguments and one of them is a function f dependent on variables t and x (precisely: f(t,x)). When I tried to execute Euler's method with a given function f, I got errors, because I did not declare variables t and x. I declared them as equal to 1 (it could have been any other value) and decided to change their values inside the function. Unfortunately, after changing values, I still get a result for x=t=1 (I checked it by using print(f). I tried to use global, but it looks like function f is still dependent on x=1 and t=1. How do I change values of t and x inside "Euler" function? Or maybe there is more efficient way to complete the task?

from math import sin,cos

def Euler(f,x_0,t_0,T,n):
    h=(T-t_0)/n
    x_list=[x_0]
    t_list=[t_0]
    for i in range(n):
        global x
        x=x_list[i]
        global t
        t=t_list[i]
        next_x=x+h*f
        x_list.append(next_x)
        next_t=round(t+h, 2)
        t_list.append(next_t)
    return t_list,x_list

x=1
t=1

sol=Euler((-2)*(x-cos(t))-sin(t),1,0,2,20)

print(sol)


Solution

  • Firstly, it seems that there's a misunderstanding on how to pass a function as an argument in Python. When you call the Euler function with (-2)*(x-cos(t))-sin(t) as the first argument, Python immediately tries to evaluate this expression using the current values of x and t, which are both 1. This results in a number, not a function.

    To correctly pass a function that depends on t and x, you should define a separate function, and then pass this function to your Euler function.

    The use of global variables t and x inside the Euler function is unnecessary and can lead to confusion. Instead, the values for t and x should be obtained from the t_list and x_list variables, respectively, and passed to the function f.

    Here is a modified version of your code:

    from math import sin, cos
    
    def Euler(f, x_0, t_0, T, n):
        h = (T - t_0) / n
        x_list = [x_0]
        t_list = [t_0]
        for i in range(n):
            x = x_list[i]
            t = t_list[i]
            next_x = x + h * f(t, x)
            x_list.append(next_x)
            next_t = round(t + h, 2)
            t_list.append(next_t)
        return t_list, x_list
    
    # Defining the function to pass to Euler's method
    def my_func(t, x):
        return -2 * (x - cos(t)) - sin(t)
    
    sol = Euler(my_func, 1, 0, 2, 20)
    
    print(sol)
    

    In this updated version, my_func is defined as a function of t and x, and this function is passed to Euler. Inside the Euler function, my_func (or more generally f) is called with the appropriate arguments t and x.