private double scoreGraphChange(Node y, Set<Node> parents1, Set<Node> parents2) { int yIndex = hashIndices.get(y); double score1, score2; int[] parentIndices1 = new int[parents1.size()]; int count = -1; for (Node parent : parents1) { parentIndices1[++count] = hashIndices.get(parent); } if (isDiscrete()) { score1 = localDiscreteScore(yIndex, parentIndices1); } else { score1 = localSemScore(yIndex, parentIndices1); } int[] parentIndices2 = new int[parents2.size()]; int count2 = -1; for (Node parent : parents2) { parentIndices2[++count2] = hashIndices.get(parent); } if (isDiscrete()) { score2 = localDiscreteScore(yIndex, parentIndices2); } else { score2 = localSemScore(yIndex, parentIndices2); } return score1 - score2; }
/** Get a graph and direct only the unshielded colliders. */ public static void basicPattern(Graph graph) { Set<Edge> undirectedEdges = new HashSet<Edge>(); NEXT_EDGE: for (Edge edge : graph.getEdges()) { Node head = null, tail = null; if (edge.getEndpoint1() == Endpoint.ARROW && edge.getEndpoint2() == Endpoint.TAIL) { head = edge.getNode1(); tail = edge.getNode2(); } else if (edge.getEndpoint2() == Endpoint.ARROW && edge.getEndpoint1() == Endpoint.TAIL) { head = edge.getNode2(); tail = edge.getNode1(); } if (head != null) { for (Node node : graph.getParents(head)) { if (node != tail && !graph.isAdjacentTo(tail, node)) { continue NEXT_EDGE; } } undirectedEdges.add(edge); } } for (Edge nextUndirected : undirectedEdges) { Node node1 = nextUndirected.getNode1(), node2 = nextUndirected.getNode2(); graph.removeEdge(nextUndirected); graph.addUndirectedEdge(node1, node2); } }
public Set<Edge> getAdjacencies() { Set<Edge> adjacencies = new HashSet<Edge>(); for (Edge edge : graph.getEdges()) { adjacencies.add(edge); } return adjacencies; }
// ===========================SCORING METHODS===================// public double scoreDag(Graph graph) { Graph dag = new EdgeListGraphSingleConnections(graph); buildIndexing(graph); double score = 0.0; for (Node y : dag.getNodes()) { Set<Node> parents = new HashSet<Node>(dag.getParents(y)); int nextIndex = -1; for (int i = 0; i < getVariables().size(); i++) { nextIndex = hashIndices.get(variables.get(i)); } int parentIndices[] = new int[parents.size()]; Iterator<Node> pi = parents.iterator(); int count = 0; while (pi.hasNext()) { Node nextParent = pi.next(); parentIndices[count++] = hashIndices.get(nextParent); } if (this.isDiscrete()) { score += localDiscreteScore(nextIndex, parentIndices); } else { score += localSemScore(nextIndex, parentIndices); } } return score; }
private boolean existsUnblockedSemiDirectedPath(Node from, Node to, List<Node> cond, Graph G) { Queue<Node> Q = new LinkedList<Node>(); Set<Node> V = new HashSet<Node>(); Q.offer(from); V.add(from); while (!Q.isEmpty()) { Node t = Q.remove(); if (t == to) return true; for (Node u : G.getAdjacentNodes(t)) { Edge edge = G.getEdge(t, u); Node c = Edges.traverseSemiDirected(t, edge); if (c == null) continue; if (cond.contains(c)) continue; if (c == to) return true; if (!V.contains(c)) { V.add(c); Q.offer(c); } } } return false; }
public Set<Edge> getNonadjacencies() { Graph complete = GraphUtils.completeGraph(graph); Set<Edge> nonAdjacencies = complete.getEdges(); Graph undirected = GraphUtils.undirectedGraph(graph); nonAdjacencies.removeAll(undirected.getEdges()); return new HashSet<Edge>(nonAdjacencies); }
/** Sets the variable in a given tier to the specified list. */ public void setTier(int tier, List<String> vars) { ensureTiers(tier); Set<MyNode> _tier = tierSpecs.get(tier); if (_tier != null) _tier.clear(); for (String var : vars) { addToTier(tier, var); } }
private Set<Integer> unionPure(Set<Set<Integer>> pureClusters) { Set<Integer> unionPure = new HashSet<Integer>(); for (Set<Integer> cluster : pureClusters) { unionPure.addAll(cluster); } return unionPure; }
/** Evaluate the Insert(X, Y, T) operator (Definition 12 from Chickering, 2002). */ private double insertEval(Node x, Node y, List<Node> t, List<Node> naYX, Graph graph) { Set<Node> set1 = new HashSet<Node>(naYX); set1.addAll(t); List<Node> paY = graph.getParents(y); set1.addAll(paY); Set<Node> set2 = new HashSet<Node>(set1); set1.add(x); return scoreGraphChange(y, set1, set2); }
private void addLookupArrow(Node i, Node j, Arrow arrow) { OrderedPair<Node> pair = new OrderedPair<Node>(i, j); Set<Arrow> arrows = lookupArrows.get(pair); if (arrows == null) { arrows = new HashSet<Arrow>(); lookupArrows.put(pair, arrows); } arrows.add(arrow); }
/** * @param node the node doing the referencing. * @return the freeParameters referenced by the given variable (variable node or error node). */ public Set<String> getReferencedParameters(Node node) { Set<String> parameters = new HashSet<>(); for (String parameter : this.referencedParameters.keySet()) { if (this.referencedParameters.get(parameter).contains(node)) { parameters.add(parameter); } } return parameters; }
/** * @param node the node doing the referencing. * @return the variables referenced by the expression for the given node (variable node or error * node. */ public Set<Node> getReferencedNodes(Node node) { Set<Node> nodes = new HashSet<>(); for (Node _node : this.referencedNodes.keySet()) { if (this.referencedNodes.get(_node).contains(node)) { nodes.add(_node); } } return nodes; }
private boolean quartetVanishes(Set<Integer> quartet) { if (quartet.size() != 4) throw new IllegalArgumentException("Expecting a quartet, size = " + quartet.size()); Iterator<Integer> iter = quartet.iterator(); int x = iter.next(); int y = iter.next(); int z = iter.next(); int w = iter.next(); return testVanishing(x, y, z, w); }
private Set<Integer> triple(int n1, int n2, int n3) { Set<Integer> triple = new HashSet<Integer>(); triple.add(n1); triple.add(n2); triple.add(n3); if (triple.size() < 3) throw new IllegalArgumentException( "Triple elements must be unique: <" + n1 + ", " + n2 + ", " + n3 + ">"); return triple; }
private Set<String> split(String spec) { String[] tokens = spec.split(","); Set<String> _tokens = new HashSet<>(); for (String _token : tokens) { if (!_token.trim().equals("")) { _tokens.add(_token); } } return _tokens; }
private OrderedPair<Set<MyNode>> getGroupRule(KnowledgeGroup group) { Set<String> from = group.getFromVariables(); Set<String> to = group.getToVariables(); Set<MyNode> fromExtent = new HashSet<>(); Set<MyNode> toExtent = new HashSet<>(); for (String s : from) { fromExtent.addAll(getExtent(s)); } for (String s : to) { toExtent.addAll(getExtent(s)); } return new OrderedPair<>(fromExtent, toExtent); }
private Set<Integer> quartet(int x, int y, int z, int w) { Set<Integer> set = new HashSet<Integer>(); set.add(x); set.add(y); set.add(z); set.add(w); if (set.size() < 4) throw new IllegalArgumentException( "Quartet elements must be unique: <" + x + ", " + y + ", " + z + ", " + w + ">"); return set; }
private Graph convertToGraph(Set<Set<Integer>> allClusters) { Set<Set<Node>> _clustering = new HashSet<Set<Node>>(); for (Set<Integer> cluster : allClusters) { Set<Node> nodes = new HashSet<Node>(); for (int i : cluster) { nodes.add(variables.get(i)); } _clustering.add(nodes); } return convertSearchGraphNodes(_clustering); }
public static List<Set<Node>> powerSet(List<Node> nodes) { List<Set<Node>> subsets = new ArrayList<Set<Node>>(); int total = (int) Math.pow(2, nodes.size()); for (int i = 0; i < total; i++) { Set<Node> newSet = new HashSet<Node>(); String selection = Integer.toBinaryString(i); for (int j = selection.length() - 1; j >= 0; j--) { if (selection.charAt(j) == '1') { newSet.add(nodes.get(selection.length() - j - 1)); } } subsets.add(newSet); } return subsets; }
private boolean clique(Set<Integer> cluster, Map<Node, Set<Node>> adjacencies) { List<Integer> _cluster = new ArrayList<Integer>(cluster); for (int i = 0; i < cluster.size(); i++) { for (int j = i + 1; j < cluster.size(); j++) { Node nodei = variables.get(_cluster.get(i)); Node nodej = variables.get(_cluster.get(j)); if (!adjacencies.get(nodei).contains(nodej)) { return false; } } } return true; }
/** Adds the given variable name to knowledge. Duplicates are ignored. */ public void addVariable(String varName) { if (!namesToVars.containsKey(varName) && checkVarName(varName)) { MyNode e = new MyNode(varName); myNodes.add(e); namesToVars.put(varName, e); } }
/** * Forward equivalence search. * * @param graph The graph in the state prior to the forward equivalence search. */ private void fes(Graph graph, List<Node> nodes) { TetradLogger.getInstance().log("info", "** FORWARD EQUIVALENCE SEARCH"); lookupArrows = new HashMap<OrderedPair, Set<Arrow>>(); initializeArrowsForward(nodes); while (!sortedArrows.isEmpty()) { Arrow arrow = sortedArrows.first(); sortedArrows.remove(arrow); Node x = arrow.getX(); Node y = arrow.getY(); clearArrow(x, y); if (graph.isAdjacentTo(x, y)) { continue; } if (!validInsert(x, y, arrow.getHOrT(), arrow.getNaYX(), graph)) { continue; } List<Node> t = arrow.getHOrT(); double bump = arrow.getBump(); Set<Edge> edges = graph.getEdges(); insert(x, y, t, graph, bump); score += bump; rebuildPattern(graph); // Try to avoid duplicating scoring calls. First clear out all of the edges that need to be // changed, // then change them, checking to see if they're already been changed. I know, roundabout, but // there's // a performance boost. for (Edge edge : graph.getEdges()) { if (!edges.contains(edge)) { reevaluateForward(graph, nodes, edge.getNode1(), edge.getNode2()); } } storeGraph(graph); } }
/** Iterator over the KnowledgeEdge's representing required edges. */ public final Iterator<KnowledgeEdge> requiredEdgesIterator() { Set<KnowledgeEdge> edges = new HashSet<>(); for (OrderedPair<Set<MyNode>> o : requiredRulesSpecs) { final Set<MyNode> first = o.getFirst(); for (MyNode s1 : first) { final Set<MyNode> second = o.getSecond(); for (MyNode s2 : second) { if (!s1.equals(s2)) { edges.add(new KnowledgeEdge(s1.getName(), s2.getName())); } } } } return edges.iterator(); }
public static boolean existsLocalSepsetWithoutDet( Node x, Node y, Node z, IndependenceTest test, Graph graph, int depth) { Set<Node> __nodes = new HashSet<Node>(graph.getAdjacentNodes(x)); __nodes.addAll(graph.getAdjacentNodes(z)); __nodes.remove(x); __nodes.remove(z); List<Node> _nodes = new LinkedList<Node>(__nodes); TetradLogger.getInstance() .log("adjacencies", "Adjacents for " + x + "--" + y + "--" + z + " = " + _nodes); int _depth = depth; if (_depth == -1) { _depth = 1000; } _depth = Math.min(_depth, _nodes.size()); for (int d = 0; d <= _depth; d++) { if (_nodes.size() >= d) { ChoiceGenerator cg2 = new ChoiceGenerator(_nodes.size(), d); int[] choice; while ((choice = cg2.next()) != null) { List<Node> condSet = asList(choice, _nodes); if (condSet.contains(y)) { continue; } if (test.determines(condSet, y)) { continue; } // LogUtils.getInstance().finest("Trying " + condSet); if (test.isIndependent(x, z, condSet)) { return true; } } } } return false; }
private Set<MyNode> getExtent(String spec) { Set<String> split = split(spec); Set<MyNode> matches = new HashSet<>(); for (String _spec : split) { _spec = _spec.replace("*", ".*"); java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(_spec); for (MyNode var : myNodes) { Matcher matcher = pattern.matcher(var.getName()); if (matcher.matches()) { matches.add(var); } } } return matches; }
private boolean pure(Set<Integer> quartet, List<Integer> variables) { if (quartetVanishes(quartet)) { for (int o : variables) { if (quartet.contains(o)) continue; for (int p : quartet) { Set<Integer> _quartet = new HashSet<Integer>(quartet); _quartet.remove(p); _quartet.add(o); if (!quartetVanishes(_quartet)) { return false; } } } return significant(new ArrayList<Integer>(quartet)); } return false; }
/** Removes the given variable from the list of myNodes and all rules. */ public void removeVariable(String name) { if (!checkVarName(name)) { throw new IllegalArgumentException("Bad variable name: " + name); } MyNode MyNode = getVar(name); myNodes.remove(MyNode); for (OrderedPair<Set<MyNode>> o : forbiddenRulesSpecs) { o.getFirst().remove(MyNode); o.getSecond().remove(MyNode); } for (OrderedPair<Set<MyNode>> o : requiredRulesSpecs) { o.getFirst().remove(MyNode); o.getSecond().remove(MyNode); } for (Set<MyNode> tier : tierSpecs) { tier.remove(MyNode); } }
/** * Constructs a new FCI search for the given independence test and background knowledge and a list * of variables to search over. */ public Rfci(IndependenceTest independenceTest, List<Node> searchVars) { if (independenceTest == null || knowledge == null) { throw new NullPointerException(); } this.independenceTest = independenceTest; this.variables.addAll(independenceTest.getVariables()); Set<Node> remVars = new HashSet<Node>(); for (Node node1 : this.variables) { boolean search = false; for (Node node2 : searchVars) { if (node1.getName().equals(node2.getName())) { search = true; } } if (!search) { remVars.add(node1); } } this.variables.removeAll(remVars); }
/** Iterator over the knowledge's explicitly forbidden edges. */ public final Iterator<KnowledgeEdge> explicitlyForbiddenEdgesIterator() { Set<OrderedPair<Set<MyNode>>> copy = new HashSet<>(forbiddenRulesSpecs); copy.removeAll(forbiddenTierRules()); for (KnowledgeGroup group : knowledgeGroups) { copy.remove(knowledgeGroupRules.get(group)); } Set<KnowledgeEdge> edges = new HashSet<>(); for (OrderedPair<Set<MyNode>> o : copy) { final Set<MyNode> first = o.getFirst(); for (MyNode s1 : first) { final Set<MyNode> second = o.getSecond(); for (MyNode s2 : second) { edges.add(new KnowledgeEdge(s1.getName(), s2.getName())); } } } return edges.iterator(); }
// Can be done concurrently. private double deleteEval(Node x, Node y, List<Node> h, List<Node> naYX, Graph graph) { List<Node> paY = graph.getParents(y); Set<Node> paYMinuxX = new HashSet<Node>(paY); paYMinuxX.remove(x); Set<Node> set1 = new HashSet<Node>(naYX); set1.removeAll(h); set1.addAll(paYMinuxX); Set<Node> set2 = new HashSet<Node>(naYX); set2.removeAll(h); set2.addAll(paY); return scoreGraphChange(y, set1, set2); }