Esempio n. 1
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;
  }