Example #1
0
    def setUp(self):
        # Reset random seed for repeatability
        np.random.seed(1)

        # Random Example
        n = 30
        m = 50
        p = 5  # Number of integer variables

        # Generate random Matrices
        Pt = spa.random(n, n, density=0.6)
        P = Pt.dot(Pt.T).tocsc()
        q = np.random.randn(n)
        A = spa.random(m, n, density=0.6).tocsc()
        u = 3 + np.random.randn(m)
        l = -3 + np.random.randn(m)

        # Generate random vector of indeces
        i_idx = np.random.choice(np.arange(0, n), p, replace=False)

        # Generate variable bounds 
        i_l = -1*np.ones(p)
        i_u = 1*np.ones(p)

        self.p = mpbpy.QuadprogProblem(P, q, A, l, u, i_idx, i_l, i_u)
Example #2
0
    def setUp(self):

        # Dual infeasible example
        P = spa.csc_matrix(np.diag(np.array([4., 0.])))
        q = np.array([0., 2])
        A = spa.csc_matrix([[1., 1.], [-1., 1.]])
        l = np.array([-np.inf, -np.inf])
        u = np.array([2., 3.])

        self.p = mpbpy.QuadprogProblem(P, q, A, l, u)
def load_maros_meszaros_problem(f):
    # Load file
    m = spio.loadmat(f)

    # Convert matrices
    P = m['Q'].astype(float)
    n = P.shape[0]
    q = m['c'].T.flatten().astype(float)
    A = m['A'].astype(float)
    A = spspa.vstack([A, spspa.eye(n)])
    u = np.append(m['ru'].T.flatten().astype(float),
                  m['ub'].T.flatten().astype(float))
    l = np.append(m['rl'].T.flatten().astype(float),
                  m['lb'].T.flatten().astype(float))
    # Define problem
    p = mpbpy.QuadprogProblem(P, q, A, l, u)

    return p
    def setUp(self):
        # Reset random seed for repeatability
        np.random.seed(1)

        # Random Example
        n = 30
        m = 50

        # Generate random Matrices
        Pt = spa.random(n, n, density=0.6)
        P = Pt.dot(Pt.T).tocsc()
        q = np.random.randn(n)
        A = spa.random(m, n, density=0.6).tocsc()
        u = 3 + np.random.randn(m)
        l = -3 + np.random.randn(m)

        # Make random problem primal infeasible
        A[int(n / 2), :] = A[int(n / 2) + 1, :]
        l[int(n / 2)] = u[int(n / 2) + 1] + 10 * np.random.rand()
        u[int(n / 2)] = l[int(n / 2)] + 0.5

        self.p = mpbpy.QuadprogProblem(P, q, A, l, u)
Example #5
0
def solve_problem(qp_matrices, n_prob, solver='osqp'):
    """
    Solve SVM problem
    """
    # Shorter name for qp_matrices
    qp = qp_matrices

    # Initialize time vector
    time = np.zeros(n_prob)

    # Initialize number of iterations vector
    niter = np.zeros(n_prob)

    # Get dimensions
    m = len(qp.lx)
    n = len(qp.q) - m

    print('n = %d and solver %s' % (n, solver))

    if solver == 'osqp':
        # Construct qp matrices
        Aosqp = spa.vstack([
            qp.A,
            spa.hstack([spa.csc_matrix((m, n)),
                        spa.eye(m)]),
        ]).tocsc()
        losqp = np.hstack([qp.l, qp.lx])
        uosqp = np.hstack([qp.u, qp.ux])

        for i in range(n_prob):
            # Setup OSQP
            m = osqp.OSQP()
            m.setup(qp.P,
                    qp.q,
                    Aosqp,
                    losqp,
                    uosqp,
                    auto_rho=True,
                    polish=False,
                    verbose=False)

            # Solve
            results = m.solve()
            x = results.x
            status = results.info.status_val
            niter[i] = results.info.iter
            time[i] = results.info.run_time

            # Check if status correct
            if status != m.constant('OSQP_SOLVED'):
                import ipdb
                ipdb.set_trace()
                raise ValueError('OSQP did not solve the problem!')

            # DEBUG
            # solve with gurobi
            # import mathprogbasepy as mpbpy
            # prob = mpbpy.QuadprogProblem(qp.P, qp.q, Aosqp, losqp, uosqp)
            # res = prob.solve(solver=mpbpy.GUROBI, verbose=False)
            # print('Norm difference OSQP-GUROBI %.3e' %
            #       np.linalg.norm(x - res.x))
            # import ipdb; ipdb.set_trace()

    elif solver == 'qpoases':

        for i in range(n_prob):
            n_dim = qp.P.shape[0]  # Number of variables
            m_dim = qp.A.shape[0]  # Number of constraints without bounds

            # Initialize qpoases and set options
            qpoases_m = qpoases.PyQProblem(n_dim, m_dim)
            options = qpoases.PyOptions()
            options.printLevel = qpoases.PyPrintLevel.NONE
            qpoases_m.setOptions(options)

            # Construct bounds for qpoases
            lx = np.append(-np.inf * np.ones(n), qp.lx)
            ux = np.append(np.inf * np.ones(n), qp.ux)

            # Setup matrix P and A
            P = np.ascontiguousarray(qp.P.todense())
            A = np.ascontiguousarray(qp.A.todense())

            # Reset cpu time
            qpoases_cpu_time = np.array([20.])

            # Reset number of working set recalculations
            nWSR = np.array([1000])

            # Solve
            res_qpoases = qpoases_m.init(P, np.ascontiguousarray(qp.q), A,
                                         np.ascontiguousarray(lx),
                                         np.ascontiguousarray(ux),
                                         np.ascontiguousarray(qp.l),
                                         np.ascontiguousarray(qp.u), nWSR,
                                         qpoases_cpu_time)

            if res_qpoases != 0:
                raise ValueError('qpoases did not solve the problem!')

            # Save time and number of iterations
            time[i] = qpoases_cpu_time[0]
            niter[i] = nWSR[0]

    elif solver == 'gurobi':

        for i in range(n_prob):
            # Construct qp matrices
            Agurobi = spa.vstack([
                qp.A,
                spa.hstack([spa.csc_matrix((m, n)),
                            spa.eye(m)]),
            ]).tocsc()
            lgurobi = np.hstack([qp.l, qp.lx])
            ugurobi = np.hstack([qp.u, qp.ux])

            # Solve with gurobi
            prob = mpbpy.QuadprogProblem(qp.P, qp.q, Agurobi, lgurobi, ugurobi)
            res = prob.solve(solver=mpbpy.GUROBI, verbose=False)
            niter[i] = res.total_iter
            time[i] = res.cputime

    elif solver == 'mosek':

        for i in range(n_prob):
            # Construct qp matrices
            Amosek = spa.vstack([
                qp.A,
                spa.hstack([spa.csc_matrix((m, n)),
                            spa.eye(m)]),
            ]).tocsc()
            lmosek = np.hstack([qp.l, qp.lx])
            umosek = np.hstack([qp.u, qp.ux])

            # Solve with mosek
            prob = mpbpy.QuadprogProblem(qp.P, qp.q, Amosek, lmosek, umosek)
            res = prob.solve(solver=mpbpy.MOSEK, verbose=False)
            niter[i] = res.total_iter
            time[i] = res.cputime

    elif solver == 'ecos':

        for i in range(n_prob):
            # Construct the problem
            #       minimize	 x.T * x + gamma 1.T * t
            #       subject to  t >= diag(b) A x + 1
            #                   t >= 0
            n_var = qp.A_svm.shape[1]
            m_var = qp.A_svm.shape[0]
            x = cvxpy.Variable(n_var)
            t = cvxpy.Variable(m_var)

            objective = cvxpy.Minimize(
                cvxpy.quad_form(x, spa.eye(n_var)) +
                qp.gamma * np.ones(m_var) * t)
            constraints = [
                t >= spa.diags(qp.b_svm).dot(qp.A_svm) * x + 1, t >= 0
            ]

            problem = cvxpy.Problem(objective, constraints)
            problem.solve(solver=cvxpy.ECOS, verbose=False)

            # Obtain time and number of iterations
            time[i] = problem.solver_stats.setup_time + \
                problem.solver_stats.solve_time

            niter[i] = problem.solver_stats.num_iters

            # # DEBUG: solve with mosek
            # Amosek = spa.vstack([
            #             qp.A,
            #             spa.hstack([spa.csc_matrix((m, n)), spa.eye(m)]),
            #           ]).tocsc()
            # lmosek = np.hstack([qp.l, qp.lx])
            # umosek = np.hstack([qp.u, qp.ux])
            #
            # # Solve with mosek
            # prob = mpbpy.QuadprogProblem(qp.P, qp.q, Amosek, lmosek, umosek)
            # res = prob.solve(solver=mpbpy.MOSEK, verbose=False)
            # x_mosek = res.x[:n_var]
            #
            # import ipdb; ipdb.set_trace()

    else:
        raise ValueError('Solver not understood')

    # Return statistics
    return utils.Statistics(time), utils.Statistics(niter)
Example #6
0
def solve(n_vec, m_vec, p_vec, repeat, dns_level, seed, solver='gurobi'):
    """
    Solve random optimization problems
    """

    print("Solving random problems with solver %s\n" % solver)

    # Define statistics to record
    std_solve_time = np.zeros(len(n_vec))
    avg_solve_time = np.zeros(len(n_vec))
    min_solve_time = np.zeros(len(n_vec))
    max_solve_time = np.zeros(len(n_vec))

    n_prob = len(n_vec)

    # Store also OSQP time
    if solver == 'miosqp':
        # Add OSQP solve times statistics
        avg_osqp_solve_time = np.zeros(len(n_vec))

    # reset random seed
    np.random.seed(seed)

    for i in range(n_prob):

        # Get dimensions
        n = n_vec[i]
        m = m_vec[i]
        p = p_vec[i]

        print("problem n = %i, m = %i, p = %i" % (n, m, p))

        # Define vector of cpu times
        solve_time_temp = np.zeros(repeat)

        # Store also OSQP time
        if solver == 'miosqp':
            osqp_solve_time_temp = np.zeros(repeat)

        for j in tqdm(range(repeat)):
        #  for j in range(repeat):

            # Generate random vector of indeces
            i_idx = np.random.choice(np.arange(0, n), p, replace=False)

            # Generate random Matrices
            Pt = spa.random(n, n, density=dns_level)
            P = spa.csc_matrix(np.dot(Pt, Pt.T))
            q = sp.randn(n)
            A = spa.random(m, n, density=dns_level)
            u = 2 + sp.rand(m)
            l = -2 + sp.rand(m)

            # Enforce [0, 1] bounds on variables
            i_l = np.zeros(p)
            i_u = np.ones(p)
            #  A, l, u = miosqp.add_bounds(i_idx, 0., 1., A, l, u)

            if solver == 'gurobi':
                # Solve with gurobi
                prob = mpbpy.QuadprogProblem(P, q, A, l, u, i_idx, i_l, i_u)
                res_gurobi = prob.solve(solver=mpbpy.GUROBI,
                                        verbose=False, Threads=1)
                if res_gurobi.status != 'optimal':
                    import ipdb
                    ipdb.set_trace()
                solve_time_temp[j] = 1e3 * res_gurobi.cputime

            elif solver == 'miosqp':
                # Define problem settings
                miosqp_settings = {
                                   # integer feasibility tolerance
                                   'eps_int_feas': 1e-03,
                                   # maximum number of iterations
                                   'max_iter_bb': 1000,
                                   # tree exploration rule
                                   #   [0] depth first
                                   #   [1] two-phase: depth first until first incumbent and then  best bound
                                   'tree_explor_rule': 1,
                                   # branching rule
                                   #   [0] max fractional part
                                   'branching_rule': 0,
                                   'verbose': False,
                                   'print_interval': 1}

                osqp_settings = {'eps_abs': 1e-03,
                                 'eps_rel': 1e-03,
                                 'eps_prim_inf': 1e-04,
                                 'verbose': False}

                model = miosqp.MIOSQP()
                model.setup(P, q, A, l, u, i_idx, i_l, i_u,
                            miosqp_settings,
                            osqp_settings)
                res_miosqp = model.solve()

                # DEBUG (check if solutions match)
                #  prob = mpbpy.QuadprogProblem(P, q, A, l, u, i_idx, i_l, i_u)
                #  res_gurobi = prob.solve(solver=mpbpy.GUROBI, verbose=False)
                #  if (np.linalg.norm(res_gurobi.x - res_miosqp.x) /
                #          np.linalg.norm(res_gurobi.x)) > 1e-02:
                #     import ipdb; ipdb.set_trace()
#
                #  import ipdb; ipdb.set_trace()

                if res_miosqp.status != miosqp.MI_SOLVED:
                    import ipdb
                    ipdb.set_trace()
                
                # Solution time 
                solve_time_temp[j] = 1e3 * res_miosqp.run_time

                # Store OSQP time in percentage
                if solver == 'miosqp':
                    osqp_solve_time_temp[j] = \
                        100 * (res_miosqp.osqp_solve_time / res_miosqp.run_time)

        # Get time statistics
        std_solve_time[i] = np.std(solve_time_temp)
        avg_solve_time[i] = np.mean(solve_time_temp)
        max_solve_time[i] = np.max(solve_time_temp)
        min_solve_time[i] = np.min(solve_time_temp)

        # Store also OSQP time
        if solver == 'miosqp':
            avg_osqp_solve_time[i] = np.mean(osqp_solve_time_temp)

    # Create pandas dataframe for the results
    df_dict = {'n': n_vec,
               'm': m_vec,
               'p': p_vec,
               't_min': min_solve_time,
               't_max': max_solve_time,
               't_avg': avg_solve_time,
               't_std': std_solve_time}

    # Store also OSQP time
    if solver == 'miosqp':
        df_dict.update({'t_osqp_avg': avg_osqp_solve_time})

    timings = pd.DataFrame(df_dict)

    return timings
Example #7
0
    def compute_mpc_input(self, x0, u_prev, solver='gurobi'):
        """
        Compute MPC input at initial state x0 with specified solver
        """
        qp = self.qp_matrices

        N = qp.N

        # Update objective
        q = 2. * (qp.q_x.dot(x0) + qp.q_u)

        # Update bounds
        SA_tildex0 = qp.SA_tilde.dot(x0)
        qp.u[:6 * N] = SA_tildex0
        # qp.l[:6 * N] = -SA_tildex0

        if solver == 'gurobi':
            # Solve problem
            prob = mpbpy.QuadprogProblem(qp.P, q, qp.A, qp.l, qp.u, qp.i_idx,
                                         qp.i_l, qp.i_u, x0=u_prev)
            res_gurobi = prob.solve(solver=mpbpy.GUROBI, verbose=False,
                                    Threads=1)
            u = res_gurobi.x
            obj_val = res_gurobi.obj_val
            solve_time = res_gurobi.cputime

        elif solver == 'miosqp':

            if self.solver is None:
                # Define problem settings
                miosqp_settings = {'eps_int_feas': 1e-02,   # integer feasibility tolerance
                                   'max_iter_bb': 2000,     # maximum number of iterations
                                   'tree_explor_rule': 1,   # tree exploration rule
                                                            #   [0] depth first
                                                            #   [1] two-phase: depth first  until first incumbent and then  best bound
                                   'branching_rule': 0,     # branching rule
                                                            #   [0] max fractional part
                                   'verbose': False,
                                   'print_interval': 1}

                osqp_settings = {'eps_abs': 1e-03,
                                 'eps_rel': 1e-03,
                                 'eps_prim_inf': 1e-04,
                                 #  'rho': 0.001,
                                 #  'rho': 0.1,
                                 'verbose': False}
                self.solver = miosqp.MIOSQP()
                self.solver.setup(qp.P, q, qp.A, qp.l,
                                  qp.u, qp.i_idx, qp.i_l, qp.i_u,
                                  miosqp_settings,
                                  osqp_settings)
            else:
                self.solver.update_vectors(q, qp.l, qp.u)

            self.solver.set_x0(u_prev)
            res_miosqp = self.solver.solve()

            # import ipdb; ipdb.set_trace()

            # DEBUG Check if gurobi gives same solution
            # N.B. They do not match when the norm of the
            #      difference of the objective functions
            #      is below the tolerance
            #
            # prob = mpbpy.QuadprogProblem(qp.P, q, qp.A, qp.l, qp.u, qp.i_idx)
            # res_gurobi = prob.solve(solver=mpbpy.GUROBI, verbose=False, x0=u_prev)
            # if np.linalg.norm(res_miosqp.x - res_gurobi.x)> 1e-02:
            #     print("Norm of difference of solution = %.4e" % \
            #           np.linalg.norm(res_miosqp.x - res_gurobi.x))
                # import ipdb; ipdb.set_trace()


            if res_miosqp.status != miosqp.MI_SOLVED:
                import ipdb; ipdb.set_trace()
            u = res_miosqp.x
            obj_val = res_miosqp.upper_glob
            solve_time = res_miosqp.run_time
            osqp_solve_time = 100 * res_miosqp.osqp_solve_time / res_miosqp.run_time

        # Get first input
        u0 = u[:6]

        if solver == 'miosqp':
            return u0, obj_val, solve_time, u, \
                    osqp_solve_time, \
                    res_miosqp.osqp_iter_avg
        else:
            return u0, obj_val, solve_time, u, 0, 0
Example #8
0
def solve_loop(qp_matrices, solver='osqp', osqp_settings=None):
    """
    Solve lasso optimization loop for all lambdas
    """
    # Shorter name for qp_matrices
    qp = qp_matrices

    # Extract features
    n = qp.n

    print('n = %d and solver %s' % (n, solver))

    # Get number of problems to solve
    n_prob = qp.q.shape[1]

    # Initialize time vector
    time = np.zeros(n_prob)

    # Initialize number of iterations vector
    niter = np.zeros(n_prob)

    if solver == 'osqp':

        # Setup OSQP
        m = osqp.OSQP()
        m.setup(qp.P, qp.q[:, 0], qp.A, qp.l, qp.u, **osqp_settings)

        for i in range(n_prob):
            q = qp.q[:, i]

            # Update linear cost
            m.update(q=q)

            # Solve
            results = m.solve()
            x = results.x
            y = results.y
            status = results.info.status_val
            niter[i] = results.info.iter
            time[i] = results.info.run_time

            # Check if status correct
            if status != m.constant('OSQP_SOLVED'):
                import ipdb
                ipdb.set_trace()
                raise ValueError('OSQP did not solve the problem!')

            # DEBUG
            # solve with gurobi
            # prob = mpbpy.QuadprogProblem(qp.P, q, Aosqp, losqp, uosqp)
            # res = prob.solve(solver=mpbpy.GUROBI, verbose=False)
            # print('Norm difference OSQP-GUROBI %.3e' %
            #       np.linalg.norm(x - res.x))
            # import ipdb; ipdb.set_trace()

    elif solver == 'osqp_coldstart':

        # Setup OSQP
        m = osqp.OSQP()
        m.setup(qp.P, qp.q[:, 0], qp.A, qp.l, qp.u, **osqp_settings)

        for i in range(n_prob):
            q = qp.q[:, i]

            # Update linear cost
            m.update(q=q)

            # Solve
            results = m.solve()
            x = results.x
            y = results.y
            status = results.info.status_val
            niter[i] = results.info.iter
            time[i] = results.info.run_time

            # Check if status correct
            if status != m.constant('OSQP_SOLVED'):
                import ipdb
                ipdb.set_trace()
                raise ValueError('OSQP did not solve the problem!')

            # DEBUG
            # solve with gurobi
            # prob = mpbpy.QuadprogProblem(qp.P, q, qp.A, qp.l, qp.u)
            # res = prob.solve(solver=mpbpy.GUROBI, verbose=False)
            # print('Norm difference OSQP-GUROBI %.3e' %
            #       np.linalg.norm(x - res.x))
            # import ipdb; ipdb.set_trace()

        # DEBUG print iterations per value of lambda
        # lambda_vals = np.logspace(-2, 2, 101)[::-1]
        #
        # import matplotlib.pylab as plt
        # plt.figure()
        # ax = plt.gca()
        # plt.plot(lambda_vals, niter)
        # ax.set_xlabel(r'$\lambda$')
        # ax.set_ylabel(r'iter')
        # plt.show(block=False)

        # import ipdb; ipdb.set_trace()

    elif solver == 'osqp_no_caching':

        for i in range(n_prob):

            # Setup OSQP
            m = osqp.OSQP()
            m.setup(qp.P, qp.q[:, i], qp.A, qp.l, qp.u, **osqp_settings)

            # Solve
            results = m.solve()
            x = results.x
            y = results.y
            status = results.info.status_val
            niter[i] = results.info.iter
            time[i] = results.info.run_time

            # Check if status correct
            if status != m.constant('OSQP_SOLVED'):
                import ipdb
                ipdb.set_trace()
                raise ValueError('OSQP did not solve the problem!')

            # DEBUG
            # solve with gurobi
            # prob = mpbpy.QuadprogProblem(qp.P, q, Aosqp, losqp, uosqp)
            # res = prob.solve(solver=mpbpy.GUROBI, verbose=False)
            # print('Norm difference OSQP-GUROBI %.3e' %
            #       np.linalg.norm(x - res.x))
            # import ipdb; ipdb.set_trace()

    elif solver == 'qpoases':

        n_dim = qp.P.shape[0]  # Number of variables
        m_dim = qp.A.shape[0]  # Number of constraints without bounds

        # Initialize qpoases and set options
        qpoases_m = qpoases.PyQProblem(n_dim, m_dim)
        options = qpoases.PyOptions()
        options.printLevel = qpoases.PyPrintLevel.NONE
        qpoases_m.setOptions(options)

        # Setup matrix P and A
        P = np.ascontiguousarray(qp.P.todense())
        A = np.ascontiguousarray(qp.A.todense())

        for i in range(n_prob):

            # Get linera cost as contiguous array
            q = np.ascontiguousarray(qp.q[:, i])

            # Reset cpu time
            qpoases_cpu_time = np.array([10.])

            # Reset number of of working set recalculations
            nWSR = np.array([1000])

            if i == 0:
                # First iteration
                res_qpoases = qpoases_m.init(P, q, A,
                                             np.ascontiguousarray(qp.lx),
                                             np.ascontiguousarray(qp.ux),
                                             np.ascontiguousarray(qp.l),
                                             np.ascontiguousarray(qp.u), nWSR,
                                             qpoases_cpu_time)
            else:
                # Solve new hot started problem
                res_qpoases = qpoases_m.hotstart(q,
                                                 np.ascontiguousarray(qp.lx),
                                                 np.ascontiguousarray(qp.ux),
                                                 np.ascontiguousarray(qp.l),
                                                 np.ascontiguousarray(qp.u),
                                                 nWSR, qpoases_cpu_time)

            # # DEBUG Solve with gurobi
            # qpoases solution
            # sol_qpoases = np.zeros(n + k)
            # qpoases_m.getPrimalSolution(sol_qpoases)
            # import mathprogbasepy as mpbpy
            # Agrb = spa.vstack((qp.A,
            #                     spa.hstack((spa.eye(n), spa.csc_matrix((n, k)))
            #                                ))).tocsc()
            # lgrb = np.append(qp.l, qp.lx)
            # ugrb = np.append(qp.u, qp.ux)
            # prob = mpbpy.QuadprogProblem(spa.csc_matrix(qp.P), q,
            #                              Agrb, lgrb, ugrb)
            # res = prob.solve(solver=mpbpy.GUROBI, verbose=True)
            # print("Norm difference x qpoases - GUROBI = %.4f" %
            #       np.linalg.norm(sol_qpoases - res.x))
            # print("Norm difference objval qpoases - GUROBI = %.4f" %
            #       abs(qpoases_m.getObjVal() - res.obj_val))
            # import ipdb; ipdb.set_trace()

            # if res_qpoases != 0:
            #     raise ValueError('qpoases did not solve the problem!')

            # Save time
            time[i] = qpoases_cpu_time[0]

            # Save number of iterations
            niter[i] = nWSR[0]

    elif solver == 'gurobi':

        for i in range(n_prob):

            # Get linera cost as contiguous array
            q = qp.q[:, i]

            # Solve with gurobi
            prob = mpbpy.QuadprogProblem(qp.P, q, qp.A, qp.l, qp.u)
            res = prob.solve(solver=mpbpy.GUROBI, verbose=False)

            # Save time
            time[i] = res.cputime

            # Save number of iterations
            niter[i] = res.total_iter

    elif solver == 'mosek':

        for i in range(n_prob):

            # Get linera cost as contiguous array
            q = qp.q[:, i]

            # Solve with mosek
            prob = mpbpy.QuadprogProblem(qp.P, q, qp.A, qp.l, qp.u)
            res = prob.solve(solver=mpbpy.MOSEK, verbose=False)

            # Save time
            time[i] = res.cputime

            # Save number of iterations
            niter[i] = res.total_iter

    elif solver == 'ecos':

        n_var = qp_matrices.A_lasso.shape[1]
        m_var = qp_matrices.A_lasso.shape[0]

        for i in range(n_prob):
            if n_var <= 60:  # (problem becomes too big otherwise):

                # Model with CVXPY
                #       minimize	y' * y + lambda * 1' * t
                #       subject to  y = Ax - b
                #                   -t <= x <= t
                lambda_i = qp_matrices.lambdas[i]
                x = cvxpy.Variable(n_var)
                y = cvxpy.Variable(m_var)
                t = cvxpy.Variable(n_var)

                objective = cvxpy.Minimize(
                    cvxpy.quad_form(y, spa.eye(m_var)) +
                    lambda_i * np.ones(n_var) * t)
                constraints = [
                    y == qp_matrices.A_lasso * x - qp_matrices.b_lasso,
                    -t <= x, x <= t
                ]
                problem = cvxpy.Problem(objective, constraints)
                problem.solve(solver=cvxpy.ECOS, verbose=False)

                # DEBUG: Solve with MOSEK
                q = qp.q[:, i]

                # Solve with mosek
                # prob = mpbpy.QuadprogProblem(qp.P, q, qp.A, qp.l, qp.u)
                # res = prob.solve(solver=mpbpy.MOSEK, verbose=False)
                # x_mosek = res.x[:n_var]
                # import ipdb; ipdb.set_trace()

                # Obtain time and number of iterations
                time[i] = problem.solver_stats.setup_time + \
                    problem.solver_stats.solve_time

                niter[i] = problem.solver_stats.num_iters
            else:
                time[i] = 0
                niter[i] = 0

    else:
        raise ValueError('Solver not understood')

    # Return statistics
    return utils.Statistics(time), utils.Statistics(niter)
Example #9
0
# Test
rho = 0.1

osqp_opts = {'rho': rho,
             'adaptive_rho': True,
             'adaptive_rho_interval': 25,
             'sigma': 1e-06,
             'scaled_termination': False,
             'check_termination': 1,
             'polish': False,
             'verbose': True,
             'linsys_solver': 'suitesparse ldl'
             }

qp = mpbpy.QuadprogProblem(P, q, A, l, u)
res_gurobi = qp.solve(solver=mpbpy.GUROBI, verbose=True)

model = osqppurepy.OSQP()
model.setup(P=P, q=q, A=A, l=l, u=u, **osqp_opts)
res_osqppurepy = model.solve()

# Solve with SuiteSparse LDL
model = osqp.OSQP()
model.setup(P=P, q=q, A=A, l=l, u=u, **osqp_opts)
res_osqp = model.solve()


# Check difference with gurobi
if res_gurobi.status == 'optimal':
    print("Difference OSQP vs Gurobi")
Example #10
0
def main():
    sp.random.seed(1)
    # Possible ops:  {'small1', 'small2', 'random',
    #                 'primal_infeasible', 'random_primal_infeasible',
    #                 'maros_meszaros', 'lp', 'dual_infeasible_lp',
    #                 'dual_infeasible_qp'}
    example = 'random_primal_infeasible'

    if example == 'maros_meszaros':
        # Maros Meszaros Examples
        # f = 'tests/maros_meszaros/CVXQP2_S.mat'
        # f = 'tests/maros_meszaros/CVXQP1_S.mat'
        # f = 'tests/maros_meszaros/AUG2D.mat'
        f = 'maros_meszaros/CONT-200.mat'
        # f = 'tests/maros_meszaros/PRIMAL3.mat'
        # f = 'tests/maros_meszaros/QBANDM.mat'
        p = load_maros_meszaros_problem(f)

    elif example == 'small1':
        # Our Examples
        # Small Example 1
        P = spspa.csc_matrix(np.array([[4., 1.], [1., 2.]]))
        q = np.ones(2)
        A = spspa.vstack(
            [spspa.csc_matrix(np.ones((1, 2))),
             spspa.eye(P.shape[0])]).tocsc()
        l = np.array([1.0, 0.0, 0.0])
        u = np.array([1.0, 0.7, 0.7])
        p = mpbpy.QuadprogProblem(P, q, A, l, u)
    elif example == 'small2':
        # Small Example 2
        P = spspa.csc_matrix(np.array([[11., 0.], [0., 0.]]))
        q = np.array([3, 4])
        A = spspa.csc_matrix(
            np.array([[-1, 0], [0, -1], [-1, -3], [2, 5], [3, 4]]))
        u = np.array([0., 0., -15, 100, 80])
        l = -np.inf * np.ones(len(u))
        p = mpbpy.QuadprogProblem(P, q, A, l, u)
    elif example == 'primal_infeasible':
        # primal_infeasible example
        # P = spspa.eye(2)
        P = spspa.csc_matrix((2, 2))
        q = np.ones(2)
        A = spspa.csc_matrix(np.array([[1, 0], [0, 1], [1, 1]]))
        l = np.array([0., 0., -1.])
        u = np.array([np.inf, np.inf, -1.])
        p = mpbpy.QuadprogProblem(P, q, A, l, u)
    elif example == 'random_primal_infeasible':
        # Random Example
        n = 50
        m = 500
        # Generate random Matrices
        Pt = sp.randn(n, n)
        P = spspa.csc_matrix(np.dot(Pt.T, Pt))
        q = sp.randn(n)
        A = spspa.csc_matrix(sp.randn(m, n))
        u = 3 + sp.randn(m)
        # l = u
        l = -3 + sp.randn(m)

        # Make random problem primal_infeasible
        A[int(n / 2), :] = A[int(n / 2) + 1, :]
        l[int(n / 2)] = u[int(n / 2) + 1] + 100 * sp.rand()
        u[int(n / 2)] = l[int(n / 2)] + 0.5
        # l[int(n/3)] = u[int(n/3)] + 100 * sp.rand()
        # l[int(n/4)] = u[int(n/4)] + 50. * sp.rand()

        p = mpbpy.QuadprogProblem(P, q, A, l, u)
    elif example == 'dual_infeasible_lp':
        # Dual infeasible example
        P = spspa.csc_matrix((2, 2))
        q = np.array([2, -1])
        A = spspa.eye(2)
        l = np.array([0., 0.])
        u = np.array([np.inf, np.inf])
        p = mpbpy.QuadprogProblem(P, q, A, l, u)
    elif example == 'dual_infeasible_qp':
        # Dual infeasible example
        P = spspa.csc_matrix(np.diag(np.array([4., 0.])))
        q = np.array([0, 2])
        A = spspa.csc_matrix([[1., 1.], [-1., 1.]])
        l = np.array([-np.inf, -np.inf])
        u = np.array([2., 3.])
        p = mpbpy.QuadprogProblem(P, q, A, l, u)
    elif example == 'random':
        # Random Example
        n = 30
        m = 50
        # Generate random Matrices
        Pt = sp.randn(n, n)
        P = spspa.csc_matrix(np.dot(Pt.T, Pt))
        q = sp.randn(n)
        A = spspa.csc_matrix(sp.randn(m, n))
        u = 3 + sp.randn(m)
        # l = u
        l = -3 + sp.randn(m)

        p = mpbpy.QuadprogProblem(P, q, A, l, u)
    elif example == 'lp':
        # Random Example
        n = 10
        m = 1000
        # Generate random Matrices
        P = spspa.csc_matrix(np.zeros((n, n)))
        q = sp.randn(n)
        A = spspa.vstack([spspa.csc_matrix(sp.randn(m, n)), spspa.eye(n)])
        l = np.append(-3 + sp.randn(m), -3 + sp.randn(n))
        u = np.append(3 + sp.randn(m), 3 + sp.randn(n))
        p = mpbpy.QuadprogProblem(P, q, A, l, u)
    else:
        assert False, "Unknown example"

    # Solve with CPLEX
    # print("\nSolve with CPLEX")
    # print("-----------------")
    # resultsCPLEX = p.solve(solver=mpbpy.CPLEX, verbose=True)

    # Solve with GUROBI
    print("\nSolve with GUROBI")
    print("-----------------")
    resultsGUROBI = p.solve(solver=mpbpy.GUROBI, OutputFlag=1)

    # Solve with OSQP. You can pass options to OSQP solver
    print("\nSolve with OSQP")
    print("-----------------")
    resultsOSQP = p.solve(
        solver=mpbpy.OSQP,
        max_iter=5000,
        #  eps_rel=1e-3,
        #  eps_abs=1e-3,
        #  alpha=1.6,
        #  rho=0.00001,  # Works with LP
        check_termination=1,
        #   sigma=1e-3,
        polish=True,
        verbose=True)

    import ipdb
    ipdb.set_trace()

    if resultsGUROBI.status in mpbpy_prob.SOLUTION_PRESENT:
        # print("\n")
        # print("Comparison CPLEX - GUROBI")
        # print("-------------------------")
        # print("Difference in objective value %.8f" %
        #       np.linalg.norm(resultsCPLEX.objval - resultsGUROBI.objval))
        # print("Norm of solution difference %.8f" %
        #       np.linalg.norm(resultsCPLEX.x - resultsGUROBI.x))
        # print("Norm of dual difference %.8f" %
        #       np.linalg.norm(resultsCPLEX.y - resultsGUROBI.y))

        print("\n")
        print("Comparison OSQP - GUROBI")
        print("-------------------------")
        print("Difference in objective value %.8f" %
              np.linalg.norm(resultsOSQP.obj_val - resultsGUROBI.obj_val))
        print("Norm of solution difference %.8f" %
              np.linalg.norm(resultsOSQP.x - resultsGUROBI.x))
        print("Norm of dual difference %.8f" %
              np.linalg.norm(resultsOSQP.y - resultsGUROBI.y))
Example #11
0
import pickle

# Load one problem
with open('./data/%s.pickle' % 'helicopter_scaling_small', 'rb') as f:
    problem = pickle.load(f)

# OSQP settings
osqp_settings = {
    'verbose': True,
    'scaling': True,
    'scaling_iter': 50,
    'early_terminate_interval': 1,
    'auto_rho': True,
    'rho': 0.1,
    'polish': False
}

# Solve with OSQP
model = osqp.OSQP()
model.setup(problem['P'], problem['q'], problem['A'], problem['l'],
            problem['u'], **osqp_settings)
res_osqp = model.solve()

# Solve with GUROBI
import mathprogbasepy as mpbpy
qp = mpbpy.QuadprogProblem(problem['P'], problem['q'], problem['A'],
                           problem['l'], problem['u'])
res_gurobi = qp.solve(solver=mpbpy.GUROBI, verbose=False)
print("GUROBI time = %.4e" % res_gurobi.cputime)
print("OSQP time = %.4e" % res_osqp.info.run_time)
Example #12
0
def solve_loop(qp_matrices, problem, nsim, solver='osqp'):
    """
    Solve MPC loop
    """
    # Shorter name for qp_matrices
    qp = qp_matrices

    # Get dimensions
    (nx, nu) = problem.B.shape
    N = problem.N

    print('N = %d and solver %s' % (N, solver))

    # Initialize time and number of iterations vectors
    time = np.zeros(nsim)
    niter = np.zeros(nsim)

    if solver == 'osqp':
        # Construct qp matrices
        if len(problem.xmin) > 0:
            # If the problem has state constraints
            Aosqp = spa.vstack([
                qp.A,
                spa.eye((N + 1) * nx + N * nu),
            ]).tocsc()
        else:
            Aosqp = spa.vstack([
                qp.A,
                spa.hstack(
                    [spa.csc_matrix((N * nu, (N + 1) * nx)),
                     spa.eye(N * nu)]),
            ]).tocsc()
        losqp = np.hstack([qp.l, qp.lx])
        uosqp = np.hstack([qp.u, qp.ux])

        # Initial state
        x0 = problem.x0

        # Setup OSQP
        m = osqp.OSQP()
        m.setup(
            qp.P,
            qp.q,
            Aosqp,
            losqp,
            uosqp,
            # auto_rho=False,
            auto_rho=True,
            max_iter=2500,
            scaling=True,
            scaling_iter=50,
            polish=False,
            verbose=False)

        for i in range(nsim):
            # Solve with osqp
            res = m.solve()

            # Save time and number of iterations
            time[i] = res.info.run_time
            niter[i] = res.info.iter

            # Check if status is correct
            status = res.info.status_val
            if status != m.constant('OSQP_SOLVED'):

                # # Dump file to 'bad_convergence/data'folder
                # import pickle
                # problem = {'P': qp.P,
                #            'q': qp.q,
                #            'A': Aosqp,
                #            'l': losqp,
                #            'u': uosqp}
                # with open('bad_convergence/data/%s.pickle' % 'helicopter_scaling_large', 'wb') as f:
                #     pickle.dump(problem, f)

                import ipdb
                ipdb.set_trace()
                raise ValueError('OSQP did not solve the problem!')

            # Apply first control input to the plant
            u = res.x[-N * nu:-(N - 1) * nu]
            x0 = problem.A.dot(x0) + problem.B.dot(u)

            # Update linear constraints
            if len(problem.tmin) > 0:
                losqp = np.hstack([b(x0, nx, N), problem.tmin, qp.lx])
                uosqp = np.hstack([b(x0, nx, N), problem.tmax, qp.ux])
            else:
                losqp = np.hstack([b(x0, nx, N), qp.lx])
                uosqp = np.hstack([b(x0, nx, N), qp.ux])
            m.update(l=losqp, u=uosqp)

    elif solver == 'osqp_coldstart':
        # Construct qp matrices
        if len(problem.xmin) > 0:
            # If the problem has state constraints
            Aosqp = spa.vstack([
                qp.A,
                spa.eye((N + 1) * nx + N * nu),
            ]).tocsc()
        else:
            Aosqp = spa.vstack([
                qp.A,
                spa.hstack(
                    [spa.csc_matrix((N * nu, (N + 1) * nx)),
                     spa.eye(N * nu)]),
            ]).tocsc()
        losqp = np.hstack([qp.l, qp.lx])
        uosqp = np.hstack([qp.u, qp.ux])

        # Initial state
        x0 = problem.x0

        # Setup OSQP
        m = osqp.OSQP()
        m.setup(
            qp.P,
            qp.q,
            Aosqp,
            losqp,
            uosqp,
            warm_start=False,
            auto_rho=True,
            # auto_rho=False,
            rho=0.1,
            max_iter=2500,
            scaling_iter=50,
            polish=False,
            verbose=False)

        for i in range(nsim):
            # Solve with osqp
            res = m.solve()

            # Save time and number of iterations
            time[i] = res.info.run_time
            niter[i] = res.info.iter

            # Check if status is correct
            status = res.info.status_val
            if status != m.constant('OSQP_SOLVED'):
                import ipdb
                ipdb.set_trace()
                raise ValueError('OSQP did not solve the problem!')

            # Apply first control input to the plant
            u = res.x[-N * nu:-(N - 1) * nu]
            x0 = problem.A.dot(x0) + problem.B.dot(u)

            # Update linear constraints
            if len(problem.tmin) > 0:
                losqp = np.hstack([b(x0, nx, N), problem.tmin, qp.lx])
                uosqp = np.hstack([b(x0, nx, N), problem.tmax, qp.ux])
            else:
                losqp = np.hstack([b(x0, nx, N), qp.lx])
                uosqp = np.hstack([b(x0, nx, N), qp.ux])
            m.update(l=losqp, u=uosqp)

    elif solver == 'osqp_no_caching':

        # Construct qp matrices
        if len(problem.xmin) > 0:
            # If the problem has state constraints
            Aosqp = spa.vstack([
                qp.A,
                spa.eye((N + 1) * nx + N * nu),
            ]).tocsc()
        else:
            Aosqp = spa.vstack([
                qp.A,
                spa.hstack(
                    [spa.csc_matrix((N * nu, (N + 1) * nx)),
                     spa.eye(N * nu)]),
            ]).tocsc()
        losqp = np.hstack([qp.l, qp.lx])
        uosqp = np.hstack([qp.u, qp.ux])

        # Initial state
        x0 = problem.x0

        for i in range(nsim):
            # Setup OSQP
            m = osqp.OSQP()
            m.setup(
                qp.P,
                qp.q,
                Aosqp,
                losqp,
                uosqp,
                warm_start=False,
                auto_rho=True,
                # auto_rho=False,
                rho=0.1,
                max_iter=2500,
                scaling_iter=50,
                polish=False,
                verbose=False)
            # Solve
            res = m.solve()

            # Save time and number of iterations
            time[i] = res.info.run_time
            niter[i] = res.info.iter

            # Check if status is correct
            status = res.info.status_val
            if status != m.constant('OSQP_SOLVED'):
                import ipdb
                ipdb.set_trace()
                raise ValueError('OSQP did not solve the problem!')

            # Apply first control input to the plant
            u = res.x[-N * nu:-(N - 1) * nu]
            x0 = problem.A.dot(x0) + problem.B.dot(u)

            # Update linear constraints
            if len(problem.tmin) > 0:
                losqp = np.hstack([b(x0, nx, N), problem.tmin, qp.lx])
                uosqp = np.hstack([b(x0, nx, N), problem.tmax, qp.ux])
            else:
                losqp = np.hstack([b(x0, nx, N), qp.lx])
                uosqp = np.hstack([b(x0, nx, N), qp.ux])
            m.update(l=losqp, u=uosqp)

    elif solver == 'qpoases':

        n_dim = qp.P.shape[0]  # Number of variables
        m_dim = qp.A.shape[0]  # Number of constraints without bounds

        # Initialize qpoases and set options
        qpoases_m = qpoases.PyQProblem(n_dim, m_dim)
        options = qpoases.PyOptions()
        options.printLevel = qpoases.PyPrintLevel.NONE
        qpoases_m.setOptions(options)

        # Construct bounds for qpoases
        lx = np.append(-np.inf * np.ones((N + 1) * nx), qp.lx)
        ux = np.append(np.inf * np.ones((N + 1) * nx), qp.ux)

        # Setup matrix P and A
        P = np.ascontiguousarray(qp.P.todense())
        A = np.ascontiguousarray(qp.A.todense())

        # Initial state
        x0 = problem.x0

        # RHS of the linear equality constraints
        lqpoases = qp.l
        uqpoases = qp.u

        for i in range(nsim):
            # Reset cpu time
            qpoases_cpu_time = np.array([60.])

            # Reset number of of working set recalculations
            nWSR = np.array([1e6])

            if i == 0:
                # First iteration
                res_qpoases = qpoases_m.init(P, np.ascontiguousarray(qp.q), A,
                                             np.ascontiguousarray(lx),
                                             np.ascontiguousarray(ux),
                                             np.ascontiguousarray(lqpoases),
                                             np.ascontiguousarray(uqpoases),
                                             nWSR, qpoases_cpu_time)
            else:
                # Solve new hot started problem
                res_qpoases = qpoases_m.hotstart(
                    np.ascontiguousarray(qp.q), np.ascontiguousarray(lx),
                    np.ascontiguousarray(ux), np.ascontiguousarray(lqpoases),
                    np.ascontiguousarray(uqpoases), nWSR, qpoases_cpu_time)

            if res_qpoases != 0:
                raise ValueError('qpoases did not solve the problem!')

            # Save time and number of iterations
            time[i] = qpoases_cpu_time[0]
            niter[i] = nWSR[0]

            # Get qpoases solution
            sol_qpoases = np.zeros((N + 1) * nx + N * nu)
            qpoases_m.getPrimalSolution(sol_qpoases)

            # Apply first control input to the plant
            u = sol_qpoases[-N * nu:-(N - 1) * nu]
            x0 = problem.A.dot(x0) + problem.B.dot(u)

            # Update linear constraints
            if len(problem.tmin) > 0:
                lqpoases = np.hstack([b(x0, nx, N), problem.tmin])
                uqpoases = np.hstack([b(x0, nx, N), problem.tmax])
            else:
                lqpoases = np.hstack([b(x0, nx, N)])
                uqpoases = np.hstack([b(x0, nx, N)])

    elif solver == 'gurobi' or solver == 'mosek':
        # Construct qp matrices
        if len(problem.xmin) > 0:
            # If the problem has state constraints
            Agurobi = spa.vstack([
                qp.A,
                spa.eye((N + 1) * nx + N * nu),
            ]).tocsc()
        else:
            Agurobi = spa.vstack([
                qp.A,
                spa.hstack(
                    [spa.csc_matrix((N * nu, (N + 1) * nx)),
                     spa.eye(N * nu)]),
            ]).tocsc()
        lgurobi = np.hstack([qp.l, qp.lx])
        ugurobi = np.hstack([qp.u, qp.ux])

        # Initial state
        x0 = problem.x0

        for i in range(nsim):
            # Solve with gurobi
            prob = mpbpy.QuadprogProblem(qp.P, qp.q, Agurobi, lgurobi, ugurobi)
            if solver == 'gurobi':
                res = prob.solve(solver=mpbpy.GUROBI, verbose=False)
            else:
                res = prob.solve(solver=mpbpy.MOSEK, verbose=False)

            # Save time and number of iterations
            time[i] = res.cputime
            niter[i] = res.total_iter

            # Check if status is correct
            status = res.status
            if status != 'optimal':
                import ipdb
                ipdb.set_trace()
                raise ValueError('Gurobi did not solve the problem!')

            # Apply first control input to the plant
            u = res.x[-N * nu:-(N - 1) * nu]
            x0 = problem.A.dot(x0) + problem.B.dot(u)

            # Update QP problem
            if len(problem.tmin) > 0:
                lgurobi = np.hstack([b(x0, nx, N), problem.tmin, qp.lx])
                ugurobi = np.hstack([b(x0, nx, N), problem.tmax, qp.ux])
            else:
                lgurobi = np.hstack([b(x0, nx, N), qp.lx])
                ugurobi = np.hstack([b(x0, nx, N), qp.ux])

    else:
        raise ValueError('Solver not understood')

    # Return statistics
    return utils.Statistics(time), utils.Statistics(niter)
Example #13
0
import numpy as np
import mathprogbasepy as mpbpy
sp.random.seed(2)

n = 100
m = 500
A = sparse.random(m, n, density=0.9, format='csc')
lA = -sp.rand(m) * 2.
uA = sp.rand(m) * 2.

P = sparse.random(n, n, density=0.9, format='csc')
P = P.dot(P.T)
q = sp.randn(n)


qp = mpbpy.QuadprogProblem(P, q, A, lA, uA)


osqp_opts = {'rho': 1e-7,
             'auto_rho': True,
             'sigma': 1e-06,
            #  'eps_rel': 1e-08,
            #  'eps_abs': 1e-08,
             'scaled_termination': False,
             'early_terminate_interval': 1,
             'polish': False,
             'scaling': True,
             'scaling_iter': 15,
             'max_iter': 2500,
             'verbose': True
             }
Example #14
0
def solve_loop(qp_matrices, solver='osqp'):
    """
    Solve portfolio optimization loop for all gammas
    """
    # Shorter name for qp_matrices
    qp = qp_matrices

    # Get dimensions
    n = len(qp.lx)
    k = len(qp.l) - 1

    print('n = %d and solver %s' % (n, solver))

    # Get number of problems to solve
    n_prob = qp.q.shape[1]

    # Initialize time vector
    time = np.zeros(n_prob)

    # Initialize number of iterations vector
    niter = np.zeros(n_prob)

    if solver == 'osqp':
        # Construct qp matrices
        Aosqp = spa.vstack(
            (qp.A, spa.hstack((spa.eye(n), spa.csc_matrix((n, k)))))).tocsc()
        losqp = np.append(qp.l, qp.lx)
        uosqp = np.append(qp.u, qp.ux)

        # Setup OSQP
        m = osqp.OSQP()
        m.setup(qp.P,
                qp.q[:, 0],
                Aosqp,
                losqp,
                uosqp,
                auto_rho=True,
                polish=False,
                verbose=False)

        for i in range(n_prob):
            q = qp.q[:, i]

            # Update linear cost
            m.update(q=q)

            # Solve
            results = m.solve()
            x = results.x
            y = results.y
            status = results.info.status_val
            niter[i] = results.info.iter
            time[i] = results.info.run_time

            # Check if status correct
            if status != m.constant('OSQP_SOLVED'):
                import ipdb
                ipdb.set_trace()
                raise ValueError('OSQP did not solve the problem!')

            # DEBUG
            # solve with gurobi
            # prob = mpbpy.QuadprogProblem(qp.P, q, Aosqp, losqp, uosqp)
            # res = prob.solve(solver=mpbpy.GUROBI, verbose=False)
            # print('Norm difference OSQP-GUROBI %.3e' %
            #       np.linalg.norm(x - res.x))
            # import ipdb; ipdb.set_trace()

    elif solver == 'osqp_coldstart':
        # Construct qp matrices
        Aosqp = spa.vstack(
            (qp.A, spa.hstack((spa.eye(n), spa.csc_matrix((n, k)))))).tocsc()
        losqp = np.append(qp.l, qp.lx)
        uosqp = np.append(qp.u, qp.ux)

        # Setup OSQP
        m = osqp.OSQP()
        m.setup(qp.P,
                qp.q[:, 0],
                Aosqp,
                losqp,
                uosqp,
                warm_start=False,
                auto_rho=True,
                polish=False,
                verbose=False)

        for i in range(n_prob):
            q = qp.q[:, i]

            # Update linear cost
            m.update(q=q)

            # Solve
            results = m.solve()
            x = results.x
            y = results.y
            status = results.info.status_val
            niter[i] = results.info.iter
            time[i] = results.info.run_time

            # Check if status correct
            if status != m.constant('OSQP_SOLVED'):
                import ipdb
                ipdb.set_trace()
                raise ValueError('OSQP did not solve the problem!')

            # DEBUG
            # solve with gurobi
            # prob = mpbpy.QuadprogProblem(qp.P, q, Aosqp, losqp, uosqp)
            # res = prob.solve(solver=mpbpy.GUROBI, verbose=False)
            # print('Norm difference OSQP-GUROBI %.3e' %
            #       np.linalg.norm(x - res.x))
            # import ipdb; ipdb.set_trace()

        # DEBUG print iterations per value of gamma
        # gamma_vals = np.logspace(-2, 2, 101)[::-1]
        #
        # import matplotlib.pylab as plt
        # plt.figure()
        # ax = plt.gca()
        # plt.plot(gamma_vals, niter)
        # ax.set_xlabel(r'$\gamma$')
        # ax.set_ylabel(r'iter')
        # plt.show(block=False)

        # import ipdb; ipdb.set_trace()

    elif solver == 'osqp_no_caching':
        # Construct qp matrices
        Aosqp = spa.vstack(
            (qp.A, spa.hstack((spa.eye(n), spa.csc_matrix((n, k)))))).tocsc()
        losqp = np.append(qp.l, qp.lx)
        uosqp = np.append(qp.u, qp.ux)

        for i in range(n_prob):

            # Setup OSQP
            m = osqp.OSQP()
            m.setup(qp.P,
                    qp.q[:, i],
                    Aosqp,
                    losqp,
                    uosqp,
                    warm_start=False,
                    auto_rho=True,
                    polish=False,
                    verbose=False)

            # Solve
            results = m.solve()
            x = results.x
            y = results.y
            status = results.info.status_val
            niter[i] = results.info.iter
            time[i] = results.info.run_time

            # Check if status correct
            if status != m.constant('OSQP_SOLVED'):
                import ipdb
                ipdb.set_trace()
                raise ValueError('OSQP did not solve the problem!')

            # DEBUG
            # solve with gurobi
            # prob = mpbpy.QuadprogProblem(qp.P, q, Aosqp, losqp, uosqp)
            # res = prob.solve(solver=mpbpy.GUROBI, verbose=False)
            # print('Norm difference OSQP-GUROBI %.3e' %
            #       np.linalg.norm(x - res.x))
            # import ipdb; ipdb.set_trace()

        # DEBUG print iterations per value of gamma
        # gamma_vals = np.logspace(-2, 2, 101)[::-1]
        #
        # import matplotlib.pylab as plt
        # plt.figure()
        # ax = plt.gca()
        # plt.plot(gamma_vals, niter)
        # ax.set_xlabel(r'$\gamma$')
        # ax.set_ylabel(r'iter')
        # plt.show(block=False)

        # import ipdb; ipdb.set_trace()

    elif solver == 'qpoases':

        n_dim = qp.P.shape[0]  # Number of variables
        m_dim = qp.A.shape[0]  # Number of constraints without bounds

        # Initialize qpoases and set options
        qpoases_m = qpoases.PyQProblem(n_dim, m_dim)
        options = qpoases.PyOptions()
        options.printLevel = qpoases.PyPrintLevel.NONE
        qpoases_m.setOptions(options)

        # Construct bounds for qpoases
        lx = np.append(qp.lx, -np.inf * np.ones(k))
        ux = np.append(qp.ux, np.inf * np.ones(k))

        # Setup matrix P and A
        P = np.ascontiguousarray(qp.P.todense())
        A = np.ascontiguousarray(qp.A.todense())

        for i in range(n_prob):

            # Get linera cost as contiguous array
            q = np.ascontiguousarray(qp.q[:, i])

            # Reset cpu time
            qpoases_cpu_time = np.array([20.])

            # Reset number of of working set recalculations
            nWSR = np.array([1000])

            if i == 0:
                # First iteration
                res_qpoases = qpoases_m.init(P, q, A, np.ascontiguousarray(lx),
                                             np.ascontiguousarray(ux),
                                             np.ascontiguousarray(qp.l),
                                             np.ascontiguousarray(qp.u), nWSR,
                                             qpoases_cpu_time)
            else:
                # Solve new hot started problem
                res_qpoases = qpoases_m.hotstart(q, np.ascontiguousarray(lx),
                                                 np.ascontiguousarray(ux),
                                                 np.ascontiguousarray(qp.l),
                                                 np.ascontiguousarray(qp.u),
                                                 nWSR, qpoases_cpu_time)

            # # DEBUG Solve with gurobi
            # qpoases solution
            # sol_qpoases = np.zeros(n + k)
            # qpoases_m.getPrimalSolution(sol_qpoases)
            # import mathprogbasepy as mpbpy
            # Agrb = spa.vstack((qp.A,
            #                     spa.hstack((spa.eye(n), spa.csc_matrix((n, k)))
            #                                ))).tocsc()
            # lgrb = np.append(qp.l, qp.lx)
            # ugrb = np.append(qp.u, qp.ux)
            # prob = mpbpy.QuadprogProblem(spa.csc_matrix(qp.P), q,
            #                              Agrb, lgrb, ugrb)
            # res = prob.solve(solver=mpbpy.GUROBI, verbose=True)
            # print("Norm difference x qpoases - GUROBI = %.4f" %
            #       np.linalg.norm(sol_qpoases - res.x))
            # print("Norm difference objval qpoases - GUROBI = %.4f" %
            #       abs(qpoases_m.getObjVal() - res.obj_val))
            # import ipdb; ipdb.set_trace()

            if res_qpoases != 0:
                raise ValueError('qpoases did not solve the problem!')

            # Save time
            time[i] = qpoases_cpu_time[0]

            # Save number of iterations
            niter[i] = nWSR[0]

    elif solver == 'gurobi':

        # Construct qp matrices
        Agurobi = spa.vstack(
            (qp.A, spa.hstack((spa.eye(n), spa.csc_matrix((n, k)))))).tocsc()
        lgurobi = np.append(qp.l, qp.lx)
        ugurobi = np.append(qp.u, qp.ux)

        for i in range(n_prob):

            # Get linera cost as contiguous array
            q = qp.q[:, i]

            # Solve with gurobi
            prob = mpbpy.QuadprogProblem(qp.P, q, Agurobi, lgurobi, ugurobi)
            res = prob.solve(solver=mpbpy.GUROBI, verbose=False)

            # Save time
            time[i] = res.cputime

            # Save number of iterations
            niter[i] = res.total_iter

    elif solver == 'mosek':

        # Construct qp matrices
        Amosek = spa.vstack(
            (qp.A, spa.hstack((spa.eye(n), spa.csc_matrix((n, k)))))).tocsc()
        lmosek = np.append(qp.l, qp.lx)
        umosek = np.append(qp.u, qp.ux)

        for i in range(n_prob):

            # Get linera cost as contiguous array
            q = qp.q[:, i]

            # Solve with mosek
            prob = mpbpy.QuadprogProblem(qp.P, q, Amosek, lmosek, umosek)
            res = prob.solve(solver=mpbpy.MOSEK, verbose=False)

            # Save time
            time[i] = res.cputime

            # Save number of iterations
            niter[i] = res.total_iter

    elif solver == 'ecos':

        for i in range(n_prob):
            # Construct the problem
            #       minimize	x' D x + y' I y - (1/gamma) * mu' x
            #       subject to  1' x = 1
            #                   F' x = y
            #                   0 <= x <= 1
            n_var = qp.F.shape[0]
            m_var = qp.F.shape[1]
            x = cvxpy.Variable(n_var)
            y = cvxpy.Variable(m_var)

            objective = cvxpy.Minimize(
                cvxpy.quad_form(x, qp.D) + cvxpy.quad_form(y, spa.eye(m_var)) +
                -1 / qp.gammas[i] * qp.mu * x)
            constraints = [
                np.ones(n_var) * x == 1, qp.F.T * x == y, 0 <= x, x <= 1
            ]
            problem = cvxpy.Problem(objective, constraints)
            problem.solve(solver=cvxpy.ECOS, verbose=False)

            # Obtain time and number of iterations
            time[i] = problem.solver_stats.setup_time + \
                problem.solver_stats.solve_time

            niter[i] = problem.solver_stats.num_iters

            # # DEBUG: Solve with MOSEK
            # Amosek = spa.vstack((qp.A,
            #                      spa.hstack((spa.eye(n), spa.csc_matrix((n, k)))
            #                                 ))).tocsc()
            # lmosek = np.append(qp.l, qp.lx)
            # umosek = np.append(qp.u, qp.ux)
            # prob = mpbpy.QuadprogProblem(qp.P, qp.q[:, i],
            #                              Amosek, lmosek, umosek)
            # res = prob.solve(solver=mpbpy.MOSEK, verbose=False)
            # x_mosek = res.x[:n_var]
            # import ipdb; ipdb.set_trace()

    else:
        raise ValueError('Solver not understood')

    # Return statistics
    return utils.Statistics(time), utils.Statistics(niter)
Example #15
0
def solve_problem(qp_matrices, n_prob, solver='osqp'):
    """
    Solve equality constrained optimization
    """
    # Shorter name for qp_matrices
    qp = qp_matrices

    # Get dimensions
    n = len(qp.q)
    m = len(qp.l)

    print('n = %d and solver %s' % (n, solver))

    # Initialize time vector
    time = np.zeros(n_prob)

    # Initialize number of iterations vector
    niter = np.zeros(n_prob)

    if solver == 'osqp':

        for i in range(n_prob):
            # Setup OSQP
            m = osqp.OSQP()
            m.setup(qp.P, qp.q, qp.A, qp.l, qp.u,
                    rho=1000,   # Set high rho to enforce feasibility
                    auto_rho=False,
                    polish=False,
                    verbose=False)

            # Solve
            results = m.solve()
            x = results.x
            y = results.y
            status = results.info.status_val
            niter[i] = results.info.iter
            time[i] = results.info.run_time

            # Check if status correct
            if status != m.constant('OSQP_SOLVED'):
                import ipdb; ipdb.set_trace()
                # raise ValueError('OSQP did not solve the problem!')

                # DEBUG
                # solve with gurobi
                # prob = mpbpy.QuadprogProblem(qp.P, q, Aosqp, losqp, uosqp)
                # res = prob.solve(solver=mpbpy.GUROBI, verbose=False)
                # print('Norm difference OSQP-GUROBI %.3e' %
                #       np.linalg.norm(x - res.x))
                # import ipdb; ipdb.set_trace()

    elif solver == 'qpoases':

        n_dim = qp.P.shape[0]  # Number of variables
        m_dim = qp.A.shape[0]  # Number of constraints without bounds

        for i in range(n_prob):

            # Initialize qpoases and set options
            qpoases_m = qpoases.PyQProblem(n_dim, m_dim)
            options = qpoases.PyOptions()
            options.printLevel = qpoases.PyPrintLevel.NONE
            qpoases_m.setOptions(options)

            # Reset cpu time
            qpoases_cpu_time = np.array([60.])

            # Reset number of of working set recalculations
            nWSR = np.array([10000])

            # First iteration
            res_qpoases = qpoases_m.init(np.ascontiguousarray(qp.P.todense()),
                                         np.ascontiguousarray(qp.q),
                                         np.ascontiguousarray(qp.A.todense()),
                                         np.ascontiguousarray(qp.lx),
                                         np.ascontiguousarray(qp.ux),
                                         np.ascontiguousarray(qp.l),
                                         np.ascontiguousarray(qp.u),
                                         nWSR, qpoases_cpu_time)


            # # DEBUG Solve with gurobi
            # qpoases solution
            # sol_qpoases = np.zeros(n + k)
            # qpoases_m.getPrimalSolution(sol_qpoases)
            # import mathprogbasepy as mpbpy
            # Agrb = spa.vstack((qp.A,
            #                     spa.hstack((spa.eye(n), spa.csc_matrix((n, k)))
            #                                ))).tocsc()
            # lgrb = np.append(qp.l, qp.lx)
            # ugrb = np.append(qp.u, qp.ux)
            # prob = mpbpy.QuadprogProblem(spa.csc_matrix(qp.P), q,
            #                              Agrb, lgrb, ugrb)
            # res = prob.solve(solver=mpbpy.GUROBI, verbose=True)
            # print("Norm difference x qpoases - GUROBI = %.4f" %
            #       np.linalg.norm(sol_qpoases - res.x))
            # print("Norm difference objval qpoases - GUROBI = %.4f" %
            #       abs(qpoases_m.getObjVal() - res.obj_val))
            # import ipdb; ipdb.set_trace()

            if res_qpoases != 0:
                raise ValueError('qpoases did not solve the problem!')

            # Save time
            time[i] = qpoases_cpu_time[0]

            # Save number of iterations
            niter[i] = nWSR[0]

    elif solver == 'gurobi':
        for i in range(n_prob):

            # Solve with gurobi
            prob = mpbpy.QuadprogProblem(qp.P, qp.q, qp.A, qp.l, qp.u)
            res = prob.solve(solver=mpbpy.GUROBI, verbose=False)

            # Save time
            time[i] = res.cputime

            # Save number of iterations
            niter[i] = res.total_iter

    elif solver == 'mosek':
        for i in range(n_prob):

            # Solve with mosek
            prob = mpbpy.QuadprogProblem(qp.P, qp.q, qp.A, qp.l, qp.u)
            res = prob.solve(solver=mpbpy.MOSEK, verbose=False)

            # Save time
            time[i] = res.cputime

            # Save number of iterations
            niter[i] = res.total_iter

    elif solver == 'ecos':
        for i in range(n_prob):

            # Solve with ECOS (via CVXPY)
            n_var = qp.P.shape[0]
            x_var = cvxpy.Variable(n_var)
            objective = cvxpy.Minimize(.5 * cvxpy.quad_form(x_var, qp.P) + qp.q * x_var)
            constraints = [qp.A * x_var <= qp.u, qp.A * x_var >= qp.l]
            problem = cvxpy.Problem(objective, constraints)
            problem.solve(solver=cvxpy.ECOS)

            # Obtain time and number of iterations
            time[i] = problem.solver_stats.setup_time + \
                problem.solver_stats.solve_time

            niter[i] = problem.solver_stats.num_iters

    else:
        raise ValueError('Solver not understood')

    # Return statistics
    return utils.Statistics(time), utils.Statistics(niter)