Exemple #1
0
void loglikelihoodCIFun(omxFitFunction *ff, int want, FitContext *fc)
{
	const omxConfidenceInterval *CI = fc->CI;

	if (want & FF_COMPUTE_PREOPTIMIZE) {
		fc->targetFit = (fc->lowerBound? CI->lbound : CI->ubound) + fc->fit;
		//mxLog("Set target fit to %f (MLE %f)", fc->targetFit, fc->fit);
		return;
	}

	if (!(want & FF_COMPUTE_FIT)) {
		Rf_error("Not implemented yet");
	}

	omxMatrix *fitMat = ff->matrix;

	// We need to compute the fit here because that's the only way to
	// check our soft feasibility constraints. If parameters don't
	// change between here and the constraint evaluation then we
	// should avoid recomputing the fit again in the constraint. TODO

	omxFitFunctionCompute(fitMat->fitFunction, FF_COMPUTE_FIT, fc);
	const double fit = totalLogLikelihood(fitMat);
	omxRecompute(CI->matrix, fc);
	double CIElement = omxMatrixElement(CI->matrix, CI->row, CI->col);
	omxResizeMatrix(fitMat, 1, 1);

	if (!std::isfinite(fit) || !std::isfinite(CIElement)) {
		fc->recordIterationError("Confidence interval is in a range that is currently incalculable. Add constraints to keep the value in the region where it can be calculated.");
		fitMat->data[0] = nan("infeasible");
		return;
	}

	if (want & FF_COMPUTE_FIT) {
		double param = (fc->lowerBound? CIElement : -CIElement);
		if (fc->compositeCIFunction) {
			double diff = fc->targetFit - fit;
			diff *= diff;
			if (diff > 1e2) {
				// Ensure there aren't any creative solutions
				diff = nan("infeasible");
				return;
			}
			fitMat->data[0] = diff + param;
		} else {
			fitMat->data[0] = param;
		}
		//mxLog("param at %f", fitMat->data[0]);
	}
	if (want & (FF_COMPUTE_GRADIENT | FF_COMPUTE_HESSIAN | FF_COMPUTE_IHESSIAN)) {
		// add deriv adjustments here TODO
	}
}
Exemple #2
0
void FitMultigroup::compute(int want, FitContext *fc)
{
	omxMatrix *fitMatrix = matrix;
	double fit = 0;
	double mac = 0;

	FitMultigroup *mg = (FitMultigroup*) this;

	for (size_t ex=0; ex < mg->fits.size(); ex++) {
		omxMatrix* f1 = mg->fits[ex];
		if (f1->fitFunction) {
			omxFitFunctionCompute(f1->fitFunction, want, fc);
			if (want & FF_COMPUTE_MAXABSCHANGE) {
				mac = std::max(fc->mac, mac);
			}
			if (want & FF_COMPUTE_PREOPTIMIZE) {
				if (units == FIT_UNITS_UNINITIALIZED) {
					units = f1->fitFunction->units;
				} else if (units != f1->fitFunction->units) {
					mxThrow("%s: cannot combine units %s and %s (from %s)",
						matrix->name(), fitUnitsToName(units),
						fitUnitsToName(f1->fitFunction->units), f1->name());
				}
			}
		} else {
			omxRecompute(f1, fc);
		}
		if (want & FF_COMPUTE_FIT) {
			if(f1->rows != 1 || f1->cols != 1) {
				omxRaiseErrorf("%s[%d]: %s of type %s does not evaluate to a 1x1 matrix",
					       fitMatrix->name(), (int)ex, f1->name(), f1->fitFunction->fitType);
			}
			fit += f1->data[0];
			if (mg->verbose >= 1) { mxLog("%s: %s fit=%f", fitMatrix->name(), f1->name(), f1->data[0]); }
		}
	}

	if (fc) fc->mac = mac;

	if (want & FF_COMPUTE_FIT) {
		fitMatrix->data[0] = fit;
		if (mg->verbose >= 1) { mxLog("%s: fit=%f", fitMatrix->name(), fit); }
	}
}
Exemple #3
0
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);
	}
}
Exemple #4
0
	void state::compute(int want, FitContext *fc)
	{
		state *st = (state*) this;
		auto *oo = this;

		for (auto c1 : components) {
			if (c1->fitFunction) {
				omxFitFunctionCompute(c1->fitFunction, want, fc);
			} else {
				omxRecompute(c1, fc);
			}
		}
		if (!(want & FF_COMPUTE_FIT)) return;

		int nrow = components[0]->rows;
		for (auto c1 : components) {
			if (c1->rows != nrow) {
				mxThrow("%s: component '%s' has %d rows but component '%s' has %d rows",
					 oo->name(), components[0]->name(), nrow, c1->name(), c1->rows);
			}
		}

		Eigen::VectorXd expect;
		Eigen::VectorXd rowResult;
		int numC = components.size();
		Eigen::VectorXd tp(numC);
		double lp=0;
		for (int rx=0; rx < nrow; ++rx) {
			if (expectation->loadDefVars(rx) || rx == 0) {
				omxExpectationCompute(fc, expectation, NULL);
				if (!st->transition || rx == 0) {
					EigenVectorAdaptor Einitial(st->initial);
					expect = Einitial;
					if (expect.rows() != numC || expect.cols() != 1) {
						omxRaiseErrorf("%s: initial prob matrix must be %dx%d not %dx%d",
							       name(), numC, 1, expect.rows(), expect.cols());
						return;
					}
				}
				if (st->transition && (st->transition->rows != numC || st->transition->cols != numC)) {
					omxRaiseErrorf("%s: transition prob matrix must be %dx%d not %dx%d",
						       name(), numC, numC, st->transition->rows, st->transition->cols);
					return;
				}
			}
			for (int cx=0; cx < int(components.size()); ++cx) {
				EigenVectorAdaptor Ecomp(components[cx]);
				tp[cx] = Ecomp[rx];
			}
			if (st->verbose >= 4) {
				mxPrintMat("tp", tp);
			}
			if (st->transition) {
				EigenMatrixAdaptor Etransition(st->transition);
				expect = (Etransition * expect).eval();
			}
			rowResult = tp.array() * expect.array();
			double rowp = rowResult.sum();
			rowResult /= rowp;
			lp += log(rowp);
			if (st->transition) expect = rowResult;
		}
		oo->matrix->data[0] = Global->llScale * lp;
		if (st->verbose >= 2) mxLog("%s: fit=%f", oo->name(), lp);
	}