def eval_jac_g(x, flag, userdata = (I, J)): (I, J) = userdata if flag and p.isFDmodel: return (I, J) r = [] if p.userProvided.c: r.append(p.dc(x)) if p.userProvided.h: r.append(p.dh(x)) if p.nb != 0: r.append(p.A) if p.nbeq != 0: r.append(p.Aeq) # TODO: fix it! if any([isspmatrix(elem) for elem in r]): r = Vstack([(atleast_2d(elem) if elem.ndim < 2 else elem) for elem in r]) elif len(r)!=0: r = vstack(r) if p.isFDmodel: # TODO: make it more properly R = (r.tocsr() if isspmatrix(r) else r)[I, J] if isspmatrix(R): return R.A elif isinstance(R, ndarray): return R else: p.err('bug in OpenOpt-ipopt connection, inform OpenOpt developers, type(R) = %s' % type(R)) if flag: return (I, J) else: if isspmatrix(r): r = r.A return r.flatten()
def eval_jac_g(x, flag, userdata=(I, J)): (I, J) = userdata if flag and p.isFDmodel: return (I, J) r = [] if p.userProvided.c: r.append(p.dc(x)) if p.userProvided.h: r.append(p.dh(x)) if p.nb != 0: r.append(p.A) if p.nbeq != 0: r.append(p.Aeq) # TODO: fix it! if any([isspmatrix(elem) for elem in r]): r = Vstack([(atleast_2d(elem) if elem.ndim < 2 else elem) for elem in r]) elif len(r) != 0: r = vstack(r) if p.isFDmodel: # TODO: make it more properly R = (r.tocsr() if isspmatrix(r) else r)[I, J] if isspmatrix(R): return R.A elif isinstance(R, ndarray): return R else: p.err( 'bug in OpenOpt-ipopt connection, inform OpenOpt developers, type(R) = %s' % type(R)) if flag: return (I, J) else: if isspmatrix(r): r = r.A return r.flatten()
def eval_jac_g(x): r = [] if p.userProvided.c: r.append(p.dc(x)) if p.userProvided.h: r.append(p.dh(x)) if p.nb != 0: r.append(p.A) if p.nbeq != 0: r.append(p.Aeq) # TODO: fix it! # if any([isspmatrix(elem) for elem in r]): # r = Vstack([(atleast_2d(elem) if elem.ndim < 2 else elem) for elem in r]) # elif len(r)!=0: # r = vstack(r) r = Vstack(r) # TODO: make it more properly rr = (r.tocsr() if isspmatrix(r) else r) R = rr[I, J] if np.prod(rr.shape) != 0 else np.array([]) if isspmatrix(R) or type(R) == np.matrix: R = R.A elif not isinstance(R, np.ndarray): p.err('bug in OpenOpt-knitro connection, inform OpenOpt developers, type(R) = %s' % type(R)) return R.flatten()
def __solver__(self, p): A = p.C if isspmatrix(A): p.warn( 'numpy.linalg.eig cannot handle sparse matrices, cast to dense will be performed' ) A = A.A #M = p.M if p._goal != 'all': p.err('numpy_eig cannot handle the goal "%s" yet' % p._goal) eigenvalues, eigenvectors = eig(A) p.xf = p.xk = Vstack((eigenvalues, eigenvectors)) p.eigenvalues = eigenvalues p.eigenvectors = eigenvectors p.ff = 0
def CVXOPT_SOCP_Solver(p, solverName): if solverName == 'native_CVXOPT_SOCP_Solver': solverName = None cvxopt_solvers.options['maxiters'] = p.maxIter cvxopt_solvers.options['feastol'] = p.contol cvxopt_solvers.options['abstol'] = p.ftol if p.iprint <= 0: cvxopt_solvers.options['show_progress'] = False cvxopt_solvers.options['LPX_K_MSGLEV'] = 0 cvxopt_solvers.options['MSK_IPAR_LOG'] = 0 xBounds2Matrix(p) #FIXME: if problem is search for MAXIMUM, not MINIMUM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! f = copy(p.f).reshape(-1, 1) # CVXOPT has some problems with x0 so currently I decided to avoid using the one Gq, hq = [], [] C, d, q, s = p.C, p.d, p.q, p.s for i in range(len(q)): Gq.append( Matrix( Vstack((-atleast_1d(q[i]), -atleast_1d(C[i]) if not isspmatrix(C[i]) else C[i])))) hq.append(matrix(hstack((atleast_1d(s[i]), atleast_1d(d[i]))), tc='d')) sol = cvxopt_solvers.socp(Matrix(p.f), Gl=Matrix(p.A), hl=Matrix(p.b), Gq=Gq, hq=hq, A=Matrix(p.Aeq), b=Matrix(p.beq), solver=solverName) p.msg = sol['status'] if p.msg == 'optimal': p.istop = SOLVED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON else: p.istop = -100 if sol['x'] is not None: p.xf = asarray(sol['x']).flatten() p.ff = sum(p.dotmult(p.f, p.xf)) else: p.ff = nan p.xf = nan * ones(p.n)
def __solver__(self, p): if not pyipoptInstalled: p.err('you should have pyipopt installed') # try: # os.close(1); os.close(2) # may not work for non-Unix OS # except: # pass nvar = p.n x_L = p.lb x_U = p.ub ncon = p.nc + p.nh + p.b.size + p.beq.size g_L, g_U = zeros(ncon), zeros(ncon) g_L[:p.nc] = -inf g_L[p.nc + p.nh:p.nc + p.nh + p.b.size] = -inf # IPOPT non-linear constraints, both eq and ineq if p.isFDmodel: r = [] if p.nc != 0: r.append(p._getPattern(p.user.c)) if p.nh != 0: r.append(p._getPattern(p.user.h)) if p.nb != 0: r.append(p.A) if p.nbeq != 0: r.append(p.Aeq) if len(r) > 0: if all([isinstance(elem, ndarray) for elem in r]): r = vstack(r) else: r = Vstack(r) if isspmatrix(r): from scipy import __version__ if __version__.startswith( '0.7.3') or __version__.startswith( '0.7.2') or __version__.startswith( '0.7.1') or __version__.startswith( '0.7.0'): p.pWarn( 'updating scipy to version >= 0.7.4 is very recommended for the problem with the solver IPOPT' ) else: r = array([]) if isspmatrix(r): I, J, _ = Find(r) # DON'T remove it! I, J = array(I, int64), array(J, int64) elif isinstance(r, ndarray): if r.size == 0: I, J = array([], dtype=int64), array([], dtype=int64) else: I, J = where(r) else: p.disp('unimplemented type:%s' % str(type(r))) # dense matrix? nnzj = len(I) else: I, J = where(ones((ncon, p.n))) #I, J = None, None nnzj = ncon * p.n #TODO: reduce it def eval_g(x): r = array(()) if p.userProvided.c: r = p.c(x) if p.userProvided.h: r = hstack((r, p.h(x))) r = hstack((r, p._get_AX_Less_B_residuals(x), p._get_AeqX_eq_Beq_residuals(x))) return r def eval_jac_g(x, flag, userdata=(I, J)): (I, J) = userdata if flag and p.isFDmodel: return (I, J) r = [] if p.userProvided.c: r.append(p.dc(x)) if p.userProvided.h: r.append(p.dh(x)) if p.nb != 0: r.append(p.A) if p.nbeq != 0: r.append(p.Aeq) # TODO: fix it! if any([isspmatrix(elem) for elem in r]): r = Vstack([(atleast_2d(elem) if elem.ndim < 2 else elem) for elem in r]) elif len(r) != 0: r = vstack(r) if p.isFDmodel: # TODO: make it more properly R = (r.tocsr() if isspmatrix(r) else r)[I, J] if isspmatrix(R): return R.A elif isinstance(R, ndarray): return R else: p.err( 'bug in OpenOpt-ipopt connection, inform OpenOpt developers, type(R) = %s' % type(R)) if flag: return (I, J) else: if isspmatrix(r): r = r.A return r.flatten() """ This function might be buggy, """ # // comment by Eric nnzh = 0 def eval_h(lagrange, obj_factor, flag): return None # def apply_new(x): # return True nlp = pyipopt.create(nvar, x_L, x_U, ncon, g_L, g_U, nnzj, nnzh, p.f, p.df, eval_g, eval_jac_g) if self.optFile == 'auto': lines = [ '# generated automatically by OpenOpt\n', 'print_level 0\n' ] lines.append('tol ' + str(p.ftol) + '\n') lines.append('constr_viol_tol ' + str(p.contol) + '\n') lines.append('max_iter ' + str(min(15000, p.maxIter)) + '\n') if self.options != '': for s in re.split(',|;', self.options): lines.append(s.strip().replace('=', ' ', 1) + '\n') if p.nc == 0: lines.append('jac_d_constant yes\n') if p.nh == 0: lines.append('jac_c_constant yes\n') if p.castFrom.lower() in ('lp', 'qp', 'llsp'): lines.append('hessian_constant yes\n') ipopt_opt_file = open('ipopt.opt', 'w') ipopt_opt_file.writelines(lines) ipopt_opt_file.close() try: x, zl, zu, obj = nlp.solve(p.x0)[:4] if p.point(p.xk).betterThan(p.point(x)): obj = p.fk p.xk = p.xk.copy() # for more safety else: p.xk, p.fk = x.copy(), obj if p.istop == 0: p.istop = 1000 finally: nlp.close()
def lp_engine(c, A, b): # c = asarray(c) # A = asarray(A) # b = asarray(b) m,n = A.shape ind = b < 0 if any(ind): b = abs(b) #A[ind, :] = -A[ind, :] doesn't work for sparse if type(A) == ndarray and not isPyPy: A[ind] = -A[ind] else: for i in where(ind)[0]: A[i,:] = -A[i,:] d = -A.sum(axis=0) if not isscalar(d) and type(d) != ndarray: d = d.A.flatten() if not isinstance(d, ndarray): d = d.A.flatten() # d may be dense matrix w0 = sum(b) # H = [A b;c' 0;d -w0]; #H = bmat('A b; c 0; d -w0') '''''' H = Vstack([ # The initial _simplex table of phase one Hstack([A, atleast_2d(b).T]), # first m rows hstack([c, 0.]), # last-but-one hstack([d, -asfarray(w0)])]) # last #print sum(abs(Hstack([A, array([b]).T]))) if isspmatrix(H): H = H.tolil() '''''' indx = arange(n) basis = arange(n, n+m) #H, basis, is_bounded = _simplex(H, basis, indx, 1) is_bounded = _simplex(H, basis, indx, 1) if H[m+1,n] < -1e-10: # last row, last column sol = False #print('unsolvable') optx = [] zmin = [] is_bounded = False else: sol = True j = -1 #NEW tmp = H[m+1,:] if type(tmp) != ndarray: tmp = tmp.A.flatten() ind = tmp > 1e-10 if any(ind): j = where(logical_not(ind))[0] H = H[:, j] indx = indx[j] #Old # for i in range(n): # j = j+1 # if H[m+1,j] > 1e-10: # H[:,j] = [] # indx[j] = [] # j = j-1 #H(m+2,:) = [] % delete last row H = H[0:m+1,:] if size(indx) > 0: # Phase two #H, basis, is_bounded = _simplex(H,basis,indx,2); is_bounded = _simplex(H,basis,indx,2) if is_bounded: optx = zeros(n+m) n1,n2 = H.shape for i in range(m): optx[basis[i]] = H[i,n2-1] # optx(n+1:n+m,1) = []; % delete last m elements optx = optx[0:n] zmin = -H[n1-1,n2-1] # last row, last column else: optx = [] zmin = -Inf else: optx = zeros(n+m) zmin = 0 return (optx, zmin, is_bounded, sol, basis)
def __solver__(self, p): xBounds2Matrix(p) n = p.n Ind_unbounded = logical_and(isinf(p.lb), isinf(p.ub)) ind_unbounded = where(Ind_unbounded)[0] n_unbounded = ind_unbounded.size # Cast linear inequality constraints into linear equality constraints using slack variables nLinInEq, nLinEq = p.b.size, p.beq.size #p.lb, p.ub = empty(n+nLinInEq+n_unbounded), empty(n+nLinInEq+n_unbounded) #p.lb.fill(-inf) #p.ub.fill(inf) # for fn in ['_A', '_Aeq']: # if hasattr(p, fn): delattr(p, fn) # TODO: handle p.useSparse parameter # if n_unbounded != 0: # R = SparseMatrixConstructor((n_unbounded, n)) # R[range(n_unbounded), ind_unbounded] = 1.0 # R2 = Diag([1]*nLinInEq+[-1]*n_unbounded) # _A = Hstack((Vstack((p.A, R)), R2)) # else: # _A = Hstack((p.A, Eye(nLinInEq))) _A = Hstack( (p.A, Eye(nLinInEq), -Vstack([p.A[:, i] for i in ind_unbounded]).T if isPyPy else -p.A[:, ind_unbounded])) # if isspmatrix(_A): # _A = _A.A # add lin eq cons if nLinEq != 0: Constructor = SparseMatrixConstructor if scipyInstalled and nLinInEq > 100 else DenseMatrixConstructor _A = Vstack((_A, Hstack((p.Aeq, Constructor((nLinEq, nLinInEq)), \ -Vstack([p.Aeq[:, i] for i in ind_unbounded]).T if isPyPy else -p.Aeq[:, ind_unbounded])))) if isspmatrix(_A): if _A.size > 0.3 * prod(_A.shape): _A = _A.A else: _A = _A.tolil() #_A = _A.A #p.A, p.b = zeros((0, p.n)), array([]) #_f = hstack((p.f, zeros(nLinInEq+n_unbounded))) #_f = Hstack((p.f, zeros(nLinInEq), -p.f[ind_unbounded])) #_b = hstack((p.b, [0]*n_unbounded, p.beq)) _f = hstack((p.f, zeros(nLinInEq), -p.f[Ind_unbounded])) _b = hstack((p.b, p.beq)) if p.useSparse is False and isspmatrix(_A): _A = _A.A p.debugmsg('handling as sparse: ' + str(isspmatrix(_A))) optx, zmin, is_bounded, sol, basis = lp_engine(_f, _A, _b) p.xf = optx[:n] - optx[-n:] if len(optx) != 0 else nan p.istop = 1000 if p.xf is not nan else -1000
def lp_engine(c, A, b): # c = asarray(c) # A = asarray(A) # b = asarray(b) m, n = A.shape ind = b < 0 if any(ind): b = abs(b) #A[ind, :] = -A[ind, :] doesn't work for sparse if type(A) == ndarray and not isPyPy: A[ind] = -A[ind] else: for i in where(ind)[0]: A[i, :] = -A[i, :] d = -A.sum(axis=0) if not isscalar(d) and type(d) != ndarray: d = d.A.flatten() if not isinstance(d, ndarray): d = d.A.flatten() # d may be dense matrix w0 = sum(b) # H = [A b;c' 0;d -w0]; #H = bmat('A b; c 0; d -w0') '''''' H = Vstack([ # The initial _simplex table of phase one Hstack([A, atleast_2d(b).T]), # first m rows hstack([c, 0.]), # last-but-one hstack([d, -asfarray(w0)]) ]) # last #print sum(abs(Hstack([A, array([b]).T]))) if isspmatrix(H): H = H.tolil() '''''' indx = arange(n) basis = arange(n, n + m) #H, basis, is_bounded = _simplex(H, basis, indx, 1) is_bounded = _simplex(H, basis, indx, 1) if H[m + 1, n] < -1e-10: # last row, last column sol = False #print('unsolvable') optx = [] zmin = [] is_bounded = False else: sol = True j = -1 #NEW tmp = H[m + 1, :] if type(tmp) != ndarray: tmp = tmp.A.flatten() ind = tmp > 1e-10 if any(ind): j = where(logical_not(ind))[0] H = H[:, j] indx = indx[j] #Old # for i in range(n): # j = j+1 # if H[m+1,j] > 1e-10: # H[:,j] = [] # indx[j] = [] # j = j-1 #H(m+2,:) = [] % delete last row H = H[0:m + 1, :] if size(indx) > 0: # Phase two #H, basis, is_bounded = _simplex(H,basis,indx,2); is_bounded = _simplex(H, basis, indx, 2) if is_bounded: optx = zeros(n + m) n1, n2 = H.shape for i in range(m): optx[basis[i]] = H[i, n2 - 1] # optx(n+1:n+m,1) = []; % delete last m elements optx = optx[0:n] zmin = -H[n1 - 1, n2 - 1] # last row, last column else: optx = [] zmin = -Inf else: optx = zeros(n + m) zmin = 0 return (optx, zmin, is_bounded, sol, basis)
def __solver__(self, p): # try: # os.close(1); os.close(2) # may not work for non-Unix OS # except: # pass p.kernelIterFuncs.pop(SMALL_DELTA_X, None) p.kernelIterFuncs.pop(SMALL_DELTA_F, None) n = p.n ncon = p.nc + p.nh + p.b.size + p.beq.size g_L, g_U = np.zeros(ncon), np.zeros(ncon) g_L[:p.nc] = -np.inf g_L[p.nc+p.nh:p.nc+p.nh+p.b.size] = -np.inf # non-linear constraints, both eq and ineq if p.isFDmodel: r = [] if p.nc != 0: r.append(p._getPattern(p.user.c)) if p.nh != 0: r.append(p._getPattern(p.user.h)) if p.nb != 0: r.append(p.A) if p.nbeq != 0: r.append(p.Aeq) if len(r)>0: # if all([isinstance(elem, np.ndarray) for elem in r]): r = Vstack(r) # else: # r = Vstack(r) # if isspmatrix(r): # from scipy import __version__ # if __version__.startswith('0.7.3') or __version__.startswith('0.7.2') or __version__.startswith('0.7.1') or __version__.startswith('0.7.0'): # p.pWarn('updating scipy to version >= 0.7.4 is very recommended for the problem with the solver %s' % self.__name__) else: r = np.array([]) if isspmatrix(r): I, J, _ = Find(r) # DON'T remove it! I, J = np.array(I, np.int64), np.array(J, np.int64) elif isinstance(r, np.ndarray): if r.size == 0: I, J= np.array([], dtype=np.int64),np.array([], dtype=np.int64) else: I, J = np.where(r) else: p.disp('unimplemented type:%s' % str(type(r))) # dense matrix? # nnzj = len(I) else: I, J = np.where(np.ones((ncon, p.n))) #I, J = None, None # nnzj = ncon * p.n #TODO: reduce it def eval_cons(x): r = np.array(()) if p.userProvided.c: r = p.c(x) if p.userProvided.h: r = np.hstack((r, p.h(x))) r = np.hstack((r, p._get_AX_Less_B_residuals(x), p._get_AeqX_eq_Beq_residuals(x))) return r def evaluateFC (x, c): x = np.array(x)#TODO: REMOVE IT IN FUTURE VERSIONS obj = p.f(x) c[:] = eval_cons(x) return obj def eval_jac_g(x): r = [] if p.userProvided.c: r.append(p.dc(x)) if p.userProvided.h: r.append(p.dh(x)) if p.nb != 0: r.append(p.A) if p.nbeq != 0: r.append(p.Aeq) # TODO: fix it! # if any([isspmatrix(elem) for elem in r]): # r = Vstack([(atleast_2d(elem) if elem.ndim < 2 else elem) for elem in r]) # elif len(r)!=0: # r = vstack(r) r = Vstack(r) # TODO: make it more properly rr = (r.tocsr() if isspmatrix(r) else r) R = rr[I, J] if np.prod(rr.shape) != 0 else np.array([]) if isspmatrix(R) or type(R) == np.matrix: R = R.A elif not isinstance(R, np.ndarray): p.err('bug in OpenOpt-knitro connection, inform OpenOpt developers, type(R) = %s' % type(R)) return R.flatten() def evaluateGA(x, objGrad, jac): x = np.array(x)#TODO: REMOVE IT IN FUTURE VERSIONS df = p.df(x) dcons = eval_jac_g(x).tolist() objGrad[:] = df jac[:] = dcons objGoal = KTR_OBJGOAL_MINIMIZE objType = KTR_OBJTYPE_GENERAL; bndsLo = p.lb.copy() bndsUp = p.ub.copy() bndsLo[bndsLo < -KTR_INFBOUND] = -KTR_INFBOUND bndsUp[bndsUp > KTR_INFBOUND] = KTR_INFBOUND bndsLo = bndsLo.tolist() bndsUp = bndsUp.tolist() m = p.nc + p.nh + p.nb + p.nbeq cType = [ KTR_CONTYPE_GENERAL ] * (p.nc+p.nh) + [ KTR_CONTYPE_LINEAR ] * (p.nb+p.nbeq) cBndsLo = np.array([-np.inf]*p.nc + [0.0]*p.nh + [-np.inf]*p.nb + [0.0] * p.nbeq) cBndsLo[cBndsLo < -KTR_INFBOUND] = -KTR_INFBOUND cBndsLo = cBndsLo.tolist() cBndsUp = [0.0]* m jacIxConstr = I.tolist() jacIxVar = J.tolist() hessRow = None#[ ] hessCol = None#[ ] xInit = p.x0.tolist() #---- CREATE A NEW KNITRO SOLVER INSTANCE. kc = KTR_new() if kc == None: raise RuntimeError ("Failed to find a Ziena license.") if KTR_set_int_param_by_name(kc, "hessopt", 4): raise RuntimeError ("Error setting knitro parameter 'hessopt'") if KTR_set_double_param_by_name(kc, "feastol", p.contol): raise RuntimeError ("Error setting knitro parameter 'feastol'") if KTR_set_char_param_by_name(kc, "outlev", "0"): raise RuntimeError ("Error setting parameter 'outlev'") if KTR_set_int_param_by_name(kc, "maxit", p.maxIter): raise RuntimeError ("Error setting parameter 'maxit'") #---- INITIALIZE KNITRO WITH THE PROBLEM DEFINITION. ret = KTR_init_problem (kc, n, objGoal, objType, bndsLo, bndsUp, cType, cBndsLo, cBndsUp, jacIxVar, jacIxConstr, hessRow, hessCol, xInit, None) if ret: raise RuntimeError ("Error initializing the problem, KNITRO status = %d" % ret) #------------------------------------------------------------------ # FUNCTION callbackEvalFC #------------------------------------------------------------------ ## The signature of this function matches KTR_callback in knitro.h. # Only "obj" and "c" are modified. ## def callbackEvalFC (evalRequestCode, n, m, nnzJ, nnzH, x, lambda_, obj, c, objGrad, jac, hessian, hessVector, userParams): if evalRequestCode == KTR_RC_EVALFC: obj[0] = evaluateFC(x, c) return 0 else: return KTR_RC_CALLBACK_ERR #------------------------------------------------------------------ # FUNCTION callbackEvalGA #------------------------------------------------------------------ ## The signature of this function matches KTR_callback in knitro.h. # Only "objGrad" and "jac" are modified. ## def callbackEvalGA (evalRequestCode, n, m, nnzJ, nnzH, x, lambda_, obj, c, objGrad, jac, hessian, hessVector, userParams): if evalRequestCode == KTR_RC_EVALGA: evaluateGA(x, objGrad, jac) p.iterfcn(np.array(x), obj[0], np.max(np.array(c))) return 0 if p.istop == 0 else KTR_RC_USER_TERMINATION else: return KTR_RC_CALLBACK_ERR #---- REGISTER THE CALLBACK FUNCTIONS THAT PERFORM PROBLEM EVALUATION. #---- THE HESSIAN CALLBACK ONLY NEEDS TO BE REGISTERED FOR SPECIFIC #---- HESSIAN OPTIONS (E.G., IT IS NOT REGISTERED IF THE OPTION FOR #---- BFGS HESSIAN APPROXIMATIONS IS SELECTED). if KTR_set_func_callback(kc, callbackEvalFC): raise RuntimeError ("Error registering function callback.") if KTR_set_grad_callback(kc, callbackEvalGA): raise RuntimeError ("Error registering gradient callback.") # if KTR_set_hess_callback(kc, callbackEvalH): # raise RuntimeError ("Error registering hessian callback.") # def callbackProcessNode (evalRequestCode, n, m, nnzJ, nnzH, x, lambda_, obj, c, objGrad, jac, hessian, hessVector, userParams): # #---- THE KNITRO CONTEXT POINTER WAS PASSED IN THROUGH "userParams". # #kc = userParams ## p.iterfcn(np.array(x), obj[0], np.max(np.array(c))) # # #---- USER DEFINED TERMINATION EXAMPLE. # #---- UNCOMMENT BELOW TO FORCE TERMINATION AFTER 3 NODES. # #if KTR_get_mip_num_nodes (kc) == 3: # # return KTR_RC_USER_TERMINATION ## print p.istop ## if p.istop != 0: ## return KTR_RC_USER_TERMINATION # # return 0 #---- REGISTER THE CALLBACK FUNCTION THAT PERFORMS SOME TASK AFTER #---- EACH COMPLETION OF EACH NODE IN BRANCH-AND-BOUND TREE. # for MINLP: # if KTR_set_mip_node_callback (kc, callbackProcessNode): # raise RuntimeError ("Error registering node process callback.") # for NLP: # if KTR_set_newpoint_callback (kc, callbackProcessNode): # raise RuntimeError ("Error registering newpoint callback.") # if KTR_set_grad_callback (kc, callbackProcessNode): # raise RuntimeError ("Error registering grad callback.") try: #---- SOLVE THE PROBLEM. #---- #---- RETURN STATUS CODES ARE DEFINED IN "knitro.h" AND DESCRIBED #---- IN THE KNITRO MANUAL. x = [0] * n lambda_ = [0] * (m + n) obj = [0] nStatus = KTR_solve (kc, x, lambda_, 0, obj, None, None, None, None, None, None) x = np.array(x) if p.point(p.xk).betterThan(p.point(x)): obj = p.fk p.xk = p.xk.copy() # for more safety else: p.xk, p.fk = x.copy(), obj if p.istop == 0: p.istop = 1000 finally: #---- BE CERTAIN THE NATIVE OBJECT INSTANCE IS DESTROYED. KTR_free(kc)