public GeneralizedSemPm(SemPm semPm) { this(semPm.getGraph()); // Write down equations. try { List<Node> variableNodes = getVariableNodes(); for (int i = 0; i < variableNodes.size(); i++) { Node node = variableNodes.get(i); List<Node> parents = getVariableParents(node); StringBuilder buf = new StringBuilder(); for (int j = 0; j < parents.size(); j++) { if (!(variableNodes.contains(parents.get(j)))) { continue; } Node parent = parents.get(j); Parameter _parameter = semPm.getParameter(parent, node); String parameter = _parameter.getName(); Set<Node> nodes = new HashSet<>(); nodes.add(node); referencedParameters.put(parameter, nodes); buf.append(parameter); buf.append("*"); buf.append(parents.get(j).getName()); setParameterExpression(parameter, "Split(-1.5, -.5, .5, 1.5)"); setStartsWithParametersTemplate(parameter.substring(0, 1), "Split(-1.5, -.5, .5, 1.5)"); setStartsWithParametersEstimationInitializaationTemplate( parameter.substring(0, 1), "Split(-1.5, -.5, .5, 1.5)"); if (j < parents.size() - 1) { buf.append(" + "); } } if (buf.toString().trim().length() != 0) { buf.append(" + "); } buf.append(errorNodes.get(i)); setNodeExpression(node, buf.toString()); } for (Node node : variableNodes) { Parameter _parameter = semPm.getParameter(node, node); String parameter = _parameter.getName(); String distributionFormula = "N(0," + parameter + ")"; setNodeExpression(getErrorNode(node), distributionFormula); setParameterExpression(parameter, "U(0, 1)"); setStartsWithParametersTemplate(parameter.substring(0, 1), "U(0, 1)"); setStartsWithParametersEstimationInitializaationTemplate( parameter.substring(0, 1), "U(0, 1)"); } variableNames = new ArrayList<>(); for (Node _node : variableNodes) variableNames.add(_node.getName()); for (Node _node : errorNodes) variableNames.add(_node.getName()); } catch (ParseException e) { throw new IllegalStateException("Parse error in constructing initial model.", e); } }
/** * 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()); }