我正在使用scipy.optimize.minimize(method=‘SLSQP’)
,函数和约束使用scipy.interpolate.LinearNDInterpolator
进行插值。起始值是边界内的随机数。
我正在使用:
优化有时会运行并产生合理的结果,但有时优化器会开始请求大量内存,最高可达20GB,然后我的计算机就会停止工作。这种情况总是发生在边界之外的值。
scipy.interpolate.LinearNDInterpolator
是否可能无法与scipy.optimize.minimize(method=‘SLSQP’)
一起使用?在边界之外我没有模拟数据,因此插值给出fill_Value = 0或fill_value = 1e10。
当我使用scipy.optimize.fmin_slsqp
时会发生相同的行为不幸的是我的代码非常大但是使用这个数据集我总是会遇到内存问题:
#########################################
###Memory Leak scipy.optimize.minimize###
#########################################
import numpy as np
from scipy.optimize import minimize
from scipy.interpolate import LinearNDInterpolator
def objfun(x):
print x
return x[1]
points = np.array([[ 0.00000000e+00, 0.00000000e+00],[ 0.00000000e+00, 1.00334000e+00],[ 0.00000000e+00, 2.00669000e+00],[ 7.07700000e+02, 0.00000000e+00],[ 7.07700000e+02, 1.00334000e+00],[ 7.07700000e+02, 2.00669000e+00],[ 1.56890000e+03, 0.00000000e+00],[ 1.56890000e+03, 1.00334000e+00],[ 1.56890000e+03, 2.00669000e+00],[ 2.50080000e+03, 0.00000000e+00],[ 2.50080000e+03, 1.00334000e+00],[ 2.50080000e+03, 2.00669000e+00],[ 3.47090000e+03, 0.00000000e+00],[ 3.47090000e+03, 1.00334000e+00],[ 3.47090000e+03, 2.00669000e+00],[ 4.46380000e+03, 0.00000000e+00],[ 4.46380000e+03, 1.00334000e+00],[ 4.46380000e+03, 2.00669000e+00],[ 5.47130000e+03, 0.00000000e+00],[ 5.47130000e+03, 1.00334000e+00],[ 5.47130000e+03, 2.00669000e+00],[ 6.48890000e+03, 0.00000000e+00],[ 6.48890000e+03, 1.00334000e+00],[ 6.48890000e+03, 2.00669000e+00],[ 7.51360000e+03, 0.00000000e+00],[ 7.51360000e+03, 1.00334000e+00],[ 7.51360000e+03, 2.00669000e+00],[ 8.54350000e+03, 0.00000000e+00],[ 8.54350000e+03, 1.00334000e+00],[ 8.54350000e+03, 2.00669000e+00],[ 9.57740000e+03, 0.00000000e+00],[ 9.57740000e+03, 1.00334000e+00],[ 9.57740000e+03, 2.00669000e+00],[ 1.06143000e+04, 0.00000000e+00],[ 1.06143000e+04, 1.00334000e+00],[ 1.06143000e+04, 2.00669000e+00],[ 1.16535000e+04, 0.00000000e+00],[ 1.16535000e+04, 1.00334000e+00],[ 1.16535000e+04, 2.00669000e+00],[ 1.26945000e+04, 0.00000000e+00],[ 1.26945000e+04, 1.00334000e+00],[ 1.26945000e+04, 2.00669000e+00],[ 1.37369000e+04, 0.00000000e+00],[ 1.37369000e+04, 1.00334000e+00],[ 1.37369000e+04, 2.00669000e+00],[ 1.47804000e+04, 0.00000000e+00],[ 1.47804000e+04, 1.00334000e+00],[ 1.47804000e+04, 2.00669000e+00],[ 1.58248000e+04, 0.00000000e+00],[ 1.58248000e+04, 1.00334000e+00],[ 1.58248000e+04, 2.00669000e+00],[ 1.68698000e+04, 0.00000000e+00],[ 1.68698000e+04, 1.00334000e+00],[ 1.68698000e+04, 2.00669000e+00],[ 1.79153000e+04, 0.00000000e+00],[ 1.79153000e+04, 1.00334000e+00],[ 1.79153000e+04, 2.00669000e+00],[ 1.89612000e+04, 0.00000000e+00],[ 1.89612000e+04, 1.00334000e+00],[ 1.89612000e+04, 2.00669000e+00],[ 2.00074000e+04, 0.00000000e+00],[ 2.00074000e+04, 1.00334000e+00],[ 2.00074000e+04, 2.00669000e+00]])
values = np.array([ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,4.29730000e+01, 5.72947500e-01, -5.35464000e-01,9.11676000e+01, 1.31063500e+00, -1.05937500e+00,1.38660750e+02, 2.11484000e+00, -1.50850500e+00,1.84497000e+02, 2.96052000e+00, -1.88466000e+00,2.28622000e+02, 3.83846000e+00, -2.19702000e+00,2.71163000e+02, 4.74426500e+00, -2.45397000e+00,3.12274500e+02, 5.67547500e+00, -2.66222500e+00,3.52102000e+02, 6.63058000e+00, -2.82711000e+00,3.90774000e+02, 7.60858000e+00, -2.95286000e+00,4.28399500e+02, 8.60879000e+00, -3.04289000e+00,4.65074500e+02, 9.63071000e+00, -3.10001500e+00,5.00881500e+02, 1.06739850e+01, -3.12655500e+00,5.35893000e+02, 1.17383500e+01, -3.12444000e+00,5.70166500e+02, 1.28235000e+01, -3.09540500e+00,6.03760000e+02, 1.39293500e+01, -3.04082500e+00,6.36721500e+02, 1.50557500e+01, -2.96194500e+00,6.69093500e+02, 1.62026000e+01, -2.85982000e+00,7.00915000e+02, 1.73698000e+01, -2.73539500e+00,7.32222000e+02, 1.85573500e+01, -2.58950000e+00,7.63042500e+02, 1.97651000e+01, -2.42286000e+00])
S22_Adh1Ad_inter = LinearNDInterpolator(points,values,1e10)
def Fsigcon(x):
rf1_int = x[1]
rf_eval=[]
x_eval=[]
interval = np.linspace(0,x[0],x[0]/0.01)
if interval.size == 0:
interval=np.array([x[0]])
for xcoord in interval:
rf_eval.append(rf1_int)
x_eval.append(xcoord)
val_interp = S22_Adh1Ad_inter(rf_eval,x_eval) #'nearest' #'linear' #'cubic'
out = (val_interp.min()-39.45)
return out
points = np.array([[ 0.00000000e+00, 0.00000000e+00],[ 0.00000000e+00, 1.99997000e-01],[ 0.00000000e+00, 4.00002000e-01],[ 7.07700000e+02, 1.39999000e-01],[ 7.07700000e+02, 3.39996000e-01],[ 1.56890000e+03, 8.00020000e-02],[ 1.56890000e+03, 2.79999000e-01],[ 2.50080000e+03, 1.99970000e-02],[ 2.50080000e+03, 2.20001000e-01],[ 2.50080000e+03, 1.90000200e+00],[ 3.47090000e+03, 1.60004000e-01],[ 3.47090000e+03, 3.60001000e-01],[ 4.46380000e+03, 9.99980000e-02],[ 4.46380000e+03, 3.00003000e-01],[ 5.47130000e+03, 4.00010000e-02],[ 5.47130000e+03, 2.39998000e-01],[ 5.47130000e+03, 3.00000000e+00],[ 6.48890000e+03, 1.80000000e-01],[ 6.48890000e+03, 3.79997000e-01],[ 7.51360000e+03, 1.20003000e-01],[ 7.51360000e+03, 3.20000000e-01],[ 8.54350000e+03, 5.99980000e-02],[ 8.54350000e+03, 2.60002000e-01],[ 9.57740000e+03, 0.00000000e+00],[ 9.57740000e+03, 1.99997000e-01],[ 9.57740000e+03, 4.00002000e-01],[ 1.06143000e+04, 1.39999000e-01],[ 1.06143000e+04, 3.39996000e-01],[ 1.16535000e+04, 8.00020000e-02],[ 1.16535000e+04, 2.79999000e-01],[ 1.26945000e+04, 1.99970000e-02],[ 1.26945000e+04, 2.20001000e-01],[ 1.26945000e+04, 1.90000200e+00],[ 1.37369000e+04, 1.60004000e-01],[ 1.37369000e+04, 3.60001000e-01],[ 1.47804000e+04, 9.99980000e-02],[ 1.47804000e+04, 3.00003000e-01],[ 1.58248000e+04, 4.00010000e-02],[ 1.58248000e+04, 2.39998000e-01],[ 1.58248000e+04, 3.00000000e+00],[ 1.68698000e+04, 1.80000000e-01],[ 1.68698000e+04, 3.79997000e-01],[ 1.79153000e+04, 1.20003000e-01],[ 1.79153000e+04, 3.20000000e-01],[ 1.89612000e+04, 5.99980000e-02],[ 1.89612000e+04, 2.60002000e-01],[ 2.00074000e+04, 0.00000000e+00],[ 2.00074000e+04, 1.99997000e-01],[ 2.00074000e+04, 4.00002000e-01]])
values = np.array([ 0. , 0. , 0. , 0.010168, 0.010055, 0.046252,0.045731, 0.092687, 0.107056, 0.11196 , 0.19232 , 0.190859,0.29924 , 0.295611, 0.401297, 0.42018 , 0.450553, 0.564416,0.561699, 0.727387, 0.719631, 0.883825, 0.894486, 0. ,1.087256, 1.084631, 1.298136, 1.287209, 1.507127, 1.505308,1.424393, 1.740491, 1.839568, 1.993769, 1.981605, 2.251336,2.238475, 2.330676, 2.511822, 2.723058, 2.803453, 2.792818,3.104855, 3.08533 , 3.29549 , 3.393902, 0. , 3.721085,3.714504])
G_Adh1Ad_inter = LinearNDInterpolator(points,values,0)
def Gcon(x):
val_interp = G_Adh1Ad_inter(x[1],x[0])
out = (val_interp.min()-0.33)
return out
cons = (
{'type': 'ineq',
'fun' : Fsigcon},
{'type': 'ineq',
'fun' : Gcon}
)
amin = 0.0
amax = 3.0
bounds=[(amin,amax),(0.0, 20007.400000000001)]
a_start= 1.5343936873636999
rf1_start= 6824.9659188661817
res_int = minimize(objfun, [a_start,rf1_start],method='SLSQP',jac=None,bounds=bounds,constraints=cons,tol =1e-4,options={'iprint':2, 'disp': True , 'maxiter':1e2})
答案 0 :(得分:0)
到目前为止,我自己的解决方案是不使用scipy.interpolate.LinearNDInterpolator,而是用几个一维插值替换它。 对于3D问题和使用scipy.interpolate.UnivariateSpline的三次插值,我需要在矩形网格上有64个数据点。在第一步中,我仅在坐标方向1上插值(16次)并将我的问题减少到具有16个点的2D-one。在下一步中,我在坐标方向2上插值(4次)并进一步减少到1D promlem,剩下4个点。最后一步是在坐标方向3上进行一次1D插补。 使用此过程scipy.optimize.minimize(method ='SLSQP')即使超出边界也不会遇到内存问题。 插值代码如下:
#!/usr/bin/python
# coding: utf8
# Filename: N1Dsplines.py
import numpy as np
from scipy.interpolate import UnivariateSpline
from scipy.interpolate import LinearNDInterpolator
def sort2lists(list1=[],list2=[]):
'''
Lists must be equal size
sorts after list1
'''
list1list2 = [(list1[i1],list2[i1]) for i1 in range(len(list1))]
list1list2 = sorted(list1list2, key=lambda x:x[0])
list1 = [i1[0] for i1 in list1list2]
list2 = [i1[1] for i1 in list1list2]
return list1,list2
def sortdictkeysandreturnvalues(dictionary):
keyvalues = [[i1,dictionary[i1]] for i1 in dictionary]
keyvalues = sorted(keyvalues, key= lambda x: x[0])
points = [i1[1] for i1 in keyvalues]
return points
def meshgrid2(*arrs):
if len(arrs)==1:
arrs = tuple(arrs[0])
# list with entries= length of the input arrays
lens = map(len, arrs)
# dim = number of arrays
dim = len(arrs)
# sz is the multiplication of the length of the *arrs
sz = 1
for s in lens:
sz*=s
ans = []
for i, arr in enumerate(arrs):
slc = [1]*dim
slc[i] = lens[i]
arr2 = np.asarray(arr).reshape(slc)
for j, sz in enumerate(lens):
if j!=i:
arr2 = arr2.repeat(sz, axis=j)
ans.append(arr2)
return tuple(ans)
def arr2points(*arrs):
'''
arrs = ([list1], [list2], ...)
ans = [[x1,y1,z1...],[x1,y1,z2,...],...,[x1,y2,z1,...],...[x2,y1,z1]
'''
if len(arrs)==1:
arrs = tuple(arrs[0])
# list with entries= length of the input arrays
lens = map(len, arrs)
# dim = number of arrays
dim = len(arrs)
# sz is the multiplication of the length of the *arrs
sz = 1
for s in lens:
sz*=s
ans = [[] for i1 in range(sz)]
for i1, arr in enumerate(arrs):
count = 0
sz2 = 1
for s in lens[i1+1:]:
sz2*=s
for i4 in range(sz/(lens[i1]*sz2)):
for i2 in arr:
for i3 in range(sz2):
ans[count].append(i2)
count+=1
return ans
#
def N1Dsplines(pointsvaluesdict={}, point =(), scheme = (1,0), k=3):
'''
Geht nur für reguläre Grids nicht für scattered data points
pointsvaluesdict = {(x,y,z):value , (x,y,z):value ....}
point = (x,y,z)
k = interpolation order
scheme = (2,1,0) bedeutet erst wird in Richtung z=2 dann in Richtung y=1 und als letztes in Richtung x=0 interpoliert
'''
#Find the closest Datapoints to the point coordinates
closest = {i1:[] for i1 in scheme}
for i1 in scheme:
for count in range(k+1):
points = [i2 for i2 in pointsvaluesdict.keys() if i2[i1] not in closest[i1]]
closest[i1].append(min(points, key=lambda x:abs(x[i1]-point[i1]))[i1])
#Make pointgrid from closest points
liste = sortdictkeysandreturnvalues(closest)
pointsgrid = arr2points(liste)
pointsgrid = [tuple(i1) for i1 in pointsgrid]
valuesgrid = [pointsvaluesdict[i1] for i1 in pointsgrid]
griddict = {pointsgrid[i1]:valuesgrid[i1] for i1 in range(len(pointsgrid))}
#Get 1D Splines by letting scheme[>0]=const and vary scheme[0]
for i1 in scheme:
pointsinter = []
valuesinter = []
temp = closest.copy()
del temp[i1]
points = sortdictkeysandreturnvalues(temp)
points = arr2points(points)
for coords in points:
points2inter=[]
for i2 in pointsgrid:
i2red = list(i2)
del i2red[i1]
if coords == i2red:
points2inter.append(i2)
values2inter = [griddict[i2] for i2 in points2inter]
points2inter = [i2[i1] for i2 in points2inter]
points2inter,values2inter = sort2lists(list1=points2inter,list2=values2inter)
coords.insert(i1,point[i1])
pointsinter.append(coords)
s = UnivariateSpline(points2inter, values2inter,k=k, s=0)
value = s(point[i1])
valuesinter.append(value)
closest[i1]=[point[i1]]
pointsgrid = pointsinter
pointsgrid = [tuple(i1) for i1 in pointsgrid]
valuesgrid = valuesinter
griddict = {pointsgrid[i1]:valuesgrid[i1] for i1 in range(len(pointsgrid))}
return griddict
#
x = np.array([1, 2, 3, 4, 5, 6, 7 ,8 ,9, 10])
y = x
z= x
w = x
xx, yy, zz, ww = meshgrid2(x, y,z,w)
v= xx**2 + yy**2 +zz**2 +ww**2
xx = xx.flatten()
yy = yy.flatten()
zz = zz.flatten()
ww = ww.flatten()
v = v.flatten()
pointsvalues = [((xx[i1],yy[i1],zz[i1], ww[i1]),v[i1]) for i1 in range(len(v))]
pointsvaluesdict = {key: value for (key, value) in pointsvalues}
pointsvaluesdict.keys()
pointsvaluesdict.values()
point = (5.5,4.5,3.5,2.5)
5.5**2 + 4.5**2 + 3.5**2 +2.5**2== 69
N1Dsplines(pointsvaluesdict=pointsvaluesdict, point =(5.5,4.5,3.5,2.5), scheme = (0,1,2,3), k=3)
#Outside Bounds
N1Dsplines(pointsvaluesdict=pointsvaluesdict, point =(0,0,0,0), scheme = (0,1,2,3), k=3)
答案 1 :(得分:0)
但是,为什么你的插值首先超出你定义的变量范围?
您似乎已为自己的变量定义了 max
和 min
界限。
我知道根据我使用的scipy
版本,有时最小化函数不接受我的界限,除非它们以浮点数给出(这是一个非常可怕的错误)。
您可以尝试重新定义界限
bnds = np.array( [ [min_var1, max_var1], [min_var2, max_var2] ], dtype = float )
这通常适合我。
答案 2 :(得分:0)
sudo -H pip install --upgrade scipy
sudo -H pip install --upgrade numpy
完全解决了这个问题