我如何要求牛顿法在 Python 中用不同的初始猜测重试
How do I ask Newton method to try again with different initial guess in Python
我正在解决一个大问题,其中方程的根位置从一个值快速变化到另一个值。然而函数接近于0,所以牛顿法认为那里有一个根,但自己迭代出来。我希望能够让 root finder 再试一次,但如果第一次不能收敛,则使用不同的初始猜测,但我不确定如何处理这个错误。值得注意的是,我想使用 Newton/Secant 方法,因为由于我要解决的问题,二分法不会很有用。我在下面有一个例子可以说明我的问题。
我搜索了如何处理错误并查看了 scipy.optimize.newton 的文档,但找不到如何处理错误并要求它重试。我一直不得不手动输入新的猜测。
from numpy import *
from scipy import optimize
# Define a function that passes 1, but grazes it at another point
def f(x):
y = log(exp(-0.8*x)*cos(5*x) + 0.62)
return(y)
# Try find the root
root= optimize.newton(f, x0, tol = 1e-7, maxiter=80)
如果我 运行 这个 x0 值相当接近真正的根 (~0.2201),它会很快找到它。然而,该函数在 1.25 附近非常接近 0,但随后又掉头了。如果我将 x0 输入为 1.25,则根查找器无法收敛并且错误显示为 'Failed to converge after 80 iterations, value is nan'。我只是想要一种方法来处理这个错误,并要求它用另一个猜测再试一次。我有一个根查找器作为一个大功能的一部分,我知道它有一个根,它刚刚移动了。因此,当我收到此错误时,它只是终止了我想避免的整个代码。
发生的事情是您的根查找程序抛出异常,而您没有对此采取任何措施,这就是您看到错误消息的原因。
来自 Python 3.7.4 spec (Section 8.2):
Even if a statement or expression is syntactically correct, it may cause an error
...
Errors detected during execution are called exceptions
...
Most exceptions are not handled ... and result in error messages
由此可以看出,报错信息是因为发生了异常,没有进行处理。
的下一部分定义了您应该如何处理错误。
来自Python 3.7.4 spec (Section 8.3):
It is possible to write programs that handle selected exceptions.
...
The try statement works as follows.
• First, the try clause ... is executed.
• If an exception occurs during execution of the try clause, the rest of the clause is skipped. Then if its type matches the exception named after the except keyword, the except clause is executed, [then the program skips the rest of the try clause and continues after the except clause]
• If an exception occurs which does not match the exception named in the except clause, [the exception is thrown and can be caught by try-catch clauses wrapping around the current one]
使用这些信息,我们可以解决您的问题。
我们需要将您对根查找器的调用包装在 try
子句中:
try:
root = optimize.newton(f, x0, tol = 1e-7, maxiter=80)
...
由于 root
现在是 try
子句的局部范围,我们需要在外部声明它:
root = x0
try:
root = optimize.newton(f, x0, tol = 1e-7, maxiter=80)
...
我们现在需要添加 except 子句以尝试使用不同的值:
root = x0
try:
root = optimize.newton(f, x0, tol = 1e-7, maxiter=80)
except YOUR EXCEPTION:
root = optimizes.newton(f, other_x0, tol = 1e-7, maxiter=80)
您需要将 YOUR EXCEPTION
替换为达到最大迭代次数时抛出的异常的名称。
或者,您可以将其替换为 Exception
以捕获抛出的任何异常,但不推荐这样做,因为您可能会捕获另一个您不知道必须修复的异常。
我正在解决一个大问题,其中方程的根位置从一个值快速变化到另一个值。然而函数接近于0,所以牛顿法认为那里有一个根,但自己迭代出来。我希望能够让 root finder 再试一次,但如果第一次不能收敛,则使用不同的初始猜测,但我不确定如何处理这个错误。值得注意的是,我想使用 Newton/Secant 方法,因为由于我要解决的问题,二分法不会很有用。我在下面有一个例子可以说明我的问题。
我搜索了如何处理错误并查看了 scipy.optimize.newton 的文档,但找不到如何处理错误并要求它重试。我一直不得不手动输入新的猜测。
from numpy import *
from scipy import optimize
# Define a function that passes 1, but grazes it at another point
def f(x):
y = log(exp(-0.8*x)*cos(5*x) + 0.62)
return(y)
# Try find the root
root= optimize.newton(f, x0, tol = 1e-7, maxiter=80)
如果我 运行 这个 x0 值相当接近真正的根 (~0.2201),它会很快找到它。然而,该函数在 1.25 附近非常接近 0,但随后又掉头了。如果我将 x0 输入为 1.25,则根查找器无法收敛并且错误显示为 'Failed to converge after 80 iterations, value is nan'。我只是想要一种方法来处理这个错误,并要求它用另一个猜测再试一次。我有一个根查找器作为一个大功能的一部分,我知道它有一个根,它刚刚移动了。因此,当我收到此错误时,它只是终止了我想避免的整个代码。
发生的事情是您的根查找程序抛出异常,而您没有对此采取任何措施,这就是您看到错误消息的原因。
来自 Python 3.7.4 spec (Section 8.2):
Even if a statement or expression is syntactically correct, it may cause an error
...
Errors detected during execution are called exceptions
...
Most exceptions are not handled ... and result in error messages
由此可以看出,报错信息是因为发生了异常,没有进行处理。
的下一部分定义了您应该如何处理错误。
来自Python 3.7.4 spec (Section 8.3):
It is possible to write programs that handle selected exceptions.
...
The try statement works as follows.
• First, the try clause ... is executed.
• If an exception occurs during execution of the try clause, the rest of the clause is skipped. Then if its type matches the exception named after the except keyword, the except clause is executed, [then the program skips the rest of the try clause and continues after the except clause]
• If an exception occurs which does not match the exception named in the except clause, [the exception is thrown and can be caught by try-catch clauses wrapping around the current one]
使用这些信息,我们可以解决您的问题。
我们需要将您对根查找器的调用包装在
try
子句中:
try:
root = optimize.newton(f, x0, tol = 1e-7, maxiter=80)
...
由于 root
现在是 try
子句的局部范围,我们需要在外部声明它:
root = x0
try:
root = optimize.newton(f, x0, tol = 1e-7, maxiter=80)
...
我们现在需要添加 except 子句以尝试使用不同的值:
root = x0
try:
root = optimize.newton(f, x0, tol = 1e-7, maxiter=80)
except YOUR EXCEPTION:
root = optimizes.newton(f, other_x0, tol = 1e-7, maxiter=80)
您需要将 YOUR EXCEPTION
替换为达到最大迭代次数时抛出的异常的名称。
或者,您可以将其替换为 Exception
以捕获抛出的任何异常,但不推荐这样做,因为您可能会捕获另一个您不知道必须修复的异常。