private static Element makeVariables(SemIm semIm) {
   Element variablesElement = new Element(SemXmlConstants.SEM_VARIABLES);
   Element variable;
   Node measuredNode, latentNode;
   for (Node node1 : semIm.getSemPm().getMeasuredNodes()) {
     measuredNode = node1;
     variable = new Element(SemXmlConstants.CONTINUOUS_VARIABLE);
     variable.addAttribute(new Attribute(SemXmlConstants.NAME, measuredNode.getName()));
     variable.addAttribute(new Attribute(SemXmlConstants.IS_LATENT, "no"));
     variable.addAttribute(
         new Attribute(SemXmlConstants.MEAN, Double.toString(semIm.getMean(measuredNode))));
     variable.addAttribute(
         new Attribute(SemXmlConstants.X, Integer.toString(measuredNode.getCenterX())));
     variable.addAttribute(
         new Attribute(SemXmlConstants.Y, Integer.toString(measuredNode.getCenterY())));
     variablesElement.appendChild(variable);
   }
   for (Node node : semIm.getSemPm().getLatentNodes()) {
     latentNode = node;
     variable = new Element(SemXmlConstants.CONTINUOUS_VARIABLE);
     variable.addAttribute(new Attribute(SemXmlConstants.NAME, latentNode.getName()));
     variable.addAttribute(new Attribute(SemXmlConstants.IS_LATENT, "yes"));
     variable.addAttribute(
         new Attribute(SemXmlConstants.MEAN, Double.toString(semIm.getMean(latentNode))));
     variable.addAttribute(
         new Attribute(SemXmlConstants.X, Integer.toString(latentNode.getCenterX())));
     variable.addAttribute(
         new Attribute(SemXmlConstants.Y, Integer.toString(latentNode.getCenterY())));
     variablesElement.appendChild(variable);
   }
   return variablesElement;
 }
Exemple #2
0
  public int getNodeIndex(Node node) {
    List<Node> nodes = semIm.getSemPm().getVariableNodes();

    for (int i = 0; i < nodes.size(); i++) {
      Node _node = nodes.get(i);

      if (node == _node) {
        return i;
      }
    }

    return -1;
  }
Exemple #3
0
  public int getNodeIndex(String nodeName) {
    List<Node> nodes = semIm.getSemPm().getVariableNodes();

    for (int i = 0; i < nodes.size(); i++) {
      Node node = nodes.get(i);

      if (node.getName().equals(nodeName)) {
        return i;
      }
    }

    return -1;
  }
  private static Element makeMarginalErrorDistribution(SemIm semIm) {
    Element marginalErrorElement = new Element(SemXmlConstants.MARGINAL_ERROR_DISTRIBUTION);
    Element normal;

    SemGraph semGraph = semIm.getSemPm().getGraph();
    semGraph.setShowErrorTerms(true);

    for (Node node : getExogenousNodes(semGraph)) {
      normal = new Element(SemXmlConstants.NORMAL);
      normal.addAttribute(new Attribute(SemXmlConstants.VARIABLE, node.getName()));
      normal.addAttribute(new Attribute(SemXmlConstants.MEAN, "0.0"));
      normal.addAttribute(
          new Attribute(
              SemXmlConstants.VARIANCE, Double.toString(semIm.getParamValue(node, node))));
      marginalErrorElement.appendChild(normal);
    }
    return marginalErrorElement;
  }
  private static Element makeJointErrorDistribution(SemIm semIm) {
    Element jointErrorElement = new Element(SemXmlConstants.JOINT_ERROR_DISTRIBUTION);
    Element normal;
    Parameter param;

    for (Parameter parameter : semIm.getSemPm().getParameters()) {
      param = parameter;
      if (param.getType() == ParamType.COVAR) {
        normal = new Element(SemXmlConstants.NORMAL);
        normal.addAttribute(new Attribute(SemXmlConstants.NODE_1, param.getNodeA().getName()));
        normal.addAttribute(new Attribute(SemXmlConstants.NODE_2, param.getNodeB().getName()));
        normal.addAttribute(
            new Attribute(SemXmlConstants.COVARIANCE, Double.toString(param.getStartingValue())));
        jointErrorElement.appendChild(normal);
      }
    }

    return jointErrorElement;
  }
  private static Element makeEdges(SemIm semIm) {
    Element edgesElement = new Element(SemXmlConstants.EDGES);
    Parameter param;
    Element edge;

    for (Parameter parameter : semIm.getSemPm().getParameters()) {
      param = parameter;
      if (param.getType() == ParamType.COEF) {
        edge = new Element(SemXmlConstants.EDGE);
        edge.addAttribute(new Attribute(SemXmlConstants.CAUSE_NODE, param.getNodeA().getName()));
        edge.addAttribute(new Attribute(SemXmlConstants.EFFECT_NODE, param.getNodeB().getName()));
        edge.addAttribute(
            new Attribute(SemXmlConstants.VALUE, Double.toString(semIm.getParamValue(param))));
        edge.addAttribute(
            new Attribute(SemXmlConstants.FIXED, Boolean.valueOf(param.isFixed()).toString()));
        edgesElement.appendChild(edge);
      }
    }
    return edgesElement;
  }
Exemple #7
0
  protected SemIm estimateCoeffs(SemIm semIm) {

    // System.out.print("\n****************\nCalling 2SLS... ");
    SemGraph semGraph = semIm.getSemPm().getGraph();

    // Get list of fixed measurements that will be kept fixed, and the
    // respective latent variables that are their parents.
    // "X" variables are exogenous, while "Y" variables are endogenous.
    List<Node> ly = new LinkedList<Node>();
    List<Node> lx = new LinkedList<Node>();
    List<Node> my1 = new LinkedList<Node>();
    List<Node> mx1 = new LinkedList<Node>();
    List<Node> observed = new LinkedList<Node>();

    for (Node nodeA : semGraph.getNodes()) {
      if (nodeA.getNodeType() == NodeType.ERROR) {
        continue;
      }
      if (nodeA.getNodeType() == NodeType.LATENT) {
        if (semGraph.getParents(nodeA).size() == 0) {
          lx.add(nodeA);
        } else {
          ly.add(nodeA);
        }
      } else {
        observed.add(nodeA);
      }
    }
    setFixedNodes(semGraph, mx1, my1);

    // ------------------------------------------------------------------

    // Estimate freeParameters for the latent/latent edges
    for (Node current : ly) {
      if (nodeName != null && !nodeName.equals(current.getName())) {
        continue;
      }
      // Build Z, the matrix containing the data for the fixed measurements
      // associated with the parents of the getModel (endogenous) latent node
      List<Node> endo_parents_m = new LinkedList<Node>();
      List<Node> exo_parents_m = new LinkedList<Node>();
      List<Node> endo_parents = new LinkedList<Node>();
      List<Node> exo_parents = new LinkedList<Node>();
      Iterator<Node> it_p = semGraph.getParents(current).iterator();
      lNames = new String[lx.size() + ly.size()];
      while (it_p.hasNext()) {
        Node node = it_p.next();
        if (node.getNodeType() == NodeType.ERROR) {
          continue;
        }
        if (lx.contains(node)) {
          int position = lx.indexOf(node);
          exo_parents_m.add(mx1.get(position));
          exo_parents.add(node);
        } else {
          int position = ly.indexOf(node);
          endo_parents_m.add(my1.get(position));
          endo_parents.add(node);
        }
      }
      Object endp_a_m[] = endo_parents_m.toArray();
      Object exop_a_m[] = exo_parents_m.toArray();
      Object endp_a[] = endo_parents.toArray();
      Object exop_a[] = exo_parents.toArray();
      int n = dataSet.getNumRows(), c = endp_a_m.length + exop_a_m.length;
      if (c == 0) {
        continue;
      }
      double Z[][] = new double[n][c];
      int count = 0;

      for (int i = 0; i < endp_a_m.length; i++) {
        Node node = (Node) endp_a_m[i];
        String name = node.getName();
        Node variable = dataSet.getVariable(name);
        int colIndex = dataSet.getVariables().indexOf(variable);

        //                Column column = dataSet.getColumnObject(variable);
        //                double column_data[] = (double[]) column.getRawData();

        for (int j = 0; j < n; j++) {
          //                    Z[j][i] = column_data[j];
          Z[j][i] = dataSet.getDouble(j, colIndex);
        }

        lNames[count++] = (endo_parents.get(i)).getName();
      }
      for (int i = 0; i < exop_a_m.length; i++) {
        Node node = (Node) exop_a_m[i];
        String name = node.getName();
        Node variable = dataSet.getVariable(name);
        int colIndex = dataSet.getVariables().indexOf(variable);

        //                Column column = dataSet.getColumnObject(variable);
        //                double column_data[] = (double[]) column.getRawData();

        for (int j = 0; j < n; j++) {
          //                    Z[j][endp_a_m.length + i] = column_data[j];
          Z[j][endp_a_m.length + i] = dataSet.getDouble(j, colIndex);
        }
        lNames[count++] = exo_parents.get(i).getName();
      }
      // Build V, the matrix containing the data for the nonfixed measurements
      // associated with the parents of the getModel (endogenous) latent node
      endo_parents_m = new LinkedList<Node>();
      exo_parents_m = new LinkedList<Node>();
      it_p = semGraph.getParents(current).iterator();
      while (it_p.hasNext()) {
        Node node = it_p.next();
        if (node.getNodeType() == NodeType.ERROR) {
          continue;
        }
        List<Node> other_measures = new LinkedList<Node>();

        for (Node next : semGraph.getChildren(node)) {
          if (next.getNodeType() == NodeType.MEASURED) {
            other_measures.add(next);
          }
        }

        if (lx.contains(node)) {
          int position = lx.indexOf(node);
          other_measures.remove(mx1.get(position));
          exo_parents_m.addAll(other_measures);
        } else {
          int position = ly.indexOf(node);
          other_measures.remove(my1.get(position));
          endo_parents_m.addAll(other_measures);
        }
      }
      endp_a_m = endo_parents_m.toArray();
      exop_a_m = exo_parents_m.toArray();
      n = dataSet.getNumRows();
      c = endp_a_m.length + exop_a_m.length;
      double V[][] = new double[n][c];
      if (c == 0) {
        continue;
      }
      for (int i = 0; i < endp_a_m.length; i++) {
        Node node = ((Node) endp_a_m[i]);
        String name = node.getName();
        Node variable = dataSet.getVariable(name);
        int colIndex = dataSet.getVariables().indexOf(variable);

        //                Column column = dataSet.getColumnObject(variable);
        //                double column_data[] = (double[]) column.getRawData();

        for (int j = 0; j < n; j++) {
          //                    V[j][i] = column_data[j];
          V[j][i] = dataSet.getDouble(j, colIndex);
        }
      }
      for (int i = 0; i < exop_a_m.length; i++) {
        Node node = (Node) exop_a_m[i];
        String name = node.getName();
        Node variable = dataSet.getVariable(name);
        int colIndex = dataSet.getVariables().indexOf(variable);

        //                Column column = dataSet.getColumnObject(variable);
        //                double column_data[] = (double[]) column.getRawData();

        for (int j = 0; j < n; j++) {
          //                    V[j][endp_a_m.length + i] = column_data[j];
          V[j][endp_a_m.length + i] = dataSet.getDouble(j, colIndex);
        }
      }
      double yi[] = new double[n];
      if (lx.contains(current)) {
        int position = lx.indexOf(current);
        Node node = mx1.get(position);
        String name = node.getName();
        Node variable = dataSet.getVariable(name);
        int colIndex = dataSet.getVariables().indexOf(variable);

        //                Column column = dataSet.getColumnObject(variable);
        //
        //                System.arraycopy(column.getRawData(), 0, yi, 0, n);

        for (int i = 0; i < n; i++) {
          yi[i] = dataSet.getDouble(i, colIndex);
        }
      } else {
        int position = ly.indexOf(current);
        Node node = my1.get(position);
        String name = node.getName();
        Node variable = dataSet.getVariable(name);
        int colIndex = dataSet.getVariables().indexOf(variable);

        //                System.arraycopy(dataSet.getColumnObject(variable).getRawData(), 0, yi, 0,
        // n);

        for (int i = 0; i < n; i++) {
          yi[i] = dataSet.getDouble(i, colIndex);
        }
      }
      // Build Z_hat
      double Z_hat[][] =
          MatrixUtils.product(
              V,
              MatrixUtils.product(
                  MatrixUtils.inverse(MatrixUtils.product(MatrixUtils.transpose(V), V)),
                  MatrixUtils.product(MatrixUtils.transpose(V), Z)));
      A_hat =
          MatrixUtils.product(
              MatrixUtils.inverse(MatrixUtils.product(MatrixUtils.transpose(Z_hat), Z_hat)),
              MatrixUtils.product(MatrixUtils.transpose(Z_hat), yi));
      // Set the edge for the fixed measurement
      int position = ly.indexOf(current);
      semIm.setParamValue(current, my1.get(position), 1.);
      // Set the edge for the latents
      for (int i = 0; i < endp_a.length; i++) {
        semIm.setParamValue((Node) endp_a[i], current, A_hat[i]);
      }
      for (int i = 0; i < exop_a.length; i++) {
        semIm.setParamValue((Node) exop_a[i], current, A_hat[endp_a.length + i]);
      }
      if (nodeName != null && nodeName.equals(current.getName())) {
        computeAsymptLatentCovar(yi, A_hat, Z, Z_hat, dataSet.getNumRows());
        break;
      }
    }

    // ------------------------------------------------------------------

    // Estimate freeParameters of the measurement model

    // Set the edges of the fixed measurements of exogenous
    for (Node current : lx) {
      int position = lx.indexOf(current);
      semIm.setParamValue(current, mx1.get(position), 1.);
    }

    for (Node current : observed) {
      if (nodeName != null && !nodeName.equals(current.getName())) {
        continue;
      }
      if (mx1.contains(current) || my1.contains(current)) {
        continue;
      }

      // First, get the parent of this observed
      Node current_latent = null;

      for (Node node : semGraph.getParents(current)) {
        if (node.getNodeType() == NodeType.ERROR) {
          continue;
        }
        current_latent = node;
      }
      Iterator<Node> children = semGraph.getChildren(current_latent).iterator();
      List<Node> other_measures = new LinkedList<Node>();
      Node fixed_measurement;
      while (children.hasNext()) {
        Node next = children.next();
        if ((next.getNodeType() == NodeType.MEASURED) && next != current) {
          other_measures.add(next);
        }
      }
      if (lx.contains(current_latent)) {
        int position = lx.indexOf(current_latent);
        other_measures.remove(mx1.get(position));
        fixed_measurement = mx1.get(position);
      } else {
        int position = ly.indexOf(current_latent);
        other_measures.remove(my1.get(position));
        fixed_measurement = my1.get(position);
      }
      // Regress other_measures over the fixed measurement x1 (y1) correspondent
      // to the measurement variable that is being evaluated
      int n = dataSet.getNumRows(), c = other_measures.size();
      if (c == 0) {
        continue;
      }
      double Z[][] = new double[n][c];
      for (int i = 0; i < c; i++) {
        Node variable = dataSet.getVariable((other_measures.get(i)).getName());
        int varIndex = dataSet.getVariables().indexOf(variable);

        //                Column column = dataSet.getColumnObject(variable);
        //                double column_data[] = (double[]) column.getRawData();

        for (int j = 0; j < n; j++) {
          //                    Z[j][i] = column_data[j];
          Z[j][i] = dataSet.getDouble(varIndex, j);
        }
      }

      // Build C, the column matrix containing the data for the fixed
      // measurement associated with the only latent parent of the getModel
      // observed node (as assumed by the structure of our measurement model).
      Node variable = dataSet.getVariable(fixed_measurement.getName());
      int colIndex = dataSet.getVariables().indexOf(variable);
      //            Column column = dataSet.getColumnObject(variable);
      //            double C[] = (double[]) column.getRawData();

      double[] C = new double[dataSet.getNumRows()];

      for (int i = 0; i < dataSet.getNumRows(); i++) {
        C[i] = dataSet.getDouble(colIndex, i);
      }

      // Build V, the matrix containing the data for the other measurements
      // associated with the parents of the (latent) parent of getModel
      // observed node. The only difference with respect to the estimation
      // of the within-latent coefficients is that here we only include
      // the other measurements attached to the parent of the getModel node,
      // assuming that the error term of the getModel node is independent
      // of the error term of the others and that each measurement is
      // taken with respect to only one latent.
      n = dataSet.getNumRows();
      c = other_measures.size();
      double V[][] = new double[n][c];
      for (int i = 0; i < c; i++) {
        Node variable2 = dataSet.getVariable((other_measures.get(i)).getName());
        int var2index = dataSet.getVariables().indexOf(variable2);

        //                Column column = dataSet.getColumnObject(variable2);
        //                double column_data[] = (double[]) column.getRawData();

        for (int j = 0; j < n; j++) {
          //                    V[j][i] = column_data[j];
          V[j][i] = dataSet.getDouble(j, var2index);
        }
      }
      double yi[] = new double[n];
      Node variable3 = dataSet.getVariable((current).getName());
      int var3Index = dataSet.getVariables().indexOf(variable3);

      for (int i = 0; i < n; i++) {
        yi[i] = dataSet.getDouble(i, var3Index);
      }

      //            Object rawData = dataSet.getColumnObject(variable3).getRawData();
      //            System.arraycopy(rawData, 0, yi, 0, n);
      double C_hat[] =
          MatrixUtils.product(
              V,
              MatrixUtils.product(
                  MatrixUtils.inverse(MatrixUtils.product(MatrixUtils.transpose(V), V)),
                  MatrixUtils.product(MatrixUtils.transpose(V), C)));
      double A_hat =
          MatrixUtils.innerProduct(
              MatrixUtils.scalarProduct(1. / MatrixUtils.innerProduct(C_hat, C_hat), C_hat), yi);
      // Set the edge for the getModel measurement
      semIm.setParamValue(current_latent, current, A_hat);
    }

    return semIm;
  }
  /**
   * 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());
  }