private List<String> getNames(List<Node> nodes) { List<String> names = new ArrayList<String>(); for (Node node : nodes) { names.add(node.getName()); } return names; }
private Graph condense(Graph mimStructure, Graph mimbuildStructure) { // System.out.println("Uncondensed: " + mimbuildStructure); Map<Node, Node> substitutions = new HashMap<Node, Node>(); for (Node node : mimbuildStructure.getNodes()) { for (Node _node : mimStructure.getNodes()) { if (node.getName().startsWith(_node.getName())) { substitutions.put(node, _node); break; } substitutions.put(node, node); } } HashSet<Node> nodes = new HashSet<Node>(substitutions.values()); Graph graph = new EdgeListGraph(new ArrayList<Node>(nodes)); for (Edge edge : mimbuildStructure.getEdges()) { Node node1 = substitutions.get(edge.getNode1()); Node node2 = substitutions.get(edge.getNode2()); if (node1 == node2) continue; if (graph.isAdjacentTo(node1, node2)) continue; graph.addEdge(new Edge(node1, node2, edge.getEndpoint1(), edge.getEndpoint2())); } // System.out.println("Condensed: " + graph); return graph; }
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; }
private void calculateArrowsForward(Node x, Node y, Graph graph) { clearArrow(x, y); if (!knowledgeEmpty()) { if (getKnowledge().isForbidden(x.getName(), y.getName())) { return; } } List<Node> naYX = getNaYX(x, y, graph); List<Node> t = getTNeighbors(x, y, graph); DepthChoiceGenerator gen = new DepthChoiceGenerator(t.size(), t.size()); int[] choice; while ((choice = gen.next()) != null) { List<Node> s = GraphUtils.asList(choice, t); if (!knowledgeEmpty()) { if (!validSetByKnowledge(y, s)) { continue; } } double bump = insertEval(x, y, s, naYX, graph); if (bump > 0.0) { Arrow arrow = new Arrow(bump, x, y, s, naYX); sortedArrows.add(arrow); addLookupArrow(x, y, arrow); } } }
/** * Use background knowledge to decide if an insert or delete operation does not orient edges in a * forbidden direction according to prior knowledge. If some orientation is forbidden in the * subset, the whole subset is forbidden. */ private boolean validSetByKnowledge(Node y, List<Node> subset) { for (Node node : subset) { if (getKnowledge().isForbidden(node.getName(), y.getName())) { return false; } } return true; }
private Graph structure(Graph mim) { List<Node> latents = new ArrayList<Node>(); for (Node node : mim.getNodes()) { if (node.getNodeType() == NodeType.LATENT) { latents.add(node); } } return mim.subgraph(latents); }
private String reportIfDiscrete(Graph dag, DataSet dataSet) { List vars = dataSet.getVariables(); Map<String, DiscreteVariable> nodesToVars = new HashMap<String, DiscreteVariable>(); for (int i = 0; i < dataSet.getNumColumns(); i++) { DiscreteVariable var = (DiscreteVariable) vars.get(i); String name = var.getName(); Node node = new GraphNode(name); nodesToVars.put(node.getName(), var); } BayesPm bayesPm = new BayesPm(new Dag(dag)); List<Node> nodes = bayesPm.getDag().getNodes(); for (Node node : nodes) { Node var = nodesToVars.get(node.getName()); if (var instanceof DiscreteVariable) { DiscreteVariable var2 = nodesToVars.get(node.getName()); int numCategories = var2.getNumCategories(); List<String> categories = new ArrayList<String>(); for (int j = 0; j < numCategories; j++) { categories.add(var2.getCategory(j)); } bayesPm.setCategories(node, categories); } } BayesProperties properties = new BayesProperties(dataSet, dag); properties.setGraph(dag); NumberFormat nf = NumberFormat.getInstance(); nf.setMaximumFractionDigits(4); StringBuilder buf = new StringBuilder(); buf.append("\nP-value = ").append(properties.getLikelihoodRatioP()); buf.append("\nDf = ").append(properties.getPValueDf()); buf.append("\nChi square = ").append(nf.format(properties.getPValueChisq())); buf.append("\nBIC score = ").append(nf.format(properties.getBic())); buf.append("\n\nH0: Completely disconnected graph."); return buf.toString(); }
// Invalid if then nodes or graph changes. private void calculateArrowsBackward(Node x, Node y, Graph graph) { if (x == y) { return; } if (!graph.isAdjacentTo(x, y)) { return; } if (!knowledgeEmpty()) { if (!getKnowledge().noEdgeRequired(x.getName(), y.getName())) { return; } } List<Node> naYX = getNaYX(x, y, graph); clearArrow(x, y); List<Node> _naYX = new ArrayList<Node>(naYX); DepthChoiceGenerator gen = new DepthChoiceGenerator(_naYX.size(), _naYX.size()); int[] choice; while ((choice = gen.next()) != null) { List<Node> H = GraphUtils.asList(choice, _naYX); if (!knowledgeEmpty()) { if (!validSetByKnowledge(y, H)) { continue; } } double bump = deleteEval(x, y, H, naYX, graph); if (bump > 0.0) { Arrow arrow = new Arrow(bump, x, y, H, naYX); sortedArrows.add(arrow); addLookupArrow(x, y, arrow); } } }
private void initializeArrowsBackward(Graph graph) { sortedArrows.clear(); lookupArrows.clear(); for (Edge edge : graph.getEdges()) { Node x = edge.getNode1(); Node y = edge.getNode2(); if (!knowledgeEmpty()) { if (!getKnowledge().noEdgeRequired(x.getName(), y.getName())) { continue; } } if (Edges.isDirectedEdge(edge)) { calculateArrowsBackward(x, y, graph); } else { calculateArrowsBackward(x, y, graph); calculateArrowsBackward(y, x, graph); } } }
private void addRequiredEdges(Graph graph) { if (true) return; if (knowledgeEmpty()) return; for (Iterator<KnowledgeEdge> it = getKnowledge().requiredEdgesIterator(); it.hasNext(); ) { KnowledgeEdge next = it.next(); Node nodeA = graph.getNode(next.getFrom()); Node nodeB = graph.getNode(next.getTo()); if (!graph.isAncestorOf(nodeB, nodeA)) { graph.removeEdges(nodeA, nodeB); graph.addDirectedEdge(nodeA, nodeB); TetradLogger.getInstance() .log("insertedEdges", "Adding edge by knowledge: " + graph.getEdge(nodeA, nodeB)); } } for (Edge edge : graph.getEdges()) { final String A = edge.getNode1().getName(); final String B = edge.getNode2().getName(); if (knowledge.isForbidden(A, B)) { Node nodeA = edge.getNode1(); Node nodeB = edge.getNode2(); if (nodeA != null && nodeB != null && graph.isAdjacentTo(nodeA, nodeB) && !graph.isChildOf(nodeA, nodeB)) { if (!graph.isAncestorOf(nodeA, nodeB)) { graph.removeEdges(nodeA, nodeB); graph.addDirectedEdge(nodeB, nodeA); TetradLogger.getInstance() .log("insertedEdges", "Adding edge by knowledge: " + graph.getEdge(nodeB, nodeA)); } } if (!graph.isChildOf(nodeA, nodeB) && getKnowledge().isForbidden(nodeA.getName(), nodeB.getName())) { if (!graph.isAncestorOf(nodeA, nodeB)) { graph.removeEdges(nodeA, nodeB); graph.addDirectedEdge(nodeB, nodeA); TetradLogger.getInstance() .log("insertedEdges", "Adding edge by knowledge: " + graph.getEdge(nodeB, nodeA)); } } } else if (knowledge.isForbidden(B, A)) { Node nodeA = edge.getNode2(); Node nodeB = edge.getNode1(); if (nodeA != null && nodeB != null && graph.isAdjacentTo(nodeA, nodeB) && !graph.isChildOf(nodeA, nodeB)) { if (!graph.isAncestorOf(nodeA, nodeB)) { graph.removeEdges(nodeA, nodeB); graph.addDirectedEdge(nodeB, nodeA); TetradLogger.getInstance() .log("insertedEdges", "Adding edge by knowledge: " + graph.getEdge(nodeB, nodeA)); } } if (!graph.isChildOf(nodeA, nodeB) && getKnowledge().isForbidden(nodeA.getName(), nodeB.getName())) { if (!graph.isAncestorOf(nodeA, nodeB)) { graph.removeEdges(nodeA, nodeB); graph.addDirectedEdge(nodeB, nodeA); TetradLogger.getInstance() .log("insertedEdges", "Adding edge by knowledge: " + graph.getEdge(nodeB, nodeA)); } } } } }
/** Do an actual deletion (Definition 13 from Chickering, 2002). */ private void delete(Node x, Node y, List<Node> subset, Graph graph, double bump) { Edge trueEdge = null; if (trueGraph != null) { Node _x = trueGraph.getNode(x.getName()); Node _y = trueGraph.getNode(y.getName()); trueEdge = trueGraph.getEdge(_x, _y); } if (log && verbose) { Edge oldEdge = graph.getEdge(x, y); String label = trueGraph != null && trueEdge != null ? "*" : ""; TetradLogger.getInstance() .log( "deletedEdges", (graph.getNumEdges() - 1) + ". DELETE " + oldEdge + " " + subset + " (" + bump + ") " + label); out.println( (graph.getNumEdges() - 1) + ". DELETE " + oldEdge + " " + subset + " (" + bump + ") " + label); } else { int numEdges = graph.getNumEdges() - 1; if (numEdges % 50 == 0) out.println(numEdges); } graph.removeEdge(x, y); for (Node h : subset) { Edge oldEdge = graph.getEdge(y, h); graph.removeEdge(y, h); graph.addDirectedEdge(y, h); if (log) { TetradLogger.getInstance() .log("directedEdges", "--- Directing " + oldEdge + " to " + graph.getEdge(y, h)); } if (verbose) { out.println("--- Directing " + oldEdge + " to " + graph.getEdge(y, h)); } if (Edges.isUndirectedEdge(graph.getEdge(x, h))) { if (!graph.isAdjacentTo(x, h)) throw new IllegalArgumentException("Not adjacent: " + x + ", " + h); oldEdge = graph.getEdge(x, h); graph.removeEdge(x, h); graph.addDirectedEdge(x, h); if (log) { TetradLogger.getInstance() .log("directedEdges", "--- Directing " + oldEdge + " to " + graph.getEdge(x, h)); } if (verbose) { out.println("--- Directing " + oldEdge + " to " + graph.getEdge(x, h)); } } } }
// serial. private void insert(Node x, Node y, List<Node> t, Graph graph, double bump) { if (graph.isAdjacentTo(x, y)) { return; // The initial graph may already have put this edge in the graph. // throw new IllegalArgumentException(x + " and " + y + " are already adjacent in // the graph."); } Edge trueEdge = null; if (trueGraph != null) { Node _x = trueGraph.getNode(x.getName()); Node _y = trueGraph.getNode(y.getName()); trueEdge = trueGraph.getEdge(_x, _y); } graph.addDirectedEdge(x, y); if (log) { String label = trueGraph != null && trueEdge != null ? "*" : ""; TetradLogger.getInstance() .log( "insertedEdges", graph.getNumEdges() + ". INSERT " + graph.getEdge(x, y) + " " + t + " " + bump + " " + label); } else { int numEdges = graph.getNumEdges() - 1; if (verbose) { if (numEdges % 50 == 0) out.println(numEdges); } } if (verbose) { String label = trueGraph != null && trueEdge != null ? "*" : ""; out.println( graph.getNumEdges() + ". INSERT " + graph.getEdge(x, y) + " " + t + " " + bump + " " + label); } else { int numEdges = graph.getNumEdges() - 1; if (verbose) { if (numEdges % 50 == 0) out.println(numEdges); } } for (Node _t : t) { Edge oldEdge = graph.getEdge(_t, y); if (oldEdge == null) throw new IllegalArgumentException("Not adjacent: " + _t + ", " + y); graph.removeEdge(_t, y); graph.addDirectedEdge(_t, y); if (log && verbose) { TetradLogger.getInstance() .log("directedEdges", "--- Directing " + oldEdge + " to " + graph.getEdge(_t, y)); out.println("--- Directing " + oldEdge + " to " + graph.getEdge(_t, y)); } } }
public DataSet simulateDataCholesky( int sampleSize, TetradMatrix covar, List<Node> variableNodes) { List<Node> variables = new LinkedList<Node>(); for (Node node : variableNodes) { variables.add(node); } List<Node> newVariables = new ArrayList<Node>(); for (Node node : variables) { ContinuousVariable continuousVariable = new ContinuousVariable(node.getName()); continuousVariable.setNodeType(node.getNodeType()); newVariables.add(continuousVariable); } TetradMatrix impliedCovar = covar; DataSet fullDataSet = new ColtDataSet(sampleSize, newVariables); TetradMatrix cholesky = MatrixUtils.choleskyC(impliedCovar); // Simulate the data by repeatedly calling the Cholesky.exogenousData // method. Store only the data for the measured variables. ROW: for (int row = 0; row < sampleSize; row++) { // Step 1. Generate normal samples. double exoData[] = new double[cholesky.rows()]; for (int i = 0; i < exoData.length; i++) { exoData[i] = RandomUtil.getInstance().nextNormal(0, 1); // exoData[i] = randomUtil.nextUniform(-1, 1); } // Step 2. Multiply by cholesky to get correct covariance. double point[] = new double[exoData.length]; for (int i = 0; i < exoData.length; i++) { double sum = 0.0; for (int j = 0; j <= i; j++) { sum += cholesky.get(i, j) * exoData[j]; } point[i] = sum; } double rowData[] = point; for (int col = 0; col < variables.size(); col++) { int index = variableNodes.indexOf(variables.get(col)); double value = rowData[index]; if (Double.isNaN(value) || Double.isInfinite(value)) { throw new IllegalArgumentException("Value out of range: " + value); } fullDataSet.setDouble(row, col, value); } } return DataUtils.restrictToMeasured(fullDataSet); }