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 aprod(mode, m, n, x): if mode == 1: r = dot(C, x).flatten() if not isspmatrix(C) else C._mul_sparse_matrix(csr_matrix(x.reshape(x.size, 1))).A.flatten() # It doesn't implemented properly yet # f = p.norm(r-d) # assert damp == 0 # if damp != 0: # assert not condX # p.iterfcn(x) # if p.istop: raise isSolved return r elif mode == 2: return dot(CT, x).flatten() if not isspmatrix(C) else CT._mul_sparse_matrix(csr_matrix(x.reshape(x.size, 1))).A.flatten()
def __solver__(self, p): x, obj, info, Lambda = oc.qp( p.x0.reshape(-1, 1), p.H.tocsr() if isspmatrix(p.H) else np.asfarray(p.H), np.asfarray(p.f).reshape(-1, 1), p.Aeq.tocsr() if isspmatrix(p.Aeq) else np.asfarray(p.Aeq) if p.nbeq != 0 else [], p.beq.reshape(-1, 1) if p.nbeq != 0 else [], p.lb.reshape(-1, 1), p.ub.reshape(-1, 1), [], p.A.tocsr() if isspmatrix(p.A) else np.asfarray(p.A) if p.nb != 0 else [1.0]*p.n, p.b.reshape(-1, 1) if p.nb != 0 else np.inf#p.b.reshape(p.n, 0) ) p.xk = p.xf = x.flatten() p.istop = 1000
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): condX = hasattr(p, 'X') and any(p.X) if condX: p.err( "sorry, the solver can't handle non-zero X data yet, but you can easily handle it by yourself" ) C, d = p.C, p.d m, n = C.shape[0], p.n if scipyInstalled: if isspmatrix(C) or 0.25 * C.size > flatnonzero(C).size: C = csc_matrix(C) elif not isPyPy and 0.25 * C.size > flatnonzero(C).size: p.pWarn(scipyAbsentMsg) # if isinstance(C, ndarray) and 0.25* C.size > flatnonzero(C).size: # if not scipyInstalled: # p.pWarn(scipyAbsentMsg) # else: # C = csc_matrix(C) CT = C.T def aprod(mode, m, n, x): if mode == 1: r = dot(C, x).flatten( ) if not isspmatrix(C) else C._mul_sparse_matrix( csr_matrix(x.reshape(x.size, 1))).A.flatten() # It doesn't implemented properly yet # f = p.norm(r-d) # assert damp == 0 # if damp != 0: # assert not condX # p.iterfcn(x) # if p.istop: raise isSolved return r elif mode == 2: return dot(CT, x).flatten( ) if not isspmatrix(C) else CT._mul_sparse_matrix( csr_matrix(x.reshape(x.size, 1))).A.flatten() if self.conlim == 'autoselect': conlim = 1e12 if m == n else 1e8 damp = self.damp if hasattr(self, 'damp') and self.damp is not None else 0 show = False [ x, istop, itn, r1norm, r2norm, anorm, acond, arnorm, xnorm, var ] = \ LSQR(m, n, aprod, d, damp, 1e-9, 1e-9, conlim, p.maxIter, show, wantvar = False, callback = p.iterfcn) # ( m, n, aprod, b, damp, atol, btol, conlim, itnlim, show, wantvar = False ) #p.istop, p.msg, p.iter = istop, msg.rstrip(), iter p.istop = 1000 p.debugmsg('lsqr iterations elapsed: %d' % itn) #p.iter = 1 # itn p.xf = x
def aprod(mode, m, n, x): if mode == 1: r = dot(C, x).flatten( ) if not isspmatrix(C) else C._mul_sparse_matrix( csr_matrix(x.reshape(x.size, 1))).A.flatten() # It doesn't implemented properly yet # f = p.norm(r-d) # assert damp == 0 # if damp != 0: # assert not condX # p.iterfcn(x) # if p.istop: raise isSolved return r elif mode == 2: return dot(CT, x).flatten( ) if not isspmatrix(C) else CT._mul_sparse_matrix( csr_matrix(x.reshape(x.size, 1))).A.flatten()
def _pivot(H,ip,jp): # H is MODIFIED n, m = H.shape piv = H[ip,jp] if piv == 0: #print('singular') return False else: #NEW H[ip,:] /= piv tmp2 = H[:,jp]*H[ip,:] if isspmatrix(H) else H[:,jp].reshape(-1, 1)*H[ip,:] if isspmatrix(tmp2): tmp2 = tmp2.tolil() tmp2[ip, :] = 0 H -= tmp2 #OLD # for i in range(n): # if i != ip: # H[i,:] -= H[i,jp]*H[ip,:] return True
def _pivot(H, ip, jp): # H is MODIFIED n, m = H.shape piv = H[ip, jp] if piv == 0: #print('singular') return False else: #NEW H[ip, :] /= piv tmp2 = H[:, jp] * H[ip, :] if isspmatrix(H) else H[:, jp].reshape( -1, 1) * H[ip, :] if isspmatrix(tmp2): tmp2 = tmp2.tolil() tmp2[ip, :] = 0 H -= tmp2 #OLD # for i in range(n): # if i != ip: # H[i,:] -= H[i,jp]*H[ip,:] return True
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): condX = hasattr(p, 'X') and any(p.X) if condX: p.err("sorry, the solver can't handle non-zero X data yet, but you can easily handle it by yourself") C, d = p.C, p.d m, n = C.shape[0], p.n if scipyInstalled: if isspmatrix(C) or 0.25* C.size > flatnonzero(C).size: C = csc_matrix(C) elif not isPyPy and 0.25* C.size > flatnonzero(C).size: p.pWarn(scipyAbsentMsg) # if isinstance(C, ndarray) and 0.25* C.size > flatnonzero(C).size: # if not scipyInstalled: # p.pWarn(scipyAbsentMsg) # else: # C = csc_matrix(C) CT = C.T def aprod(mode, m, n, x): if mode == 1: r = dot(C, x).flatten() if not isspmatrix(C) else C._mul_sparse_matrix(csr_matrix(x.reshape(x.size, 1))).A.flatten() # It doesn't implemented properly yet # f = p.norm(r-d) # assert damp == 0 # if damp != 0: # assert not condX # p.iterfcn(x) # if p.istop: raise isSolved return r elif mode == 2: return dot(CT, x).flatten() if not isspmatrix(C) else CT._mul_sparse_matrix(csr_matrix(x.reshape(x.size, 1))).A.flatten() if self.conlim == 'autoselect': conlim = 1e12 if m == n else 1e8 damp = self.damp if hasattr(self, 'damp') and self.damp is not None else 0 show = False [ x, istop, itn, r1norm, r2norm, anorm, acond, arnorm, xnorm, var ] = \ LSQR(m, n, aprod, d, damp, 1e-9, 1e-9, conlim, p.maxIter, show, wantvar = False, callback = p.iterfcn) # ( m, n, aprod, b, damp, atol, btol, conlim, itnlim, show, wantvar = False ) #p.istop, p.msg, p.iter = istop, msg.rstrip(), iter p.istop = 1000 p.debugmsg('lsqr iterations elapsed: %d' % itn) #p.iter = 1 # itn p.xf = x
def Matrix(x): if x is None or (hasattr(x, 'shape') and prod(x.shape) == 0): return None if isspmatrix(x): if min(x.shape) > 1: from scipy.sparse import find I, J, values = find(x) return Sparse(array(values, float).tolist(), I.tolist(), J.tolist(), x.shape) else: x = x.toarray() x = asfarray(x) if x.ndim > 1 and x.nonzero()[0].size < 0.3*x.size: #todo: replace 0.3 by prob param return sparse(x.tolist()).T # without tolist currently it doesn't work else: return matrix(x, tc='d')
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 Matrix(x): if x is None or (hasattr(x, 'shape') and prod(x.shape) == 0): return None if isspmatrix(x): if min(x.shape) > 1: from scipy.sparse import find I, J, values = find(x) return Sparse( array(values, float).tolist(), I.tolist(), J.tolist(), x.shape) else: x = x.toarray() x = asfarray(x) if x.ndim > 1 and x.nonzero( )[0].size < 0.3 * x.size: #todo: replace 0.3 by prob param return sparse(x.tolist()).T # without tolist currently it doesn't work else: return matrix(x, tc='d')
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): 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): 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 __solver__(self, p): #p.debug = 1 # TODO: code clean up solver = self.matrixSLEsolver if solver in self.denseSolvers: useDense = True elif solver in self.sparseSolvers: useDense = False elif solver == 'autoselect': if not scipyInstalled: useDense = True if isspmatrix(p.C) and prod(p.C.shape)>100000: s = """You have no scipy installed . Thus the SLE will be solved as dense. """ p.pWarn(s) solver = self.defaultDenseSolver self.matrixSLEsolver = solver else: solver = self.defaultSparseSolver self.matrixSLEsolver = solver useDense = False else: p.err('Incorrect SLE solver (%s)' % solver) if isinstance(solver, str): if solver == 'numpy_linalg_solve': solver = linalg.solve else: solver = getattr(scipy.sparse.linalg, solver) if useDense: #p.debugmsg('dense SLE solver') try: C = p.C.toarray() if not isinstance(p.C, ndarray) else p.C if self.matrixSLEsolver == 'autoselect': self.matrixSLEsolver = linalg.solve xf = solver(C, p.d) istop, msg = 10, 'solved' p.xf = xf p.ff = norm(dot(C, xf)-p.d, inf) except linalg.LinAlgError: istop, msg = -10, 'singular matrix' else: # is sparse #p.debugmsg('sparse SLE solver') try: if not hasattr(p, 'C_as_csc'):p.C_as_csc = scipy.sparse.csc_matrix(p.C) xf = solver(p.C_as_csc, p.d)#, maxiter=10000) solver_istop = 0 if solver_istop == 0: istop, msg = 10, 'solved' else: istop, msg = -104, 'the solver involved failed to solve the SLE' if solver_istop < 0: msg += ', matter: illegal input or breakdown' else: msg += ', matter: convergence to tolerance not achieved, number of iterations: %d' % solver_istop p.xf = xf p.ff = norm(p.C_as_csc._mul_sparse_matrix(scipy.sparse.csr_matrix(xf.reshape(-1, 1))).toarray().flatten()-p.d, inf) except: istop, msg = -100, 'unimplemented exception while solving sparse SLE' p.istop, p.msg = istop, msg
def _simplex(H, basis, indx, s): ''' [H1,basis,is_bounded] = _simplex(H,basis,indx,s) H: simplex table (MODIFIED). basis: the indices of basis (MODIFIED). indx: the indices of x. s: 1 for phase one; 2 for phase two. H1: new simplex table. is_bounded: True if the solution is bounded; False if unbounded. ''' if s == 1: s0 = 2 elif s == 2: s0 = 1 n1, n2 = H.shape sol = False while not sol: #print 'new Iter' # [fm,jp] = min(H(n1,1:n2-1)); q = H[n1 - 1, 0:n2 - 1] # last row, all columns but last if type(q) != ndarray: q = q.toarray().flatten() jp = argmin(q) fm = q[jp] if fm >= 0: is_bounded = True # bounded solution sol = True else: # [hm,ip] = max(H(1:n1-s0,jp)); q = H[0:n1 - s0, jp] if type(q) != ndarray: q = q.toarray().flatten() ip = argmax(q) hm = q[ip] if hm <= 0: is_bounded = False # unbounded solution sol = True else: h1 = empty(n1 - s0) h1.fill(inf) # NEW tmp = H[:n1 - s0, jp] if isspmatrix(tmp): tmp = tmp.A.flatten() ind = tmp > 0 #tmp2 = H[ind,n2-1]/H[ind,jp] tmp2 = hstack([ H[i, n2 - 1] / H[i, jp] for i in where(ind)[0] ]) if 1 or isPyPy else H[ind, n2 - 1] / H[ind, jp] #assert hstack([H[i,n2-1]/H[i, jp] for i in where(ind)[0]]).shape == (H[ind,n2-1]/H[ind,jp]).shape if isspmatrix(tmp2): tmp2 = tmp2.A if isPyPy: for i, val in enumerate(where(ind)[0]): h1[val] = tmp2[i] else: h1[atleast_1d(ind)] = tmp2 #OLD # for i in range(n1-s0): # if H[i,jp] > 0: # h1[i] = H[i,n2-1]/H[i,jp] ip = argmin(h1) minh1 = h1[ip] basis[ip] = indx[jp] if not _pivot(H, ip, jp): raise ValueError( "the first parameter is a Singular matrix") return is_bounded
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): 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 _simplex(H,basis,indx,s): ''' [H1,basis,is_bounded] = _simplex(H,basis,indx,s) H: simplex table (MODIFIED). basis: the indices of basis (MODIFIED). indx: the indices of x. s: 1 for phase one; 2 for phase two. H1: new simplex table. is_bounded: True if the solution is bounded; False if unbounded. ''' if s == 1: s0 = 2 elif s == 2: s0 = 1 n1, n2 = H.shape sol = False while not sol: #print 'new Iter' # [fm,jp] = min(H(n1,1:n2-1)); q = H[n1-1, 0:n2-1] # last row, all columns but last if type(q) != ndarray: q = q.toarray().flatten() jp = argmin(q) fm = q[jp] if fm >= 0: is_bounded = True # bounded solution sol = True else: # [hm,ip] = max(H(1:n1-s0,jp)); q = H[0:n1-s0,jp] if type(q) != ndarray: q = q.toarray().flatten() ip = argmax(q) hm = q[ip] if hm <= 0: is_bounded = False # unbounded solution sol = True else: h1 = empty(n1-s0) h1.fill(inf) # NEW tmp = H[:n1-s0,jp] if isspmatrix(tmp): tmp = tmp.A.flatten() ind = tmp>0 #tmp2 = H[ind,n2-1]/H[ind,jp] tmp2 = hstack([H[i,n2-1]/H[i, jp] for i in where(ind)[0]]) if 1 or isPyPy else H[ind,n2-1]/H[ind,jp] #assert hstack([H[i,n2-1]/H[i, jp] for i in where(ind)[0]]).shape == (H[ind,n2-1]/H[ind,jp]).shape if isspmatrix(tmp2): tmp2 = tmp2.A if isPyPy: for i, val in enumerate(where(ind)[0]): h1[val] = tmp2[i] else: h1[atleast_1d(ind)] = tmp2 #OLD # for i in range(n1-s0): # if H[i,jp] > 0: # h1[i] = H[i,n2-1]/H[i,jp] ip = argmin(h1) minh1 = h1[ip] basis[ip] = indx[jp] if not _pivot(H,ip,jp): raise ValueError("the first parameter is a Singular matrix") return is_bounded
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)