scipy.optimize SHGO sobol可能存在错误:TypeError:< lambda>()接受1个位置参数,但给出了3个

sz81bmfz  于 2023-05-22  发布在  Go
关注(0)|答案(2)|浏览(189)

我一直在尝试用SciPy optimizer SHGO进行一些全局优化,但在采样方法'sobol'上遇到了问题。具体来说,我得到一个类型的错误:TypeError: <lambda>() takes 1 positional argument but 3 were given
让我怀疑它可能与采样方法本身的错误有关的事情是,当我使用simplicial作为采样方法或不同的(仍然受约束的)优化算法(如SLSQP)时,错误不会发生。
下面是代码,我有兴趣了解其他人是否可以重现此错误。

import numpy as np
from numpy import linalg as la
import scipy as sc
import scipy.optimize as opt

print("numpy version: ", np.__version__)
print("scipy version: ", sc.__version__)

# d-dim Shannon entropy
def ShEntr(x):
    s=0
    for p_i in x:
        if p_i > 1e-16 and p_i < 1-1e-16:
            s = s - p_i*np.log2(p_i)
    return s

# Function to be optimized
def fun(y, k, g):
    p,c = y
    mat = [[p,c],[c,1-p]]
    return -ShEntr(la.eigvals(mat))   #- sign in front of it due to the fact that scipy.otimize is a minimization

# Optimization parameters
x0 = [0.5,0.2] # Starting point for SLSQP
boun = [(0,1),(0,1)] # Optimization parameters bounds
cons = ({'type':'ineq', 'fun': lambda y: y[0]-y[0]**2-y[1]**2}) # Optimization parameters constraints

## Optimization
# SLSQP
res = opt.minimize(fun, x0, (0.3,0.3), method='SLSQP', constraints=cons, bounds=boun, options={'maxiter':10000})
print("SLSQP: ", -res.fun)
# SHGO: simplicial
res = opt.shgo(fun, bounds=boun, args=(0.3,0.3), n = 30, iters = 5, sampling_method = 'simplicial', constraints=cons)
print("SHGO simplicial: ", -res.fun)
# SHGO: sobol
res = opt.shgo(fun, bounds=boun, args=(0.3,0.3), n = 30, iters = 5, sampling_method = 'sobol', constraints=cons)
print("SHGO sobol: ", -res.fun)

我得到的结果是

numpy version:  1.20.3
scipy version:  1.7.3
SLSQP:  0.9999999999999942
SHGO simplicial:  1.0
Traceback (most recent call last):
  File "... path /test.py", line 36, in <module>
    res = opt.shgo(fun, bounds=boun, args=(0.3,0.3), n = 30, iters = 5, sampling_method = 'sobol', constraints=cons)
  File "... path \Anaconda3\lib\site-packages\scipy\optimize\_shgo.py", line 419, in shgo
    shc.construct_complex()
  File "... path \Anaconda3\lib\site-packages\scipy\optimize\_shgo.py", line 733, in construct_complex
    self.iterate()
  File "... path \Anaconda3\lib\site-packages\scipy\optimize\_shgo.py", line 876, in iterate
    self.iterate_complex()
  File "... path \Anaconda3\lib\site-packages\scipy\optimize\_shgo.py", line 912, in iterate_delaunay
    self.sampled_surface(infty_cons_sampl=self.infty_cons_sampl)
  File "... path \Anaconda3\lib\site-packages\scipy\optimize\_shgo.py", line 1243, in sampled_surface
    self.fun_ref()
  File "... path \Anaconda3\lib\site-packages\scipy\optimize\_shgo.py", line 1356, in fun_ref
    if g(self.C[i, :], *self.args) < 0.0:
TypeError: <lambda>() takes 1 positional argument but 3 were given

P.S.:我知道这里的函数fun(y, k, g)不需要args kg,但我只是(过度)简化了我使用的原始函数(需要kg)来重现错误。

von4xj4u

von4xj4u1#

g(self.C[i, :], *self.args)scipy如何将搜索变量和args元组传递给您的函数。我认为你的fun(y,k,g)处理得很好。
但我认为错误在于调用了其中一个约束或边界函数。它们都必须具有相同的签名-2项args意味着3个变量。
if g(self.C[i, :], *self.args) < 0.0:测试某些函数结果与0.0的对比。

2q5ifsrm

2q5ifsrm2#

为了完整起见,我将解决方法报告为here
而不是给opt.shgo提供funargs=(k,g),只需定义一个新的lambda函数并将其提供给shgo

func = lambda x,a=a,b=b: fun(x,a,b)
res = opt.shgo(func, bounds=boun, n = 30, iters = 5, sampling_method = 'sobol', constraints=cons)

相关问题