Exemplo n.º 1
0
def test_create(data, query, sign):
    """ Tests creation of constraints """
    c1 = Constraint(query, query.answer(data), sign, 'cons1')
    assert c1.name == 'cons1'
    assert c1.query == query
    assert c1.rhs.size == 4
    assert c1.sign == sign
    assert np.array_equal(c1.rhs, np.array([330, 405, 480, 555]))
    c2 = Constraint(query,
                    np.zeros(query.answer(data).shape).astype(int), sign)
    assert c2.name == ''
    assert c2.query == query
    assert c2.rhs.size == 4
    assert c2.sign == sign
    assert np.array_equal(c2.rhs, np.array([0, 0, 0, 0]))
Exemplo n.º 2
0
 def makeConstraints(hist_shape, invariants, constraint_names):
     cons_dict = {}
     if 'total' in constraint_names:
         cons_dict.update({
             'total':
             Constraint(
                 MultiHistQuery((QueryFactory.makeTabularGroupQuery(
                     (2, ), add_over_margins=(0, )),
                                 StubQuery((2, 1), "stub")), (1, 0)),
                 np.array(invariants['tot']), "=", "total")
         })
     return cons_dict
Exemplo n.º 3
0
def test_createErrorRaising(data, query, queryarg, rhs, sign, err_type,
                            err_msg):
    """ Tests that constructor raises appropriate errors """
    if not queryarg:
        queryarg = query

    if rhs is None:
        rhs = query.answer(data)

    with pytest.raises(err_type) as err:
        Constraint(queryarg, rhs, sign)
    assert err_msg in str(err.value)
Exemplo n.º 4
0
    def interleave_optimizations(self, outerPassNum=None):
        """
        Perform optimization for a single outer pass
        :param outerPassNum:
        :return: L2 answer and rounded answer
        """
        l2_approach, rounder_approach = self.optimizers
        l2_opt_class, requires_ols_prepass = self.l2_optimizers_dict[l2_approach]
        rounder_opt_class = self.rounder_optimizers_dict[rounder_approach]

        # Note: Not using L2 with OLS pre-prepass, if needed, copy the prepass from L2PlusRounderWithBackup
        L2_dpq_names = reduce(add, self.L2_DPqueryOrdering[outerPassNum].values())
        L2_queries = [list(filter(lambda dpq: dpq.name in L2_dpq_names, dpq_hist_set)) for dpq_hist_set in self.DPqueries]
        L2opt = self.createL2opt(backup_feas=False, l2opt=l2_opt_class, DPqueries=L2_queries,
                                nnls=True, DPqueryOrdering=self.L2_DPqueryOrdering[outerPassNum],
                                Constrain_to_Ordering=self.L2_Constrain_to_Ordering[outerPassNum])
        L2opt.run()
        if L2opt.mstatus not in self.acceptable_l2_statuses:
            raise NotImplementedError("ERROR: Interleaved optimization does not currently support failsafe!")

        rq_names = reduce(add, self.Rounder_DPqueryOrdering[outerPassNum].values())
        rounder_queries = [list(filter(lambda rq: rq.name in rq_names, rq_hist_set)) for rq_hist_set in self.rounder_queries]
        Rounder = self.createRounder(L2opt, backup_feas=False, rounder_opt_class=rounder_opt_class, DPqueries=rounder_queries,
                                        DPqueryOrdering=self.Rounder_DPqueryOrdering[outerPassNum])
        Rounder.run()
        self.checkModelStatus(Rounder.mstatus, "Rounder_standard", CC.L1_FEAS_FAIL)
        answer = Rounder.answer
        print(f"outerPass {outerPassNum} ---> L2: {L2_dpq_names}, L2_queries:: {L2_queries}, Rounder: {rq_names}, rounder_queries:: {rounder_queries}")

        for ihist, dp_queries in enumerate(self.rounder_queries):
            for st_dpq in dp_queries:
                final_rounder_pass = sorted(self.Rounder_DPqueryOrdering[outerPassNum].keys())[-1]
                if self.Rounder_revDPqueryOrdering[st_dpq.name] == (outerPassNum, final_rounder_pass):
                    q = st_dpq.query
                    queries = [StubQuery((int(np.prod(hist.shape) / self.childGeoLen), q.numAnswers()), "stub") for hist in answer]
                    coeffs = [0] * len(answer)
                    queries[ihist] = q
                    coeffs[ihist] = 1
                    multi_query = MultiHistQuery( tuple(queries), tuple(coeffs), f"{q.name}_multi")
                    if outerPassNum != self.outerPassNums[-1]:
                        constraints_indices_equal = []
                        for sc_child_ind, child_num in enumerate(st_dpq.indices):
                            pass_answer = multi_query.answer(np.hstack([hist.reshape((int(np.prod(hist.shape) / self.childGeoLen), self.childGeoLen))[:, child_num] for hist in answer]))
                            constraints_indices_equal.append((Constraint(multi_query, pass_answer, "=", f"outerPassNum_{outerPassNum}Constr_{q.name}_{child_num}"), child_num))
                        self.constraints.append(StackedConstraint(constraints_indices_equal))

        return L2opt.answer, Rounder.answer
Exemplo n.º 5
0
def test_add(constraint, query, sign):
    """ Test addition of two constraints """
    newrhs = np.random.rand(constraint.rhs.size)
    constraint.sign = sign
    c2 = Constraint(query, newrhs, sign, 'teststandard')
    sum_cons = constraint + c2
    assert sum_cons.query == constraint.query
    assert sum_cons.query == c2.query
    assert sum_cons.sign == constraint.sign
    assert sum_cons.sign == c2.sign
    assert np.allclose(sum_cons.rhs, constraint.rhs + c2.rhs)

    # Let's check that the sum is good too, and can be added further
    sum_cons1 = sum_cons + c2
    assert sum_cons1.query == sum_cons.query
    assert sum_cons1.query == c2.query
    assert sum_cons1.sign == sum_cons.sign
    assert sum_cons1.sign == c2.sign
    assert np.allclose(sum_cons1.rhs, sum_cons.rhs + c2.rhs)
Exemplo n.º 6
0
def test_eq(constraint, query, data, samequery, samerhs, samesign, samename,
            rhstype):
    """ Test __eq__ constraint comparison"""
    if not samequery:
        query = querybase.SumoverQuery(data.shape, add_over_margins=(0, 1, 2))

    rhs = (query.answer(data) + 1e-14).astype(rhstype)
    constraint.rhs = constraint.rhs.astype(rhstype)
    if not samerhs:
        rhs = rhs + 1

    sign = '=' if samesign else 'le'
    name = 'teststandard' if samename else 'othername'

    c2 = Constraint(query, rhs, sign, name)

    if samequery and samerhs and samesign and samename:
        assert c2 == constraint
    else:
        assert c2 != constraint
Exemplo n.º 7
0
def test_addValueErrorsRaising(constraint, data, wrongattr):
    """ Test raising errors when trying to add Constraints with different queries, signs or names"""
    err_msg = f" cannot be added: addends have different {wrongattr}"
    argdict = {
        'query': constraint.query,
        'sign': constraint.sign,
        'name': constraint.name,
    }
    wrongargdict = {
        'query': querybase.SumoverQuery(data.shape,
                                        add_over_margins=(0, 1, 2)),
        'sign': 'le',
        'name': 'othername',
    }
    argdict[wrongattr] = wrongargdict[wrongattr]
    argdict['rhs'] = argdict['query'].answer(data)
    c2 = Constraint(**argdict)
    with pytest.raises(IncompatibleAddendsError) as err:
        cons_sum = constraint + c2
    assert err_msg in str(err.value)
Exemplo n.º 8
0
def constraint(query, data):
    return Constraint(query, query.answer(data), "=", 'teststandard')