def solve(self,net): # Parameters params = self.parameters # Problem problem = self.create_problem(net) A = problem.A b = problem.b x = problem.x # Solve try: assert(A.shape[0] == A.shape[1]) linsolver = new_linsolver('default','unsymmetric') linsolver.analyze(A) x = linsolver.factorize_and_solve(A,b) net.update_properties(x) self.set_status('solved') except Exception as e: raise PFmethodError_SolverError(self,e) finally: # Update net properties net.update_properties(x) # Get results self.set_iterations(1) self.set_primal_variables(x) self.set_dual_variables(4*[None]) self.set_net_properties(net.get_properties()) self.set_problem(problem)
def solve(self,net): from optalg.lin_solver import new_linsolver # Parameters params = self._parameters solver_name = params['solver'] # Copy network net = net.get_copy(merge_buses=True) # Problem t0 = time.time() problem = self.create_problem(net) problem_time = time.time()-t0 A = problem.A b = problem.b x = problem.x # Solve update = True t0 = time.time() try: assert(A.shape[0] == A.shape[1]) linsolver = new_linsolver(solver_name,'unsymmetric') linsolver.analyze(A) x = linsolver.factorize_and_solve(A,b) except Exception as e: update = False raise PFmethodError_SolverError(e) finally: # Update network if update: net.set_var_values(x) net.update_properties() net.clear_sensitivities() # Save results self.set_solver_name(solver_name) self.set_solver_status('solved' if update else 'error') self.set_solver_message('') self.set_solver_iterations(1) self.set_solver_time(time.time()-t0) self.set_solver_primal_variables(x) self.set_solver_dual_variables(4*[None]) self.set_problem(None) # skip for now self.set_problem_time(problem_time) self.set_network_snapshot(net)
def solve(self,net): from optalg.lin_solver import new_linsolver # Parameters params = self._parameters solver_name = params['solver'] # Copy network net = net.get_copy() # Problem t0 = time.time() problem = self.create_problem(net) problem_time = time.time()-t0 A = problem.A b = problem.b x = problem.x # Solve update = True t0 = time.time() try: assert(A.shape[0] == A.shape[1]) linsolver = new_linsolver(solver_name,'unsymmetric') linsolver.analyze(A) x = linsolver.factorize_and_solve(A,b) except Exception as e: update = False raise PFmethodError_SolverError(e) finally: # Update network if update: net.set_var_values(x) net.update_properties() net.clear_sensitivities() # Save results self.set_solver_name(solver_name) self.set_solver_status('solved' if update else 'error') self.set_solver_message('') self.set_solver_iterations(1) self.set_solver_time(time.time()-t0) self.set_solver_primal_variables(x) self.set_solver_dual_variables(4*[None]) self.set_problem(None) # skip for now self.set_problem_time(problem_time) self.set_network_snapshot(net)
def get_sol_sensitivity(self,problem,x,lam,mu,pi): """ Computes sensitivity of optimal q with respect to p as a linear operator. NEED TO EXTEND TO ALL x Parameters ---------- problem : QuadProblem x : primal lam : dual var (eq constraints) mu : dual var (upper bounds) pi : dual var (lower bounds) Returns ------- dqdpT : Linear Operator """ H = problem.H g = problem.g A = problem.A b = problem.b u = problem.u l = problem.l n = A.shape[1] m = A.shape[0] Dmu = spdiags(mu,0,n,n) Dpi = spdiags(pi,0,n,n) Dux = spdiags(u-x,0,n,n) Dxl = spdiags(x-l,0,n,n) In = eye(n) K = bmat([[H,-A.T,In,-In], [A,None,None,None], [-Dmu,None,Dux,None], [Dpi,None,None,Dxl]], format='coo') KT = K.T Ibar = eye(self.num_p,K.shape[0]) Onp = coo_matrix((n,self.num_p)) bp = bmat([[-self.G], [coo_matrix((self.num_br,self.num_p))]], format='coo') up = -eye(n,self.num_p) lp = -eye(n,self.num_p) eta_p = bmat([[Onp], [bp], [-Dmu*up], [Dpi*lp]], format='coo') linsolver = new_linsolver('mumps','unsymmetric') linsolver.analyze(KT) linsolver.factorize(KT) dqdpT = LinearOperator((self.num_p,self.num_p), lambda y : eta_p.T*linsolver.solve(Ibar.T*y)) return dqdpT
def solve(self, problem): # Local vars norm2 = self.norm2 norminf = self.norminf params = self.parameters # Parameters tau = params['tau'] gamma = params['gamma'] kappa = params['kappa'] optol = params['optol'] feastol = params['feastol'] beta_small = params['beta_small'] beta_large = params['beta_large'] sigma_init_min = params['sigma_init_min'] sigma_init_max = params['sigma_init_max'] theta_init_min = params['theta_init_min'] theta_init_max = params['theta_init_max'] theta_min = params['theta_min'] # Problem problem = cast_problem(problem) self.problem = problem # Linear solver self.linsolver1 = new_linsolver(params['linsolver'], 'symmetric') self.linsolver2 = new_linsolver(params['linsolver'], 'symmetric') # Reset self.reset() # Barrier self.barrier = AugLBarrier(problem.get_num_primal_variables(), problem.l, problem.u) # Init primal if problem.x is not None: self.x = self.barrier.to_interior(problem.x.copy()) else: self.x = (self.barrier.umax + self.barrier.umin) / 2. assert (np.all(self.x > self.barrier.umin)) assert (np.all(self.x < self.barrier.umax)) # Init dual if problem.lam is not None: self.lam = problem.lam.copy() else: self.lam = np.zeros(problem.b.size) if problem.nu is not None: self.nu = problem.nu.copy() else: self.nu = np.zeros(problem.f.size) try: if problem.pi is not None: self.pi = problem.pi.copy() else: self.pi = np.zeros(self.x.size) except AttributeError: self.pi = np.zeros(self.x.size) try: if problem.mu is not None: self.mu = problem.mu.copy() else: self.mu = np.zeros(self.x.size) except AttributeError: self.mu = np.zeros(self.x.size) # Constants self.sigma = 0. self.theta = 0. self.code = '' self.nx = self.x.size self.na = problem.b.size self.nf = problem.f.size self.ox = np.zeros(self.nx) self.oa = np.zeros(self.na) self.of = np.zeros(self.nf) self.Ixx = eye(self.nx, format='coo') self.Iff = eye(self.nf, format='coo') self.Iaa = eye(self.na, format='coo') # Objective scaling fdata = self.func(self.x) self.obj_sca = np.maximum(np.abs(fdata.phi) / 100., 1.) fdata = self.func(self.x) # Init penalty and barrier parameters self.sigma = kappa * norm2(fdata.GradF) / np.maximum( norm2(fdata.gphi), 1.) self.sigma = np.minimum(np.maximum(self.sigma, sigma_init_min), sigma_init_max) self.theta = kappa * norm2( fdata.GradF) / (self.sigma * np.maximum(norm2(fdata.gphiB), 1.)) self.theta = np.minimum(np.maximum(self.theta, theta_init_min), theta_init_max) fdata = self.func(self.x) # Init residuals pres_prev = norminf(fdata.pres) gLmax_prev = norminf(fdata.GradF) # Init dual update if pres_prev <= feastol: self.update_multiplier_estimates() fdata = self.func(self.x) # Outer iterations self.k = 0 self.useH = False self.code = list('----') while True: # Solve subproblem self.solve_subproblem(tau * gLmax_prev) # Check done if self.is_status_solved(): return # Measure progress pres = norminf(fdata.pres) dres = norminf(fdata.dres) gLmax = norminf(fdata.GradF) # Penaly update if pres <= np.maximum(gamma * pres_prev, feastol): self.sigma *= beta_large self.code[1] = 'p' else: self.sigma *= beta_small self.code[1] = 'n' # Dual update self.update_multiplier_estimates() # Barrier update self.theta = np.maximum(self.theta * beta_small, theta_min) # Update refs pres_prev = pres gLmax_prev = gLmax # Update iters self.k += 1
def solve(self,problem): """ Solves optimization problem. Parameters ---------- problem : OptProblem """ # Local vars norm2 = self.norm2 norminf = self.norminf parameters = self.parameters # Parameters tol = parameters['tol'] maxiter = parameters['maxiter'] quiet = parameters['quiet'] sigma = parameters['sigma'] eps = parameters['eps'] eps_cold = parameters['eps_cold'] # Linsolver self.linsolver = new_linsolver(parameters['linsolver'],'symmetric') # Problem self.problem = problem # Reset self.reset() # Data self.A = problem.A self.AT = problem.A.T self.b = problem.b self.l = problem.l self.u = problem.u self.n = self.A.shape[1] self.m = self.A.shape[0] self.e = np.ones(self.n) self.I = eye(self.n,format='coo') self.Onm = coo_matrix((self.n,self.m)) self.Omm = coo_matrix((self.m,self.m)) # Checks assert(np.all(self.l < self.u)) # Initial point if problem.x is None: self.x = (self.u + self.l)/2. else: dul = eps*(self.u-self.l) self.x = np.maximum(np.minimum(problem.x,self.u-dul),self.l+dul) if problem.lam is None: self.lam = np.zeros(self.m) else: self.lam = problem.lam.copy() if problem.mu is None: self.mu = np.ones(self.x.size)*eps_cold else: self.mu = np.maximum(problem.mu,eps) if problem.pi is None: self.pi = np.ones(self.x.size)*eps_cold else: self.pi = np.maximum(problem.pi,eps) # Check interior assert(np.all(self.l < self.x)) assert(np.all(self.x < self.u)) assert(np.all(self.mu > 0)) assert(np.all(self.pi > 0)) # Init vector self.y = np.hstack((self.x,self.lam,self.mu,self.pi)) # Header if not quiet: print('\nSolver: LCCP') print('------------') # Outer s = 0. self.k = 0 pmax = 0 while True: # Complementarity measures self.eta_mu = np.dot(self.mu,self.u-self.x)/self.x.size self.eta_pi = np.dot(self.pi,self.x-self.l)/self.x.size # Init eval fdata = self.func(self.y) fmax = norminf(fdata.f) gmax = norminf(fdata.GradF) # Done if fmax < tol and sigma*np.maximum(self.eta_mu,self.eta_pi) < tol: self.set_status(self.STATUS_SOLVED) self.set_error_msg('') return # Target tau = sigma*norminf(fdata.GradF) # Header if not quiet: if self.k > 0: print('') print('{0:^3s}'.format('iter'), end=' ') print('{0:^9s}'.format('phi'), end=' ') print('{0:^9s}'.format('fmax'), end=' ') print('{0:^9s}'.format('gmax'), end=' ') print('{0:^8s}'.format('cu'), end=' ') print('{0:^8s}'.format('cl'), end=' ') print('{0:^8s}'.format('s'), end=' ') print('{0:^8s}'.format('pmax')) # Inner while True: # Eval fdata = self.func(self.y) fmax = norminf(fdata.f) gmax = norminf(fdata.GradF) compu = norminf(self.mu*(self.u-self.x)) compl = norminf(self.pi*(self.x-self.l)) # Show progress if not quiet: print('{0:^3d}'.format(self.k), end=' ') print('{0:^9.2e}'.format(problem.phi), end=' ') print('{0:^9.2e}'.format(fmax), end=' ') print('{0:^9.2e}'.format(gmax), end=' ') print('{0:^8.1e}'.format(compu), end=' ') print('{0:^8.1e}'.format(compl), end=' ') print('{0:^8.1e}'.format(s), end=' ') print('{0:^8.1e}'.format(pmax)) # Done if gmax < tau: break # Maxiters if self.k >= maxiter: raise OptSolverError_MaxIters(self) # Search direction ux = self.u-self.x xl = self.x-self.l D1 = spdiags(self.mu/ux,0,self.n,self.n,format='coo') D2 = spdiags(self.pi/xl,0,self.n,self.n,format='coo') fbar = np.hstack((-fdata.rd+fdata.ru/ux-fdata.rl/xl,fdata.rp)) Jbar = bmat([[problem.Hphi+D1+D2,None], [-self.A,self.Omm]],format='coo') if not self.linsolver.is_analyzed(): self.linsolver.analyze(Jbar) pbar = self.linsolver.factorize_and_solve(Jbar,fbar) px = pbar[:self.n] plam = pbar[self.n:self.n+self.m] pmu = (-fdata.ru + self.mu*px)/ux ppi = (-fdata.rl - self.pi*px)/xl p = np.hstack((pbar,pmu,ppi)) pmax = norminf(p) # Steplength bounds indices = px > 0 s1 = np.min(np.hstack(((1.-eps)*(self.u-self.x)[indices]/px[indices],np.inf))) indices = px < 0 s2 = np.min(np.hstack(((eps-1.)*(self.x-self.l)[indices]/px[indices],np.inf))) indices = pmu < 0 s3 = np.min(np.hstack(((eps-1.)*self.mu[indices]/pmu[indices],np.inf))) indices = ppi < 0 s4 = np.min(np.hstack(((eps-1.)*self.pi[indices]/ppi[indices],np.inf))) smax = np.min([s1,s2,s3,s4]) # Line search try: s,fdata = self.line_search(self.y,p,fdata.F,fdata.GradF,self.func,smax) except OptSolverError_LineSearch: raise # Update x self.y += s*p self.k += 1 self.x,self.lam,self.mu,self.pi = self.extract_components(self.y) # Check assert(np.all(self.x < self.u)) assert(np.all(self.x > self.l)) assert(np.all(self.mu > 0)) assert(np.all(self.pi > 0))
def solve(self,problem): # Local vars norm2 = self.norm2 norminf = self.norminf params = self.parameters # Parameters feastol = params['feastol'] maxiter = params['maxiter'] quiet = params['quiet'] # Linear solver self.linsolver = new_linsolver(params['linsolver'],'unsymmetric') # Problem problem = cast_problem(problem) self.problem = problem # Reset self.reset() # Init point if problem.x is not None: self.x = problem.x.copy() else: raise OptSolverError_BadInitPoint(self) # Init eval fdata = self.func(self.x) # Analyze phase try: self.linsolver.analyze(bmat([[problem.J],[problem.A]])) except Exception: raise OptSolverError_BadLinSystem(self) # Print header if not quiet: print('\nSolver: NR') print('----------') print('{0:^3}'.format('k'), end=' ') print('{0:^9}'.format('fmax'), end=' ') print('{0:^9}'.format('gmax'), end=' ') print('{0:^8}'.format('pmax'), end=' ') print('{0:^8}'.format('alpha'), end=' ') if self.info_printer: self.info_printer(self,True) else: print('') # Main loop s = 0. pmax = 0. self.k = 0 while True: # Callbacks for c in self.callbacks: c(self) fdata = self.func(self.x) # Compute info quantities fmax = np.maximum(norminf(fdata.f),norminf(fdata.r)) gmax = norminf(fdata.GradF) # Show progress if not quiet: print('{0:^3d}'.format(self.k), end=' ') print('{0:^9.2e}'.format(fmax), end=' ') print('{0:^9.2e}'.format(gmax), end=' ') print('{0:^8.1e}'.format(pmax), end=' ') print('{0:^8.1e}'.format(s), end=' ') if self.info_printer: self.info_printer(self,False) else: print('') # Check solved if fmax < feastol: self.set_status(self.STATUS_SOLVED) self.set_error_msg('') return # Check maxiters if self.k >= maxiter: raise OptSolverError_MaxIters(self) # Check custom terminations for t in self.terminations: t(self) # Search direction try: p = self.linsolver.factorize_and_solve(bmat([[problem.J],[problem.A]]), np.hstack([-fdata.f,-fdata.r])) except Exception: raise OptSolverError_BadLinSystem(self) pmax = norminf(p) # Line search s,fdata = self.line_search(self.x,p,fdata.F,fdata.GradF,self.func) # Update x self.x += s*p self.k += 1
def solve(self, problem): """ Solves optimization problem. Parameters ---------- problem : Object """ # Local vars norm2 = self.norm2 norminf = self.norminf parameters = self.parameters # Parameters feastol = parameters['feastol'] optol = parameters['optol'] maxiter = parameters['maxiter'] quiet = parameters['quiet'] sigma = parameters['sigma'] eps = parameters['eps'] ls_maxiter = parameters['line_search_maxiter'] # Problem problem = cast_problem(problem) self.problem = problem # Linsolver self.linsolver = new_linsolver(parameters['linsolver'],'symmetric') # Reset self.reset() # Checks if not np.all(problem.l <= problem.u): raise OptSolverError_NoInterior(self) # Constants self.A = problem.A self.AT = problem.A.T self.b = problem.b self.u = problem.u+feastol/10. self.l = problem.l-feastol/10. self.n = problem.get_num_primal_variables() self.m1 = problem.get_num_linear_equality_constraints() self.m2 = problem.get_num_nonlinear_equality_constraints() self.e = np.ones(self.n) self.I = eye(self.n,format='coo') self.Omm1 = coo_matrix((self.m1,self.m1)) self.Omm2 = coo_matrix((self.m2,self.m2)) # Initial primal if problem.x is None: self.x = (self.u + self.l)/2. else: self.x = np.maximum(np.minimum(problem.x,problem.u),problem.l) # Initial duals if problem.lam is None: self.lam = np.zeros(problem.get_num_linear_equality_constraints()) else: self.lam = problem.lam.copy() if problem.nu is None: self.nu = np.zeros(problem.get_num_nonlinear_equality_constraints()) else: self.nu = problem.nu.copy() self.mu = np.minimum(1./(self.u-self.x), 1.) self.pi = np.minimum(1./(self.x-self.l), 1.) # Init vector self.y = np.hstack((self.x,self.lam,self.nu,self.mu,self.pi)) # Average violation of complementarity slackness self.eta_mu = (np.dot(self.mu,self.u-self.x)/self.x.size) if self.x.size else 0. self.eta_pi = (np.dot(self.pi,self.x-self.l)/self.x.size) if self.x.size else 0. # Objective scaling fdata = self.func(self.y) self.obj_sca = np.maximum(norminf(problem.gphi)/10.,1.) fdata = self.func(self.y) # Header if not quiet: print('\nSolver: inlp') print('------------') # Outer s = 0. self.k = 0 while True: # Average violation of complementarity slackness self.eta_mu = (np.dot(self.mu,self.u-self.x)/self.x.size) if self.x.size else 0. self.eta_pi = (np.dot(self.pi,self.x-self.l)/self.x.size) if self.x.size else 0. # Init eval fdata = self.func(self.y) # Target tau = sigma*norminf(fdata.GradF) # Header if not quiet: if self.k > 0: print('') print('{0:^3s}'.format('iter'),end=' ') print('{0:^9s}'.format('phi'),end=' ') print('{0:^9s}'.format('pres'),end=' ') print('{0:^9s}'.format('dres'),end=' ') print('{0:^9s}'.format('gmax'),end=' ') print('{0:^8s}'.format('cu'),end=' ') print('{0:^8s}'.format('cl'),end=' ') print('{0:^8s}'.format('alpha')) # Inner while True: # Eval fdata = self.func(self.y) pres = norminf(np.hstack((fdata.rp1,fdata.rp2))) dres = norminf(np.hstack((fdata.rd,fdata.ru,fdata.rl))) gmax = norminf(fdata.GradF) compu = norminf(self.mu*(self.u-self.x)) compl = norminf(self.pi*(self.x-self.l)) phi = problem.phi # Show progress if not quiet: print('{0:^3d}'.format(self.k),end=' ') print('{0:^9.2e}'.format(phi),end=' ') print('{0:^9.2e}'.format(pres),end=' ') print('{0:^9.2e}'.format(dres),end=' ') print('{0:^9.2e}'.format(gmax),end=' ') print('{0:^8.1e}'.format(compu),end=' ') print('{0:^8.1e}'.format(compl),end=' ') print('{0:^8.1e}'.format(s)) # Done if self.k > 0 and pres < feastol and dres < optol and sigma*np.maximum(self.eta_mu,self.eta_pi) < optol: self.set_status(self.STATUS_SOLVED) self.set_error_msg('') return # Done if gmax < tau: break # Done if pres < feastol and dres < optol and np.maximum(compu,compl) < optol: break # Maxiters if self.k >= maxiter: raise OptSolverError_MaxIters(self) # Search direction ux = self.u-self.x xl = self.x-self.l D1 = spdiags(self.mu/ux,0,self.n,self.n,format='coo') D2 = spdiags(self.pi/xl,0,self.n,self.n,format='coo') fbar = np.hstack((-fdata.rd+fdata.ru/ux-fdata.rl/xl,fdata.rp1,fdata.rp2)) Hbar = coo_matrix((np.concatenate((problem.Hphi.data/self.obj_sca, problem.H_combined.data, D1.data, D2.data)), (np.concatenate((problem.Hphi.row, problem.H_combined.row, D1.row, D2.row)), np.concatenate((problem.Hphi.col, problem.H_combined.col, D1.col, D2.col))))) Jbar = bmat([[Hbar,None,None], [-self.A,self.Omm1,None], [-problem.J,None,self.Omm2]], format='coo') try: if not self.linsolver.is_analyzed(): self.linsolver.analyze(Jbar) pbar = self.linsolver.factorize_and_solve(Jbar,fbar) except RuntimeError: raise OptSolverError_BadLinSystem(self) px = pbar[:self.n] pmu = (-fdata.ru + self.mu*px)/ux ppi = (-fdata.rl - self.pi*px)/xl p = np.hstack((pbar,pmu,ppi)) # Steplength bounds indices = px > 0 s1 = np.min(np.hstack(((self.u-self.x)[indices]/px[indices],np.inf))) indices = px < 0 s2 = np.min(np.hstack(((self.l-self.x)[indices]/px[indices],np.inf))) indices = pmu < 0 s3 = np.min(np.hstack((-self.mu[indices]/pmu[indices],np.inf))) indices = ppi < 0 s4 = np.min(np.hstack((-self.pi[indices]/ppi[indices],np.inf))) smax = (1.-eps)*np.min([s1,s2,s3,s4]) spmax = (1.-eps)*np.min([s1,s2]) sdmax = (1.-eps)*np.min([s3,s4]) # Line search try: s, fdata = self.line_search(self.y, p, fdata.F, fdata.GradF, self.func, smax=smax, maxiter=ls_maxiter) # Update point self.y += s*p self.x, self.lam, self.nu, self.mu, self.pi = self.extract_components(self.y) except OptSolverError_LineSearch: sp = np.minimum(1., spmax) sd = np.minimum(1., sdmax) s = np.minimum(sp,sd) # Update point self.x += sp*px self.lam += sd*pbar[self.x.size:self.x.size+self.lam.size] self.nu += sd*pbar[self.x.size+self.lam.size:] self.mu += sd*pmu self.pi += sd*ppi self.y = np.hstack((self.x,self.lam,self.nu,self.mu,self.pi)) # Update iters self.k += 1 # Check try: assert(np.all(self.x < self.u)) assert(np.all(self.x > self.l)) assert(np.all(self.mu > 0)) assert(np.all(self.pi > 0)) except AssertionError: raise OptSolverError_Infeasibility(self) # Update iters self.k += 1
def solve(self,problem): # Local vars norm2 = self.norm2 norminf = self.norminf params = self.parameters # Parameters tau = params['tau'] gamma = params['gamma'] kappa = params['kappa'] subtol = params['subtol'] feastol = params['feastol'] beta_small = params['beta_small'] beta_large = params['beta_large'] miu_init_min = params['miu_init_min'] miu_init_max = params['miu_init_max'] # Linear solver self.linsolver1 = new_linsolver(params['linsolver'],'symmetric') self.linsolver2 = new_linsolver(params['linsolver'],'symmetric') # Problem self.problem = problem # Reset self.reset() # Init primal if problem.x is not None: self.x = problem.x.copy() else: raise OptSolverError_BadInitPoint(self) # Init dual if problem.lam is not None: self.lam = problem.lam.copy() else: self.lam = np.zeros(problem.b.size) if problem.nu is not None: self.nu = problem.nu.copy() else: self.nu = np.zeros(problem.f.size) # Constants self.miu = 1. self.code = '' self.nx = self.x.size self.na = problem.b.size self.nf = problem.f.size self.ox = np.zeros(self.nx) self.oa = np.zeros(self.na) self.of = np.zeros(self.nf) self.Ixx = eye(self.nx,format='coo') self.Iff = eye(self.nf,format='coo') self.Iaa = eye(self.na,format='coo') # Init eval fdata = self.func(self.x) # Init penalty parameter if fdata.phi == 0.: self.miu = 1. else: self.miu = 0.5*kappa*(fdata.fTf+fdata.rTr)/fdata.phi self.miu = np.minimum(np.maximum(self.miu,miu_init_min),miu_init_max) fdata = self.func(self.x) # Outer iterations self.k = 0 self.useH = False self.code = list('----') fmax_prev = np.maximum(norminf(fdata.f),norminf(fdata.r)) gLmax_prev = norminf(fdata.GradF) while True: # Solve subproblem sub_solved = self.solve_subproblem(np.maximum(tau*gLmax_prev,subtol)) # Dual update self.update_multiplier_estimates() # Check solved if self.is_status_solved(): return # Penaly update if np.maximum(norminf(fdata.f),norminf(fdata.r)) < np.maximum(gamma*fmax_prev,feastol): self.miu *= beta_large self.code[1] = 'p' else: self.miu *= beta_small self.code[1] = 'n' # Eval function fdata = self.func(self.x) # Update refs fmax_prev = np.maximum(norminf(fdata.f),norminf(fdata.r)) gLmax_prev = norminf(fdata.GradF)
def solve(self, problem): """ Solves optimization problem. Parameters ---------- problem : Object """ # Local vars norm2 = self.norm2 norminf = self.norminf parameters = self.parameters # Parameters tol = parameters['tol'] maxiter = parameters['maxiter'] quiet = parameters['quiet'] sigma = parameters['sigma'] eps = parameters['eps'] eps_cold = parameters['eps_cold'] # Problem try: problem = cast_problem(problem) quad_problem = problem.to_quad() self.problem = problem self.quad_problem = quad_problem except: raise OptSolverError_BadProblemType(self) # Linsolver self.linsolver = new_linsolver(parameters['linsolver'],'symmetric') # Reset self.reset() # Checks if not np.all(problem.l <= problem.u): raise OptSolverError_NoInterior(self) # Data self.H = quad_problem.H self.g = quad_problem.g self.A = quad_problem.A self.AT = quad_problem.A.T self.b = quad_problem.b self.l = quad_problem.l-tol/10. self.u = quad_problem.u+tol/10. self.n = quad_problem.H.shape[0] self.m = quad_problem.A.shape[0] self.e = np.ones(self.n) self.I = eye(self.n,format='coo') self.Onm = coo_matrix((self.n,self.m)) self.Omm = coo_matrix((self.m,self.m)) # Initial primal if quad_problem.x is None: self.x = (self.u + self.l)/2. else: self.x = np.maximum(np.minimum(quad_problem.x,problem.u),problem.l) # Initial duals if quad_problem.lam is None: self.lam = np.zeros(self.m) else: self.lam = quad_problem.lam.copy() if quad_problem.mu is None: self.mu = np.ones(self.x.size)*eps_cold else: self.mu = np.maximum(quad_problem.mu,eps) if quad_problem.pi is None: self.pi = np.ones(self.x.size)*eps_cold else: self.pi = np.maximum(quad_problem.pi,eps) # Check interior try: assert(np.all(self.l < self.x)) assert(np.all(self.x < self.u)) assert(np.all(self.mu > 0)) assert(np.all(self.pi > 0)) except AssertionError: raise OptSolverError_Infeasibility(self) # Init vector self.y = np.hstack((self.x,self.lam,self.mu,self.pi)) # Complementarity measures self.eta_mu = np.dot(self.mu,self.u-self.x)/self.x.size self.eta_pi = np.dot(self.pi,self.x-self.l)/self.x.size # Objective scaling fdata = self.func(self.y) self.obj_sca = np.maximum(norminf(self.g+self.H*self.x)/10.,1.) self.H = self.H/self.obj_sca self.g = self.g/self.obj_sca fdata = self.func(self.y) # Header if not quiet: print('\nSolver: IQP') print('-----------') # Outer s = 0. self.k = 0 while True: # Complementarity measures self.eta_mu = np.dot(self.mu,self.u-self.x)/self.x.size self.eta_pi = np.dot(self.pi,self.x-self.l)/self.x.size # Init eval fdata = self.func(self.y) fmax = norminf(fdata.f) gmax = norminf(fdata.GradF) # Done if fmax < tol and sigma*np.maximum(self.eta_mu,self.eta_pi) < tol: self.set_status(self.STATUS_SOLVED) self.set_error_msg('') return # Target tau = sigma*norminf(fdata.GradF) # Header if not quiet: if self.k > 0: print('') print('{0:^3s}'.format('iter'), end=' ') print('{0:^9s}'.format('phi'), end=' ') print('{0:^9s}'.format('fmax'), end=' ') print('{0:^9s}'.format('gmax'), end=' ') print('{0:^8s}'.format('cu'), end=' ') print('{0:^8s}'.format('cl'), end=' ') print('{0:^8s}'.format('s')) # Inner while True: # Eval fdata = self.func(self.y) fmax = norminf(fdata.f) gmax = norminf(fdata.GradF) compu = norminf(self.mu*(self.u-self.x)) compl = norminf(self.pi*(self.x-self.l)) phi = (0.5*np.dot(self.x,self.H*self.x)+np.dot(self.g,self.x))*self.obj_sca # Show progress if not quiet: print('{0:^3d}'.format(self.k), end=' ') print('{0:^9.2e}'.format(phi), end=' ') print('{0:^9.2e}'.format(fmax), end=' ') print('{0:^9.2e}'.format(gmax), end=' ') print('{0:^8.1e}'.format(compu), end=' ') print('{0:^8.1e}'.format(compl), end=' ') print('{0:^8.1e}'.format(s)) # Done if gmax < tau: break # Done if fmax < tol and np.maximum(compu,compl) < tol: break # Maxiters if self.k >= maxiter: raise OptSolverError_MaxIters(self) # Search direction ux = self.u-self.x xl = self.x-self.l D1 = spdiags(self.mu/ux,0,self.n,self.n,format='coo') D2 = spdiags(self.pi/xl,0,self.n,self.n,format='coo') fbar = np.hstack((-fdata.rd+fdata.ru/ux-fdata.rl/xl,fdata.rp)) if self.A.shape[0] > 0: Jbar = bmat([[tril(self.H)+D1+D2,None], [-self.A,self.Omm]],format='coo') else: Jbar = bmat([[tril(self.H)+D1+D2]], format='coo') try: if not self.linsolver.is_analyzed(): self.linsolver.analyze(Jbar) pbar = self.linsolver.factorize_and_solve(Jbar,fbar) except RuntimeError: raise OptSolverError_BadLinSystem(self) px = pbar[:self.n] pmu = (-fdata.ru + self.mu*px)/ux ppi = (-fdata.rl - self.pi*px)/xl p = np.hstack((pbar,pmu,ppi)) # Steplength bounds indices = px > 0 s1 = np.min(np.hstack(((1.-eps)*(self.u-self.x)[indices]/px[indices],np.inf))) indices = px < 0 s2 = np.min(np.hstack(((eps-1.)*(self.x-self.l)[indices]/px[indices],np.inf))) indices = pmu < 0 s3 = np.min(np.hstack(((eps-1.)*self.mu[indices]/pmu[indices],np.inf))) indices = ppi < 0 s4 = np.min(np.hstack(((eps-1.)*self.pi[indices]/ppi[indices],np.inf))) smax = np.min([s1,s2,s3,s4]) # Line search s,fdata = self.line_search(self.y,p,fdata.F,fdata.GradF,self.func,smax) # Update x self.y += s*p self.k += 1 self.x,self.lam,self.mu,self.pi = self.extract_components(self.y) # Check try: assert(np.all(self.x < self.u)) assert(np.all(self.x > self.l)) assert(np.all(self.mu > 0)) assert(np.all(self.pi > 0)) except AssertionError: raise OptSolverError_Infeasibility(self)
def solve(self,problem): # Local vars norm2 = self.norm2 norminf = self.norminf params = self.parameters # Parameters tau = params['tau'] gamma = params['gamma'] kappa = params['kappa'] optol = params['optol'] feastol = params['feastol'] beta_small = params['beta_small'] beta_large = params['beta_large'] sigma_init_min = params['sigma_init_min'] sigma_init_max = params['sigma_init_max'] theta_init_min = params['theta_init_min'] theta_init_max = params['theta_init_max'] theta_min = params['theta_min'] # Problem problem = cast_problem(problem) self.problem = problem # Linear solver self.linsolver1 = new_linsolver(params['linsolver'],'symmetric') self.linsolver2 = new_linsolver(params['linsolver'],'symmetric') # Reset self.reset() # Barrier self.barrier = AugLBarrier(problem.get_num_primal_variables(), problem.l, problem.u) # Init primal if problem.x is not None: self.x = self.barrier.to_interior(problem.x.copy()) else: self.x = (self.barrier.umax+self.barrier.umin)/2. assert(np.all(self.x > self.barrier.umin)) assert(np.all(self.x < self.barrier.umax)) # Init dual if problem.lam is not None: self.lam = problem.lam.copy() else: self.lam = np.zeros(problem.b.size) if problem.nu is not None: self.nu = problem.nu.copy() else: self.nu = np.zeros(problem.f.size) try: if problem.pi is not None: self.pi = problem.pi.copy() else: self.pi = np.zeros(self.x.size) except AttributeError: self.pi = np.zeros(self.x.size) try: if problem.mu is not None: self.mu = problem.mu.copy() else: self.mu = np.zeros(self.x.size) except AttributeError: self.mu = np.zeros(self.x.size) # Constants self.sigma = 0. self.theta = 0. self.code = '' self.nx = self.x.size self.na = problem.b.size self.nf = problem.f.size self.ox = np.zeros(self.nx) self.oa = np.zeros(self.na) self.of = np.zeros(self.nf) self.Ixx = eye(self.nx,format='coo') self.Iff = eye(self.nf,format='coo') self.Iaa = eye(self.na,format='coo') # Objective scaling fdata = self.func(self.x) self.obj_sca = np.maximum(np.abs(fdata.phi)/100.,1.) fdata = self.func(self.x) # Init penalty and barrier parameters self.sigma = kappa*norm2(fdata.GradF)/np.maximum(norm2(fdata.gphi),1.) self.sigma = np.minimum(np.maximum(self.sigma,sigma_init_min),sigma_init_max) self.theta = kappa*norm2(fdata.GradF)/(self.sigma*np.maximum(norm2(fdata.gphiB),1.)) self.theta = np.minimum(np.maximum(self.theta,theta_init_min),theta_init_max) fdata = self.func(self.x) # Init residuals pres_prev = norminf(fdata.pres) gLmax_prev = norminf(fdata.GradF) # Init dual update if pres_prev <= feastol: self.update_multiplier_estimates() fdata = self.func(self.x) # Outer iterations self.k = 0 self.useH = False self.code = list('----') while True: # Solve subproblem self.solve_subproblem(tau*gLmax_prev) # Check done if self.is_status_solved(): return # Measure progress pres = norminf(fdata.pres) dres = norminf(fdata.dres) gLmax = norminf(fdata.GradF) # Penaly update if pres <= np.maximum(gamma*pres_prev,feastol): self.sigma *= beta_large self.code[1] = 'p' else: self.sigma *= beta_small self.code[1] = 'n' # Dual update self.update_multiplier_estimates() # Barrier update self.theta = np.maximum(self.theta*beta_small,theta_min) # Update refs pres_prev = pres gLmax_prev = gLmax # Update iters self.k += 1
def solve(self,problem): """ Solves optimization problem. Parameters ---------- problem : Object """ # Local vars norm2 = self.norm2 norminf = self.norminf parameters = self.parameters # Parameters tol = parameters['tol'] maxiter = parameters['maxiter'] quiet = parameters['quiet'] sigma = parameters['sigma'] eps = parameters['eps'] eps_cold = parameters['eps_cold'] # Problem if not isinstance(problem,QuadProblem): problem = cast_problem(problem) quad_problem = QuadProblem(None,None,None,None,None,None,problem=problem) else: quad_problem = problem self.problem = problem self.quad_problem = quad_problem # Linsolver self.linsolver = new_linsolver(parameters['linsolver'],'symmetric') # Reset self.reset() # Checks if not np.all(problem.l < problem.u): raise OptSolverError_NoInterior(self) # Data self.H = quad_problem.H self.g = quad_problem.g self.A = quad_problem.A self.AT = quad_problem.A.T self.b = quad_problem.b self.l = quad_problem.l self.u = quad_problem.u self.n = quad_problem.H.shape[0] self.m = quad_problem.A.shape[0] self.e = np.ones(self.n) self.I = eye(self.n,format='coo') self.Onm = coo_matrix((self.n,self.m)) self.Omm = coo_matrix((self.m,self.m)) # Initial primal if quad_problem.x is None: self.x = (self.u + self.l)/2. else: dul = eps*(self.u-self.l) self.x = np.maximum(np.minimum(quad_problem.x,self.u-dul),self.l+dul) # Initial duals if quad_problem.lam is None: self.lam = np.zeros(self.m) else: self.lam = quad_problem.lam.copy() if quad_problem.mu is None: self.mu = np.ones(self.x.size)*eps_cold else: self.mu = np.maximum(quad_problem.mu,eps) if quad_problem.pi is None: self.pi = np.ones(self.x.size)*eps_cold else: self.pi = np.maximum(quad_problem.pi,eps) # Check interior try: assert(np.all(self.l < self.x)) assert(np.all(self.x < self.u)) assert(np.all(self.mu > 0)) assert(np.all(self.pi > 0)) except AssertionError: raise OptSolverError_Infeasibility(self) # Init vector self.y = np.hstack((self.x,self.lam,self.mu,self.pi)) # Complementarity measures self.eta_mu = np.dot(self.mu,self.u-self.x)/self.x.size self.eta_pi = np.dot(self.pi,self.x-self.l)/self.x.size # Objective scaling fdata = self.func(self.y) self.obj_sca = np.maximum(norminf(self.g+self.H*self.x)/10.,1.) self.H = self.H/self.obj_sca self.g = self.g/self.obj_sca fdata = self.func(self.y) # Header if not quiet: print('\nSolver: IQP') print('-----------') # Outer s = 0. self.k = 0 while True: # Complementarity measures self.eta_mu = np.dot(self.mu,self.u-self.x)/self.x.size self.eta_pi = np.dot(self.pi,self.x-self.l)/self.x.size # Init eval fdata = self.func(self.y) fmax = norminf(fdata.f) gmax = norminf(fdata.GradF) # Done if fmax < tol and sigma*np.maximum(self.eta_mu,self.eta_pi) < tol: self.set_status(self.STATUS_SOLVED) self.set_error_msg('') return # Target tau = sigma*norminf(fdata.GradF) # Header if not quiet: if self.k > 0: print('') print('{0:^3s}'.format('iter'), end=' ') print('{0:^9s}'.format('phi'), end=' ') print('{0:^9s}'.format('fmax'), end=' ') print('{0:^9s}'.format('gmax'), end=' ') print('{0:^8s}'.format('cu'), end=' ') print('{0:^8s}'.format('cl'), end=' ') print('{0:^8s}'.format('s')) # Inner while True: # Eval fdata = self.func(self.y) fmax = norminf(fdata.f) gmax = norminf(fdata.GradF) compu = norminf(self.mu*(self.u-self.x)) compl = norminf(self.pi*(self.x-self.l)) phi = (0.5*np.dot(self.x,self.H*self.x)+np.dot(self.g,self.x))*self.obj_sca # Show progress if not quiet: print('{0:^3d}'.format(self.k), end=' ') print('{0:^9.2e}'.format(phi), end=' ') print('{0:^9.2e}'.format(fmax), end=' ') print('{0:^9.2e}'.format(gmax), end=' ') print('{0:^8.1e}'.format(compu), end=' ') print('{0:^8.1e}'.format(compl), end=' ') print('{0:^8.1e}'.format(s)) # Done if gmax < tau: break # Done if fmax < tol and np.maximum(compu,compl) < tol: break # Maxiters if self.k >= maxiter: raise OptSolverError_MaxIters(self) # Search direction ux = self.u-self.x xl = self.x-self.l D1 = spdiags(self.mu/ux,0,self.n,self.n,format='coo') D2 = spdiags(self.pi/xl,0,self.n,self.n,format='coo') fbar = np.hstack((-fdata.rd+fdata.ru/ux-fdata.rl/xl,fdata.rp)) if self.A.shape[0] > 0: Jbar = bmat([[tril(self.H)+D1+D2,None], [-self.A,self.Omm]],format='coo') else: Jbar = bmat([[tril(self.H)+D1+D2]], format='coo') try: if not self.linsolver.is_analyzed(): self.linsolver.analyze(Jbar) pbar = self.linsolver.factorize_and_solve(Jbar,fbar) except RuntimeError: raise OptSolverError_BadLinSystem(self) px = pbar[:self.n] pmu = (-fdata.ru + self.mu*px)/ux ppi = (-fdata.rl - self.pi*px)/xl p = np.hstack((pbar,pmu,ppi)) # Steplength bounds indices = px > 0 s1 = np.min(np.hstack(((1.-eps)*(self.u-self.x)[indices]/px[indices],np.inf))) indices = px < 0 s2 = np.min(np.hstack(((eps-1.)*(self.x-self.l)[indices]/px[indices],np.inf))) indices = pmu < 0 s3 = np.min(np.hstack(((eps-1.)*self.mu[indices]/pmu[indices],np.inf))) indices = ppi < 0 s4 = np.min(np.hstack(((eps-1.)*self.pi[indices]/ppi[indices],np.inf))) smax = np.min([s1,s2,s3,s4]) # Line search s,fdata = self.line_search(self.y,p,fdata.F,fdata.GradF,self.func,smax) # Update x self.y += s*p self.k += 1 self.x,self.lam,self.mu,self.pi = self.extract_components(self.y) # Check try: assert(np.all(self.x < self.u)) assert(np.all(self.x > self.l)) assert(np.all(self.mu > 0)) assert(np.all(self.pi > 0)) except AssertionError: raise OptSolverError_Infeasibility(self)