private boolean missingColliders(Graph graph) { List<Triple> colliders = getUnshieldedCollidersFromGraph(graph); Graph copy = new EdgeListGraphSingleConnections(graph); new MeekRules().orientImplied(copy); if (copy.existsDirectedCycle()) return true; List<Triple> newColliders = getUnshieldedCollidersFromGraph(copy); newColliders.removeAll(colliders); if (!newColliders.isEmpty()) { return true; } return false; }
public void setParametersTemplate(String parametersTemplate) throws ParseException { if (parametersTemplate == null) { throw new NullPointerException(); } // Test to make sure it's parsable. ExpressionParser parser = new ExpressionParser(); Expression expression = parser.parseExpression(parametersTemplate); List<String> parameterNames = parser.getParameters(); if (!parameterNames.isEmpty()) { throw new IllegalArgumentException( "Initial distribution for a parameter may not " + "contain parameters: " + expression.toString()); } this.parametersTemplate = parametersTemplate; }
//////////////////////////////////////////// // RFCI Algorithm 4.4 (Colombo et al, 2012) // Orient colliders //////////////////////////////////////////// private void ruleR0_RFCI(List<Node[]> rTuples) { List<Node[]> lTuples = new ArrayList<Node[]>(); List<Node> nodes = graph.getNodes(); /////////////////////////////// // process tuples in rTuples while (!rTuples.isEmpty()) { Node[] thisTuple = rTuples.remove(0); Node i = thisTuple[0]; Node j = thisTuple[1]; Node k = thisTuple[2]; final List<Node> nodes1 = getSepset(i, k); if (nodes1 == null) continue; List<Node> sepSet = new ArrayList<Node>(nodes1); sepSet.remove(j); boolean independent1 = false; if (knowledge.noEdgeRequired(i.getName(), j.getName())) // if BK allows { try { independent1 = independenceTest.isIndependent(i, j, sepSet); } catch (Exception e) { independent1 = true; } } boolean independent2 = false; if (knowledge.noEdgeRequired(j.getName(), k.getName())) // if BK allows { try { independent2 = independenceTest.isIndependent(j, k, sepSet); } catch (Exception e) { independent2 = true; } } if (!independent1 && !independent2) { lTuples.add(thisTuple); } else { // set sepSets to minimal separating sets if (independent1) { setMinSepSet(sepSet, i, j); graph.removeEdge(i, j); } if (independent2) { setMinSepSet(sepSet, j, k); graph.removeEdge(j, k); } // add new unshielded tuples to rTuples for (Node thisNode : nodes) { List<Node> adjacentNodes = graph.getAdjacentNodes(thisNode); if (independent1) // <i, ., j> { if (adjacentNodes.contains(i) && adjacentNodes.contains(j)) { Node[] newTuple = {i, thisNode, j}; rTuples.add(newTuple); } } if (independent2) // <j, ., k> { if (adjacentNodes.contains(j) && adjacentNodes.contains(k)) { Node[] newTuple = {j, thisNode, k}; rTuples.add(newTuple); } } } // remove tuples involving either (if independent1) <i, j> // or (if independent2) <j, k> from rTuples Iterator<Node[]> iter = rTuples.iterator(); while (iter.hasNext()) { Node[] curTuple = iter.next(); if ((independent1 && (curTuple[1] == i) && ((curTuple[0] == j) || (curTuple[2] == j))) || (independent2 && (curTuple[1] == k) && ((curTuple[0] == j) || (curTuple[2] == j))) || (independent1 && (curTuple[1] == j) && ((curTuple[0] == i) || (curTuple[2] == i))) || (independent2 && (curTuple[1] == j) && ((curTuple[0] == k) || (curTuple[2] == k)))) { iter.remove(); } } // remove tuples involving either (if independent1) <i, j> // or (if independent2) <j, k> from lTuples iter = lTuples.iterator(); while (iter.hasNext()) { Node[] curTuple = iter.next(); if ((independent1 && (curTuple[1] == i) && ((curTuple[0] == j) || (curTuple[2] == j))) || (independent2 && (curTuple[1] == k) && ((curTuple[0] == j) || (curTuple[2] == j))) || (independent1 && (curTuple[1] == j) && ((curTuple[0] == i) || (curTuple[2] == i))) || (independent2 && (curTuple[1] == j) && ((curTuple[0] == k) || (curTuple[2] == k)))) { iter.remove(); } } } } /////////////////////////////////////////////////////// // orient colliders (similar to original FCI ruleR0) for (Node[] thisTuple : lTuples) { Node i = thisTuple[0]; Node j = thisTuple[1]; Node k = thisTuple[2]; List<Node> sepset = getSepset(i, k); if (sepset == null) { continue; } if (!sepset.contains(j) && graph.isAdjacentTo(i, j) && graph.isAdjacentTo(j, k)) { if (!isArrowpointAllowed(i, j)) { continue; } if (!isArrowpointAllowed(k, j)) { continue; } graph.setEndpoint(i, j, Endpoint.ARROW); graph.setEndpoint(k, j, Endpoint.ARROW); printWrongColliderMessage(i, j, k, "R0_RFCI"); } } }
// Finds clusters of size 4 or higher. private Set<Set<Integer>> findPureClusters( List<Integer> _variables, Map<Node, Set<Node>> adjacencies) { // System.out.println("Original variables = " + variables); Set<Set<Integer>> clusters = new HashSet<Set<Integer>>(); List<Integer> allVariables = new ArrayList<Integer>(); for (int i = 0; i < this.variables.size(); i++) allVariables.add(i); VARIABLES: while (!_variables.isEmpty()) { if (_variables.size() < 4) break; for (int x : _variables) { Node nodeX = variables.get(x); List<Node> adjX = new ArrayList<Node>(adjacencies.get(nodeX)); adjX.retainAll(variablesForIndices(new ArrayList<Integer>(_variables))); for (Node node : new ArrayList<Node>(adjX)) { if (adjacencies.get(node).size() < 3) { adjX.remove(node); } } if (adjX.size() < 3) { continue; } ChoiceGenerator gen = new ChoiceGenerator(adjX.size(), 3); int[] choice; while ((choice = gen.next()) != null) { Node nodeY = adjX.get(choice[0]); Node nodeZ = adjX.get(choice[1]); Node nodeW = adjX.get(choice[2]); int y = variables.indexOf(nodeY); int w = variables.indexOf(nodeW); int z = variables.indexOf(nodeZ); Set<Integer> cluster = quartet(x, y, z, w); if (!clique(cluster, adjacencies)) { continue; } // Note that purity needs to be assessed with respect to all of the variables in order to // remove all latent-measure impurities between pairs of latents. if (pure(cluster, allVariables)) { // Collections.shuffle(_variables); O: for (int o : _variables) { if (cluster.contains(o)) continue; cluster.add(o); List<Integer> _cluster = new ArrayList<Integer>(cluster); if (!clique(cluster, adjacencies)) { cluster.remove(o); continue O; } // if (!allVariablesDependent(cluster)) { // cluster.remove(o); // continue O; // } ChoiceGenerator gen2 = new ChoiceGenerator(_cluster.size(), 4); int[] choice2; int count = 0; while ((choice2 = gen2.next()) != null) { int x2 = _cluster.get(choice2[0]); int y2 = _cluster.get(choice2[1]); int z2 = _cluster.get(choice2[2]); int w2 = _cluster.get(choice2[3]); Set<Integer> quartet = quartet(x2, y2, z2, w2); // Optimizes for large clusters. if (quartet.contains(o)) { if (++count > 50) continue O; } if (quartet.contains(o) && !pure(quartet, allVariables)) { cluster.remove(o); continue O; } } } System.out.println( "Cluster found: " + variablesForIndices(new ArrayList<Integer>(cluster))); clusters.add(cluster); _variables.removeAll(cluster); continue VARIABLES; } } } break; } return clusters; }