// Does vector=TRUE mean something sensible? Mixture of mixtures? void state::init() { auto *oo = this; auto *ms = this; if (!oo->expectation) { mxThrow("%s requires an expectation", oo->fitType); } oo->units = FIT_UNITS_MINUS2LL; oo->canDuplicate = true; omxState *currentState = oo->matrix->currentState; const char *myex1 = "MxExpectationHiddenMarkov"; const char *myex2 = "MxExpectationMixture"; if (!expectation || !(strEQ(expectation->expType, myex1) || strEQ(expectation->expType, myex2))) mxThrow("%s must be paired with %s or %s", oo->name(), myex1, myex2); ProtectedSEXP Rverbose(R_do_slot(oo->rObj, Rf_install("verbose"))); ms->verbose = Rf_asInteger(Rverbose); ProtectedSEXP Rcomponents(R_do_slot(oo->rObj, Rf_install("components"))); int nc = Rf_length(Rcomponents); int *cvec = INTEGER(Rcomponents); componentUnits = FIT_UNITS_UNINITIALIZED; for (int cx=0; cx < nc; ++cx) { omxMatrix *fmat = currentState->algebraList[ cvec[cx] ]; if (fmat->fitFunction) { omxCompleteFitFunction(fmat); auto ff = fmat->fitFunction; if (ff->units != FIT_UNITS_PROBABILITY) { omxRaiseErrorf("%s: component %s must be in probability units", oo->name(), ff->name()); return; } if (componentUnits == FIT_UNITS_UNINITIALIZED) { componentUnits = ff->units; } else if (ff->units != componentUnits) { omxRaiseErrorf("%s: components with heterogenous units %s and %s in same mixture", oo->name(), fitUnitsToName(ff->units), fitUnitsToName(componentUnits)); } } ms->components.push_back(fmat); } if (componentUnits == FIT_UNITS_UNINITIALIZED) componentUnits = FIT_UNITS_PROBABILITY; ms->initial = expectation->getComponent("initial"); ms->transition = expectation->getComponent("transition"); }
void FitMultigroup::init() { auto *oo = this; FitMultigroup *mg =this; SEXP rObj = oo->rObj; if (!rObj) return; if (mg->fits.size()) return; // hack to prevent double initialization, remove TOOD oo->units = FIT_UNITS_UNINITIALIZED; oo->gradientAvailable = TRUE; oo->hessianAvailable = TRUE; oo->canDuplicate = true; omxState *os = oo->matrix->currentState; ProtectedSEXP Rverb(R_do_slot(rObj, Rf_install("verbose"))); mg->verbose = Rf_asInteger(Rverb); ProtectedSEXP Rgroups(R_do_slot(rObj, Rf_install("groups"))); int *fits = INTEGER(Rgroups); for(int gx = 0; gx < Rf_length(Rgroups); gx++) { if (isErrorRaised()) break; omxMatrix *mat; if (fits[gx] >= 0) { mat = os->algebraList[fits[gx]]; } else { mxThrow("Can only add algebra and fitfunction"); } if (mat == oo->matrix) mxThrow("Cannot add multigroup to itself"); mg->fits.push_back(mat); if (mat->fitFunction) { omxCompleteFitFunction(mat); oo->gradientAvailable = (oo->gradientAvailable && mat->fitFunction->gradientAvailable); oo->hessianAvailable = (oo->hessianAvailable && mat->fitFunction->hessianAvailable); } else { oo->gradientAvailable = FALSE; oo->hessianAvailable = FALSE; } } }
void omxState::initialRecalc(FitContext *fc) { omxInitialMatrixAlgebraCompute(fc); for(size_t j = 0; j < expectationList.size(); j++) { // TODO: Smarter inference for which expectations to duplicate omxCompleteExpectation(expectationList[j]); } for (int ax=0; ax < (int) algebraList.size(); ++ax) { omxMatrix *matrix = algebraList[ax]; if (!matrix->fitFunction) continue; omxCompleteFitFunction(matrix); omxFitFunctionCompute(matrix->fitFunction, FF_COMPUTE_INITIAL_FIT, fc); } for (size_t xx=0; xx < conListX.size(); ++xx) { conListX[xx]->prep(fc); } }