/*******************************************************************************
* Copyright 2014 Felipe Takiyama
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package br.usp.poli.takiyama.utils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import br.usp.poli.takiyama.acfove.AggParfactor;
import br.usp.poli.takiyama.acfove.AggParfactor.AggParfactorBuilder;
import br.usp.poli.takiyama.acfove.ConvertToStdParfactors;
import br.usp.poli.takiyama.acfove.MacroOperation;
import br.usp.poli.takiyama.acfove.Propositionalize;
import br.usp.poli.takiyama.cfove.StdParfactor.StdParfactorBuilder;
import br.usp.poli.takiyama.common.Factor;
import br.usp.poli.takiyama.common.Marginal;
import br.usp.poli.takiyama.common.Parfactor;
import br.usp.poli.takiyama.common.StdFactor;
import br.usp.poli.takiyama.common.StdMarginal.StdMarginalBuilder;
import br.usp.poli.takiyama.prv.And;
import br.usp.poli.takiyama.prv.Constant;
import br.usp.poli.takiyama.prv.CountingFormula;
import br.usp.poli.takiyama.prv.LogicalVariable;
import br.usp.poli.takiyama.prv.Or;
import br.usp.poli.takiyama.prv.Prv;
import br.usp.poli.takiyama.prv.RandomVariableSet;
import br.usp.poli.takiyama.prv.StdLogicalVariable;
import br.usp.poli.takiyama.prv.StdPrv;
import br.usp.poli.takiyama.prv.Term;
import br.usp.poli.takiyama.prv.Xor;
/**
* Stores parfactors, logical variables, parameterized random variables (PRV)
* and other data structures used in AC-FOVE tests.
*
* @author ftakiyama
*
*/
public class Example {
private final Map<String, LogicalVariable> logicalVariable;
private final Map<String, Prv> parameterizedRandomVariable;
private final Map<String, Factor> factor;
private final Map<String, Parfactor> parfactor;
private Parfactor expected;
private Example() {
logicalVariable = new LinkedHashMap<String, LogicalVariable>();
parameterizedRandomVariable = new LinkedHashMap<String, Prv>();
factor = new LinkedHashMap<String, Factor>();
parfactor = new LinkedHashMap<String, Parfactor>();
expected = null;
}
// Setters
private LogicalVariable putLogicalVariable(String name, String prefix, int populationSize) {
LogicalVariable lv = StdLogicalVariable.getInstance(name, prefix, populationSize);
logicalVariable.put(name, lv);
return lv;
}
private Prv putPrv(String name, Term ... parameters) {
Prv prv = StdPrv.getBooleanInstance(name, parameters);
parameterizedRandomVariable.put(prv.toString(), prv);
return prv;
}
private Prv putCountingFormula(LogicalVariable bound, Prv counted) {
Prv cf = CountingFormula.getInstance(bound, counted);
String name = "#." + bound.value() + " " + counted.name();
parameterizedRandomVariable.put(name, cf);
return cf;
}
private Parfactor putParfactor(String name, Parfactor parfactor) {
this.parfactor.put(name, parfactor);
return parfactor;
}
private Parfactor putExpected(Parfactor e) {
this.expected = e;
return e;
}
private Factor putFactor(String name, List<Prv> prvs, List<BigDecimal> values) {
Factor f = StdFactor.getInstance(name, prvs, values);
factor.put(name, f);
return f;
}
private Factor putFactor(String name, Factor f) {
factor.put(name, f);
return f;
}
// Getters
public LogicalVariable lv(String name) throws NoSuchElementException {
if (logicalVariable.containsKey(name)) {
return logicalVariable.get(name);
} else {
throw new NoSuchElementException();
}
}
public Prv prv(String name) throws NoSuchElementException {
if (parameterizedRandomVariable.containsKey(name)) {
return parameterizedRandomVariable.get(name);
} else {
throw new NoSuchElementException();
}
}
public Set<Prv> allPrvs() {
return new HashSet<Prv>(parameterizedRandomVariable.values());
}
public Parfactor parfactor(String name) throws NoSuchElementException {
if (parfactor.containsKey(name)) {
return parfactor.get(name);
} else {
throw new NoSuchElementException();
}
}
public Parfactor expected() {
return expected;
}
public Factor factor(String name) throws NoSuchElementException {
if (factor.containsKey(name)) {
return factor.get(name);
} else {
throw new NoSuchElementException();
}
}
public Set<Factor> allFactors() {
return new HashSet<Factor>(factor.values());
}
public Marginal marginal(RandomVariableSet query) {
int capacity = parfactor.size();
Set<Parfactor> p = new HashSet<Parfactor>(parfactor.values());
Marginal marginal = new StdMarginalBuilder(capacity).parfactors(p)
.preservable(query).build();
return marginal;
}
/**
* Returns data structures corresponding to CRALC expression ∃r.b(X).
*
* @param domainSize The number of individuals of X.
* @return data structures corresponding to CRALC expression ∃r.b(X).
*/
public static Example existsNetwork(int domainSize) {
Example network = new Example();
LogicalVariable x = network.putLogicalVariable("X", "x", domainSize);
LogicalVariable y = network.putLogicalVariable("Y", "y", domainSize);
Prv b = network.putPrv("b", y);
Prv r = network.putPrv("r", x, y);
Prv a = network.putPrv("and", x, y);
Prv e = network.putPrv("exists", x);
Prv ex = network.putCountingFormula(x, e);
List<BigDecimal> fb = TestUtils.toBigDecimalList(0.1, 0.9);
List<BigDecimal> fr = TestUtils.toBigDecimalList(0.2, 0.8);
List<BigDecimal> fand = TestUtils.toBigDecimalList(1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0);
List<BigDecimal> fexp = new ArrayList<BigDecimal>();
// populates fexp
BigDecimal vFalse = BigDecimal.valueOf(0.28).pow(domainSize, MathUtils.CONTEXT);
BigDecimal vTrue = BigDecimal.ONE.subtract(vFalse, MathUtils.CONTEXT);
for (int n = domainSize; n >= 0; n--) {
fexp.add(vFalse.pow(n, MathUtils.CONTEXT).multiply(vTrue.pow(domainSize - n, MathUtils.CONTEXT), MathUtils.CONTEXT));
}
Parfactor g1 = new StdParfactorBuilder().variables(b).values(fb).build();
Parfactor g2 = new StdParfactorBuilder().variables(r).values(fr).build();
Parfactor g3 = new StdParfactorBuilder().variables(r, b, a).values(fand).build();
Parfactor g4 = new AggParfactorBuilder(a, e, Or.OR).context(b).build();
Parfactor g5 = new StdParfactorBuilder().variables(ex).values(fexp).build();
network.putParfactor("gb", g1);
network.putParfactor("gr", g2);
network.putParfactor("gand", g3);
network.putParfactor("gexists", g4);
network.putExpected(g5);
return network;
}
/**
* Returns data structures corresponding to CRALC expression ∃r.b(X).
* The network is propositionalized.
*
* @param domainSize The number of individuals of X.
* @return data structures corresponding to CRALC expression ∃r.b(X).
*/
public static Example existsNetworkPropositionalized(int domainSize) {
// List of constants
List<Constant> x = new ArrayList<Constant>(domainSize);
List<Constant> y = new ArrayList<Constant>(domainSize);
for (int i = 0; i < domainSize; i++) {
x.add(Constant.getInstance("x" + i));
y.add(Constant.getInstance("y" + i));
}
Example network = new Example();
// Creates random variables
for (int i = 0; i < domainSize; i++) {
network.putPrv("b", y.get(i));
network.putPrv("exists", x.get(i));
for (int j = 0; j < domainSize; j++) {
network.putPrv("r", x.get(i), y.get(j));
network.putPrv("and", x.get(i), y.get(j));
}
}
// Creates factors on b(Y)
List<BigDecimal> vb = TestUtils.toBigDecimalList(0.1, 0.9);
for (int i = 0; i < domainSize; i++) {
String b = "b ( " + y.get(i) + " )";
List<Prv> rvs = Lists.listOf(network.prv(b));
network.putFactor(b, rvs, vb);
}
// Creates factors on r(X,Y)
List<BigDecimal> vr = TestUtils.toBigDecimalList(0.2, 0.8);
for (int i = 0; i < domainSize; i++) {
for (int j = 0; j < domainSize; j++) {
String r = "r ( " + x.get(i) + " " + y.get(j) + " )";
List<Prv> rvs = Lists.listOf(network.prv(r));
network.putFactor(r, rvs, vr);
}
}
// Creates factors on r(X,Y), b(Y), and(X,Y)
List<BigDecimal> vand = TestUtils.toBigDecimalList(1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0);
for (int i = 0; i < domainSize; i++) {
for (int j = 0; j < domainSize; j++) {
String b = "b ( " + y.get(j) + " )";
String r = "r ( " + x.get(i) + " " + y.get(j) + " )";
String and = "and ( " + x.get(i) + " " + y.get(j) + " )";
List<Prv> rvs = Lists.listOf(network.prv(b), network.prv(r), network.prv(and));
network.putFactor(and, rvs, vand);
}
}
// Creates factors on and(X,y1), ..., and(X,yn), exists(X)
int vexistsSize = (int) Math.pow(2, domainSize);
List<BigDecimal> vexists = new ArrayList<BigDecimal>(vexistsSize);
for (int i = 0; i < vexistsSize; i++) {
vexists.add(BigDecimal.ZERO);
vexists.add(BigDecimal.ONE);
}
vexists.set(0, BigDecimal.ONE);
vexists.set(1, BigDecimal.ZERO);
for (int i = 0; i < domainSize; i++) {
List<Prv> rvs = new ArrayList<Prv>(domainSize + 1);
for (int j = 0; j < domainSize; j++) {
String and = "and ( " + x.get(i) + " " + y.get(j) + " )";
rvs.add(network.prv(and));
}
String exists = "exists ( " + x.get(i) + " )";
rvs.add(network.prv(exists));
network.putFactor(exists, rvs, vexists);
}
return network;
}
/**
* Returns data structures corresponding to CRALC expression ∃r.b(X).
* It uses b(X) instead of b(Y) to test if context variables can be
* parameterized by the extra logical variable.
*
* @param domainSize The number of individuals of X.
* @return data structures corresponding to CRALC expression ∃r.b(X).
*/
public static Example existsNetworkWithBX(int domainSize) {
Example network = new Example();
LogicalVariable x = network.putLogicalVariable("X", "x", domainSize);
LogicalVariable y = network.putLogicalVariable("Y", "y", domainSize);
Prv b = network.putPrv("b", x);
Prv r = network.putPrv("r", x, y);
Prv a = network.putPrv("and", x, y);
Prv e = network.putPrv("exists", x);
List<BigDecimal> fb = TestUtils.toBigDecimalList(0.1, 0.9);
List<BigDecimal> fr = TestUtils.toBigDecimalList(0.2, 0.8);
List<BigDecimal> fand = TestUtils.toBigDecimalList(1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0);
Parfactor g1 = new StdParfactorBuilder().variables(b).values(fb).build();
Parfactor g2 = new StdParfactorBuilder().variables(r).values(fr).build();
Parfactor g3 = new StdParfactorBuilder().variables(r, b, a).values(fand).build();
Parfactor g4 = new AggParfactorBuilder(a, e, Or.OR).context(b).build();
network.putParfactor("gb", g1);
network.putParfactor("gr", g2);
network.putParfactor("gand", g3);
network.putParfactor("gexists", g4);
return network;
}
/**
* Returns data structures corresponding to CRALC expression ∃r.b(X).
* The network is propositionalized.
* It uses b(X) instead of b(Y) to test if context variables can be
* parameterized by the extra logical variable.
*
* @param domainSize The number of individuals of X.
* @return data structures corresponding to CRALC expression ∃r.b(X).
*/
public static Example existsNetworkPropositionalizedWithBX(int domainSize) {
// List of constants
List<Constant> x = new ArrayList<Constant>(domainSize);
List<Constant> y = new ArrayList<Constant>(domainSize);
for (int i = 0; i < domainSize; i++) {
x.add(Constant.getInstance("x" + i));
y.add(Constant.getInstance("y" + i));
}
Example network = new Example();
// Creates random variables
for (int i = 0; i < domainSize; i++) {
network.putPrv("b", x.get(i));
network.putPrv("exists", x.get(i));
for (int j = 0; j < domainSize; j++) {
network.putPrv("r", x.get(i), y.get(j));
network.putPrv("and", x.get(i), y.get(j));
}
}
// Creates factors on b(X)
List<BigDecimal> vb = TestUtils.toBigDecimalList(0.1, 0.9);
for (int i = 0; i < domainSize; i++) {
String b = "b ( " + x.get(i) + " )";
List<Prv> rvs = Lists.listOf(network.prv(b));
network.putFactor(b, rvs, vb);
}
// Creates factors on r(X,Y)
List<BigDecimal> vr = TestUtils.toBigDecimalList(0.2, 0.8);
for (int i = 0; i < domainSize; i++) {
for (int j = 0; j < domainSize; j++) {
String r = "r ( " + x.get(i) + " " + y.get(j) + " )";
List<Prv> rvs = Lists.listOf(network.prv(r));
network.putFactor(r, rvs, vr);
}
}
// Creates factors on r(X,Y), b(X), and(X,Y)
List<BigDecimal> vand = TestUtils.toBigDecimalList(1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0);
for (int i = 0; i < domainSize; i++) {
for (int j = 0; j < domainSize; j++) {
String b = "b ( " + x.get(i) + " )";
String r = "r ( " + x.get(i) + " " + y.get(j) + " )";
String and = "and ( " + x.get(i) + " " + y.get(j) + " )";
List<Prv> rvs = Lists.listOf(network.prv(b), network.prv(r), network.prv(and));
network.putFactor(and, rvs, vand);
}
}
// Creates factors on and(X,y1), ..., and(X,yn), exists(X)
int vexistsSize = (int) Math.pow(2, domainSize);
List<BigDecimal> vexists = new ArrayList<BigDecimal>(vexistsSize);
for (int i = 0; i < vexistsSize; i++) {
vexists.add(BigDecimal.ZERO);
vexists.add(BigDecimal.ONE);
}
vexists.set(0, BigDecimal.ONE);
vexists.set(1, BigDecimal.ZERO);
for (int i = 0; i < domainSize; i++) {
List<Prv> rvs = new ArrayList<Prv>(domainSize + 1);
for (int j = 0; j < domainSize; j++) {
String and = "and ( " + x.get(i) + " " + y.get(j) + " )";
rvs.add(network.prv(and));
}
String exists = "exists ( " + x.get(i) + " )";
rvs.add(network.prv(exists));
network.putFactor(exists, rvs, vexists);
}
return network;
}
/**
* Returns data structures corresponding to CRALC expression ∃r.b(X).
* It uses b(Y) and r(X,Y) as context variables.
*
* @param domainSize The number of individuals of X.
* @return data structures corresponding to CRALC expression ∃r.b(X).
*/
public static Example existsNetworkWithMultipleContext(int domainSize) {
Example network = Example.existsNetwork(domainSize);
Prv b = network.prv("b ( Y )");
Prv r = network.prv("r ( X Y )");
Prv a = network.prv("and ( X Y )");
Prv e = network.prv("exists ( X )");
Parfactor g4 = new AggParfactorBuilder(a, e, Or.OR).context(b, r).build();
network.putParfactor("gexists", g4);
return network;
}
/**
* Returns data structures corresponding to example 3.14 of Kisynski (2010)
*
* @param domainSize The number of individuals in logical variable Person.
* @return data structures corresponding to example 3.14 of Kisynski (2010)
*/
public static Example bigJackpotNetwork(int domainSize) {
Example network = new Example();
LogicalVariable person = network.putLogicalVariable("Person", "x", domainSize);
Prv big_jackpot = network.putPrv("big_jackpot");
Prv played = network.putPrv("played", person);
Prv matched_6 = network.putPrv("matched_6", person);
Prv jackpot_won = network.putPrv("jackpot_won");
List<BigDecimal> fBigJackpot = TestUtils.toBigDecimalList(0.8, 0.2);
List<BigDecimal> fPlayed = TestUtils.toBigDecimalList(0.95, 0.05, 0.85, 0.15);
List<BigDecimal> fMatched6 = TestUtils.toBigDecimalList(1.0, 0.0, 0.99999993, 0.00000007);
Parfactor g1 = new StdParfactorBuilder().variables(big_jackpot).values(fBigJackpot).build();
Parfactor g2 = new StdParfactorBuilder().variables(big_jackpot, played).values(fPlayed).build();
Parfactor g3 = new StdParfactorBuilder().variables(played, matched_6).values(fMatched6).build();
Parfactor g4 = new AggParfactorBuilder(matched_6, jackpot_won, Or.OR).context(big_jackpot).build();
Parfactor g2xg3 = g2.multiply(g3);
Parfactor afterEliminatingPlayed = g2xg3.sumOut(played);
Parfactor g4xg5 = g4.multiply(afterEliminatingPlayed);
Parfactor afterEliminatingMatched6 = g4xg5.sumOut(matched_6);
Parfactor g6xg1 = g1.multiply(afterEliminatingMatched6);
Parfactor afterEliminatingBigJackpot = g6xg1.sumOut(big_jackpot);
network.putParfactor("gbigjackpot", g1);
network.putParfactor("gplayed", g2);
network.putParfactor("gmatched6", g3);
network.putParfactor("gjackpotwon", g4);
network.putExpected(afterEliminatingBigJackpot);
return network;
}
/**
* Returns data structures corresponding to example 3.14 of Kisynski (2010),
* without using context variables (generalized aggregation parfactors)
*
* @param domainSize The number of individuals in logical variable Person.
* @return data structures corresponding to example 3.14 of Kisynski (2010)
*/
public static Example bigJackpotNetworkNoContext(int domainSize) {
Example network = new Example();
LogicalVariable person = network.putLogicalVariable("Person", "x", domainSize);
Prv big_jackpot = network.putPrv("big_jackpot");
Prv played = network.putPrv("played", person);
Prv matched_6 = network.putPrv("matched_6", person);
Prv jackpot_won = network.putPrv("jackpot_won");
List<BigDecimal> fBigJackpot = TestUtils.toBigDecimalList(0.8, 0.2);
List<BigDecimal> fPlayed = TestUtils.toBigDecimalList(0.95, 0.05, 0.85, 0.15);
List<BigDecimal> fMatched6 = TestUtils.toBigDecimalList(1.0, 0.0, 0.99999993, 0.00000007);
Parfactor g1 = new StdParfactorBuilder().variables(big_jackpot).values(fBigJackpot).build();
Parfactor g2 = new StdParfactorBuilder().variables(big_jackpot, played).values(fPlayed).build();
Parfactor g3 = new StdParfactorBuilder().variables(played, matched_6).values(fMatched6).build();
Parfactor g4 = new AggParfactorBuilder(matched_6, jackpot_won, Or.OR).build();
network.putParfactor("gbigjackpot", g1);
network.putParfactor("gplayed", g2);
network.putParfactor("gmatched6", g3);
network.putParfactor("gjackpotwon", g4);
Example correct = Example.bigJackpotNetwork(domainSize);
network.putExpected(correct.expected());
return network;
}
/**
* Water sprinkler network proposed by Kevin Murphy. The network was
* adapted to a lifted version: sprinkler and wet_grass are random
* variables parameterized on a logical variable Lot.
*
* The original network is shown here:
* http://www.cs.ubc.ca/~murphyk/Bayes/bnintro.html
*
* The number of nodes in this network is 2 * (domainSize + 1)
*
* @param domainSize
* @return
*/
public static Example waterSprinklerNetWork(int domainSize) {
Example network = new Example();
LogicalVariable lot = network.putLogicalVariable("Lot", "lot", domainSize);
Prv cloudy = network.putPrv("cloudy");
Prv rain = network.putPrv("rain");
Prv sprinkler = network.putPrv("sprinkler", lot);
Prv wetGrass = network.putPrv("wet_grass", lot);
List<BigDecimal> fCloudy = TestUtils.toBigDecimalList(0.5, 0.5);
List<BigDecimal> fRain = TestUtils.toBigDecimalList(0.8, 0.2, 0.2, 0.8);
List<BigDecimal> fSprinkler = TestUtils.toBigDecimalList(0.5, 0.5, 0.9, 0.1);
List<BigDecimal> fWetGrass = TestUtils.toBigDecimalList(1.0, 0.0, 0.1, 0.9, 0.1, 0.9, 0.01, 0.99);
Parfactor g1 = new StdParfactorBuilder().variables(cloudy).values(fCloudy).build();
Parfactor g2 = new StdParfactorBuilder().variables(cloudy, rain).values(fRain).build();
Parfactor g3 = new StdParfactorBuilder().variables(cloudy, sprinkler).values(fSprinkler).build();
Parfactor g4 = new StdParfactorBuilder().variables(sprinkler, rain, wetGrass).values(fWetGrass).build();
network.putParfactor("gcloudy", g1);
network.putParfactor("grain", g2);
network.putParfactor("gsprinkler", g3);
network.putParfactor("gwetgrass", g4);
network.putFactor("fcloudy", g1.factor());
network.putFactor("frain", g2.factor());
network.putFactor("fsprinkler", g3.factor());
network.putFactor("fwetgrass", g4.factor());
return network;
}
/**
* The Sick and Death network used as example by Rodrigo de Salvo Braz in
* his IJCAI-05 paper. The network has been adapted to use aggregation
* parfactors by adding a 'someDeath' node. It also uses a directed graph
* to represent cause/consequence relations (the original is a Markov
* network).
* <p>
* The number of nodes in this network is 2 * (domainSize + 1)
* </p>
*
* @param domainSize
* @return
*/
public static Example sickDeathNetwork(int domainSize) {
Example network = new Example();
LogicalVariable person = network.putLogicalVariable("Person", "person", domainSize);
Prv epidemic = network.putPrv("epidemic");
Prv sick = network.putPrv("sick", person);
Prv death = network.putPrv("death", person);
Prv someDeath = network.putPrv("someDeath");
List<BigDecimal> fEpidemic = TestUtils.toBigDecimalList(0.45, 0.55);
List<BigDecimal> fSick = TestUtils.toBigDecimalList(0.9, 0.1, 0.3, 0.7);
List<BigDecimal> fDeath = TestUtils.toBigDecimalList(1, 0, 0.45, 0.55);
Parfactor g1 = new StdParfactorBuilder().variables(epidemic).values(fEpidemic).build();
Parfactor g2 = new StdParfactorBuilder().variables(epidemic, sick).values(fSick).build();
Parfactor g3 = new StdParfactorBuilder().variables(sick, death).values(fDeath).build();
Parfactor g4 = new AggParfactorBuilder(death, someDeath, Or.OR).context(epidemic).build();
network.putParfactor("gepidemic", g1);
network.putParfactor("gsick", g2);
network.putParfactor("gdeath", g3);
network.putParfactor("gsomedeath", g4);
return network;
}
public static Example competingWorkshopsNetwork(int numberOfWorkshops, int numberOfPeople) {
Example network = new Example();
LogicalVariable workshop = network.putLogicalVariable("Workshop", "w", numberOfWorkshops);
LogicalVariable person = network.putLogicalVariable("Person", "p", numberOfPeople);
Prv hot = network.putPrv("hot", workshop);
Prv attends = network.putPrv("attends", person);
Prv success = network.putPrv("success");
List<BigDecimal> fHot = TestUtils.toBigDecimalList(0.3, 0.7);
Parfactor g1 = new StdParfactorBuilder().variables(hot).values(fHot).build();
Parfactor g2 = new AggParfactorBuilder(hot, attends, Xor.XOR).build();
Parfactor g3 = new AggParfactorBuilder(attends, success, And.AND).build();
network.putParfactor("ghot", g1);
network.putParfactor("gattends", g2);
network.putParfactor("gsuccess", g3);
return network;
}
/**
* Returns a marginal containing all parfactors in this network and the
* specified query.
* @param query The query in the marginal
* @return A marginal containing all parfactors in this network and the
* specified query.
*/
public Marginal getMarginal(RandomVariableSet query) {
Set<Parfactor> parfactors = new HashSet<Parfactor>(this.parfactor.values());
return new StdMarginalBuilder().parfactors(parfactors).preservable(query).build();
}
/**
* Returns the specified network completely propositionalized. The resulting
* network can be used with VE algorithms.
* <p>
* The resulting network will not have logical variables and factors (space
* constraint).
* </p>
*
* @param network The network to propositionalize.
* @return the specified network completely propositionalized.
*/
public Marginal propositionalizeAll(Marginal marginal) {
Set<LogicalVariable> logicalVariables = new HashSet<LogicalVariable>();
// get all logical variables and builds list of parfactors
for (Parfactor parfactor : marginal) {
logicalVariables.addAll(parfactor.logicalVariables());
}
// Auxiliary set of parfactors
Set<Parfactor> parfactors = marginal.distribution().toSet();
for (LogicalVariable lv : logicalVariables) {
// propositionalizes all parfactors in the set containing the current logical variable
for (Parfactor parfactor : parfactors) {
if (parfactor.logicalVariables().contains(lv)) {
MacroOperation propositionalize = new Propositionalize(marginal, parfactor, lv);
marginal = propositionalize.run();
}
}
// updates the set of parfactors
parfactors = marginal.distribution().toSet();
}
return marginal;
}
/**
* Returns the specified network with aggregation parfactors converted to
* standard parfactors. The resulting network can be used with the C-FOVE
* algorithm.
*
* @param network The network where aggregation parfactors will be converted
* @return The specified network with aggregation parfactors converted to
* standard parfactors.
*/
public Marginal removeAggregation(Marginal marginal) {
for (Parfactor parfactor : marginal) {
if (parfactor instanceof AggParfactor) {
MacroOperation convert = new ConvertToStdParfactors(marginal, parfactor);
marginal = convert.run();
}
}
return marginal;
}
}