All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.cmu.tetradapp.util.GraphUtils Maven / Gradle / Ivy

The newest version!
package edu.cmu.tetradapp.util;

import edu.cmu.tetrad.data.DataGraphUtils;
import edu.cmu.tetrad.graph.*;
import edu.cmu.tetrad.util.JOptionUtils;
import edu.cmu.tetrad.util.Parameters;
import edu.cmu.tetrad.util.PointXy;
import edu.cmu.tetradapp.editor.*;
import edu.cmu.tetradapp.workbench.GraphWorkbench;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.*;
import java.util.List;

/**
 * Created by jdramsey on 12/8/15.
 *
 * @author josephramsey
 * @version $Id: $Id
 */
public class GraphUtils {
    /**
     * 

makeRandomGraph.

* * @param graph a {@link edu.cmu.tetrad.graph.Graph} object * @param parameters a {@link edu.cmu.tetrad.util.Parameters} object * @return a {@link edu.cmu.tetrad.graph.Graph} object */ public static Graph makeRandomGraph(Graph graph, Parameters parameters) { int newGraphNumEdges = parameters.getInt("newGraphNumEdges", 3); boolean connected = parameters.getBoolean("randomGraphConnected", false); boolean addCycles = parameters.getBoolean("randomGraphAddCycles", false); boolean graphRandomFoward = parameters.getBoolean("graphRandomFoward", true); int newGraphNumMeasuredNodes = parameters.getInt("newGraphNumMeasuredNodes", 5); int newGraphNumLatents = parameters.getInt("newGraphNumLatents", 0); boolean graphUniformlySelected = parameters.getBoolean("graphUniformlySelected", true); int randomGraphMaxIndegree = parameters.getInt("randomGraphMaxIndegree", 3); int randomGraphMaxOutdegree = parameters.getInt("randomGraphMaxOutdegree", 1); boolean randomGraphConnected = parameters.getBoolean("randomGraphConnected", connected); int randomGraphMaxDegree = parameters.getInt("randomGraphMaxDegree", 6); boolean graphChooseFixed = parameters.getBoolean("graphChooseFixed", false); int numStructuralNodes = parameters.getInt("numStructuralNodes", 3); int maxStructuralEdges = parameters.getInt("numStructuralEdges", 3); int measurementModelDegree = parameters.getInt("measurementModelDegree", 3); int numLatentMeasuredImpureParents = parameters.getInt("latentMeasuredImpureParents", 0); int numMeasuredMeasuredImpureParents = parameters.getInt("measuredMeasuredImpureParents", 0); int numMeasuredMeasuredImpureAssociations = parameters.getInt("measuredMeasuredImpureAssociations", 0); double alpha = parameters.getDouble("scaleFreeAlpha", 0.2); double beta = parameters.getDouble("scaleFreeBeta", 0.6); double deltaIn = parameters.getDouble("scaleFreeDeltaIn", 0.2); double deltaOut = parameters.getDouble("scaleFreeDeltaOut", 0.2); int numFactors = parameters.getInt("randomMimNumFactors", 1); String type = parameters.getString("randomGraphType", "Dag"); return switch (type) { case "Dag" -> RandomGraph.randomGraph( newGraphNumMeasuredNodes, newGraphNumLatents, newGraphNumEdges, randomGraphMaxDegree, randomGraphMaxIndegree, randomGraphMaxOutdegree, false); case "Mim" -> GraphUtils.makeRandomMim(numFactors, numStructuralNodes, maxStructuralEdges, measurementModelDegree, numLatentMeasuredImpureParents, numMeasuredMeasuredImpureParents, numMeasuredMeasuredImpureAssociations); case "ScaleFree" -> GraphUtils.makeRandomScaleFree(newGraphNumMeasuredNodes, newGraphNumLatents, alpha, beta, deltaIn, deltaOut); default -> throw new IllegalStateException("Unrecognized graph type: " + type); }; } private static Graph makeRandomDag(Graph _graph, int newGraphNumMeasuredNodes, int newGraphNumLatents, int newGraphNumEdges, int randomGraphMaxDegree, int randomGraphMaxIndegree, int randomGraphMaxOutdegree, // boolean graphRandomFoward, // boolean graphUniformlySelected, boolean randomGraphConnected, // boolean graphChooseFixed, boolean addCycles, Parameters parameters) { Graph graph = null; int numNodes = newGraphNumMeasuredNodes + newGraphNumLatents; while (graph == null) { List nodes = new ArrayList<>(); for (int i = 0; i < numNodes; i++) { nodes.add(new GraphNode("X" + (i + 1))); } // if (true) { graph = RandomGraph.randomGraph(nodes, newGraphNumLatents, newGraphNumEdges, randomGraphMaxDegree, randomGraphMaxIndegree, randomGraphMaxOutdegree, randomGraphConnected); LayoutUtil.arrangeBySourceGraph(graph, _graph); HashMap layout = GraphSaveLoadUtils.grabLayout(nodes); LayoutUtil.arrangeByLayout(graph, layout); // } else { // if (graphUniformlySelected) { // // graph = RandomGraph.randomGraphUniform(nodes, // newGraphNumLatents, // newGraphNumEdges, // randomGraphMaxDegree, // randomGraphMaxIndegree, // randomGraphMaxOutdegree, // randomGraphConnected, 50000); // LayoutUtil.arrangeBySourceGraph(graph, _graph); // HashMap layout = GraphSaveLoadUtils.grabLayout(nodes); // LayoutUtil.arrangeByLayout(graph, layout); // } else { // if (graphChooseFixed) { // do { // graph = RandomGraph.randomGraph(nodes, // newGraphNumLatents, // newGraphNumEdges, // randomGraphMaxDegree, // randomGraphMaxIndegree, // randomGraphMaxOutdegree, // randomGraphConnected); // LayoutUtil.arrangeBySourceGraph(graph, _graph); // HashMap layout = GraphSaveLoadUtils.grabLayout(nodes); // LayoutUtil.arrangeByLayout(graph, layout); // } while (graph.getNumEdges() < newGraphNumEdges); // } // } // } if (addCycles) { graph = RandomGraph.randomCyclicGraph2(numNodes, newGraphNumEdges, 8); } else { graph = new EdgeListGraph(graph); } int randomGraphMinNumCycles = parameters.getInt("randomGraphMinNumCycles", 0); RandomGraph.addTwoCycles(graph, randomGraphMinNumCycles); } return graph; } private static Graph makeRandomMim(int numFactors, int numStructuralNodes, int maxStructuralEdges, int measurementModelDegree, int numLatentMeasuredImpureParents, int numMeasuredMeasuredImpureParents, int numMeasuredMeasuredImpureAssociations) { Graph graph; if (numFactors == 1) { graph = DataGraphUtils.randomSingleFactorModel(numStructuralNodes, maxStructuralEdges, measurementModelDegree, numLatentMeasuredImpureParents, numMeasuredMeasuredImpureParents, numMeasuredMeasuredImpureAssociations); } else if (numFactors == 2) { graph = DataGraphUtils.randomBifactorModel(numStructuralNodes, maxStructuralEdges, measurementModelDegree, numLatentMeasuredImpureParents, numMeasuredMeasuredImpureParents, numMeasuredMeasuredImpureAssociations); } else { throw new IllegalArgumentException("Can only make random MIMs for 1 or 2 factors, " + "sorry dude."); } return graph; } private static Graph makeRandomScaleFree(int numNodes, int numLatents, double alpha, double beta, double deltaIn, double deltaOut) { return RandomGraph.randomScaleFreeGraph(numNodes, numLatents, alpha, beta, deltaIn, deltaOut); } public static @NotNull JMenu getCheckGraphMenu(GraphWorkbench workbench) { JMenu checkGraph = new JMenu("Check Graph Type"); JMenuItem checkGraphForDag = new JMenuItem(new CheckGraphFoDagAction(workbench)); JMenuItem checkGraphForCpdag = new JMenuItem(new CheckGraphForCpdagAction(workbench)); JMenuItem checkGraphForMpdag = new JMenuItem(new CheckGraphForMpdagAction(workbench)); JMenuItem checkGraphForMag = new JMenuItem(new CheckGraphForMagAction(workbench)); JMenuItem checkGraphForPag = new JMenuItem(new CheckGraphForPagAction(workbench)); // JMenuItem checkGraphForMpag = new JMenuItem(new CheckGraphForMpagAction(workbench)); checkGraph.add(checkGraphForDag); checkGraph.add(checkGraphForCpdag); checkGraph.add(checkGraphForMpdag); checkGraph.add(checkGraphForMag); checkGraph.add(checkGraphForPag); // checkGraph.add(checkGraphForMpag); checkGraphForDag.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_1, InputEvent.ALT_DOWN_MASK)); checkGraphForCpdag.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_2, InputEvent.ALT_DOWN_MASK)); checkGraphForMpdag.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_3, InputEvent.ALT_DOWN_MASK)); checkGraphForMag.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_4, InputEvent.ALT_DOWN_MASK)); checkGraphForPag.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_5, InputEvent.ALT_DOWN_MASK)); return checkGraph; } public static @NotNull JMenu getHighlightMenu(GraphWorkbench workbench) { JMenu highlightMenu = new JMenu("Highlight"); highlightMenu.add(new SelectDirectedAction(workbench)); highlightMenu.add(new SelectBidirectedAction(workbench)); highlightMenu.add(new SelectUndirectedAction(workbench)); highlightMenu.add(new SelectPartiallyOrientedAction(workbench)); highlightMenu.add(new SelectNondirectedAction(workbench)); highlightMenu.addSeparator(); highlightMenu.add(new SelectTrianglesAction(workbench)); highlightMenu.add(new SelectCliquesAction(workbench)); highlightMenu.add(new SelectEdgesInCyclicPaths(workbench)); highlightMenu.add(new SelectEdgesInAlmostCyclicPaths(workbench)); highlightMenu.addSeparator();; highlightMenu.add(new SelectLatentsAction(workbench)); highlightMenu.add(new SelectMeasuredNodesAction(workbench)); return highlightMenu; } /** * Breaks down a given reason into multiple lines with a maximum number of columns. * * @param reason the reason to be broken down * @param maxColumns the maximum number of columns in a line * @return a string with the reason broken down into multiple lines */ public static String breakDown(String reason, int maxColumns) { StringBuilder buf1 = new StringBuilder(); StringBuilder buf2 = new StringBuilder(); String[] tokens = reason.split(" "); for (String token : tokens) { if (buf1.length() + token.length() > maxColumns) { buf2.append(buf1); buf2.append("\n"); buf1 = new StringBuilder(); buf1.append(token); } else { buf1.append(" ").append(token); } } if (!buf1.isEmpty()) { buf2.append(buf1); } return buf2.toString().trim(); } /** * Adds graph manipulation items to the given graph menu. * * @param graph the graph menu to add the items to. */ public static void addGraphManipItems(JMenu graph, GraphWorkbench workbench) { JMenu transformGraph = new JMenu("Manipulate Graph"); JMenuItem runMeekRules = new JMenuItem(new ApplyMeekRules(workbench)); JMenuItem runFinalFciRules = new JMenuItem(new ApplyFinalFciRules(workbench)); JMenuItem revertToCpdag = new JMenuItem(new RevertToCpdag(workbench)); JMenuItem revertToPag = new JMenuItem(new RevertToPag(workbench)); JMenuItem randomDagInCpdag = new JMenuItem(new PickRandomDagInCpdagAction(workbench)); // JMenuItem randomMagInPag = new JMenuItem(new PickRandomMagInPagAction(workbench)); JMenuItem zhangMagInPag = new JMenuItem(new PickZhangMagInPagAction(workbench)); JMenuItem correlateExogenous = new JMenuItem("Correlate Exogenous Variables"); JMenuItem uncorrelateExogenous = new JMenuItem("Uncorrelate Exogenous Variables"); correlateExogenous.addActionListener(e -> { correlateExogenousVariables(workbench); workbench.invalidate(); workbench.repaint(); }); uncorrelateExogenous.addActionListener(e -> { uncorrelateExogenousVariables(workbench); workbench.invalidate(); workbench.repaint(); }); transformGraph.add(runMeekRules); transformGraph.add(revertToCpdag); transformGraph.add(randomDagInCpdag); transformGraph.addSeparator(); transformGraph.add(runFinalFciRules); transformGraph.add(revertToPag); // transformGraph.add(randomMagInPag); transformGraph.add(zhangMagInPag); transformGraph.addSeparator(); transformGraph.add(correlateExogenous); transformGraph.add(uncorrelateExogenous); graph.add(transformGraph); runMeekRules.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_M, InputEvent.ALT_DOWN_MASK)); revertToCpdag.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.ALT_DOWN_MASK)); runFinalFciRules.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.ALT_DOWN_MASK)); revertToPag.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_P, InputEvent.ALT_DOWN_MASK)); randomDagInCpdag.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_D, InputEvent.ALT_DOWN_MASK)); // randomMagInPag.setAccelerator( // KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.ALT_DOWN_MASK)); zhangMagInPag.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.ALT_DOWN_MASK)); } private static void correlateExogenousVariables(GraphWorkbench workbench) { Graph graph = workbench.getGraph(); if (graph instanceof Dag) { JOptionPane.showMessageDialog(JOptionUtils.centeringComp(), "Cannot add bidirected edges to DAG's."); return; } List nodes = graph.getNodes(); List exoNodes = new LinkedList<>(); for (Node node : nodes) { if (graph.isExogenous(node)) { exoNodes.add(node); } } for (int i = 0; i < exoNodes.size(); i++) { loop: for (int j = i + 1; j < exoNodes.size(); j++) { Node node1 = exoNodes.get(i); Node node2 = exoNodes.get(j); List edges = graph.getEdges(node1, node2); for (Edge edge : edges) { if (Edges.isBidirectedEdge(edge)) { continue loop; } } graph.addBidirectedEdge(node1, node2); } } } private static void uncorrelateExogenousVariables(GraphWorkbench workbench) { Graph graph = workbench.getGraph(); Set edges = graph.getEdges(); for (Edge edge : edges) { if (Edges.isBidirectedEdge(edge)) { try { graph.removeEdge(edge); } catch (Exception e) { // Ignore. } } } } public static @NotNull JMenu addPagEdgeSpecializationsItems(GraphWorkbench workbench) { JMenu pagEdgeSpecializations = new JMenu("PAG Edge Specialization Markups"); pagEdgeSpecializations.add(new PagEdgeSpecialization(workbench)); pagEdgeSpecializations.add(new PagEdgeTypeInstructions()); return pagEdgeSpecializations; } /** * Returns the JScrollPane containing the given component, or null if no such JScrollPane exists. * * @param component the component to search for a containing JScrollPane * @return the JScrollPane containing the given component, or null if no such JScrollPane exists */ public static JScrollPane getContainingScrollPane(Component component) { while (component != null && !(component instanceof JScrollPane)) { component = component.getParent(); } return (JScrollPane) component; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy