gpt4 book ai didi

Python:具有约束的多元非线性求解器

转载 作者:太空狗 更新时间:2023-10-29 17:17:10 27 4
gpt4 key购买 nike

给定一个函数 f(x),它接受一个输入向量 x 并返回一个相同长度的向量,你如何找到函数设置约束的根在 x 上? (例如,x 的每个分量的范围。)

令我惊讶的是,我找不到很多关于此的有用信息。在 Optimization and Root finding algorithms 的 scipy 列表中标量函数似乎有一些选项,例如 brentq .不过,我找不到任何支持多变量情况下的这种选项的算法。

当然可以做一个解决方法,比如对返回向量的每个分量进行平方,然后使用最小化器之一,例如 differential_evolution (这是我实际认为的唯一一个)。我无法想象这是一个好的策略,因为它破坏了牛顿算法的二次收敛。此外,我发现似乎没有针对此的选项真的很令人惊讶,因为这一定是一个非常普遍的问题。我错过了什么吗?

最佳答案

解决此问题的一个(不是特别好但希望可行)选项是为求解器提供一个函数,该函数仅在受限区域中有根,并且以确保求解器在约束区域中被推回的方式继续适当的区域(有点像 here 但在多个维度上)。

要实现这一点(至少对于矩形约束),可以做的是实现一个 constrainedFunction,它从函数的边界值开始线性延续:

import numpy as np

def constrainedFunction(x, f, lower, upper, minIncr=0.001):
x = np.asarray(x)
lower = np.asarray(lower)
upper = np.asarray(upper)
xBorder = np.where(x<lower, lower, x)
xBorder = np.where(x>upper, upper, xBorder)
fBorder = f(xBorder)
distFromBorder = (np.sum(np.where(x<lower, lower-x, 0.))
+np.sum(np.where(x>upper, x-upper, 0.)))
return (fBorder + (fBorder
+np.where(fBorder>0, minIncr, -minIncr))*distFromBorder)

您可以向该函数传递一个 x 值、您要继续的函数 f 以及两个数组 lowerupper 具有与 x 相同的形状,给出所有维度的下限和上限。现在您可以将这个函数而不是您的原始函数传递给求解器来求根。

continuation 的陡度暂时简单地作为边界值,以防止边界处符号变化的陡峭跳跃。为了防止根在约束区域之外,将一些小值添加/减去正/负边界值。我同意这不是处理此问题的好方法,但它似乎有效。

这里有两个例子。对于这两种情况,初始猜测都在约束区域之外,但在约束区域中找到了正确的根。

求约束为 [-2, -1]x[1, 2] 的多维余弦的根给出:

from scipy import optimize as opt

opt.root(constrainedFunction, x0=np.zeros(2),
args=(np.cos, np.asarray([-2., 1.]), np.asarray([-1, 2.])))

给出:

    fjac: array([[ -9.99999975e-01,   2.22992740e-04],
[ 2.22992740e-04, 9.99999975e-01]])
fun: array([ 6.12323400e-17, 6.12323400e-17])
message: 'The solution converged.'
nfev: 11
qtf: array([ -2.50050470e-10, -1.98160617e-11])
r: array([-1.00281376, 0.03518108, -0.9971942 ])
status: 1
success: True
x: array([-1.57079633, 1.57079633])

这也适用于非对角函数:

def f(x):
return np.asarray([0., np.cos(x.sum())])

opt.root(constrainedFunction, x0=np.zeros(2),
args=(f, np.asarray([-2., 2.]), np.asarray([-1, 4.])))

给出:

    fjac: array([[ 0.00254922,  0.99999675],
[-0.99999675, 0.00254922]])
fun: array([ 0.00000000e+00, 6.12323400e-17])
message: 'The solution converged.'
nfev: 11
qtf: array([ 1.63189544e-11, 4.16007911e-14])
r: array([-0.75738638, -0.99212138, -0.00246647])
status: 1
success: True
x: array([-1.65863336, 3.22942968])

关于Python:具有约束的多元非线性求解器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43995862/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com