@Override public @Nullable IDatum setPrior(@Nullable Object prior) { if (prior instanceof double[]) { return setPrior((double[]) prior); } if (prior instanceof Value) { Value value = (Value) prior; final DiscreteDomain domain = getDomain(); if (!domain.equals(value.getDomain())) { // If domain does not match, create a new value with the correct domain. This ensures // that indexing operations can be assumed to be correct for this variable. prior = Value.create(domain, requireNonNull(value.getObject())); } } return super.setPrior(prior); }
/** * Sets values for domain from datum. * * <p> * * @param domain discrete domain with size matching {@link #size()}. * @param datum either an exact {@link Value}, another {@link DiscreteMessage} or other {@link * IUnaryFactorFunction} used to evaluate energies for all possible discrete values. * @since 0.08 */ public void setFrom(DiscreteDomain domain, IDatum datum) { if (datum instanceof DiscreteMessage) { setFrom((DiscreteMessage) datum); } else if (datum instanceof Value) { Value value = (Value) datum; if (domain.equals(value.getDomain())) { setDeterministicIndex(value.getIndex()); } else { setDeterministicIndex(domain.getIndex(value.getObject())); } } else { IUnaryFactorFunction function = (IUnaryFactorFunction) datum; assertSameSize(domain.size()); DiscreteValue value = Value.create(domain); for (int i = domain.size(); --i >= 0; ) { value.setIndex(i); setEnergy(i, function.evalEnergy(value)); } } }
private @Nullable IDatum joinPriors( JointDiscreteDomain<?> jointDomain, IDatum[] subdomainPriors) { final JointDomainIndexer domains = jointDomain.getDomainIndexer(); final int dimensions = jointDomain.getDimensions(); boolean hasPrior = false; int[] fixedIndices = new int[dimensions]; Arrays.fill(fixedIndices, -1); for (int i = 0; i < dimensions; ++i) { DiscreteDomain domain = domains.get(i); IDatum prior = subdomainPriors[i]; if (prior != null) { hasPrior = true; if (prior instanceof Value) { Value value = (Value) prior; fixedIndices[i] = domain.equals(value.getDomain()) ? value.getIndex() : domain.getIndex(value.getObject()); subdomainPriors[i] = new DiscreteEnergyMessage(domain, value); } else { DiscreteMessage msg = prior instanceof DiscreteMessage ? (DiscreteMessage) prior : new DiscreteWeightMessage(domain, prior); subdomainPriors[i] = msg; fixedIndices[i] = msg.toDeterministicValueIndex(); } } } if (!hasPrior) { // If none of the component variables has a prior, then neither will the joint variable. return null; } boolean hasAllFixedPriors = true; for (int i : fixedIndices) { if (i < 0) { hasAllFixedPriors = false; break; } } if (hasAllFixedPriors) { // Return fixed value with appropriate joint index. return Value.createWithIndex(jointDomain, domains.jointIndexFromIndices(fixedIndices)); } int cardinality = jointDomain.size(); double[] energies = new double[cardinality]; int inner = 1, outer = cardinality; for (int dim = 0; dim < dimensions; ++dim) { final DiscreteDomain domain = domains.get(dim); final DiscreteMessage prior = (DiscreteMessage) subdomainPriors[dim]; final int size = domain.size(); int i = 0; outer /= size; if (prior != null) { for (int o = 0; o < outer; ++o) { for (double energy : prior.getEnergies()) { for (int r = 0; r < inner; ++r) { energies[i++] += energy; } } } } inner *= size; } return new DiscreteEnergyMessage(energies); }