use of edu.cmu.tetrad.util.ChoiceGenerator in project tetrad by cmu-phil.
the class FciOrient method ruleR6R7.
/**
* Implements Zhang's rules R6 and R7, applies them over the graph once.
* Orient single tails. R6: If A---Bo-*C then A---B--*C. R7: If A--oBo-*C
* and A,C nonadjacent, then A--oB--*C
*/
public void ruleR6R7(Graph graph) {
List<Node> nodes = graph.getNodes();
for (Node b : nodes) {
if (Thread.currentThread().isInterrupted()) {
break;
}
List<Node> adjacents = graph.getAdjacentNodes(b);
if (adjacents.size() < 2) {
continue;
}
ChoiceGenerator cg = new ChoiceGenerator(adjacents.size(), 2);
for (int[] choice = cg.next(); choice != null && !Thread.currentThread().isInterrupted(); choice = cg.next()) {
Node a = adjacents.get(choice[0]);
Node c = adjacents.get(choice[1]);
if (graph.isAdjacentTo(a, c)) {
continue;
}
if (!(graph.getEndpoint(b, a) == Endpoint.TAIL)) {
continue;
}
if (!(graph.getEndpoint(c, b) == Endpoint.CIRCLE)) {
continue;
}
if (graph.getEndpoint(a, b) == Endpoint.TAIL) {
// We know A---Bo-*C: R6 applies!
graph.setEndpoint(c, b, Endpoint.TAIL);
logger.log("impliedOrientations", SearchLogUtils.edgeOrientedMsg("Single tails (tail)", graph.getEdge(c, b)));
changeFlag = true;
}
if (graph.getEndpoint(a, b) == Endpoint.CIRCLE) {
// if (graph.isAdjacentTo(a, c)) continue;
logger.log("impliedOrientations", SearchLogUtils.edgeOrientedMsg("Single tails (tail)", graph.getEdge(c, b)));
// We know A--oBo-*C and A,C nonadjacent: R7 applies!
graph.setEndpoint(c, b, Endpoint.TAIL);
changeFlag = true;
}
}
}
}
use of edu.cmu.tetrad.util.ChoiceGenerator in project tetrad by cmu-phil.
the class Fges method calculateArrowsBackward.
// Calculates the arrows for the removal in the backward direction.
private void calculateArrowsBackward(Node a, Node b) {
if (existsKnowledge()) {
if (!getKnowledge().noEdgeRequired(a.getName(), b.getName())) {
return;
}
}
Set<Node> naYX = getNaYX(a, b);
List<Node> _naYX = new ArrayList<>(naYX);
final int _depth = _naYX.size();
for (int i = 0; i <= _depth; i++) {
final ChoiceGenerator gen = new ChoiceGenerator(_naYX.size(), i);
int[] choice;
while ((choice = gen.next()) != null) {
Set<Node> diff = GraphUtils.asSet(choice, _naYX);
Set<Node> h = new HashSet<>(_naYX);
h.removeAll(diff);
if (existsKnowledge()) {
if (!validSetByKnowledge(b, h)) {
continue;
}
}
double bump = deleteEval(a, b, diff, naYX, hashIndices);
if (bump > 0.0) {
addArrow(a, b, naYX, h, bump);
}
}
}
}
use of edu.cmu.tetrad.util.ChoiceGenerator in project tetrad by cmu-phil.
the class Fges method calculateArrowsForward.
// Calculates the new arrows for an a->b edge.
private void calculateArrowsForward(Node a, Node b) {
if (mode == Mode.heuristicSpeedup && !effectEdgesGraph.isAdjacentTo(a, b)) {
return;
}
if (adjacencies != null && !adjacencies.isAdjacentTo(a, b)) {
return;
}
this.neighbors.put(b, getNeighbors(b));
if (a == b) {
throw new IllegalArgumentException();
}
if (existsKnowledge()) {
if (getKnowledge().isForbidden(a.getName(), b.getName())) {
return;
}
}
Set<Node> naYX = getNaYX(a, b);
if (!isClique(naYX)) {
return;
}
List<Node> TNeighbors = getTNeighbors(a, b);
Set<Set<Node>> previousCliques = new HashSet<>();
previousCliques.add(new HashSet<Node>());
Set<Set<Node>> newCliques = new HashSet<>();
FOR: for (int i = 0; i <= TNeighbors.size(); i++) {
final ChoiceGenerator gen = new ChoiceGenerator(TNeighbors.size(), i);
int[] choice;
while ((choice = gen.next()) != null) {
Set<Node> T = GraphUtils.asSet(choice, TNeighbors);
Set<Node> union = new HashSet<>(naYX);
union.addAll(T);
boolean foundAPreviousClique = false;
for (Set<Node> clique : previousCliques) {
if (union.containsAll(clique)) {
foundAPreviousClique = true;
break;
}
}
if (!foundAPreviousClique) {
break FOR;
}
if (!isClique(union)) {
continue;
}
newCliques.add(union);
double bump = insertEval(a, b, T, naYX, hashIndices);
if (bump > 0) {
addArrow(a, b, naYX, T, bump);
}
// if (mode == Mode.heuristicSpeedup && union.isEmpty() && score.isEffectEdge(bump) &&
// !effectEdgesGraph.isAdjacentTo(a, b) && graph.getParents(b).isEmpty()) {
// effectEdgesGraph.addUndirectedEdge(a, b);
// }
}
previousCliques = newCliques;
newCliques = new HashSet<>();
}
}
use of edu.cmu.tetrad.util.ChoiceGenerator in project tetrad by cmu-phil.
the class CpcStable method orientUnshieldedTriples.
// ==========================PRIVATE METHODS===========================//
private void orientUnshieldedTriples(IKnowledge knowledge) {
TetradLogger.getInstance().log("info", "Starting Collider Orientation:");
List<Node> nodes = graph.getNodes();
for (Node y : nodes) {
List<Node> adjacentNodes = graph.getAdjacentNodes(y);
if (adjacentNodes.size() < 2) {
continue;
}
ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2);
int[] combination;
while ((combination = cg.next()) != null) {
Node x = adjacentNodes.get(combination[0]);
Node z = adjacentNodes.get(combination[1]);
if (this.graph.isAdjacentTo(x, z)) {
continue;
}
List<List<Node>> sepsetsxz = getSepsets(x, z, graph);
if (isColliderSepset(y, sepsetsxz)) {
if (colliderAllowed(x, y, z, knowledge)) {
graph.setEndpoint(x, y, Endpoint.ARROW);
graph.setEndpoint(z, y, Endpoint.ARROW);
TetradLogger.getInstance().log("colliderOrientations", SearchLogUtils.colliderOrientedMsg(x, y, z));
}
} else {
Triple triple = new Triple(x, y, z);
graph.addAmbiguousTriple(triple.getX(), triple.getY(), triple.getZ());
}
getAllTriples().add(new Triple(x, y, z));
}
}
TetradLogger.getInstance().log("info", "Finishing Collider Orientation.");
}
use of edu.cmu.tetrad.util.ChoiceGenerator in project tetrad by cmu-phil.
the class Dci method awayFromColliderAncestorCycle.
// Does all 3 of these rules at once instead of going through all
// triples multiple times per iteration of doFinalOrientation.
private void awayFromColliderAncestorCycle(Graph graph) {
List<Node> nodes = graph.getNodes();
for (Node B : nodes) {
List<Node> adj = graph.getAdjacentNodes(B);
if (adj.size() < 2) {
continue;
}
ChoiceGenerator cg = new ChoiceGenerator(adj.size(), 2);
int[] combination;
while ((combination = cg.next()) != null) {
Node A = adj.get(combination[0]);
Node C = adj.get(combination[1]);
// choice gen doesnt do diff orders, so must switch A & C around.
awayFromCollider(graph, A, B, C);
awayFromCollider(graph, C, B, A);
awayFromAncestor(graph, A, B, C);
awayFromAncestor(graph, C, B, A);
awayFromCycle(graph, A, B, C);
awayFromCycle(graph, C, B, A);
}
}
}
Aggregations