/** Orients according to background knowledge */ private void fciOrientbk(IKnowledge bk, Graph graph, List<Node> variables) { logger.log("info", "Starting BK Orientation."); for (Iterator<KnowledgeEdge> it = bk.forbiddenEdgesIterator(); it.hasNext(); ) { KnowledgeEdge edge = it.next(); // match strings to variables in the graph. Node from = SearchGraphUtils.translate(edge.getFrom(), variables); Node to = SearchGraphUtils.translate(edge.getTo(), variables); if (from == null || to == null) { continue; } if (graph.getEdge(from, to) == null) { continue; } // Orient to*->from graph.setEndpoint(to, from, Endpoint.ARROW); graph.setEndpoint(from, to, Endpoint.CIRCLE); changeFlag = true; logger.log( "knowledgeOrientation", SearchLogUtils.edgeOrientedMsg("Knowledge", graph.getEdge(from, to))); } for (Iterator<KnowledgeEdge> it = bk.requiredEdgesIterator(); it.hasNext(); ) { KnowledgeEdge edge = it.next(); // match strings to variables in this graph Node from = SearchGraphUtils.translate(edge.getFrom(), variables); Node to = SearchGraphUtils.translate(edge.getTo(), variables); if (from == null || to == null) { continue; } if (graph.getEdge(from, to) == null) { continue; } graph.setEndpoint(to, from, Endpoint.TAIL); graph.setEndpoint(from, to, Endpoint.ARROW); changeFlag = true; logger.log( "knowledgeOrientation", SearchLogUtils.edgeOrientedMsg("Knowledge", graph.getEdge(from, to))); } logger.log("info", "Finishing BK Orientation."); }
/** * Step C of PC; orients colliders using specified sepset. That is, orients x *-* y *-* z as x *-> * y <-* z just in case y is in Sepset({x, z}). */ public Map<Triple, Double> findCollidersUsingSepsets( SepsetProducer sepsetProducer, Graph graph, boolean verbose, IKnowledge knowledge) { TetradLogger.getInstance().log("details", "Starting Collider Orientation:"); Map<Triple, Double> colliders = new HashMap<>(); System.out.println("Looking for colliders"); List<Node> nodes = graph.getNodes(); for (Node b : nodes) { List<Node> adjacentNodes = graph.getAdjacentNodes(b); if (adjacentNodes.size() < 2) { continue; } ChoiceGenerator cg = new ChoiceGenerator(adjacentNodes.size(), 2); int[] combination; while ((combination = cg.next()) != null) { Node a = adjacentNodes.get(combination[0]); Node c = adjacentNodes.get(combination[1]); // Skip triples that are shielded. if (graph.isAdjacentTo(a, c)) { continue; } List<Node> sepset = sepsetProducer.getSepset(a, c); if (sepset == null) continue; // if (sepsetProducer.getPValue() < 0.5) continue; if (!sepset.contains(b)) { if (verbose) { // boolean dsep = this.dsep.isIndependent(a, c); // System.out.println("QQQ p = " + independenceTest.getPValue() + // " " + dsep); System.out.println( "\nCollider orientation <" + a + ", " + b + ", " + c + "> sepset = " + sepset); } colliders.put(new Triple(a, b, c), sepsetProducer.getPValue()); TetradLogger.getInstance() .log("colliderOrientations", SearchLogUtils.colliderOrientedMsg(a, b, c, sepset)); } } } TetradLogger.getInstance().log("details", "Finishing Collider Orientation."); System.out.println("Done finding colliders"); return colliders; }
/** Tests to see if d separation facts are symmetric. */ public void testDSeparation() { EdgeListGraphSingleConnections graph = new EdgeListGraphSingleConnections( new Dag(GraphUtils.randomGraph(7, 0, 7, 30, 15, 15, true))); System.out.println(graph); List<Node> nodes = graph.getNodes(); int depth = -1; for (int i = 0; i < nodes.size(); i++) { for (int j = i + 1; j < nodes.size(); j++) { Node x = nodes.get(i); Node y = nodes.get(j); List<Node> theRest = new ArrayList<Node>(nodes); theRest.remove(x); theRest.remove(y); DepthChoiceGenerator gen = new DepthChoiceGenerator(theRest.size(), depth); int[] choice; while ((choice = gen.next()) != null) { List<Node> z = new LinkedList<Node>(); for (int k = 0; k < choice.length; k++) { z.add(theRest.get(choice[k])); } if (graph.isDSeparatedFrom(x, y, z) != graph.isDSeparatedFrom(y, x, z)) { fail( SearchLogUtils.independenceFact(x, y, z) + " should have same d-sep result as " + SearchLogUtils.independenceFact(y, x, z)); } } } } }