void flattenDataToVector(omxMatrix* cov, omxMatrix* means, omxMatrix *obsThresholdMat, std::vector< omxThresholdColumn > &thresholds, omxMatrix* vector) { // TODO: vectorize data flattening // if(OMX_DEBUG) { mxLog("Flattening out data vectors: cov 0x%x, mean 0x%x, thresh 0x%x[n=%d] ==> 0x%x", // cov, means, thresholds, nThresholds, vector); } int nextLoc = 0; for(int j = 0; j < cov->rows; j++) { for(int k = j; k < cov->rows; k++) { omxSetVectorElement(vector, nextLoc, omxMatrixElement(cov, j, k)); // Use upper triangle in case of SYMM-style mat. nextLoc++; } } if (means != NULL) { for(int j = 0; j < cov->rows; j++) { omxSetVectorElement(vector, nextLoc, omxVectorElement(means, j)); nextLoc++; } } for(int j = 0; j < int(thresholds.size()); j++) { omxThresholdColumn* thresh = &thresholds[j]; for(int k = 0; k < thresh->numThresholds; k++) { omxSetVectorElement(vector, nextLoc, omxMatrixElement(obsThresholdMat, k, thresh->column)); nextLoc++; } } }
static void exportLatentDistToOMX(ba81NormalQuad &quad, double *latentDist1, omxMatrix *meanOut, omxMatrix *covOut) { const int maxAbilities = quad.abilities(); if (meanOut) { for (int d1=0; d1 < maxAbilities; d1++) { omxSetVectorElement(meanOut, d1, latentDist1[d1]); } } if (covOut) { for (int d1=0; d1 < maxAbilities; d1++) { int cx = maxAbilities + triangleLoc1(d1); for (int d2=0; d2 <= d1; d2++) { double cov = latentDist1[cx]; omxSetMatrixElement(covOut, d1, d2, cov); if (d1 != d2) omxSetMatrixElement(covOut, d2, d1, cov); ++cx; } } } }
static void omxRowFitFunctionSingleIteration(omxFitFunction *localobj, omxFitFunction *sharedobj, int rowbegin, int rowcount, FitContext *fc) { omxRowFitFunction* oro = ((omxRowFitFunction*) localobj->argStruct); omxRowFitFunction* shared_oro = ((omxRowFitFunction*) sharedobj->argStruct); omxMatrix *rowAlgebra, *rowResults; omxMatrix *filteredDataRow, *dataRow, *existenceVector; omxMatrix *dataColumns; omxData *data; int isContiguous, contiguousStart, contiguousLength; rowAlgebra = oro->rowAlgebra; rowResults = shared_oro->rowResults; data = oro->data; dataColumns = oro->dataColumns; dataRow = oro->dataRow; filteredDataRow = oro->filteredDataRow; existenceVector = oro->existenceVector; isContiguous = oro->contiguous.isContiguous; contiguousStart = oro->contiguous.start; contiguousLength = oro->contiguous.length; int *toRemove = (int*) malloc(sizeof(int) * dataColumns->cols); int *zeros = (int*) calloc(dataColumns->cols, sizeof(int)); for(int row = rowbegin; row < data->rows && (row - rowbegin) < rowcount; row++) { mxLogSetCurrentRow(row); data->loadDefVars(localobj->matrix->currentState, row); // Populate data row if (isContiguous) { omxContiguousDataRow(data, row, contiguousStart, contiguousLength, dataRow); } else { omxDataRow(data, row, dataColumns, dataRow); // Populate data row } markDataRowDependencies(localobj->matrix->currentState, oro); for(int j = 0; j < dataColumns->cols; j++) { if(omxDataElementMissing(data, row, j)) { toRemove[j] = 1; omxSetVectorElement(existenceVector, j, 0); } else { toRemove[j] = 0; omxSetVectorElement(existenceVector, j, 1); } } omxCopyMatrix(filteredDataRow, dataRow); omxRemoveRowsAndColumns(filteredDataRow, zeros, toRemove); omxRecompute(rowAlgebra, fc); omxCopyMatrixToRow(rowAlgebra, row, rowResults); } free(toRemove); free(zeros); }
static void omxRowFitFunctionSingleIteration(omxFitFunction *localobj, omxFitFunction *sharedobj, int rowbegin, int rowcount, FitContext *fc) { omxRowFitFunction* oro = ((omxRowFitFunction*) localobj->argStruct); omxRowFitFunction* shared_oro = ((omxRowFitFunction*) sharedobj->argStruct); omxMatrix *rowAlgebra, *rowResults; omxMatrix *filteredDataRow, *dataRow, *existenceVector; omxMatrix *dataColumns; omxData *data; int isContiguous, contiguousStart, contiguousLength; int numCols, numRemoves; rowAlgebra = oro->rowAlgebra; rowResults = shared_oro->rowResults; data = oro->data; dataColumns = oro->dataColumns; dataRow = oro->dataRow; filteredDataRow = oro->filteredDataRow; existenceVector = oro->existenceVector; isContiguous = oro->contiguous.isContiguous; contiguousStart = oro->contiguous.start; contiguousLength = oro->contiguous.length; Eigen::VectorXd oldDefs; oldDefs.resize(data->defVars.size()); oldDefs.setConstant(NA_REAL); numCols = dataColumns->cols; int *toRemove = (int*) malloc(sizeof(int) * dataColumns->cols); int *zeros = (int*) calloc(dataColumns->cols, sizeof(int)); for(int row = rowbegin; row < data->rows && (row - rowbegin) < rowcount; row++) { data->handleDefinitionVarList(localobj->matrix->currentState, row, oldDefs.data()); omxStateNextRow(localobj->matrix->currentState); // Advance row // Populate data row numRemoves = 0; if (isContiguous) { omxContiguousDataRow(data, row, contiguousStart, contiguousLength, dataRow); } else { omxDataRow(data, row, dataColumns, dataRow); // Populate data row } markDataRowDependencies(localobj->matrix->currentState, oro); for(int j = 0; j < dataColumns->cols; j++) { double dataValue = omxVectorElement(dataRow, j); if(std::isnan(dataValue)) { numRemoves++; toRemove[j] = 1; omxSetVectorElement(existenceVector, j, 0); } else { toRemove[j] = 0; omxSetVectorElement(existenceVector, j, 1); } } // TODO: Determine if this is the correct response. if(numRemoves == numCols) { char *errstr = (char*) calloc(250, sizeof(char)); sprintf(errstr, "Row %d completely missing. omxRowFitFunction cannot have completely missing rows.", omxDataIndex(data, row)); omxRaiseError(errstr); free(errstr); continue; } omxCopyMatrix(filteredDataRow, dataRow); omxRemoveRowsAndColumns(filteredDataRow, 0, numRemoves, zeros, toRemove); omxRecompute(rowAlgebra, fc); omxCopyMatrixToRow(rowAlgebra, omxDataIndex(data, row), rowResults); } free(toRemove); free(zeros); }