Beispiel #1
0
  public boolean containsParameter(Edge edge) {
    if (Edges.isBidirectedEdge(edge)) {
      edge =
          Edges.bidirectedEdge(
              semGraph.getExogenous(edge.getNode1()), semGraph.getExogenous(edge.getNode2()));
    }

    return edgeParameters.keySet().contains(edge);
  }
Beispiel #2
0
 public void setParameterValue(Edge edge, double value) {
   if (Edges.isDirectedEdge(edge)) {
     setEdgeCoefficient(edge.getNode1(), edge.getNode2(), value);
   } else if (Edges.isBidirectedEdge(edge)) {
     setErrorCovariance(edge.getNode1(), edge.getNode2(), value);
   } else {
     throw new IllegalArgumentException(
         "Only directed and bidirected edges are supported: " + edge);
   }
 }
Beispiel #3
0
  /**
   * @return Returns the error covariance matrix of the model. i.e. [a][b] is the covariance of E_a
   *     and E_b, with [a][a] of course being the variance of E_a. THESE ARE NOT PARAMETERS OF THE
   *     MODEL; THEY ARE CALCULATED. Note that elements of this matrix may be Double.NaN; this
   *     indicates that these elements cannot be calculated.
   */
  private TetradMatrix errCovar(Map<Node, Double> errorVariances) {
    List<Node> variableNodes = getVariableNodes();
    List<Node> errorNodes = new ArrayList<Node>();

    for (Node node : variableNodes) {
      errorNodes.add(semGraph.getExogenous(node));
    }

    TetradMatrix errorCovar = new TetradMatrix(errorVariances.size(), errorVariances.size());

    for (int index = 0; index < errorNodes.size(); index++) {
      Node error = errorNodes.get(index);
      double variance = getErrorVariance(error);
      errorCovar.set(index, index, variance);
    }

    for (int index1 = 0; index1 < errorNodes.size(); index1++) {
      for (int index2 = 0; index2 < errorNodes.size(); index2++) {
        Node error1 = errorNodes.get(index1);
        Node error2 = errorNodes.get(index2);
        Edge edge = semGraph.getEdge(error1, error2);

        if (edge != null && Edges.isBidirectedEdge(edge)) {
          double covariance = getErrorCovariance(error1, error2);
          errorCovar.set(index1, index2, covariance);
        }
      }
    }

    return errorCovar;
  }
Beispiel #4
0
  public static Graph erdosRenyiGraph(int n, int e) {
    List<Node> nodes = new ArrayList<Node>();
    for (int i = 0; i < n; i++) nodes.add(new GraphNode("X" + i));

    Graph graph = new EdgeListGraph(nodes);

    for (int e0 = 0; e0 < e; e0++) {
      int i1 = RandomUtil.getInstance().nextInt(n);
      int i2 = RandomUtil.getInstance().nextInt(n);

      if (i1 == i2) {
        e0--;
        continue;
      }

      Edge edge = Edges.undirectedEdge(nodes.get(i1), nodes.get(i2));

      if (graph.containsEdge(edge)) {
        e0--;
        continue;
      }

      graph.addEdge(edge);
    }

    return graph;
  }
Beispiel #5
0
  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;
  }
Beispiel #6
0
  public boolean isViolatedBy(Graph graph) {
    for (Edge edge : graph.getEdges()) {
      if (!edge.isDirected()) {
        continue;
      }

      Node from = Edges.getDirectedEdgeTail(edge);
      Node to = Edges.getDirectedEdgeHead(edge);

      if (isForbidden(from.getName(), to.getName())) {
        return true;
      }
    }

    return false;
  }
Beispiel #7
0
  /**
   * Sets the covariance for the a<->b edge to the given covariance, if within range. Otherwise does
   * nothing.
   *
   * @param a a <-> b
   * @param b a <-> b
   * @param covar The covariance of a <-> b.
   * @return true if the coefficent was set (i.e. was within range), false if not.
   */
  public boolean setErrorCovariance(Node a, Node b, final double covar) {
    Edge edge = Edges.bidirectedEdge(semGraph.getExogenous(a), semGraph.getExogenous(b));

    if (edgeParameters.get(edge) == null) {
      throw new IllegalArgumentException("Not a covariance parameter in this model: " + edge);
    }

    if (editingEdge == null || !edge.equals(editingEdge)) {
      range = getParameterRange(edge);
      editingEdge = edge;
    }

    if (covar > range.getLow() && covar < range.getHigh()) {
      edgeParameters.put(edge, covar);
      return true;
    } else {
      return false;
    }

    //        if (!paramInBounds(edge, coef)) {
    //            edgeParameters.put(edge, d);
    //            return false;
    //        }
    //
    //        edgeParameters.put(edge, coef);
    //        return true;

    //        if (!paramInBounds(edge, covar)) {
    //            edgeParameters.put(edge, d);
    //            return false;
    //        }
    //
    //        edgeParameters.put(edge, covar);
    //        return true;
  }
Beispiel #8
0
  /**
   * Sets the coefficient for the a->b edge to the given coefficient, if within range. Otherwise
   * does nothing.
   *
   * @param a a -> b
   * @param b a -> b
   * @param coef The coefficient of a -> b.
   * @return true if the coefficent was set (i.e. was within range), false if not.
   */
  public boolean setEdgeCoefficient(Node a, Node b, final double coef) {
    Edge edge = Edges.directedEdge(a, b);

    if (edgeParameters.get(edge) == null) {
      throw new NullPointerException("Not a coefficient parameter in this model: " + edge);
    }

    if (editingEdge == null || !edge.equals(editingEdge)) {
      range = getParameterRange(edge);
      editingEdge = edge;
    }

    if (coef > range.getLow() && coef < range.getHigh()) {
      edgeParameters.put(edge, coef);
      return true;
    }

    return false;

    //        if (!paramInBounds(edge, coef)) {
    //            edgeParameters.put(edge, d);
    //            return false;
    //        }
    //
    //        edgeParameters.put(edge, coef);
    //        return true;
  }
  public TimeLagGraphWrapper(GraphWrapper graphWrapper) {
    if (graphWrapper == null) {
      throw new NullPointerException("No graph wrapper.");
    }

    TimeLagGraph graph = new TimeLagGraph();

    Graph _graph = graphWrapper.getGraph();

    for (Node node : _graph.getNodes()) {
      Node _node = node.like(node.getName() + ":0");
      _node.setNodeType(node.getNodeType());
      graph.addNode(_node);
    }

    for (Edge edge : _graph.getEdges()) {
      if (!Edges.isDirectedEdge(edge)) {
        throw new IllegalArgumentException();
      }

      Node from = edge.getNode1();
      Node to = edge.getNode2();

      Node _from = graph.getNode(from.getName(), 1);
      Node _to = graph.getNode(to.getName(), 0);

      graph.addDirectedEdge(_from, _to);
    }

    this.graph = graph;
  }
Beispiel #10
0
  private boolean isUndirected(Graph graph, Node x, Node y) {
    List<Edge> edges = graph.getEdges(x, y);
    if (edges.size() == 1) {
      Edge edge = graph.getEdge(x, y);
      return Edges.isUndirectedEdge(edge);
    }

    return false;
  }
Beispiel #11
0
  /**
   * @param a a->b
   * @param b a->b
   * @return The coefficient for a->b.
   */
  public double getErrorCovariance(Node a, Node b) {
    Edge edge = Edges.bidirectedEdge(semGraph.getExogenous(a), semGraph.getExogenous(b));
    Double d = edgeParameters.get(edge);

    if (d == null) {
      throw new IllegalArgumentException("Not a covariance parameter in this model: " + edge);
    }

    return d;
  }
Beispiel #12
0
  /**
   * @param a a->b
   * @param b a->b
   * @return The coefficient for a->b.
   */
  public double getEdgeCoefficient(Node a, Node b) {
    Edge edge = Edges.directedEdge(a, b);
    Double d = edgeParameters.get(edge);

    if (d == null) {
      return Double.NaN;
      //            throw new IllegalArgumentException("Not a directed edge in this model: " +
      // edge);
    }

    return d;
  }
Beispiel #13
0
  private Graph pickDag(Graph graph) {
    SearchGraphUtils.basicPattern(graph, false);
    addRequiredEdges(graph);
    boolean containsUndirected;

    do {
      containsUndirected = false;

      for (Edge edge : graph.getEdges()) {
        if (Edges.isUndirectedEdge(edge)) {
          containsUndirected = true;
          graph.removeEdge(edge);
          Edge _edge = Edges.directedEdge(edge.getNode1(), edge.getNode2());
          graph.addEdge(_edge);
        }
      }

      meekOrient(graph, getKnowledge());
    } while (containsUndirected);

    return graph;
  }
Beispiel #14
0
  private void ruleR1(Graph skeleton, Graph graph, List<Node> nodes) {
    for (Node node : nodes) {
      SortedMap<Double, String> scoreReports = new TreeMap<Double, String>();

      List<Node> adj = skeleton.getAdjacentNodes(node);

      DepthChoiceGenerator gen = new DepthChoiceGenerator(adj.size(), adj.size());
      int[] choice;
      double maxScore = Double.NEGATIVE_INFINITY;
      List<Node> parents = null;

      while ((choice = gen.next()) != null) {
        List<Node> _parents = GraphUtils.asList(choice, adj);

        double score = score(node, _parents);
        scoreReports.put(-score, _parents.toString());

        if (score > maxScore) {
          maxScore = score;
          parents = _parents;
        }
      }

      for (double score : scoreReports.keySet()) {
        TetradLogger.getInstance()
            .log(
                "score",
                "For " + node + " parents = " + scoreReports.get(score) + " score = " + -score);
      }

      TetradLogger.getInstance().log("score", "");

      if (parents == null) {
        continue;
      }

      if (normal(node, parents)) continue;

      for (Node _node : adj) {
        if (parents.contains(_node)) {
          Edge parentEdge = Edges.directedEdge(_node, node);

          if (!graph.containsEdge(parentEdge)) {
            graph.addEdge(parentEdge);
          }
        }
      }
    }
  }
Beispiel #15
0
  /** @return a string representation of the coefficients and variances of the model. */
  public String toString() {
    StringBuilder buf = new StringBuilder();
    NumberFormat nf = NumberFormatUtil.getInstance().getNumberFormat();

    buf.append("\nStandardized SEM:");
    buf.append("\n\nEdge coefficients (parameters):\n");

    for (Edge edge : edgeParameters.keySet()) {
      if (!Edges.isDirectedEdge(edge)) {
        continue;
      }

      buf.append("\n" + edge + " " + nf.format(edgeParameters.get(edge)));
    }

    buf.append("\n\nError covariances (parameters):\n");

    for (Edge edge : edgeParameters.keySet()) {
      if (!Edges.isBidirectedEdge(edge)) {
        continue;
      }

      buf.append("\n" + edge + " " + nf.format(edgeParameters.get(edge)));
    }

    buf.append("\n\nError variances (calculated):\n");

    for (Node error : getErrorNodes()) {
      double variance = getErrorVariance(error);
      buf.append("\n" + error + " " + (Double.isNaN(variance) ? "Undefined" : nf.format(variance)));
    }

    buf.append("\n");

    return buf.toString();
  }
Beispiel #16
0
  private void uncorrelationExogenousVariables() {
    Graph graph = getWorkbench().getGraph();

    Set<Edge> edges = graph.getEdges();

    for (Edge edge : edges) {
      if (Edges.isBidirectedEdge(edge)) {
        try {
          graph.removeEdge(edge);
        } catch (Exception e) {
          // Ignore.
        }
      }
    }
  }
Beispiel #17
0
  public static Graph weightedRandomGraph(int n, int e) {
    List<Node> nodes = new ArrayList<Node>();
    for (int i = 0; i < n; i++) nodes.add(new GraphNode("X" + i));

    Graph graph = new EdgeListGraph(nodes);

    for (int e0 = 0; e0 < e; e0++) {
      int i1 = weightedRandom(nodes, graph);
      //            int i2 = RandomUtil.getInstance().nextInt(n);
      int i2 = weightedRandom(nodes, graph);

      if (!(shortestPath(nodes.get(i1), nodes.get(i2), graph) < 9)) {
        e0--;
        continue;
      }

      if (i1 == i2) {
        e0--;
        continue;
      }

      Edge edge = Edges.undirectedEdge(nodes.get(i1), nodes.get(i2));

      if (graph.containsEdge(edge)) {
        e0--;
        continue;
      }

      graph.addEdge(edge);
    }

    for (Edge edge : graph.getEdges()) {
      Node n1 = edge.getNode1();
      Node n2 = edge.getNode2();

      if (!graph.isAncestorOf(n2, n1)) {
        graph.removeEdge(edge);
        graph.addDirectedEdge(n1, n2);
      } else {
        graph.removeEdge(edge);
        graph.addDirectedEdge(n2, n1);
      }
    }

    return graph;
  }
Beispiel #18
0
  /** Get all nodes that are connected to Y by an undirected edge and not adjacent to X. */
  private static List<Node> getTNeighbors(Node x, Node y, Graph graph) {
    List<Edge> yEdges = graph.getEdges(y);
    List<Node> tNeighbors = new ArrayList<Node>();

    for (Edge edge : yEdges) {
      if (!Edges.isUndirectedEdge(edge)) {
        continue;
      }

      Node z = edge.getDistalNode(y);

      if (graph.isAdjacentTo(z, x)) {
        continue;
      }

      tNeighbors.add(z);
    }

    return tNeighbors;
  }
Beispiel #19
0
  /**
   * Find all nodes that are connected to Y by an undirected edge that are adjacent to X (that is,
   * by undirected or directed edge).
   */
  private static List<Node> getNaYX(Node x, Node y, Graph graph) {
    List<Edge> yEdges = graph.getEdges(y);
    List<Node> nayx = new ArrayList<Node>();

    for (Edge edge : yEdges) {
      if (!Edges.isUndirectedEdge(edge)) {
        continue;
      }

      Node z = edge.getDistalNode(y);

      if (!graph.isAdjacentTo(z, x)) {
        continue;
      }

      nayx.add(z);
    }

    return nayx;
  }
Beispiel #20
0
  private void correlateExogenousVariables() {
    Graph graph = getWorkbench().getGraph();

    if (graph instanceof Dag) {
      JOptionPane.showMessageDialog(
          JOptionUtils.centeringComp(), "Cannot add bidirected edges to DAG's.");
      return;
    }

    List<Node> nodes = graph.getNodes();

    List<Node> exoNodes = new LinkedList<Node>();

    for (int i = 0; i < nodes.size(); i++) {
      Node node = nodes.get(i);
      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<Edge> edges = graph.getEdges(node1, node2);

        for (int k = 0; k < edges.size(); k++) {
          Edge edge = edges.get(k);
          if (Edges.isBidirectedEdge(edge)) {
            continue loop;
          }
        }

        graph.addBidirectedEdge(node1, node2);
      }
    }
  }
Beispiel #21
0
  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);
      }
    }
  }
Beispiel #22
0
  /**
   * @return The edge coefficient matrix of the model, a la SemIm. Note that this will normally need
   *     to be transposed, since [a][b] is the edge coefficient for a-->b, not b-->a. Sorry.
   *     History. THESE ARE PARAMETERS OF THE MODEL--THE ONLY PARAMETERS.
   */
  public TetradMatrix edgeCoef() {
    List<Node> variableNodes = getVariableNodes();

    TetradMatrix edgeCoef = new TetradMatrix(variableNodes.size(), variableNodes.size());

    for (Edge edge : edgeParameters.keySet()) {
      if (Edges.isBidirectedEdge(edge)) {
        continue;
      }

      Node a = edge.getNode1();
      Node b = edge.getNode2();

      int aindex = variableNodes.indexOf(a);
      int bindex = variableNodes.indexOf(b);

      double coef = edgeParameters.get(edge);

      edgeCoef.set(aindex, bindex, coef);
    }

    return edgeCoef;
  }
Beispiel #23
0
  /**
   * Calculates the error variance for the given error node, given all of the coefficient values in
   * the model.
   *
   * @param error An error term in the model--i.e. a variable with NodeType.ERROR.
   * @return The value of the error variance, or Double.NaN is the value is undefined.
   */
  private double calculateErrorVarianceFromParams(Node error) {
    error = semGraph.getNode(error.getName());

    Node child = semGraph.getChildren(error).get(0);
    List<Node> parents = semGraph.getParents(child);

    double otherVariance = 0;

    for (Node parent : parents) {
      if (parent == error) continue;
      double coef = getEdgeCoefficient(parent, child);
      otherVariance += coef * coef;
    }

    if (parents.size() >= 2) {
      ChoiceGenerator gen = new ChoiceGenerator(parents.size(), 2);
      int[] indices;

      while ((indices = gen.next()) != null) {
        Node node1 = parents.get(indices[0]);
        Node node2 = parents.get(indices[1]);

        double coef1, coef2;

        if (node1.getNodeType() != NodeType.ERROR) {
          coef1 = getEdgeCoefficient(node1, child);
        } else {
          coef1 = 1;
        }

        if (node2.getNodeType() != NodeType.ERROR) {
          coef2 = getEdgeCoefficient(node2, child);
        } else {
          coef2 = 1;
        }

        List<List<Node>> treks = GraphUtils.treksIncludingBidirected(semGraph, node1, node2);

        double cov = 0.0;

        for (List<Node> trek : treks) {
          double product = 1.0;

          for (int i = 1; i < trek.size(); i++) {
            Node _node1 = trek.get(i - 1);
            Node _node2 = trek.get(i);

            Edge edge = semGraph.getEdge(_node1, _node2);
            double factor;

            if (Edges.isBidirectedEdge(edge)) {
              factor = edgeParameters.get(edge);
            } else if (!edgeParameters.containsKey(edge)) {
              factor = 1;
            } else if (semGraph.isParentOf(_node1, _node2)) {
              factor = getEdgeCoefficient(_node1, _node2);
            } else {
              factor = getEdgeCoefficient(_node2, _node1);
            }

            product *= factor;
          }

          cov += product;
        }

        otherVariance += 2 * coef1 * coef2 * cov;
      }
    }

    return 1.0 - otherVariance <= 0 ? Double.NaN : 1.0 - otherVariance;
  }
Beispiel #24
0
 public ParameterRange getCoefficientRange(Node a, Node b) {
   return getParameterRange(Edges.directedEdge(a, b));
 }
Beispiel #25
0
  /** 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));
        }
      }
    }
  }
Beispiel #26
0
 public ParameterRange getCovarianceRange(Node a, Node b) {
   return getParameterRange(
       Edges.bidirectedEdge(semGraph.getExogenous(a), semGraph.getExogenous(b)));
 }
Beispiel #27
0
  /**
   * @param edge a->b or a<->b.
   * @return the range of the covariance parameter for a->b or a<->b.
   */
  public ParameterRange getParameterRange(Edge edge) {
    if (Edges.isBidirectedEdge(edge)) {
      edge =
          Edges.bidirectedEdge(
              semGraph.getExogenous(edge.getNode1()), semGraph.getExogenous(edge.getNode2()));
    }

    if (!(edgeParameters.keySet().contains(edge))) {
      throw new IllegalArgumentException("Not an edge in this model: " + edge);
    }

    double initial = edgeParameters.get(edge);

    if (initial == Double.NEGATIVE_INFINITY) {
      initial = Double.MIN_VALUE;
    } else if (initial == Double.POSITIVE_INFINITY) {
      initial = Double.MAX_VALUE;
    }

    double value = initial;

    // look upward for a point that fails.
    double high = value + 1;

    while (paramInBounds(edge, high)) {
      high = value + 2 * (high - value);

      if (high == Double.POSITIVE_INFINITY) {
        break;
      }
    }

    // find the boundary using binary search.
    double rangeHigh;

    if (high == Double.POSITIVE_INFINITY) {
      rangeHigh = high;
    } else {
      double low = value;

      while (high - low > 1e-10) {
        double midpoint = (high + low) / 2.0;

        if (paramInBounds(edge, midpoint)) {
          low = midpoint;
        } else {
          high = midpoint;
        }
      }

      rangeHigh = (high + low) / 2.0;
    }

    // look downard for a point that fails.
    double low = value - 1;

    while (paramInBounds(edge, low)) {
      low = value - 2 * (value - low);

      if (low == Double.NEGATIVE_INFINITY) {
        break;
      }
    }

    double rangeLow;

    if (low == Double.NEGATIVE_INFINITY) {
      rangeLow = low;
    } else {

      // find the boundary using binary search.
      high = value;

      while (high - low > 1e-10) {
        double midpoint = (high + low) / 2.0;

        if (paramInBounds(edge, midpoint)) {
          high = midpoint;
        } else {
          low = midpoint;
        }
      }

      rangeLow = (high + low) / 2.0;
    }

    if (Edges.isDirectedEdge(edge)) {
      edgeParameters.put(edge, initial);
    } else if (Edges.isBidirectedEdge(edge)) {
      edgeParameters.put(edge, initial);
    }

    return new ParameterRange(edge, value, rangeLow, rangeHigh);
  }
Beispiel #28
0
  /**
   * Constructs a new standardized SEM IM from the freeParameters in the given SEM IM.
   *
   * @param im Stop asking me for these things! The given SEM IM!!!
   * @param initialization CALCULATE_FROM_SEM if the initial values will be calculated from the
   *     given SEM IM; INITIALIZE_FROM_DATA if data will be simulated from the given SEM,
   *     standardized, and estimated.
   */
  public StandardizedSemIm(SemIm im, Initialization initialization) {
    this.semPm = new SemPm(im.getSemPm());
    this.semGraph = new SemGraph(semPm.getGraph());
    semGraph.setShowErrorTerms(true);

    if (semGraph.existsDirectedCycle()) {
      throw new IllegalArgumentException("The cyclic case is not handled.");
    }

    if (initialization == Initialization.CALCULATE_FROM_SEM) {
      //         This code calculates the new coefficients directly from the old ones.
      edgeParameters = new HashMap<Edge, Double>();

      List<Node> nodes = im.getVariableNodes();
      TetradMatrix impliedCovar = im.getImplCovar(true);

      for (Parameter parameter : im.getSemPm().getParameters()) {
        if (parameter.getType() == ParamType.COEF) {
          Node a = parameter.getNodeA();
          Node b = parameter.getNodeB();
          int aindex = nodes.indexOf(a);
          int bindex = nodes.indexOf(b);
          double vara = impliedCovar.get(aindex, aindex);
          double stda = Math.sqrt(vara);
          double varb = impliedCovar.get(bindex, bindex);
          double stdb = Math.sqrt(varb);
          double oldCoef = im.getEdgeCoef(a, b);
          double newCoef = (stda / stdb) * oldCoef;
          edgeParameters.put(Edges.directedEdge(a, b), newCoef);
        } else if (parameter.getType() == ParamType.COVAR) {
          Node a = parameter.getNodeA();
          Node b = parameter.getNodeB();
          Node exoa = semGraph.getExogenous(a);
          Node exob = semGraph.getExogenous(b);
          double covar = im.getErrCovar(a, b) / Math.sqrt(im.getErrVar(a) * im.getErrVar(b));
          edgeParameters.put(Edges.bidirectedEdge(exoa, exob), covar);
        }
      }
    } else {

      // This code estimates the new coefficients from simulated data from the old model.
      DataSet dataSet = im.simulateData(1000, false);
      TetradMatrix _dataSet = dataSet.getDoubleData();
      _dataSet = DataUtils.standardizeData(_dataSet);
      DataSet dataSetStandardized = ColtDataSet.makeData(dataSet.getVariables(), _dataSet);

      SemEstimator estimator = new SemEstimator(dataSetStandardized, im.getSemPm());
      SemIm imStandardized = estimator.estimate();

      edgeParameters = new HashMap<Edge, Double>();

      for (Parameter parameter : imStandardized.getSemPm().getParameters()) {
        if (parameter.getType() == ParamType.COEF) {
          Node a = parameter.getNodeA();
          Node b = parameter.getNodeB();
          double coef = imStandardized.getEdgeCoef(a, b);
          edgeParameters.put(Edges.directedEdge(a, b), coef);
        } else if (parameter.getType() == ParamType.COVAR) {
          Node a = parameter.getNodeA();
          Node b = parameter.getNodeB();
          Node exoa = semGraph.getExogenous(a);
          Node exob = semGraph.getExogenous(b);
          double covar = -im.getErrCovar(a, b) / Math.sqrt(im.getErrVar(a) * im.getErrVar(b));
          edgeParameters.put(Edges.bidirectedEdge(exoa, exob), covar);
        }
      }
    }

    this.measuredNodes = Collections.unmodifiableList(semPm.getMeasuredNodes());
  }
Beispiel #29
0
  /** Constructs a new SemPm from the given SemGraph. */
  public GeneralizedSemPm(SemGraph graph) {
    if (graph == null) {
      throw new NullPointerException("Graph must not be null.");
    }

    //        if (graph.existsDirectedCycle()) {
    //            throw new IllegalArgumentExcneption("Cycles are not supported.");
    //        }

    // Cannot afford to allow error terms on this graph to be shown or hidden from the outside; must
    // make a
    // hidden copy of it and make sure error terms are shown.
    this.graph = new SemGraph(graph);
    this.graph.setShowErrorTerms(true);

    for (Edge edge : this.graph.getEdges()) {
      if (Edges.isBidirectedEdge(edge)) {
        throw new IllegalArgumentException(
            "The generalized SEM PM cannot currently deal with bidirected " + "edges. Sorry.");
      }
    }

    this.nodes = Collections.unmodifiableList(this.graph.getNodes());

    for (Node node : nodes) {
      namesToNodes.put(node.getName(), node);
    }

    this.variableNodes = new ArrayList<>();
    this.measuredNodes = new ArrayList<>();

    for (Node variable : this.nodes) {
      if (variable.getNodeType() == NodeType.MEASURED
          || variable.getNodeType() == NodeType.LATENT) {
        variableNodes.add(variable);
      }

      if (variable.getNodeType() == NodeType.MEASURED) {
        measuredNodes.add(variable);
      }
    }

    this.errorNodes = new ArrayList<>();

    for (Node variable : this.variableNodes) {
      List<Node> parents = this.graph.getParents(variable);
      boolean added = false;

      for (Node _node : parents) {
        if (_node.getNodeType() == NodeType.ERROR) {
          errorNodes.add(_node);
          added = true;
          break;
        }
      }

      if (!added) {
        errorNodes.add(null);
      }
    }

    this.referencedParameters = new HashMap<>();
    this.referencedNodes = new HashMap<>();
    this.nodeExpressions = new HashMap<>();
    this.nodeExpressionStrings = new HashMap<>();
    this.parameterExpressions = new HashMap<>();
    this.parameterExpressionStrings = new HashMap<>();
    this.parameterEstimationInitializationExpressions = new HashMap<>();
    this.parameterEstimationInitializationExpressionStrings = new HashMap<>();
    this.startsWithParametersTemplates = new HashMap<>();
    this.startsWithParametersEstimationInitializationTemplates = new HashMap<>();

    this.variableNames = new ArrayList<>();
    for (Node _node : variableNodes) variableNames.add(_node.getName());
    for (Node _node : errorNodes) variableNames.add(_node.getName());

    try {
      List<Node> variableNodes = getVariableNodes();

      for (Node node : variableNodes) {
        if (!this.graph.isParameterizable(node)) continue;

        if (nodeExpressions.get(node) != null) {
          continue;
        }

        String variablestemplate = getVariablesTemplate();
        String formula =
            TemplateExpander.getInstance().expandTemplate(variablestemplate, this, node);
        setNodeExpression(node, formula);
        Set<String> parameters = getReferencedParameters(node);

        String parametersTemplate = getParametersTemplate();

        for (String parameter : parameters) {
          if (parameterExpressions.get(parameter) == null) {
            if (parametersTemplate != null) {
              setParameterExpression(parameter, parametersTemplate);
            } else if (this.graph.isTimeLagModel()) {
              String expressionString = "Split(-0.9, -.1, .1, 0.9)";
              setParameterExpression(parameter, expressionString);
              setParametersTemplate(expressionString);
            } else {
              String expressionString = "Split(-1.5, -.5, .5, 1.5)";
              setParameterExpression(parameter, expressionString);
              setParametersTemplate(expressionString);
            }
          }
        }

        for (String parameter : parameters) {
          if (parameterEstimationInitializationExpressions.get(parameter) == null) {
            if (parametersTemplate != null) {
              setParameterEstimationInitializationExpression(parameter, parametersTemplate);
            } else if (this.graph.isTimeLagModel()) {
              String expressionString = "Split(-0.9, -.1, .1, 0.9)";
              setParameterEstimationInitializationExpression(parameter, expressionString);
            } else {
              String expressionString = "Split(-1.5, -.5, .5, 1.5)";
              setParameterEstimationInitializationExpression(parameter, expressionString);
            }
          }

          setStartsWithParametersTemplate("s", "Split(-1.5, -.5, .5, 1.5)");
          setStartsWithParametersEstimationInitializaationTemplate(
              "s", "Split(-1.5, -.5, .5, 1.5)");
        }
      }

      for (Node node : errorNodes) {
        if (node == null) continue;

        String template = getErrorsTemplate();
        String formula = TemplateExpander.getInstance().expandTemplate(template, this, node);
        setNodeExpression(node, formula);
        Set<String> parameters = getReferencedParameters(node);

        setStartsWithParametersTemplate("s", "U(1, 3)");
        setStartsWithParametersEstimationInitializaationTemplate("s", "U(1, 3)");

        for (String parameter : parameters) {
          setParameterExpression(parameter, "U(1, 3)");
        }
      }
    } catch (ParseException e) {
      throw new IllegalStateException("Parse error in constructing initial model.", e);
    }
  }