用积分最小化函数 - scipy

发布于 2025-01-12 08:51:41 字数 751 浏览 0 评论 0原文

我想找到一个函数的参数,该函数将在定义的区间内产生特定的积分值。为了简单起见,下面的示例将函数视为一条直线,而我要查找的参数是斜率m。我使用 scipy.integrate.quad 进行积分,并尝试使用 scipy.integrate.minimize 来查找斜率:

from scipy.integrate import quad
from scipy.optimize import minimize

IntegralValue = 10
initial_guess = 0.1

def function(m):
    intgrl, abserr = quad(lambda x: m*x, 0, 10) # interval from 0 to 10
    return intgrl - IntegralValue
res = minimize(function, initial_guess, method='nelder-mead',options={'xtol': 1e-8, 'disp': True})

print(res.x)

一个简单的 0.2 应该是结果(function(0.2) 结果为 0),但由于某种原因,我收到一条警告,提示“已超出函数求值的最大数量”,并且输出为不能制造的东西意义(-6.338253e+27)。默认的最小化方法也不起作用。也许我遗漏了一些东西或被误解了,但我无法弄清楚。我很感激你的帮助。我在 Windows 10 上使用 Python 3.7.10。

I want to find the parameter of a function that will result in a specific integral value in a defined interval. To make things simpler, the example below considers the function to be a straight line, and the parameter I want to find is the slope m. I use scipy.integrate.quad to integrate and was trying to use scipy.integrate.minimize to find the slope:

from scipy.integrate import quad
from scipy.optimize import minimize

IntegralValue = 10
initial_guess = 0.1

def function(m):
    intgrl, abserr = quad(lambda x: m*x, 0, 10) # interval from 0 to 10
    return intgrl - IntegralValue
res = minimize(function, initial_guess, method='nelder-mead',options={'xtol': 1e-8, 'disp': True})

print(res.x)

A simple 0.2 should be the result (function(0.2) results in 0), but for some reason I get a warning that the "maximum number of function evaluations has been exceeded" and the output is something that doesn't make sense (-6.338253e+27). Default minimize method also did not work. Maybe I am missing something or misunderstood, but I couldn't figure it out. I appreciate the help. I am using Python 3.7.10 on Windows 10.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

二智少女 2025-01-19 08:51:41

最小值当然是负无穷大。为了得到零,我只需将问题限制为非负值,正如 @ForceBru 和 @joni 所评论的那样。谢谢!

编辑

这是最终的功能完整代码:

from scipy.integrate import quad
from scipy.optimize import minimize

IntegralValue = 10
initial_guess = 0.1

def function(m):
    intgrl, abserr = quad(lambda x: m*x, 0, 10) # interval from 0 to 10
    return abs(intgrl - IntegralValue)
res = minimize(function, initial_guess, method='nelder-mead',options={'xtol': 1e-8, 'disp': True})

print(res.x)

The minimum is of course negative infinity. To get a zero, I just had to constrain the problem to non negative values, as commented by @ForceBru and @joni. Thanks!

EDIT

here is the final functional full code:

from scipy.integrate import quad
from scipy.optimize import minimize

IntegralValue = 10
initial_guess = 0.1

def function(m):
    intgrl, abserr = quad(lambda x: m*x, 0, 10) # interval from 0 to 10
    return abs(intgrl - IntegralValue)
res = minimize(function, initial_guess, method='nelder-mead',options={'xtol': 1e-8, 'disp': True})

print(res.x)
空城缀染半城烟沙 2025-01-19 08:51:41

您描述的问题是根查找之一;也就是说,您想要找到 m 使得 function(m) = 0。解决此类问题的适当工具是根查找函数 在 SciPy 中。

例如,您可以使用 root_scalar 如以下代码所示,它使用原始函数 function

from scipy.integrate import quad
from scipy.optimize import root_scalar


def function(m):
    intgrl, abserr = quad(lambda x: m*x, 0, 10) # interval from 0 to 10
    return intgrl - IntegralValue


IntegralValue = 10
guess_bracket = [0.0, 1.0]

res = root_scalar(function, x0=guess_bracket[0], x1=guess_bracket[1])

if res.converged:
    print(f"m = {res.root}")
else:
    print(f'root_scalar failed: res.flag={res.flag}')

输出:

m = 0.2

The problem that you describe is one of root finding; that is, you want to find m such that function(m) = 0. The appropriate tool for such a problem is one of the root finding functions in SciPy.

For example, you could use root_scalar as in the following code, which uses your original function function:

from scipy.integrate import quad
from scipy.optimize import root_scalar


def function(m):
    intgrl, abserr = quad(lambda x: m*x, 0, 10) # interval from 0 to 10
    return intgrl - IntegralValue


IntegralValue = 10
guess_bracket = [0.0, 1.0]

res = root_scalar(function, x0=guess_bracket[0], x1=guess_bracket[1])

if res.converged:
    print(f"m = {res.root}")
else:
    print(f'root_scalar failed: res.flag={res.flag}')

Output:

m = 0.2
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文