Пример #1
0
    def test_isin(self):

        bv = self.bv
        test_bv = BlockVector(2)
        a = np.array([1.1, 3.3])
        b = np.array([5.5, 7.7])
        test_bv.set_block(0, a)
        test_bv.set_block(1, b)

        res = pn.isin(bv, test_bv)
        for bid, blk in enumerate(bv):
            self.assertEqual(blk.size, res.get_block(bid).size)
            res_flat = np.isin(blk, test_bv.get_block(bid))
            self.assertTrue(np.allclose(res.get_block(bid), res_flat))

        c = np.concatenate([a, b])
        res = pn.isin(bv, c)
        for bid, blk in enumerate(bv):
            self.assertEqual(blk.size, res.get_block(bid).size)
            res_flat = np.isin(blk, c)
            self.assertTrue(np.allclose(res.get_block(bid), res_flat))

        res = pn.isin(bv, test_bv, invert=True)
        for bid, blk in enumerate(bv):
            self.assertEqual(blk.size, res.get_block(bid).size)
            res_flat = np.isin(blk, test_bv.get_block(bid), invert=True)
            self.assertTrue(np.allclose(res.get_block(bid), res_flat))

        c = np.concatenate([a, b])
        res = pn.isin(bv, c, invert=True)
        for bid, blk in enumerate(bv):
            self.assertEqual(blk.size, res.get_block(bid).size)
            res_flat = np.isin(blk, c, invert=True)
            self.assertTrue(np.allclose(res.get_block(bid), res_flat))
Пример #2
0
 def set_primal_dual_kkt_solution(self, sol: BlockVector):
     for ndx, nlp in self._nlps.items():
         nlp.set_primal_dual_kkt_solution(sol.get_block(ndx).get_block(0))
         self._delta_primals.set_block(ndx, nlp.get_delta_primals())
         self._delta_slacks.set_block(ndx, nlp.get_delta_slacks())
         self._delta_duals_eq.get_block(ndx).set_block(
             0, nlp.get_delta_duals_eq())
         self._delta_duals_ineq.set_block(ndx, nlp.get_delta_duals_ineq())
         self._delta_duals_primals_lb.set_block(
             ndx, nlp.get_delta_duals_primals_lb())
         self._delta_duals_primals_ub.set_block(
             ndx, nlp.get_delta_duals_primals_ub())
         self._delta_duals_slacks_lb.set_block(
             ndx, nlp.get_delta_duals_slacks_lb())
         self._delta_duals_slacks_ub.set_block(
             ndx, nlp.get_delta_duals_slacks_ub())
         self._delta_duals_eq.get_block(ndx).set_block(
             1,
             sol.get_block(ndx).get_block(1))
         self._delta_duals_eq.get_block(ndx).set_block(
             2,
             sol.get_block(
                 self._num_time_blocks).get_block(0).get_block(ndx))
     self._delta_primals.set_block(
         self._num_time_blocks,
         sol.get_block(self._num_time_blocks).get_block(1))
Пример #3
0
 def set_duals_ineq(self, duals_ineq: BlockVector):
     """
     Parameters
     ----------
     duals_ineq: BlockVector
         The values for the duals of the inequality constraints. This BlockVector has one block for
         every time block.
     """
     for ndx, nlp in self._nlps.items():
         nlp.set_duals_ineq(duals_ineq.get_block(ndx))
         self._duals_ineq.set_block(ndx, duals_ineq.get_block(ndx))
Пример #4
0
    def set_primals(self, primals: BlockVector):
        """
        Set the values of the primal variables for evaluation (i.e., the evaluate_* methods).

        Parameters
        ----------
        primals: BlockVector
            The values for each primal variable. This BlockVector should have one block for every time block
            and one block for the coupling variables.
        """
        for ndx, nlp in self._nlps.items():
            nlp.set_primals(primals.get_block(ndx))
            self._primals.set_block(ndx, primals.get_block(ndx))
        self._primals.set_block(self._num_time_blocks,
                                primals.get_block(self._num_time_blocks))
Пример #5
0
 def set_duals_eq(self, duals_eq: BlockVector):
     """
     Parameters
     ----------
     duals_eq: BlockVector
         The values for the duals of the equality constraints, including the coupling constraints.
         This BlockVector has one block for every time block. Each block is itself a BlockVector with
         3 blocks. The first block contains the duals of the equality constraints in the corresponding time
         block. The second block has the duals for the coupling constraints linking the states at the
         beginning of the time block to the coupling variables between the time block and the previous
         time block. The third block has the duals for the coupling constraints linking the states at the
         end of the time block to the coupling variables between the time block and the next time block.
     """
     for ndx, nlp in self._nlps.items():
         sub_block = duals_eq.get_block(ndx)
         nlp.set_duals_eq(sub_block.get_block(0))
         self._duals_eq.get_block(ndx).set_block(0, sub_block.get_block(0))
         self._duals_eq.get_block(ndx).set_block(1, sub_block.get_block(1))
         self._duals_eq.get_block(ndx).set_block(2, sub_block.get_block(2))
Пример #6
0
 def set_duals_slacks_ub(self, duals: BlockVector):
     for ndx, nlp in self._nlps.items():
         nlp.set_duals_slacks_ub(duals.get_block(ndx))
         self._duals_slacks_ub.set_block(ndx, duals.get_block(ndx))
Пример #7
0
 def set_slacks(self, slacks: BlockVector):
     for ndx, nlp in self._nlps.items():
         nlp.set_slacks(slacks.get_block(ndx))
         self._slacks.set_block(ndx, slacks.get_block(ndx))
    def setUpClass(cls) -> None:
        cls.t0 = 0
        cls.delta_t = 1
        cls.num_finite_elements = 6
        cls.constant_control_duration = 2
        cls.time_scale = 1
        cls.num_time_blocks = 3
        cls.with_bounds = True
        cls.with_ineq = False
        cls.barrier_parameter = 0.1
        cls.interface = Problem(t0=cls.t0,
                                delta_t=cls.delta_t,
                                num_finite_elements=cls.num_finite_elements,
                                constant_control_duration=cls.constant_control_duration,
                                time_scale=cls.time_scale,
                                num_time_blocks=cls.num_time_blocks,
                                with_bounds=cls.with_bounds,
                                with_ineq=cls.with_ineq)
        interface = cls.interface
        num_time_blocks = cls.num_time_blocks

        primals = BlockVector(num_time_blocks + 1)
        duals_eq = BlockVector(num_time_blocks)
        duals_ineq = BlockVector(num_time_blocks)
        duals_primals_lb = BlockVector(num_time_blocks + 1)
        duals_primals_ub = BlockVector(num_time_blocks + 1)
        duals_slacks_lb = BlockVector(num_time_blocks)
        duals_slacks_ub = BlockVector(num_time_blocks)

        ownership_map = _get_ownership_map(num_time_blocks, size)

        val_map = pe.ComponentMap()

        if ownership_map[0] == rank:
            m = interface.pyomo_model(0)
            val_map[m.x[0]] = 0
            val_map[m.x[1]] = 1
            val_map[m.x[2]] = 2
            val_map[m.p[0]] = 0.5
            val_map[m.cons[1]] = 1
            val_map[m.cons[2]] = 2

        if ownership_map[1] == rank:
            m = interface.pyomo_model(1)
            val_map[m.x[2]] = 2
            val_map[m.x[3]] = 3
            val_map[m.x[4]] = 4
            val_map[m.p[2]] = 1
            val_map[m.cons[3]] = 3
            val_map[m.cons[4]] = 4

        if ownership_map[2] == rank:
            m = interface.pyomo_model(2)
            val_map[m.x[4]] = 4
            val_map[m.x[5]] = 5
            val_map[m.x[6]] = 6
            val_map[m.p[4]] = 1.5
            val_map[m.cons[5]] = 5
            val_map[m.cons[6]] = 6

        for ndx in range(num_time_blocks):
            primals.set_block(ndx, np.zeros(4, dtype=np.double))
            duals_primals_lb.set_block(ndx, np.zeros(4, dtype=np.double))
            duals_primals_ub.set_block(ndx, np.zeros(4, dtype=np.double))
            duals_ineq.set_block(ndx, np.zeros(0, dtype=np.double))
            duals_slacks_lb.set_block(ndx, np.zeros(0, dtype=np.double))
            duals_slacks_ub.set_block(ndx, np.zeros(0, dtype=np.double))
            sub_duals_eq = BlockVector(3)
            sub_duals_eq.set_block(0, np.zeros(2, dtype=np.double))
            if ndx == 0:
                sub_duals_eq.set_block(1, np.zeros(0, dtype=np.double))
            else:
                sub_duals_eq.set_block(1, np.zeros(1, dtype=np.double))
            if ndx == num_time_blocks - 1:
                sub_duals_eq.set_block(2, np.zeros(0, dtype=np.double))
            else:
                sub_duals_eq.set_block(2, np.zeros(1, dtype=np.double))
            duals_eq.set_block(ndx, sub_duals_eq)
        primals.set_block(num_time_blocks, np.zeros(2, dtype=np.double))
        duals_primals_lb.set_block(num_time_blocks, np.zeros(2, dtype=np.double))
        duals_primals_ub.set_block(num_time_blocks, np.zeros(2, dtype=np.double))

        local_block_indices = _distribute_blocks(num_time_blocks, rank, size)
        for ndx in local_block_indices:
            primals.set_block(ndx, np.array([val_map[i] for i in interface.get_pyomo_variables(ndx)], dtype=np.double))
            duals_primals_ub.set_block(ndx, np.array([0, 0, 0, ndx], dtype=np.double))
            sub_duals_eq = duals_eq.get_block(ndx)
            sub_duals_eq.set_block(0, np.array([val_map[i] for i in interface.get_pyomo_constraints(ndx)], dtype=np.double))
            if ndx == 0:
                sub_duals_eq.set_block(1, np.zeros(0, dtype=np.double))
            else:
                sub_duals_eq.set_block(1, np.ones(1, dtype=np.double) * ndx)
            if ndx == num_time_blocks - 1:
                sub_duals_eq.set_block(2, np.zeros(0, dtype=np.double))
            else:
                sub_duals_eq.set_block(2, np.ones(1, dtype=np.double) * ndx)

        primals_flat = primals.flatten()
        res = np.zeros(primals_flat.size, dtype=np.double)
        comm.Allreduce(primals_flat, res)
        primals.copyfrom(res)

        duals_primals_lb_flat = duals_primals_lb.flatten()
        res = np.zeros(duals_primals_lb_flat.size, dtype=np.double)
        comm.Allreduce(duals_primals_lb_flat, res)
        duals_primals_lb.copyfrom(res)

        duals_primals_ub_flat = duals_primals_ub.flatten()
        res = np.zeros(duals_primals_ub_flat.size, dtype=np.double)
        comm.Allreduce(duals_primals_ub_flat, res)
        duals_primals_ub.copyfrom(res)

        duals_eq_flat = duals_eq.flatten()
        res = np.zeros(duals_eq_flat.size, dtype=np.double)
        comm.Allreduce(duals_eq_flat, res)
        duals_eq.copyfrom(res)

        primals.set_block(num_time_blocks, np.array([3, 6], dtype=np.double))
        duals_primals_lb.set_block(num_time_blocks, np.zeros(2, dtype=np.double))
        duals_primals_ub.set_block(num_time_blocks, np.zeros(2, dtype=np.double))
        interface.set_primals(primals)
        interface.set_duals_eq(duals_eq)
        interface.set_duals_ineq(duals_ineq)
        interface.set_duals_slacks_lb(duals_slacks_lb)
        interface.set_duals_slacks_ub(duals_slacks_ub)
        interface.set_duals_primals_lb(duals_primals_lb)
        interface.set_duals_primals_ub(duals_primals_ub)
        interface.set_barrier_parameter(cls.barrier_parameter)
Пример #9
0
def sqp(nlp: NLP,
        linear_solver: LinearSolverInterface,
        max_iter=100,
        tol=1e-8,
        output=True):
    """
    An example of a simple SQP algoritm for 
    equality-constrained NLPs.

    Parameters
    ----------
    nlp: NLP
        A PyNumero NLP
    max_iter: int
        The maximum number of iterations
    tol: float
        The convergence tolerance
    """
    t0 = time.time()

    # setup KKT matrix
    kkt = BlockMatrix(2, 2)
    rhs = BlockVector(2)

    # create and initialize the iteration vector
    z = BlockVector(2)
    z.set_block(0, nlp.get_primals())
    z.set_block(1, nlp.get_duals())

    if output:
        print(
            f"{'Iter':<12}{'Objective':<12}{'Primal Infeasibility':<25}{'Dual Infeasibility':<25}{'Elapsed Time':<15}"
        )

    # main iteration loop
    for _iter in range(max_iter):
        nlp.set_primals(z.get_block(0))
        nlp.set_duals(z.get_block(1))

        grad_lag = (nlp.evaluate_grad_objective() +
                    nlp.evaluate_jacobian_eq().transpose() * z.get_block(1))
        residuals = nlp.evaluate_eq_constraints()

        if output:
            print(
                f"{_iter:<12}{nlp.evaluate_objective():<12.2e}{np.abs(residuals).max():<25.2e}{np.abs(grad_lag).max():<25.2e}{time.time()-t0:<15.2e}"
            )

        if (np.abs(grad_lag).max() <= tol and np.abs(residuals).max() <= tol):
            break

        kkt.set_block(0, 0, nlp.evaluate_hessian_lag())
        kkt.set_block(1, 0, nlp.evaluate_jacobian_eq())
        kkt.set_block(0, 1, nlp.evaluate_jacobian_eq().transpose())

        rhs.set_block(0, grad_lag)
        rhs.set_block(1, residuals)

        delta, res = linear_solver.solve(kkt, -rhs)
        assert res.status == LinearSolverStatus.successful
        z += delta