How to fix this error: unsupported operand type(s) for ** or pow(): 'tuple' and 'int'

How to fix this error: unsupported operand type(s) for ** or pow(): 'tuple' and 'int'

我正在尝试求解具有两个变量的 ODE。我不明白为什么或如何在这里创建一个元组。函数 f 应该是 f = 10 - x - (4xy / 1+x^2) 有人可以帮忙吗?

def RK_step(f, g, x, y, t, dt):
    
    x_new = x + dt*f(x + 0.5*dt*f(x, y, t), y + 0.5*dt*f(x, y, t), t + 0.5*dt)
    y_new = y + dt*g(x + 0.5*dt*f(x, y, t), y + 0.5*dt*g(x, y, t), t + 0.5*dt)
    
    return x_new, y_new

def RK_method(f, g, x, y, dt, n):
    
    x_array = [x]
    y_array = [y]
    for i in range(1,n+1):
        t = i*dt
        x_array.append(RK_step(f, g, x_array[-1], y_array[-1], t, dt))
        y_array.append(RK_step(f, g, x_array[-1], y_array[-1], t, dt))
      
    return x_array, y_array


def f(x, y, t):
    return 10 - x - ((4*x*y) / (1 + (x**2)))

def g(x, y, t):
    return 4*x*(1- (y / (1 + x**2)))

T = 100
dt = 0.1
n = int(T/dt)
x_initial = 0
y_initial = 1

x_RK = RK_method(f, g, x_initial, y_initial, dt, n)
y_RK = RK_method(f, g, x_initial, y_initial, dt, n)
t = np.linspace(0,T,n+1)
plt.plot(t,x_RK)
plt.plot(t,y_RK)
plt.legend(['Runge-Kutta with $dt = ${}'.format(dt)]);

<ipython-input-7-530b1d126979> in f(x, y, t)
     56 
     57 def f(x, y, t):
---> 58     return (10 - (x - ((4*x*y) / (1 + (x**2)))))
     59 
     60 def g(x, y, t):

TypeError: unsupported operand type(s) for ** or pow(): 'tuple' and 'int'

这里:

x_array.append(RK_step(f, g, x_array[-1], y_array[-1], t, dt))
y_array.append(RK_step(f, g, x_array[-1], y_array[-1], t, dt))

RK_step returns 一个元组。您正在将元组放入 x_arrayy_array.

如果你想在 x_arrayy_array 之间拆分元组,那么你需要这样的东西:

x,y = RK_step(f, g, x_array[-1], y_array[-1], t, dt)
x_array.append(x)
y_array.append(y)

您不必要地多次计算相同的值。您可以简化此操作,同时通过将中点方法的代码更改为

来消除错误
def RK_step(f, g, x, y, t, dt):
    # compute only once
    f0, g0 = f(x, y, t), g(x, y, t)
    # note the remaining duplicated operations in the arguments
    x_new = x + dt*f(x + 0.5*dt*f0, y + 0.5*dt*g0, t + 0.5*dt)
    #            there is a typo     ----------^ in the original code
    y_new = y + dt*g(x + 0.5*dt*f0, y + 0.5*dt*g0, t + 0.5*dt)
    
    return x_new, y_new

def RK_method(f, g, x, y, dt, n):
    
    x_array = [x]
    y_array = [y]
    for i in range(1,n+1):
        t = i*dt
        # call the RK2 step only once, use all of the returned values
        x,y = RK_step(f, g, x, y, t, dt)
        x_array.append(x)
        y_array.append(y)
      
    return x_array, y_array


def f(x, y, t):
    return 10 - x - ((4*x*y) / (1 + (x**2)))

def g(x, y, t):
    return 4*x*(1- (y / (1 + x**2)))

T = 100
dt = 0.1
n = int(T/dt)
x_initial = 0
y_initial = 1

# call the integration procedure only once, use all of the returned values
x_RK,y_RK = RK_method(f, g, x_initial, y_initial, dt, n)
# do not rely on floating point arithmetic being accidentally correct
t = np.arange(n+1)*dt
plt.plot(t,x_RK)
plt.plot(t,y_RK)
plt.legend(['Runge-Kutta with $dt = ${}'.format(dt)]);

导致阴谋