}
private double computeValueGradientForAssn (Assignment observations, ACRF.UnrolledVarSet clique, Variable target)
{
numCvgaCalls++;
Timing timing = new Timing ();
ACRF.Template tmpl = clique.getTemplate ();
int tidx = tmpl.index;
Assignment cliqueAssn = Assignment.restriction (observations, clique);
int M = target.getNumOutcomes ();
double[] vals = new double [M];
int[] singles = new int [M];
for (int assnIdx = 0; assnIdx < M; assnIdx++) {
cliqueAssn.setValue (target, assnIdx);
vals[assnIdx] = computeLogFactorValue (cliqueAssn, tmpl, clique.getFv ());
singles[assnIdx] = cliqueAssn.singleIndex ();
}
double logZ = Maths.sumLogProb (vals);
for (int assnIdx = 0; assnIdx < M; assnIdx++) {
double marginal = Math.exp (vals[assnIdx] - logZ);
int expIdx = singles[assnIdx];
expectations[tidx][expIdx].plusEqualsSparse (clique.getFv (), marginal);
if (defaultExpectations[tidx].location (expIdx) != -1) {
defaultExpectations[tidx].incrementValue (expIdx, marginal);
}
}
int observedVal = observations.get (target);
timePerCvgaCall += timing.elapsedTime ();
return vals[observedVal] - logZ;
}