def _checkInitialValue(x0, G, h, A, b): if x0 is None: if G is None: if A is None: raise Exception("Fail to obtain an initial value") else: x = scipy.linalg.lstsq(A,b)[0] if not feasiblePoint(x, G, h): raise Exception("Fail to obtain an initial value") else: x = feasibleStartingValue(G, h) else: x = checkArrayType(x0) x = x.reshape(len(x),1) if G is not None: if not feasiblePoint(x, G, h): x = feasibleStartingValue(G, h) # else (we do not care as we can use infeasible Newton steps return x
def trustRegion(func, grad, hessian=None, x0=None, maxiter=100, method='exact', disp=0, full_output=False): x = checkArrayType(x0) p = len(x) if grad is None: def finiteForward(x,func,p): def finiteForward1(x): return forward(func,x.ravel()) return finiteForward1 grad = finiteForward(x,func,p) if hessian is None: approxH = BFGS elif type(hessian) is str: if hessian.lower()=='bfgs': approxH = BFGS elif hessian.lower()=='sr1': approxH = SR1 elif hessian.lower()=='dfp': approxH = DFP else: raise Exception("Input name of hessian is not recognizable") hessian = None if method is None: trustMethod = trustExact elif type(method) is str: if method.lower()=='exact': trustMethod = trustExact else: raise Exception("Input name of hessian is not recognizable") fx = None oldGrad = None deltaX = None oldFx = numpy.inf i = 0 oldi = -1 j = 0 tau = 1.0 radius = 1.0 maxRadius = 1.0 dispObj = Disp(disp) while maxiter>i: # if we have successfully moved on, then # we would need to recompute some of the quantities if i!=oldi: g = grad(x) fx = func(x) if hessian is None: if oldGrad is None: H = numpy.eye(len(x)) else: diffG = numpy.array(g - oldGrad) H = approxH(H, diffG, deltaX) else: H = hessian(x) deltaX, tau = trustMethod(x, g, H, radius) deltaX = deltaX.real M = diffM(deltaX, g, H) # print x # print deltaX newFx = func(x + deltaX) predRatio = (fx - newFx) / M(deltaX) if predRatio>=0.75: if tau>0.0: radius = min(2.0*radius, maxRadius) elif predRatio<=0.25: radius *= 0.25 if predRatio>=0.25: oldGrad = g x += deltaX oldFx = fx fx = newFx i +=1 oldi = i - 1 # we only allow termination if we make a move if (abs(fx-oldFx)/fx)<=reltol: break if abs(deltaX.dot(g))<=atol: break else: oldi = i dispObj.d(j, x , fx, deltaX, g, i) j += 1 if full_output: output = dict() output['totalIter'] = i output['outerIter'] = j output['fx'] = func(x) output['H'] = H output['g'] = g return x, output else: return x