private Graph changeLatentNames(Graph full, Clusters measurements, List<String> latentVarList) { Graph g2 = null; try { g2 = (Graph) new MarshalledObject(full).get(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } for (int i = 0; i < measurements.getNumClusters(); i++) { List<String> d = measurements.getCluster(i); String latentName = latentVarList.get(i); for (Node node : full.getNodes()) { if (!(node.getNodeType() == NodeType.LATENT)) { continue; } List<Node> _children = full.getChildren(node); _children.removeAll(ReidentifyVariables.getLatents(full)); List<String> childNames = getNames(_children); if (new HashSet<String>(childNames).equals(new HashSet<String>(d))) { g2.getNode(node.getName()).setName(latentName); } } } return g2; }
// Quartets first , then triples. private Set<Set<Integer>> estimateClustersSAG() { Map<Node, Set<Node>> adjacencies; if (depth == -2) { adjacencies = new HashMap<Node, Set<Node>>(); for (Node node : variables) { HashSet<Node> _nodes = new HashSet<Node>(variables); _nodes.remove(node); adjacencies.put(node, _nodes); } } else { System.out.println("Running PC adjacency search..."); Graph graph = new EdgeListGraph(variables); Fas fas = new Fas(graph, indTest); fas.setDepth(depth); // 1? adjacencies = fas.searchMapOnly(); System.out.println("...done."); } List<Integer> _variables = new ArrayList<Integer>(); for (int i = 0; i < variables.size(); i++) _variables.add(i); Set<Set<Integer>> pureClusters = findPureClusters(_variables, adjacencies); for (Set<Integer> cluster : pureClusters) _variables.removeAll(cluster); Set<Set<Integer>> mixedClusters = findMixedClusters(_variables, unionPure(pureClusters), adjacencies); Set<Set<Integer>> allClusters = new HashSet<Set<Integer>>(pureClusters); allClusters.addAll(mixedClusters); return allClusters; }
private boolean localMarkovIndep(Node x, Node y, Graph pattern, IndependenceTest test) { List<Node> future = pattern.getDescendants(Collections.singletonList(x)); List<Node> boundary = pattern.getAdjacentNodes(x); boundary.removeAll(future); List<Node> closure = new ArrayList<>(boundary); closure.add(x); closure.remove(y); if (future.contains(y) || boundary.contains(y)) return false; return test.isIndependent(x, y, boundary); }
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; }
/** @return the list of edges not in any tier. */ public final List<String> getVariablesNotInTiers() { List<MyNode> notInTier = new ArrayList<>(myNodes); for (Set<MyNode> tier : tierSpecs) { if (tier == null) tier = new HashSet<>(); notInTier.removeAll(tier); } List<String> names = new ArrayList<>(); for (MyNode MyNode : notInTier) names.add(MyNode.getName()); return names; }
/** Test if the candidate deletion is a valid operation (Theorem 17 from Chickering, 2002). */ private static boolean validDelete(List<Node> h, List<Node> naXY, Graph graph) { List<Node> list = new ArrayList<Node>(naXY); list.removeAll(h); return isClique(list, graph); }
public void setNodeExpression(Node node, String expressionString) throws ParseException { if (node == null) { throw new NullPointerException("Node was null."); } if (expressionString == null) { // return; throw new NullPointerException("Expression string was null."); } // Parse the expression. This could throw an ParseException, but that exception needs to handed // up the // chain, because the interface will need it. ExpressionParser parser = new ExpressionParser(); Expression expression = parser.parseExpression(expressionString); List<String> parameterNames = parser.getParameters(); // Make a list of parent names. List<Node> parents = this.graph.getParents(node); List<String> parentNames = new LinkedList<>(); for (Node parent : parents) { parentNames.add(parent.getName()); } // List<String> _params = new ArrayList<String>(parameterNames); // _params.retainAll(variableNames); // _params.removeAll(parentNames); // // if (!_params.isEmpty()) { // throw new IllegalArgumentException("Conditioning on a variable other than the // parents: " + node); // } // Make a list of parameter names, by removing from the parser's list of freeParameters any that // correspond // to parent variables. If there are any variable names (including error terms) that are not // among the list of // parents, that's a time to throw an exception. We must respect the graph! (We will not // complain if any parents // are missing.) parameterNames.removeAll(variableNames); for (Node variable : nodes) { if (parameterNames.contains(variable.getName())) { parameterNames.remove(variable.getName()); // throw new IllegalArgumentException("The list of parameter names may not // include variables: " + variable.getName()); } } // Remove old parameter references. List<String> parametersToRemove = new LinkedList<>(); for (String parameter : this.referencedParameters.keySet()) { Set<Node> nodes = this.referencedParameters.get(parameter); if (nodes.contains(node)) { nodes.remove(node); } if (nodes.isEmpty()) { parametersToRemove.add(parameter); } } for (String parameter : parametersToRemove) { this.referencedParameters.remove(parameter); this.parameterExpressions.remove(parameter); this.parameterExpressionStrings.remove(parameter); this.parameterEstimationInitializationExpressions.remove(parameter); this.parameterEstimationInitializationExpressionStrings.remove(parameter); } // Add new parameter references. for (String parameter : parameterNames) { if (this.referencedParameters.get(parameter) == null) { this.referencedParameters.put(parameter, new HashSet<Node>()); } Set<Node> nodes = this.referencedParameters.get(parameter); nodes.add(node); setSuitableParameterDistribution(parameter); } // Remove old node references. List<Node> nodesToRemove = new LinkedList<>(); for (Node _node : this.referencedNodes.keySet()) { Set<Node> nodes = this.referencedNodes.get(_node); if (nodes.contains(node)) { nodes.remove(node); } if (nodes.isEmpty()) { nodesToRemove.add(_node); } } for (Node _node : nodesToRemove) { this.referencedNodes.remove(_node); } // Add new freeParameters. for (String variableString : variableNames) { Node _node = getNode(variableString); if (this.referencedNodes.get(_node) == null) { this.referencedNodes.put(_node, new HashSet<Node>()); } for (String s : parentNames) { if (s.equals(variableString)) { Set<Node> nodes = this.referencedNodes.get(_node); nodes.add(node); } } } // Finally, save the parsed expression and the original string that the user entered. No need to // annoy // the user by changing spacing. nodeExpressions.put(node, expression); nodeExpressionStrings.put(node, expressionString); }
// Finds clusters of size 3. private Set<Set<Integer>> findMixedClusters( List<Integer> remaining, Set<Integer> unionPure, Map<Node, Set<Node>> adjacencies) { Set<Set<Integer>> threeClusters = new HashSet<Set<Integer>>(); if (unionPure.isEmpty()) { return new HashSet<Set<Integer>>(); } REMAINING: while (true) { if (remaining.size() < 3) break; ChoiceGenerator gen = new ChoiceGenerator(remaining.size(), 3); int[] choice; while ((choice = gen.next()) != null) { int y = remaining.get(choice[0]); int z = remaining.get(choice[1]); int w = remaining.get(choice[2]); Set<Integer> cluster = new HashSet<Integer>(); cluster.add(y); cluster.add(z); cluster.add(w); // if (!allVariablesDependent(cluster)) { // continue; // } if (!clique(cluster, adjacencies)) { continue; } // Check all x as a cross check; really only one should be necessary. boolean allX = true; for (int x : unionPure) { Set<Integer> _cluster = new HashSet<Integer>(cluster); _cluster.add(x); if (!quartetVanishes(_cluster) || !significant(new ArrayList<Integer>(_cluster))) { allX = false; break; } } if (allX) { threeClusters.add(cluster); unionPure.addAll(cluster); remaining.removeAll(cluster); System.out.println( "3-cluster found: " + variablesForIndices(new ArrayList<Integer>(cluster))); continue REMAINING; } } break; } return threeClusters; }
// Trying to optimize the search for 4-cliques a bit. private Set<Set<Integer>> findPureClusters2( 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>(); Set<Node> foundVariables = new HashSet<Node>(); for (int i = 0; i < this.variables.size(); i++) allVariables.add(i); for (int x : _variables) { Node nodeX = variables.get(x); if (foundVariables.contains(nodeX)) continue; List<Node> adjX = new ArrayList<Node>(adjacencies.get(nodeX)); adjX.removeAll(foundVariables); if (adjX.size() < 3) continue; for (Node nodeY : adjX) { if (foundVariables.contains(nodeY)) continue; List<Node> commonXY = new ArrayList<Node>(adjacencies.get(nodeY)); commonXY.retainAll(adjX); commonXY.removeAll(foundVariables); for (Node nodeZ : commonXY) { if (foundVariables.contains(nodeZ)) continue; List<Node> commonXZ = new ArrayList<Node>(commonXY); commonXZ.retainAll(adjacencies.get(nodeZ)); commonXZ.removeAll(foundVariables); for (Node nodeW : commonXZ) { if (foundVariables.contains(nodeW)) continue; if (!adjacencies.get(nodeY).contains(nodeW)) { continue; } int y = variables.indexOf(nodeY); int w = variables.indexOf(nodeW); int z = variables.indexOf(nodeZ); Set<Integer> cluster = quartet(x, y, z, w); // 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)) { O: for (int o : _variables) { if (cluster.contains(o)) continue; cluster.add(o); if (!clique(cluster, adjacencies)) { cluster.remove(o); continue O; } // if (!allVariablesDependent(cluster)) { // cluster.remove(o); // continue O; // } List<Integer> _cluster = new ArrayList<Integer>(cluster); 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 > 2) 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); foundVariables.addAll(variablesForIndices(new ArrayList<Integer>(cluster))); } } } } } return clusters; }
// 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; }