예제 #1
0
    def _make_ygen(self):
        self._make_u()

        num_double_at_upper = self.info[
            'md_upp_deg'] + self.info['md_upp_nonactive']
        num_not_floating = self.info['md'] - self.info['md_float']

        double_at_upper = npvec(self.u[:num_double_at_upper])
        double_at_lower = zeros(
            self.info['md_low_deg'] + self.info['md_low_nonactive'])
        double_floating = npvec(
            [randcst() * x for x in self.u[num_not_floating:]])

        single_at_lower = zeros(
            self.info['ms_deg'] + self.info['ms_nonactive'])
        single_floating = rand(self.info['ms_active'])

# ygen = conmat([npvec(u[:m_upp_deg+upp_nonactive]),            # double_at_upper
#                     zeros(m_low_deg+low_nonactive),          # double_at_lower
#                     v2,                                      # double_floating
#                     zeros(m_inf_deg+inf_nonactive),          # single_at_lower
# rand(m_inf-m_inf_deg-inf_nonactive)])    # single_floating
        self.info['ygen'] = conmat([
            double_at_upper,  # y=u cases
            double_at_lower,  # y=0 cases
            double_floating,  # 0<y<u cases
            single_at_lower,  # y=0 cases
            single_floating])  # y>0 cases

        for yi in self.info['ygen']:
            assert yi >= 0
        for i in range(self.info['md']):
            assert self.info['ygen'][i] <= self.u[i]
예제 #2
0
    def get_dual_vals(self, x, y):
        """
        Computes the values of the lower level problem's dual variables
        vectors at the given solution (x, y).

        Args:
           x, y: an optimal solution to the QPEC.

        Returns:
           :math:`\lambda_D^L`: vector of dual variable values for the
           constraints :math:`y_D \geq 0`

           :math:`\lambda_S`: vector of dual variable values for the
           constraints :math:`y_S \geq 0`

           :math:`\lambda_D^U`: vector of dual variable values for the
           constraints :math:`y_D \leq y_u`
        """

        # computing the full sol at xgen, ygen
        md = self.info['md']
        ms = self.info['ms']
        lamDL = zeros(md)
        lamDU = zeros(md)
        lamS = zeros(ms)
        ETlambda = -self.N * x - self.M * y - self.q

        assert ms + md == len(ETlambda)
        for i in range(md):
            if ETlambda[i] >= 0:
                lamDL[i] = 0.
                lamDU[i] = ETlambda[i]
            else:
                lamDL[i] = -ETlambda[i]
                lamDU[i] = 0.
#            assert lamDL[i] - lamDU[i] == ETlambda[i]

#        print lamS
        for i in range(ms):
            lamS[i] = -ETlambda[md + i]
#            assert lamS[i] == ETlambda[md+i]
#            assert lamS[i] >= 0, "if this goes wrong it's because this part of
#                   q wasn't generated right!"
#        E1 = conmat([eye(md), zeros(md, ms), -eye(md)], option='h')
#        E2 = conmat([zeros(ms, md), eye(ms), zeros(ms, md)], option='h')
#        lam = conmat([lamDL, lamS, lamDU])
#        ETlambda1 = conmat([E1, E2])*lam
#        assert np.allclose(ETlambda1, ETlambda), "{0} {1}".format(ETlambda1, ETlambda)
        return lamDL, lamS, lamDU
예제 #3
0
    def _make_a_ulambda(self):
        xgen = self.info['xgen']
        ygen = self.info['ygen']

        # FIRST LEVEL CTRS A[x;y] + a <= 0
        # Generate the first level multipliers  ulambda  associated with A*[x;y]+a<=0.
        # Generate a so the constraints Ax+a <= 0 are loose or tight where
        # appropriate.
        Axy = self.A * conmat([xgen, ygen])
        self.a = -Axy - conmat([
            zeros(self.info['l_deg']),  # A + a = 0
            rand(self.info['l_nonactive']),  # A + a = 0
            zeros(self.info['l_active'])])  # A + a <=0

        self.info['ulambda'] = conmat([
            zeros(self.info['l_deg']),
            zeros(self.info['l_nonactive']),
            rand(self.info['l_active'])])
예제 #4
0
    def test_suitable_A(self):
        for P in self.Plist:
            # what size should it have
            self.assertEqual(P.A.shape[0], P.param['l'])
            self.assertEqual(P.A.shape[1], P.param['m'] + P.param['n'])

            # what structure should it have?
            if not P.param['yinfirstlevel']:
                ypart = P.A[:, P.param['n']:]
                np.testing.assert_equal(
                    ypart, hp.zeros(P.param['l'], P.param['m']))
예제 #5
0
    def evaluate(self, shape, **kwargs):
        """ Evaluate zeros.

        Args:
          shape: Shape of result matrix of randint.
          kwargs: To be passed to randint.
        """
        m = helpers.zeros(**kwargs)
        self.assertEqual(m.shape, shape)
        self.assertGreaterEqual(m.min(), 0)
        self.assertLessEqual(m.max(), 0)
예제 #6
0
    def export_QPCC_data(self):
        P, info, param = self.return_problem()
        n = param['n']
        m = param['m']
        md = info['md']
        ms = info['ms']
        l = param['l']

        varsused = [1] * (n + m) + [0] * (m + md)
        names = create_name("x", n) + create_name("y", m) + \
            create_name("lamL", md) + create_name("lamL", ms, start=md) + \
            create_name("lamU", md)

        objQ = matrix([
            [matrix(0.5 * P['P']), matrix(zeros(m + md, m + n))],
            [matrix(zeros(m + n, m + md)), matrix(zeros(m + md, m + md))]])
        objp = conmat([P['c'], P['d'], zeros(m + md)])

        objr = 0

        G1 = conmat([P['A'], zeros(l, m + md)], option='h')
        h1 = -P['a']

        G2 = conmat([zeros(md, n), -eye(md), zeros(md, 2 * m)], option='h')
        h2 = zeros(md)

        G3 = conmat([zeros(md, n), eye(md), zeros(md, 2 * m)], option='h')
        h3 = P['u']

        G4 = conmat([zeros(ms, n + md), -eye(ms),
                     zeros(ms, m + md)], option='h')
        h4 = zeros(ms)

        G5 = conmat([zeros(m, n + m), -eye(m), zeros(m, md)], option='h')
        h5 = zeros(m)

        G6 = conmat([zeros(md, n + 2 * m), -eye(md)], option='h')
        h6 = zeros(md)

        if isinstance(self, Qpecgen201):
            G7 = conmat([-eye(n), zeros(n, 2 * m + md)], option='h')
            h7 = -self.info['xl']

            G8 = conmat([eye(n), zeros(n, 2 * m + md)], option='h')
            h8 = self.info['xu']

        A1 = conmat(
            [P['N'][:md], P['M'][:md], -eye(md), zeros(md, ms), eye(md)], option='h')
        b1 = -P['q'][:md]

        A2 = conmat(
            [P['N'][md:], P['M'][md:], zeros(ms, md), -eye(ms), zeros(ms, md)],
            option='h')
        b2 = -P['q'][md:]

        details = {
            'varsused': varsused,
            'geninfo': info,
            'genparam': param,
            'gensol': self.make_QPCC_sol()}

        return locals()
예제 #7
0
    def _make_F_pi_sigma_index(self):
        N = self.N
        M = self.M
        u = self.u
        xgen = self.info['xgen']
        ygen = self.info['ygen']

        m = self.param['m']

        # Design q so that Nx + My + E^Tlambda + q = 0 at the solution (xgen,
        # ygen)

        q = -N * xgen - M * ygen
        q += conmat([
            # double bounded, degenerate at upper
            zeros(self.info['md_upp_deg']),
            # double bounded, nonactive at upper
            -rand(self.info['md_upp_nonactive']),
            # double bounded, degenerate at lower
            zeros(self.info['md_low_deg']),
            # double bounded, nonactive at lower
            rand(self.info['md_low_nonactive']),
            zeros(self.info['md_float']),         # double bounded, floating
            # single bounded, degenerate at lower
            zeros(self.info['ms_deg']),
            # single bounded, nonactive at lower
            rand(self.info['ms_nonactive']),
            zeros(self.info['ms_active'])])       # single bounded, floating

        #########################################
        ##        For later convenience        ##
        #########################################
        F = N * xgen + M * ygen + q

        mix_deg = self.param['mix_deg']
        tol_deg = self.param['tol_deg']

        # Calculate three index sets alpha, beta and gamma at (xgen, ygen).
        # alpha denotes the index set of i at which F(i) is active, but y(i) not.
        # beta_upp and beta_low denote the index sets of i at which F(i) is
        # active, and y(i) is active at the upper and the lower end point of
        # the finite interval [0, u] respectively.
        # beta_inf denotes the index set of i at which both F(i) and y(i) are
        # active for the infinite interval [0, inf).
        # gamma_upp and gamma_low denote the index sets of i at which F(i) is
        # not active, but y(i) is active at the upper and the lower point of
        # the finite interval [0, u] respectively.
        # gamma_inf denotes the index set of i at which F(i) is not active, but y(i)
        # is active for the infinite interval [0, inf).
        index = []
        md = self.info['md']

        for i in range(md):
            assert ygen[i] >= -tol_deg and ygen[i] < u[i] + tol_deg, \
                "{0} not in [0, {1}]".format(ygen[i], u[i])
            if abs(F[i]) <= tol_deg and ygen[i] > tol_deg and ygen[i] + tol_deg < u[i]:
                index.append(1)  # For the index set alpha.
            elif abs(F[i]) <= tol_deg and abs(ygen[i] - u[i]) <= tol_deg:
                index.append(2)  # For the index set beta_upp.
            elif abs(F[i]) <= tol_deg and abs(ygen[i]) <= tol_deg:
                index.append(3)  # For the index set beta_low.
            elif F[i] < -tol_deg and abs(ygen[i] - u[i]) <= tol_deg:
                index.append(-1)  # For the index set gamma_upp.
            elif F[i] > tol_deg and abs(ygen[i]) <= tol_deg:
                index.append(-1)  # For the index set gamma_low.
            else:
                raise Exception(("didn't know what to do with this case: "
                                 "ygen={0}, u[i] = {1}, F[i]={2}").format(
                                     ygen[i], u[i], F[i]))

        for i in range(md, m):
            if ygen[i] > F[i] + tol_deg:
                index.append(1)  # For the index set alpha.
            elif abs(ygen[i] - F[i]) <= tol_deg:
                index.append(4)  # For the index set beta_inf.
            else:
                index.append(-1)  # For the index set gamma_inf.

        # Generate the first level multipliers   pi    sigma
        # associated with other constraints other than the first level constraints
        # A*[x;y]+a<=0   in the relaxed nonlinear program. In particular,
        # pi            is associated with  F(x, y)=N*x+M*y+q, and
        # sigma                       with  y.
        mix_upp_deg = max(
            mix_deg - self.info['md_low_deg'] - self.info['ms_deg'],
            choose_num(self.info['md_upp_deg']))
        mix_upp_deg = min(mix_upp_deg, mix_deg)

        mix_low_deg = max(
            mix_deg - mix_upp_deg - self.info['ms_deg'],
            choose_num(self.info['md_low_deg']))
        mix_low_deg = min(mix_low_deg, mix_deg - mix_upp_deg)

        mix_inf_deg = mix_deg - mix_upp_deg - mix_low_deg
        mix_inf_deg = min(mix_inf_deg, mix_deg - mix_upp_deg - mix_inf_deg)

        assert mix_deg >= 0
        assert mix_upp_deg >= 0
        assert mix_low_deg >= 0
        assert mix_inf_deg >= 0

#        assert self.param['second_deg'] == self.info['ms_deg'] +
#               self.info['md_low_deg'] + self.info['md_upp_deg'] + mix_deg
        k_mix_inf = 0
        k_mix_upp = 0
        k_mix_low = 0
        pi = zeros(m, 1)
        sigma = zeros(m, 1)
        for i in range(m):
            if index[i] == 1:
                pi[i] = randcst() - randcst()
                sigma[i] = 0
            elif index[i] == 2:
                if k_mix_upp < mix_upp_deg:
                    pi[i] = 0
                    # The first mix_upp_deg constraints associated with F(i)<=0
                    # in the set beta_upp are degenerate.
                    sigma[i] = 0
                    # The first mix_upp_deg constraints associated with
                    # y(i)<=u(i) in the set beta_upp are degenerate.
                    k_mix_upp = k_mix_upp + 1
                else:
                    pi[i] = randcst()
                    sigma[i] = randcst()
            elif index[i] == 3:
                if k_mix_low < mix_low_deg:
                    pi[i] = 0
                    # The first mix_low_deg constraints associated with F(i)>=0
                    # in the set beta_low are degenerate.
                    sigma[i] = 0
                    # The first mix_low_deg constraints associated with
                    # y(i)>=0 in the set beta_low are degenerate.
                    k_mix_low = k_mix_low + 1
                else:
                    pi[i] = -randcst()
                    sigma[i] = -randcst()
            elif index[i] == 4:
                if k_mix_inf < mix_inf_deg:
                    pi[i] = 0
                    # The first mix_inf_deg constraints associated with F(i)>=0
                    # in the set beta_inf are degenerate.
                    sigma[i] = 0
                    # The first mix_inf_deg constraints associated with
                    # y(i)>=0 in the set beta_inf are degenerate.
                    k_mix_inf = k_mix_inf + 1
                else:
                    pi[i] = -randcst()
                    sigma[i] = -randcst()
            else:
                pi[i] = 0
                sigma[i] = randcst() - randcst()

        self.q = q
        self.info.update({
            'F': F,
            'mix_upp_deg': mix_upp_deg,
            'mix_low_deg': mix_low_deg,
            'mix_inf_deg': mix_inf_deg,
            'pi': pi,
            'sigma': sigma})