Example #1
0
    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)
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
    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
Example #5
0
    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
Example #6
0
    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))
Example #7
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
Example #8
0
    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
Example #9
0
    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)
Example #10
0
File: iqp.py Project: romcon/OPTALG
    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)
Example #11
0
    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
Example #12
0
    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)