Пример #1
0
def test_normalization_negative():
    def get_normalization_file(filename):
        return path.join(path.dirname(__file__), "res", "bug_z_negative",
                         filename)

    domain = Domain.from_file(get_normalization_file("domain"))
    support = domain.get_bounds() & read_smtlib(
        get_normalization_file("vanilla.support"))
    weight = read_smtlib(get_normalization_file("vanilla.weight"))
    new_support = read_smtlib(get_normalization_file("renorm.support"))
    pa_engine = RejectionEngine(
        domain, Iff(new_support, ~normalize_formula(new_support)), Real(1),
        1000000)
    difference_volume = pa_engine.compute_volume()
    assert difference_volume == pytest.approx(0, EXACT_REL_ERROR**2)

    support = normalize_formula(support)
    new_support = normalize_formula(new_support)
    weight = normalize_formula(weight)

    engine = XaddEngine(domain, support, weight)
    new_weight = engine.normalize(new_support, paths=False)

    computed_volume = engine.copy_with(weight=new_weight).compute_volume()
    # print(pa_engine.copy_with(support=domain.get_bounds(), weight=new_weight).compute_volume())
    # print(pa_engine.copy_with(support=new_support, weight=new_weight).compute_volume())
    illegal_volume = engine.copy_with(support=~new_support,
                                      weight=new_weight).compute_volume()
    print(computed_volume, illegal_volume)

    # new_new_weight = engine.copy_with(support=domain.get_bounds(), weight=new_weight).normalize(new_support, paths=False)
    # print(pa_engine.copy_with(support=domain.get_bounds(), weight=new_new_weight).compute_volume())

    assert computed_volume == pytest.approx(1, rel=0.1)
    assert illegal_volume == pytest.approx(0, rel=EXACT_REL_ERROR)
def test_rejection_iff_real():
    domain = Domain.make([], ["x", "y"], real_bounds=(-1, 1))
    x, y = domain.get_symbols()
    c = 0.00000001
    f1 = (x * c > 0) & (x * c <= y * c) & (y * c < c)
    f2 = normalize_formula(f1)

    rej_vol1 = RejectionEngine(domain, (f1 | f2) & (~f1 | ~f2), smt.Real(1.0),
                               100000).compute_volume()
    rej_vol2 = RejectionEngine(domain, smt.Iff(f1, ~f2), smt.Real(1.0),
                               100000).compute_volume()
    rej_vol3 = RejectionEngine(domain, ~smt.Iff(f1, f2), smt.Real(1.0),
                               100000).compute_volume()

    assert rej_vol1 == pytest.approx(0, REL_ERROR**3)
    assert rej_vol2 == pytest.approx(0, REL_ERROR**3)
    assert rej_vol3 == pytest.approx(0, REL_ERROR**3)
def test_pyxadd_automated(e):
    inspect_density(
        PyXaddEngine(),
        e,
        test_engine=RejectionEngine(e.domain,
                                    e.support,
                                    e.weight,
                                    sample_count=TEST_SAMPLE_COUNT),
    )
def test_adaptive_unweighted_real():
    domain = Domain.make([], ["x", "y"], [(-5, 10), (-5, 10)])
    x, y = domain.get_symbols(domain.variables)
    support = (x >= -4) & (x <= y) & (y <= 9) & ((y <= -1) | (y >= 6))
    weight = Real(1.0)
    engine = AdaptiveRejection(domain, support, weight, SAMPLE_COUNT,
                               SAMPLE_COUNT / 10)
    computed_volume = engine.compute_volume()
    rejection_engine = RejectionEngine(domain, support, weight, SAMPLE_COUNT)
    correction_volume_rej = rejection_engine.compute_volume()
    print(computed_volume, correction_volume_rej,
          APPROX_ERROR * correction_volume_rej)
    assert computed_volume == pytest.approx(correction_volume_rej,
                                            rel=APPROX_ERROR)

    query = x <= y / 2
    prob_adaptive = engine.compute_probability(query)
    prob_rej = rejection_engine.compute_probability(query)
    assert prob_adaptive == pytest.approx(prob_rej, rel=APPROX_ERROR)
Пример #5
0
def run_rej(density, n_bins, n_samples, log_path):

    #log_path = join(output_folder, f"{name}-rej.json")
    if not isfile(log_path):
        print(log_path)
        rej_log = {}
        # create queries
        qs = {}
        for xvar in density.domain.get_real_symbols():
            x = xvar.symbol_name()
            qs[x] = []
            low, up = density.domain.var_domains[x]
            slices = [(i / n_bins) * (up - low) + low
                      for i in range(0, n_bins + 1)]
            for i in range(len(slices) - 1):
                l, u = slices[i], slices[i + 1]
                qs[x].append((l, u, And(LE(Real(l), xvar), LE(xvar, Real(u)))))

        t0 = time.perf_counter()
        rejection_engine = RejectionEngine(density.domain,
                                           density.support,
                                           density.weight,
                                           sample_count=n_samples)
        rej_bin_probs = {}
        for x in qs:
            rej_bin_probs[x] = []
            for l, u, q in qs[x]:
                prob_q = rejection_engine.compute_probability(q)
                rej_bin_probs[x].append((l, u, prob_q))
        t1 = time.perf_counter()
        rej_log['time'] = t1 - t0
        rej_log['query_marginals'] = rej_bin_probs

        with open(log_path, 'w') as f:
            json.dump(rej_log, f)

    else:
        print(f"Found {log_path}")
        with open(log_path, 'r') as f:
            rej_bin_probs = json.load(f)['query_marginals']

    return rej_bin_probs
def test_rejection_iff_bool():
    domain = Domain.make(["a", "b"])
    a, b = domain.get_symbols()

    print(domain)
    vol_t = RejectionEngine(domain, smt.TRUE(), smt.Real(1.0),
                            100000).compute_volume()
    vol1 = RejectionEngine(domain, (a | b) & (~a | ~b), smt.Real(1.0),
                           100000).compute_volume()
    vol2 = RejectionEngine(domain, smt.Iff(a, ~b), smt.Real(1.0),
                           100000).compute_volume()
    vol3 = RejectionEngine(domain, ~smt.Iff(a, b), smt.Real(1.0),
                           100000).compute_volume()

    print(vol1, vol2, vol3, vol_t)

    # print(PredicateAbstractionEngine(domain, a | b, smt.Real(1.0)).compute_volume())
    print(XaddEngine(domain, a | b, smt.Real(1.0)).compute_volume())

    quit()
def test_adaptive_unweighted():
    domain = Domain.make(["a", "b"], ["x", "y"], [(0, 1), (0, 1)])
    a, b, x, y = domain.get_symbols(domain.variables)
    support = (a | b) & (~a | ~b) & (x >= 0) & (x <= y) & (y <= 1)
    weight = Real(1.0)
    engine = AdaptiveRejection(domain, support, weight, SAMPLE_COUNT,
                               SAMPLE_COUNT / 10)
    computed_volume = engine.compute_volume()
    correction_volume_rej = RejectionEngine(domain, support, weight,
                                            SAMPLE_COUNT).compute_volume()
    assert computed_volume == pytest.approx(correction_volume_rej,
                                            rel=APPROX_ERROR)
def test_volume():
    domain = Domain.make(["a", "b"], ["x", "y"], [(0, 1), (0, 1)])
    a, b, x, y = domain.get_symbols(domain.variables)
    support = (a | b) & (~a | ~b) & (x >= 0.0) & (x <= y) & (y <= 1.0)
    weight = Ite(a, Real(0.6), Real(0.4)) * Ite(b, Real(0.8), Real(0.2))\
             * (Ite(x >= Real(0.5), Real(0.5) * x + Real(0.1) * y, Real(0.1) * x + Real(0.7) * y))
    engine = AdaptiveRejection(domain, support, weight, SAMPLE_COUNT)
    computed_volume = engine.compute_volume()
    correction_volume_rej = RejectionEngine(domain, support, weight,
                                            SAMPLE_COUNT).compute_volume()
    assert computed_volume == pytest.approx(correction_volume_rej,
                                            rel=APPROX_ERROR)
Пример #9
0
def get_test_engine_factory(domain,
                            formula,
                            weight_function,
                            allow_rejection=True):
    if check_installation_pyxadd():
        return PyXaddEngine(domain, formula, weight_function)
    elif check_installation_pa():
        return PredicateAbstractionEngine(domain, formula, weight_function)
    elif allow_rejection:
        return RejectionEngine(domain, formula, weight_function,
                               TEST_SAMPLE_COUNT)
    else:
        raise InstallError()
Пример #10
0
def test_adaptive_threshold():
    random.seed(888)
    np.random.seed(888)

    domain = Domain.make([], ["x", "y"], [(0, 1), (0, 1)])
    x, y = domain.get_symbols(domain.variables)
    formula = (x <= y) & (x <= 0.5) & (y <= 0.5) & domain.get_bounds()
    thresholds = {"x": 0.1, "y": 0.1}
    data, _ = RejectionEngine(domain, formula, x * x, 100000).get_samples(50)
    k = 4
    nearest_neighbors = []
    for i in range(len(data)):
        nearest_neighbors.append([])
        for j in range(len(data)):
            if i != j:
                distance = 1 if any(data[i, b] != data[j, b] for b, v in enumerate(domain.variables)
                                    if domain.is_bool(v))\
                    else max(abs(data[i, r] - data[j, r]) / (domain.var_domains[v][1] - domain.var_domains[v][0]) for r, v in enumerate(domain.variables) if domain.is_real(v))
                if len(nearest_neighbors[i]) < k:
                    nearest_neighbors[i].append((j, distance))
                else:
                    index_of_furthest = None
                    for fi, f in enumerate(nearest_neighbors[i]):
                        if index_of_furthest is None or f[
                                1] > nearest_neighbors[i][index_of_furthest][1]:
                            index_of_furthest = fi
                    if distance < nearest_neighbors[i][index_of_furthest][1]:
                        nearest_neighbors[i][index_of_furthest] = (j, distance)
    print(nearest_neighbors)
    t = [[
        sum(n[1] for n in nearest_neighbors[i]) / len(nearest_neighbors[i]) *
        (domain.var_domains[v][1] - domain.var_domains[v][0])
        for v in domain.real_vars
    ] for i in range(len(nearest_neighbors))]
    t = np.array(t)
    print(t)
    print(data)
    # data = uniform(domain, 400)
    labels = evaluate(domain, formula, data)
    data = data[labels == 1]
    labels = labels[labels == 1]
    data, labels = OneClassStrategy.add_negatives(domain, data, labels, t,
                                                  1000)

    directory = "test_output{}adaptive{}{}".format(
        os.path.sep, os.path.sep, time.strftime("%Y-%m-%d %Hh%Mm%Ss"))
    os.makedirs(directory)

    name = os.path.join(directory, "combined.png")
    plot.plot_combined("x", "y", domain, formula, (data, labels), None, name,
                       set(), set())
Пример #11
0
 def accuracy_approx(experiment):
     key = "accuracy_approx:{}".format(experiment.imported_from_file)
     if Properties.db.exists(key):
         return Properties.db.get(key)
     else:
         pysmt.environment.push_env()
         pysmt.environment.get_env().enable_infix_notation = True
         if os.path.basename(experiment.imported_from_file).startswith("synthetic"):
             db = Properties.get_db_synthetic(experiment)
             name = Properties.to_synthetic_name(experiment.imported_from_file)
             entry = db.get(name)
             domain = import_domain(json.loads(entry["domain"]))
             true_formula = nested_to_smt(entry["formula"])
         else:
             density = Density.import_from(experiment.parameters.original_values["domain"])
             domain = Domain(density.domain.variables, density.domain.var_types, Properties.get_bound(experiment))
             true_formula = density.support
         learned_formula = nested_to_smt(experiment.results.formula)
         engine = RejectionEngine(domain, smt.TRUE(), smt.Real(1.0), 100000)
         accuracy = engine.compute_probability(smt.Iff(true_formula, learned_formula))
         pysmt.environment.pop_env()
         print(accuracy)
         Properties.db.set(key, accuracy)
     return accuracy
Пример #12
0
def check_Z_normalize(model, seed, sample_count):
    """Tests whether the model is normalized. If not, updates the weight
    function accordingly."""

    logger.debug("Approximating Z")
    solver = RejectionEngine(model.domain, model.support, model.weightfun,
                             sample_count=sample_count, seed=seed)
    all_ohes = dict()
    for var in model.domain.bool_vars:
        print("VAR:", var)
        if "_OHE_" in var:
            prefix = var.partition("_OHE_")[0]
            if prefix not in all_ohes:
                all_ohes[prefix] = []

            all_ohes[prefix].append(var)
    ohe_variables = list(all_ohes.values()) if len(all_ohes) > 0 else None
    Z_approx = solver.compute_volume(ohe_variables=ohe_variables)
    logger.debug("Z_approx: {}".format(Z_approx))
    if Z_approx <= 0:
        raise ModelException("Partition function is <= 0")
    
    if not abs(Z_approx - 1.0) <= DEF_CLOSE_ENOUGH:
        model.weightfun = Times(Real(float(1.0/Z_approx)), model.weightfun)
Пример #13
0
def ISE(model1, model2, seed, sample_count, engine='pa'):

    assert(set(model1.get_vars()) == set(model2.get_vars())),\
        "M1 vars: {}\n M2 vars: {}".format(model1.get_vars(),model2.get_vars())
    
    support1, weightfun1 = model1.support, model1.weightfun
    support2, weightfun2 = model2.support, model2.weightfun


    support_d = Or(support1, support2)

    weight_d = Ite(And(support1, support2),
                   Times(Minus(weightfun1, weightfun2),
                         Minus(weightfun1, weightfun2)),
                   Ite(support1, Times(weightfun1, weightfun1),
                       Times(weightfun2, weightfun2)))

    domain, _ = merged_domain(model1, model2)

    if engine == 'pa':
        engine = PredicateAbstractionEngine(domain, support_d, weight_d)
        result = solver.compute_volume()

    elif engine == 'rej':
        result = None
        solver = RejectionEngine(domain, support_d, weight_d,
                                 sample_count=sample_count, seed=seed)        
        while result is None:
            #logger.debug("Attempting with sample_count {}".format(
                #solver.sample_count))
            result = solver.compute_volume()
            solver.sample_count *= 2
    else:
        raise NotImplementedError()    

    return result
Пример #14
0
def normalize(model, seed, sample_count, engine='pa'):
    
    if engine == 'pa':
        solver = PredicateAbstractionEngine(model.domain, model.support, model.weightfun)
    elif engine == 'rej':
        solver = RejectionEngine(model.domain, model.support, model.weightfun,
                                 sample_count=sample_count, seed=seed)
    else:
        raise NotImplementedError()

    Z = solver.compute_volume()

    assert(Z >= 0), "Z is negative"

    if not np.isclose(Z, 1.0):
        logger.debug("Normalizing w with Z: {}".format(Z))
        model.weightfun = Times(Real(1.0/Z), model.weightfun)

    return Z
Пример #15
0
def test_trivial_weight_function_partial():
    # Support:  (a | b) & (~a | ~b) & (x >= 0) & (x <= y) & (y <= 10)
    # Weight:   1

    domain = Domain.make(["a", "b"], ["x", "y"], [(0, 1), (0, 1)])
    a, b, x, y = domain.get_symbols(domain.variables)
    support = (a | b) & (~a | ~b) & (x >= 0) & (x <= y) & (y <= 1)
    weight = Real(1.0)
    computed_volume = XsddEngine(
        domain=domain,
        support=support,
        weight=weight,
        convex_backend=EngineConvexIntegrationBackend(PyXaddEngine()),
    ).compute_volume()
    correction_volume_rej = RejectionEngine(domain, support, weight,
                                            1000000).compute_volume()
    correction_volume_xadd = PyXaddEngine(domain, support,
                                          weight).compute_volume()
    # print(correction_volume_rej, correction_volume_xadd, computed_volume)
    assert computed_volume == pytest.approx(correction_volume_rej, rel=ERROR)
    assert computed_volume == pytest.approx(correction_volume_xadd, rel=ERROR)
Пример #16
0
def test_volume():
    # Support:  (a | b) & (~a | ~b) & (x >= 0) & (x <= y) & (y <= 10)
    # Weight:   {
    #                a  b  (x>=0.5): 0.6*0.8*(0.5x+0.1y)  0.5 <= x <= y, x <= y <= 10
    #                a  b !(x>=0.5): 0.6*0.8*(0.1x+0.7y)  0 <= x <= [y, 0.5], x <= y <= 10
    #                a !b  (x>=0.5): 0.6*0.2*(0.5x+0.1y)  0.5 <= x <= y, x <= y <= 10
    #                a !b !(x>=0.5): 0.6*0.2*(0.1x+0.7y)  0 <= x <= [y, 0.5], x <= y <= 10
    #               !a  b  (x>=0.5): 0.4*0.8*(0.5x+0.1y)  0.5 <= x <= y, x <= y <= 10
    #               !a  b !(x>=0.5): 0.4*0.8*(0.1x+0.7y)  0 <= x <= [y, 0.5], x <= y <= 10
    #               !a !b  (x>=0.5): 0.4*0.2*(0.5x+0.1y)  0.5 <= x <= y, x <= y <= 10
    #               !a !b !(x>=0.5): 0.4*0.2*(0.1x+0.7y)  0 <= x <= [y, 0.5], x <= y <= 10
    # }

    # TODO What if we don't expand the Weight Function, only compile the support?
    # TODO => Can we reuse the SDD? It doesn't seem so... => Need multiple SDDs to use caching

    domain = Domain.make(["a", "b"], ["x", "y"], [(0, 1), (0, 1)])
    a, b, x, y = domain.get_symbols(domain.variables)
    support = (a | b) & (~a | ~b) & (x >= 0.0) & (x <= y) & (y <= 1.0)
    weight = (Ite(a, Real(0.6), Real(0.4)) * Ite(b, Real(0.8), Real(0.2)) *
              (Ite(
                  x >= Real(0.5),
                  Real(0.5) * x + Real(0.1) * y,
                  Real(0.1) * x + Real(0.7) * y,
              )))
    computed_volume = XsddEngine(
        domain=domain,
        support=support,
        weight=weight,
        convex_backend=EngineConvexIntegrationBackend(PyXaddEngine()),
    ).compute_volume()
    correction_volume_rej = RejectionEngine(domain, support, weight,
                                            1000000).compute_volume()
    correction_volume_xadd = PyXaddEngine(domain, support,
                                          weight).compute_volume()
    # print(correction_volume_rej, correction_volume_xadd, computed_volume)
    assert computed_volume == pytest.approx(correction_volume_rej, rel=ERROR)
    assert computed_volume == pytest.approx(correction_volume_xadd, rel=ERROR)
def rejection_factory(d, s, w):
    return RejectionEngine(d, s, w, SAMPLE_COUNT)
x, y = domain.get_real_symbols(
)  # Get PySMT variables for the continuous variables

# Create support
support = (a | b) & (~a | ~b) & (x <= y) & domain.get_bounds()

# Create weight function (PySMT requires constants to be wrapped, e.g., smt.Real(0.2))
weight_function = smt.Ite(a, smt.Real(0.2), smt.Real(0.8)) * (
    smt.Ite(x <= 0.5, smt.Real(0.2), 0.2 + y) + smt.Real(0.1))

# Create query
query = x <= y / 2

# Create rejection-sampling based engine (no setup required)
rejection_engine = RejectionEngine(domain,
                                   support,
                                   weight_function,
                                   sample_count=100000)

print("Volume (Rejection):           ",
      rejection_engine.compute_volume())  # Compute the weighted model integral
print("Query probability (Rejection):",
      rejection_engine.compute_probability(query))  # Compute query probability

# Create XADD engine (mode resolve refers to the integration algorithm described in
# Kolb et al. Efficient symbolic integration for probabilistic inference. IJCAI 2018)
# !! Requires XADD solver to be setup (see above) !!
xadd_engine = XaddEngine(domain, support, weight_function, mode="resolve")

print("Volume (XADD):                ",
      xadd_engine.compute_volume())  # Compute the weighted model integral
print("Query probability (XADD):     ",
Пример #19
0
def get_engine(description, domain, support, weight):
    # type: (str, Domain, FNode, FNode) -> Engine
    parts = description.split(":")

    if parts[0].lower() == "pa":
        options = parse_options(parts[1:], "timeout")
        return PredicateAbstractionEngine(domain, support, weight, **options)
    if parts[0].lower() == "mpwmi":
        options = parse_options(parts[1:], "cache")
        return MPWMIEngine(domain, support, weight, **options)
    if parts[0].lower() == "rej":
        options = parse_options(parts[1:], "sample_count", "seed")
        return RejectionEngine(domain, support, weight, **options)
    if parts[0].lower() == "adapt":
        options = parse_options(parts[1:], "sample_count", "seed")
        return AdaptiveRejection(domain, support, weight, **options)
    if parts[0].lower() == "xadd":
        options = parse_options(parts[1:], "mode", "timeout")
        return XaddEngine(domain, support, weight, **options)
    if parts[0].lower() == "pyxadd":
        options = parse_options(parts[1:], "reduce")
        return PyXaddEngine(domain, support, weight, **options)
    if parts[0].lower() == "praise":
        # options = parse_options(parts[1:])
        return PraiseEngine(domain, support, weight)
    if parts[0].lower() == "xsdd":
        options = parse_options(
            parts[1:],
            "backend",
            "factorized",
            "find_conflicts",
            "ordered",
            "balance",
            "minimize",
        )
        backend_string = options.get("backend", None)
        if backend_string is None:
            backend = None
        else:
            parts = backend_string.split(".")
            if parts[0] == "rej":
                from .engines.rejection import RejectionIntegrator

                bb = int(parts[2]) if len(parts) > 2 else 0
                seed = int(parts[3]) if len(parts) > 3 else None
                backend = RejectionIntegrator(int(parts[1]), bb, seed=seed)
            elif parts[0] == "xadd":
                from .engines.xadd import XaddIntegrator

                backend = XaddIntegrator(parts[1] if len(parts) > 1 else None)
            elif parts[0] == "latte":
                from .engines.latte_backend import LatteIntegrator

                backend = LatteIntegrator()
            else:
                raise ValueError(
                    "Please specify a valid backend instead of {}".format(parts[0])
                )

        if "backend" in options:
            del options["backend"]

        # TODO figure out this
        # return XsddEngine(domain, support, weight, factorized=True,algebra=PyXaddAlgebra(), ordered=True)
        return XsddEngine(domain, support, weight, convex_backend=backend, **options)
Пример #20
0
def test_normalization():
    def get_normalization_file(filename):
        return path.join(path.dirname(__file__), "res", "renorm_bug", filename)

    for i in range(5):
        domain = Domain.from_file(get_normalization_file("domain.json"))
        support = read_smtlib(get_normalization_file("vanilla.support"))
        weight = read_smtlib(get_normalization_file("vanilla.weight"))
        new_support = read_smtlib(
            get_normalization_file("renorm_chi_{}.support".format(i)))

        # print(smt_to_nested(support))

        clean_support = normalize_formula(support)
        clean_new_support = normalize_formula(new_support)
        clean_weight = normalize_formula(weight)

        print(smt_to_nested(clean_weight))

        assert (RejectionEngine(domain, ~Iff(support, clean_support),
                                Real(1.0), 1000000).compute_volume() == 0)
        assert (RejectionEngine(domain, ~Iff(new_support, clean_new_support),
                                Real(1.0), 1000000).compute_volume() == 0)

        # plot_formula("new_support", domain, new_support, ["r0", "r1"])
        # plot_formula("clean_new_support", domain, clean_new_support, ["r0", "r1"])

        support = clean_support
        new_support = clean_new_support
        weight = clean_weight

        # print(RejectionEngine(domain, Iff(weight, ~clean_weight), Real(1.0), 1000000).compute_volume())

        # print(smt_to_nested(support))

        print("Problem", i)
        engine = XaddEngine(domain, support, weight, "original")
        print("Volume before starting", engine.compute_volume())
        new_weight = engine.normalize(new_support, paths=False)

        Density(domain, new_support, new_weight).to_file("normalized.json")

        illegal_volume = XaddEngine(domain, ~new_support, new_weight,
                                    "mass").compute_volume()
        assert illegal_volume == pytest.approx(0, rel=EXACT_REL_ERROR)

        computed_volume = XaddEngine(domain, TRUE(), new_weight,
                                     "mass").compute_volume()
        computed_volume_within = XaddEngine(domain, new_support, new_weight,
                                            "mass").compute_volume()
        computed_volume_within2 = XaddEngine(domain, new_support,
                                             new_weight).compute_volume()
        computed_volume_within3 = RejectionEngine(domain, new_support,
                                                  new_weight,
                                                  1000000).compute_volume()
        print(
            "pa new_support new_weight",
            computed_volume_within,
            "xadd new_support new_weight:",
            computed_volume_within2,
            "rej new_support new_weight:",
            computed_volume_within3,
        )
        assert computed_volume_within == pytest.approx(computed_volume_within2,
                                                       EXACT_REL_ERROR)
        print(
            "pa true new_weight:",
            computed_volume,
            "pa new_support new_weight",
            computed_volume_within,
            "pa outside new_support new_weight",
            illegal_volume,
        )
        assert computed_volume == pytest.approx(1, rel=EXACT_REL_ERROR)
        assert computed_volume_within == pytest.approx(1, rel=EXACT_REL_ERROR)

        illegal_volume = engine.copy_with(support=~new_support,
                                          weight=new_weight).compute_volume()
        assert illegal_volume == pytest.approx(0, rel=EXACT_REL_ERROR)
Пример #21
0
def diabetes_example1():
    domain = Domain.make(["f0", "d0"], ["r0"], [(10, 45)])

    (
        f0,
        d0,
    ) = domain.get_bool_symbols()
    (r0, ) = domain.get_real_symbols()

    support = ((f0 & (((d0 | ~d0) & ~(r0 <= 35)) | ((r0 <= 35) & (~d0))))
               | (~f0 & (d0 & (r0 <= 35)))) & domain.get_bounds()
    # support_smaller = ((f0 & ((~(r0 <= 35)) | ~d0)) |
    #                    (~f0 & d0 & (r0 <= 35))) & \
    #                   domain.get_bounds()

    # support_smaller = ((f0 & ((~(r0 <= 35)) | ~d0))) & \
    #                   domain.get_bounds()

    support_smaller = ((f0 & ~(r0 <= 35) & ~d0) |
                       (f0 & (r0 <= 35) & ~d0)) & domain.get_bounds()

    weight_function = smt.Ite(f0, smt.Real(0.0001), smt.Real(0.00001)) * \
                      smt.Ite(d0, (r0/10)-1, 8-(r0/10)) * \
                      smt.Ite(r0 <= 35, -0.001*(r0-27)*(r0-27)+0.3, -0.001*(r0-27)*(r0-27)+0.3)
    #
    # weight_function_smaller = smt.Ite(f0, smt.Real(0.0001), smt.Real(0.00001)) * \
    #                           r0 *\
    #                           smt.Ite(r0 <= 35, -0.001*(r0)*(r0)+0.3, -0.001*(r0)*(r0)+0.3)
    weight_function_smaller = (
        smt.Real(0.00000001) * r0 * r0 * r0
    )  # * smt.Real(1000)  #<--- add this changes the result from 0.0 to 102
    density = Density(domain, support & domain.get_bounds(),
                      weight_function)  # weight_function)
    query = d0

    startTime = time.time()
    rejection_engine = RejectionEngine(density.domain,
                                       density.support,
                                       density.weight,
                                       sample_count=1000000)

    vol1 = rejection_engine.compute_volume()
    result1 = rejection_engine.compute_probability(query)
    endTime = time.time()
    time1 = endTime - startTime

    startTime = time.time()
    xadd_engine = PyXaddEngine(density.domain, density.support, density.weight)
    vol2 = xadd_engine.compute_volume(add_bounds=False)
    result2 = xadd_engine.compute_probability(query)
    endTime = time.time()
    time2 = endTime - startTime
    # XsddEngine
    algebra = PyXaddAlgebra(reduce_strategy=PyXaddAlgebra.FULL_REDUCE)
    mfxsdd = FXSDD(
        density.domain,
        density.support,
        density.weight,
        vtree_strategy=balanced,
        algebra=algebra,
        ordered=False,
    )
    startTime = time.time()
    vol3 = mfxsdd.compute_volume(add_bounds=False)
    result3 = mfxsdd.compute_probability(query=query, add_bounds=False)
    endTime = time.time()
    time3 = endTime - startTime

    print(f"R1 {result1}, time1: {time1}")
    print(f"R2 {result2}, time2: {time2}")
    print(f"R3 {result3}, time3: {time3}")
    print("")
    print(f"Vol1 {vol1}, time1: {time1}")
    print(f"Vol2 {vol2}, time2: {time2}")
    print(f"Vol3 {vol3}, time3: {time3}")
    return result1, result2, time1, time2