/** * Takes a Cholesky decomposition from the Cholesky.cholesky method and a set of data simulated * using the information in that matrix. Written by Don Crimbchin. Modified June 8, Matt * Easterday: added a random # seed so that data can be recalculated with the same result in * Causality lab * * @param cholesky the result from cholesky above. * @param randomUtil a random number generator, if null the method will make a new generator for * each random number needed * @return an array the same length as the width or length (cholesky should have the same width * and length) containing a randomly generate data set. */ private double[] exogenousData(TetradMatrix cholesky, RandomUtil randomUtil) { // Step 1. Generate normal samples. double exoData[] = new double[cholesky.rows()]; for (int i = 0; i < exoData.length; i++) { exoData[i] = randomUtil.nextNormal(0, 1); } // Step 2. Multiply by cholesky to get correct covariance. double point[] = new double[exoData.length]; for (int i = 0; i < exoData.length; i++) { double sum = 0.0; for (int j = 0; j <= i; j++) { sum += cholesky.get(i, j) * exoData[j]; } point[i] = sum; } return point; }
/** * @param sampleSize The sample size of the desired data set. * @param latentDataSaved True if latent variables should be included in the data set. * @return This returns a standardized data set simulated from the model, using the reduced form * method. */ public DataSet simulateDataReducedForm(int sampleSize, boolean latentDataSaved) { int numVars = getVariableNodes().size(); // Calculate inv(I - edgeCoef) TetradMatrix edgeCoef = edgeCoef().copy().transpose(); // TetradMatrix iMinusB = TetradAlgebra.identity(edgeCoef.rows()); // iMinusB.assign(edgeCoef, Functions.minus); TetradMatrix iMinusB = TetradAlgebra.identity(edgeCoef.rows()).minus(edgeCoef); TetradMatrix inv = iMinusB.inverse(); // Pick error values e, for each calculate inv * e. TetradMatrix sim = new TetradMatrix(sampleSize, numVars); // Generate error data with the right variances and covariances, then override this // with error data for varaibles that have special distributions defined. Not ideal, // but not sure what else to do at the moment. It's better than not taking covariances // into account! TetradMatrix cholesky = MatrixUtils.choleskyC(errCovar(errorVariances())); for (int i = 0; i < sampleSize; i++) { TetradVector e = new TetradVector(exogenousData(cholesky, RandomUtil.getInstance())); TetradVector ePrime = inv.times(e); sim.assignRow(i, ePrime); // sim.viewRow(i).assign(ePrime); } DataSet fullDataSet = ColtDataSet.makeContinuousData(getVariableNodes(), sim); if (latentDataSaved) { return fullDataSet; } else { return DataUtils.restrictToMeasured(fullDataSet); } }