コード例 #1
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;
  }
コード例 #2
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;
  }
コード例 #3
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;
  }
コード例 #4
0
  /**
   * @return a map from error to error variances, or to Double.NaN where these cannot be computed.
   */
  public Map<Node, Double> errorVariances() {
    Map<Node, Double> errorVarances = new HashMap<Node, Double>();

    for (Node error : getErrorNodes()) {
      errorVarances.put(error, getErrorVariance(error));
    }

    return errorVarances;
  }
コード例 #5
0
  /** Returns the next available session name in the series untitled1.tet, untitled2.tet, etc. */
  private String getNewSessionName() {
    String base = "untitled";
    String suffix = ".tet";
    int i = 0; // Sequence 1, 2, 3, ...

    loop:
    while (true) {
      i++;

      String name = base + i + suffix;

      for (Object _o : framesMap.keySet()) {
        if (_o instanceof SessionEditor) {
          SessionEditor sessionEditor = (SessionEditor) _o;
          SessionEditorWorkbench workbench = sessionEditor.getSessionWorkbench();
          SessionWrapper sessionWrapper = workbench.getSessionWrapper();

          if (sessionWrapper.getName().equals(name)) {
            continue loop;
          }
        }
      }

      return name;
    }
  }
コード例 #6
0
  public void closeFrontmostSession() {
    JInternalFrame[] frames = desktopPane.getAllFramesInLayer(0);

    if (frames.length > 0) {
      frames[0].dispose();
      Map<SessionEditor, JInternalFrame> framesMap = this.framesMap;
      for (Iterator<SessionEditor> i = framesMap.keySet().iterator(); i.hasNext(); ) {
        SessionEditor key = i.next();
        JInternalFrame value = framesMap.get(key);
        if (value == frames[0]) {
          i.remove();
          break;
        }
      }
    }
  }
コード例 #7
0
  /**
   * Adds a component to the middle layer of the desktop--that is, the layer for session node
   * editors. Note: The comp is a SessionEditor
   */
  public void addSessionEditor(SessionEditorIndirectRef editorRef) {
    SessionEditor editor = (SessionEditor) editorRef;

    JInternalFrame frame = new TetradInternalFrame(null);

    frame.getContentPane().add(editor);
    framesMap.put(editor, frame);
    editor.addPropertyChangeListener(this);

    // Set the "small" size of the frame so that it has sensible
    // bounds when the users unmazimizes it.
    Dimension fullSize = desktopPane.getSize();
    int smallSize = Math.min(fullSize.width - MARGIN, fullSize.height - MARGIN);
    Dimension size = new Dimension(smallSize, smallSize);
    setGoodBounds(frame, desktopPane, size);
    desktopPane.add(frame);

    // Set the frame to be maximized. This step must come after the frame
    // is added to the desktop. -Raul. 6/21/01
    try {
      frame.setMaximum(true);
    } catch (Exception e) {
      throw new RuntimeException("Problem setting frame to max: " + frame);
    }

    desktopPane.setLayer(frame, 0);
    frame.moveToFront();
    frame.setTitle(editor.getName());
    frame.setVisible(true);

    setMainTitle(editor.getName());
  }
コード例 #8
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);
  }
コード例 #9
0
  private boolean paramInBounds(Edge edge, double newValue) {
    edgeParameters.put(edge, newValue);
    Map<Node, Double> errorVariances = new HashMap<Node, Double>();
    for (Node node : semPm.getVariableNodes()) {
      Node error = semGraph.getExogenous(node);
      double d2 = calculateErrorVarianceFromParams(error);
      if (Double.isNaN(d2)) {
        return false;
      }

      errorVariances.put(error, d2);
    }

    if (!MatrixUtils.isPositiveDefinite(errCovar(errorVariances))) {
      return false;
    }

    return true;
  }
コード例 #10
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;
  }
コード例 #11
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;
  }
コード例 #12
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;
  }
コード例 #13
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();
  }
コード例 #14
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;
  }
コード例 #15
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);
  }
コード例 #16
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());
  }