def __init__(self, func, eps1=1e-4, eps2=1e-8, nthreads=1 ,kw={}): self.func=func if nthreads > 1: self.pool = workerpool.pool(func, nthreads=nthreads, kw=kw) self.eps1 = eps1 self.eps2 = eps2
def _minimize_neldermead_para(func, x0, callback=None, xtol=1e-4, ftol=1e-4, maxiter=None, maxfev=None, disp=False, return_all=False,pool=None, nthreads=1, nverts=None, nactive=None): maxfun = maxfev retall = return_all allvecs = [] x0 = np.asfarray(x0).flatten() N = len(x0) fcalls = [0] allcalls = [] if nverts is None: nverts = (N+1)*2 assert(nverts>=(N+1)) if nthreads>=nverts: nthreads = nverts pool = workerpool.pool(func, nthreads) if nactive is None: nactive = nthreads # number of active points if nactive >= nverts: nactive = nverts-1 def applicator(i, x): #print x pool.apply_async(i, x) fcalls[0] +=1 allcalls.append(x.tolist()) rank = len(x0.shape) if not -1 < rank < 2: raise ValueError("Initial guess must be a scalar or rank-1 sequence.") if maxiter is None: maxiter = N * 200 if maxfun is None: maxfun = N * 200 rho = 1 chi = 2 psi = 0.5 sigma = 0.5 nonzdelt = 0.05 zdelt = 0.00025 excess = nverts - N -1 one2np1 = list(range(1, nverts)) if rank == 0: sim = np.zeros((nverts,), dtype=x0.dtype) else: sim = np.zeros((nverts, N), dtype=x0.dtype) fsim = np.zeros((nverts,), float) applicator(0, x0) sim[0] = x0 if False: for k in range(0, N): y = np.array(x0, copy=True) if y[k] != 0: y[k] = (1 + nonzdelt) * y[k] else: y[k] = zdelt sim[k + 1] = y applicator(k + 1, y) nover = int(np.ceil(excess *1. / N)) for k in range(N, nverts-1): pos1 = (k-N) / nover pos2 = (k-N) % nover #print k,pos1,pos2 y = (sim[1+pos1]-x0) * (pos2+1)*1./(nover+1)+x0 #y = np.array(x0, copy=True) #fac= np.random.uniform(0,zdelt,size=N) #y = (x0*(1+fac))*(x0!=0).astype(int)+(fac)*(x0==0).astype(int) sim[k + 1] = y applicator(k + 1, y) state=np.random.get_state() np.random.seed(1) for k in range(0, nverts-1): y = np.array(x0, copy=True) rand=np.random.normal(0,1, len(x0)) rand=rand/(rand**2).sum()**.5+1./len(x0)**.5 y = (x0)*(1+rand*nonzdelt)*(x0!=0).astype(int)+(x0==0).astype(int)*(rand)*nonzdelt sim[k + 1] = y applicator(k + 1, y) np.random.set_state(state) for k in range(0, nverts): fsim[k] = pool.get(k) ind = np.argsort(fsim) fsim = np.take(fsim, ind, 0) sim = np.take(sim, ind, 0) iterations = 1 simR = sim.copy() # reflection simE = sim.copy() # expansion simC = sim.copy() # contraction simFinal = sim.copy() # final fsimR = fsim.copy() fsimE = fsim.copy() fsimC = fsim.copy() fsimFinal = fsim.copy() while (fcalls[0] < maxfun and iterations < maxiter): if (np.max(np.ravel(np.abs(sim[1:] - sim[0]))) <= xtol and np.max(np.abs(fsim[0] - fsim[1:])) <= ftol): break xbar = np.add.reduce(sim[:-nactive], 0) / (nverts - nactive) state = np.zeros(nactive, dtype=int) actives = set(range(nactive)) shrinks = [] for i in range(nactive): # reflect bad points #xbar = (np.add.reduce(sim[:], 0)-sim[-i-1,:]) / N simR[-i - 1, :] = (1 + rho) * xbar - rho * sim[-i-1,:] applicator(i, simR[-i-1, :]) state[i] = 1 #print 'A' while len(actives)>0: #print 'ST', state i, curfsim = pool.get_any() #xbar = (np.add.reduce(sim[:], 0)-sim[-i-1,:]) / N if state[i] == 1: # point just got evaled after first reflection fsimR[-i-1] = curfsim if fsimR[-i-1] < fsim[0]: # expand simE[-i-1, :] = (1 + rho * chi) * xbar - rho * chi* sim[-i -1, :] applicator(i, simE[-i - 1, :]) state[i] = 2 else: if fsimR[-i-1] < fsim[-i-2]: # better than the next worst simFinal[-i-1, :] = simR[-i-1,:] fsimFinal[-i-1] = fsimR[-i-1] state[i]= -1 # we stopped after one reflection actives.remove(i) else: # contract if fsimR[-i-1] < fsim[-i-1]: simC[-i-1, :] = (1 + rho * psi) * xbar - rho * psi* sim[-i-1, :] applicator(i, simC[-i-1,:]) state[i] = 3 else: simC[-i- 1, :] = (1 - psi) * xbar + psi * sim[-i-1, :] applicator(i, simC[-i-1,:]) state[i] = 4 elif state[i] == 2: # the expansion step has been done fsimE[-i-1] = curfsim #print 'TTT', fsimE[-i-1] , fsim[0] if fsimE[-i-1] < fsimR[-i-1]: # still better than the best simFinal[-i-1, :] = simE[-i-1,:] fsimFinal[-i-1] = fsimE[-i-1] state[i] = -2 actives.remove(i) else: simFinal[-i-1, :] = simR[-i-1,:] fsimFinal[-i-1] = fsimR[-i-1] state[i] = -3 actives.remove(i) elif state[i] == 3: # contraction1 just done fsimC[-i-1] = curfsim if fsimC[-i-1] < fsimR[-i-1]: # still better than the reflected simFinal[-i-1, :] = simC[-i-1,:] fsimFinal[-i-1] = fsimC[-i-1] state[i] = -4 actives.remove(i) else: simFinal[-i-1, :] = sim[-i-1,:] fsimFinal[-i-1] = fsim[-i-1] shrinks.append(i) state[i] = -10 actives.remove(i) elif state[i] == 4: # contraction2 just done fsimC[-i-1] = curfsim if fsimC[-i-1] < fsim[-i-1]: # still better than the reflected simFinal[-i-1, :] = simC[-i-1,:] fsimFinal[-i-1] = fsimC[-i-1] state[i] = -5 actives.remove(i) else: simFinal[-i-1, :] = sim[-i-1,:] fsimFinal[-i-1] = fsim[-i-1] shrinks.append(i) state[i] = -10 actives.remove(i) else: print 'Weird' for i in range(nactive): sim[-i-1,:] = simFinal[-i-1,:] fsim[-i-1] = fsimFinal[-i-1] #print 'ST1', state if len(shrinks) == nactive: print 'Shrink....' # no change was positive for j in one2np1: sim[j] = sim[0] + sigma * (sim[j] - sim[0]) applicator(j, sim[j, :]) for j in one2np1: fsim[j] = pool.get(j) ind = np.argsort(fsim) sim = np.take(sim, ind, 0) fsim = np.take(fsim, ind, 0) if callback is not None: callback(sim[0]) iterations += 1 if retall: allvecs.append(sim) #allvecs = allcalls x = sim[0] fval = np.min(fsim) warnflag = 0 if fcalls[0] >= maxfun: warnflag = 1 msg = _status_message['maxfev'] if disp: print('Warning: ' + msg) elif iterations >= maxiter: warnflag = 2 msg = _status_message['maxiter'] if disp: print('Warning: ' + msg) else: msg = _status_message['success'] if disp: print(msg) print(" Current function value: %f" % fval) print(" Iterations: %d" % iterations) print(" Function evaluations: %d" % fcalls[0]) result = OptimizeResult(fun=fval, nit=iterations, nfev=fcalls[0], status=warnflag, success=(warnflag == 0), message=msg, x=x) if retall: result['allvecs'] = allvecs return result