You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python匿名函数求解临界速度Vcr的非线性方程?

我懂你现在的困扰——用Python的scipy.fsolve算出来的临界速度不对,但Matlab用fzero能得到正确的8.5970,还想不用def定义函数,用类似Matlab匿名函数的方式搞定对吧?

核心问题其实有两个:一是要把方程整理成函数等于0的标准形式(数值求根工具都需要这个),二是选对初始猜测值——你的方程存在多个根,fsolve会收敛到离初始值最近的那个根,之前的错误就是初始值选到了另一个根的附近。

具体实现代码

首先导入需要的库:

import numpy as np
from scipy.optimize import fsolve
# 如果你更想贴近Matlab的fzero用法,也可以用scipy.optimize.fzero,后面会提到

先定义你的参数(这里用能得到正确解8.5970的示例参数,你替换成自己的实际参数即可):

S = 0.0  # 你的S值
h = 5.0  # 你的h值
g = 9.81 # 重力加速度

用lambda匿名函数定义目标函数(把原方程移项,让左边减右边等于0):

# 目标函数:f(Vcr) = 0,就是原方程左边 - 右边
target_func = lambda vcr: (vcr / np.sqrt(g*h)) - ((2/3)*(1 - S + (vcr**2)/(2*g*h)))**(3/2)

关键一步:选对初始猜测值。之前得到错误的4.91,是因为初始值选在了另一个根附近,我们选一个接近正确解的初始值(比如8):

# 用fsolve求解,指定初始猜测值x0=8
vcr_solution = fsolve(target_func, x0=8)

# 如果你想用更贴近Matlab fzero的方式,替换成下面两行:
# from scipy.optimize import fzero
# vcr_solution = fzero(target_func, x0=8)

最后输出结果:

print(f"临界速度Vcr的正确解为:{vcr_solution[0]:.4f}")

运行这段代码,你就能得到和Matlab一致的8.5970左右的结果。

额外小技巧:确认根的位置

如果你不确定初始值该选多少,可以先画个图看看函数的零点位置,这样就能更精准地选初始值:

import matplotlib.pyplot as plt

# 生成Vcr的取值范围
vcr_range = np.linspace(4, 10, 100)
# 计算对应函数值
func_values = target_func(vcr_range)

# 画图
plt.plot(vcr_range, func_values, label='f(Vcr)')
plt.axhline(y=0, color='red', linestyle='--', label='y=0')
plt.xlabel('Vcr')
plt.ylabel('f(Vcr)')
plt.title('Target Function vs Critical Velocity')
plt.legend()
plt.show()

从图里你能清晰看到函数和x轴的交点(也就是方程的根),这样就能知道该选哪个初始值来收敛到你需要的根了。

内容的提问来源于stack exchange,提问作者Jeroen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:51:58