У меня есть следующая функция, для которой я пытаюсь решить Vcr для заданных S, h, g:

Vcr/np.sqrt(g*h)=((2/3)*(1-S+ (Vcr**2)/(2*g*h)))**(3/2)

Я делаю следующее:

from scipy.optimize import fsolve
import numpy as np
S = 0.06
h = 15.14
g = 9.8

def eqn(Vcr,g,h,S):
    return (Vcr/np.sqrt(g*h)-((2/3)*(1-S+ (Vcr**2)/(2*g*h)))**(3/2))
ans = fsolve(lambda Vcr,g,h,S: eqn(Vcr,g,h,S), x0=5, args=(S,h,g))
print(eqn(ans,g,h,S))

Ответ напечатает 4,9109. Это НЕ правильный ответ. Я проверил это в Matlab:

fun = @(Vcr) Vcr./sqrt(g*h)-((2/3)*(1-S+ (Vcr.^2)./(2*g*h))).^(3/2);
sol = fzero(fun, 5); % solution critical speed;
# sol = 8.5970

Затем решение подставляется в уравнение Python и дает мне: print(eqn(8.5970,g,h,S))=0 Так что действительно должно быть 8,5970.

Как я могу решить эту проблему в Python с выражением, близким к заданному выражению Matlab (с анонимной функцией)? Если возможно, я не хочу определять функцию как def ():

0
Jeroen 9 Дек 2020 в 13:30

1 ответ

Лучший ответ

Дополнительные аргументы функции должны быть переданы в том порядке, в котором она ожидает, вы их изменили (args=(S,h,g), в то время как ваша функция объявляет их в обратном порядке: lambda Vcr,g,h,S:).

Размещение их в правильном порядке дает ожидаемое решение:

from scipy.optimize import fsolve
import numpy as np
S = 0.06
h = 15.14
g = 9.8

def eqn(Vcr,g,h,S):
    return (Vcr/np.sqrt(g*h)-((2/3)*(1-S+ (Vcr**2)/(2*g*h)))**(3/2))

ans = fsolve(lambda Vcr,g,h,S: eqn(Vcr,g,h,S), x0=5, args=(g, h, S))
print(ans, eqn(ans,g,h,S))
# [8.5970162] [1.11022302e-16]
1
Thierry Lathuille 9 Дек 2020 в 10:47