All Downloads are FREE. Search and download functionalities are using the official Maven repository.

aima.core.probability.full.FullJointDistributionModel Maven / Gradle / Ivy

Go to download

AIMA-Java Core Algorithms from the book Artificial Intelligence a Modern Approach 3rd Ed.

The newest version!
package aima.core.probability.full;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import aima.core.probability.CategoricalDistribution;
import aima.core.probability.FiniteProbabilityModel;
import aima.core.probability.ProbabilityModel;
import aima.core.probability.RandomVariable;
import aima.core.probability.proposition.ConjunctiveProposition;
import aima.core.probability.proposition.Proposition;
import aima.core.probability.util.ProbUtil;
import aima.core.probability.util.ProbabilityTable;

/**
 * An implementation of the FiniteProbabilityModel API using a full joint
 * distribution as the underlying model.
 * 
 * @author Ciaran O'Reilly
 */
public class FullJointDistributionModel implements FiniteProbabilityModel {

	private ProbabilityTable distribution = null;
	private Set representation = null;

	public FullJointDistributionModel(double[] values, RandomVariable... vars) {
		if (null == vars) {
			throw new IllegalArgumentException(
					"Random Variables describing the model's representation of the World need to be specified.");
		}

		distribution = new ProbabilityTable(values, vars);

		representation = new LinkedHashSet();
		for (int i = 0; i < vars.length; i++) {
			representation.add(vars[i]);
		}
		representation = Collections.unmodifiableSet(representation);
	}

	//
	// START-ProbabilityModel
	public boolean isValid() {
		// Handle rounding
		return Math.abs(1 - distribution.getSum()) <= ProbabilityModel.DEFAULT_ROUNDING_THRESHOLD;
	}

	public double prior(Proposition... phi) {
		return probabilityOf(ProbUtil.constructConjunction(phi));
	}

	public double posterior(Proposition phi, Proposition... evidence) {

		Proposition conjEvidence = ProbUtil.constructConjunction(evidence);

		// P(A | B) = P(A AND B)/P(B) - (13.3 AIMA3e)
		Proposition aAndB = new ConjunctiveProposition(phi, conjEvidence);
		double probabilityOfEvidence = prior(conjEvidence);
		if (0 != probabilityOfEvidence) {
			return prior(aAndB) / probabilityOfEvidence;
		}

		return 0;
	}

	public Set getRepresentation() {
		return representation;
	}

	// END-ProbabilityModel
	//

	//
	// START-FiniteProbabilityModel
	public CategoricalDistribution priorDistribution(Proposition... phi) {
		return jointDistribution(phi);
	}

	public CategoricalDistribution posteriorDistribution(Proposition phi,
			Proposition... evidence) {

		Proposition conjEvidence = ProbUtil.constructConjunction(evidence);

		// P(A | B) = P(A AND B)/P(B) - (13.3 AIMA3e)
		CategoricalDistribution dAandB = jointDistribution(phi, conjEvidence);
		CategoricalDistribution dEvidence = jointDistribution(conjEvidence);

		return dAandB.divideBy(dEvidence);
	}

	public CategoricalDistribution jointDistribution(
			Proposition... propositions) {
		ProbabilityTable d = null;
		final Proposition conjProp = ProbUtil
				.constructConjunction(propositions);
		final LinkedHashSet vars = new LinkedHashSet(
				conjProp.getUnboundScope());

		if (vars.size() > 0) {
			RandomVariable[] distVars = new RandomVariable[vars.size()];
			vars.toArray(distVars);

			final ProbabilityTable ud = new ProbabilityTable(distVars);
			final Object[] values = new Object[vars.size()];

			ProbabilityTable.Iterator di = new ProbabilityTable.Iterator() {

				public void iterate(Map possibleWorld,
						double probability) {
					if (conjProp.holds(possibleWorld)) {
						int i = 0;
						for (RandomVariable rv : vars) {
							values[i] = possibleWorld.get(rv);
							i++;
						}
						int dIdx = ud.getIndex(values);
						ud.setValue(dIdx, ud.getValues()[dIdx] + probability);
					}
				}
			};

			distribution.iterateOverTable(di);

			d = ud;
		} else {
			// No Unbound Variables, therefore just return
			// the singular probability related to the proposition.
			d = new ProbabilityTable();
			d.setValue(0, prior(propositions));
		}
		return d;
	}

	// END-FiniteProbabilityModel
	//

	//
	// PRIVATE METHODS
	//
	private double probabilityOf(final Proposition phi) {
		final double[] probSum = new double[1];
		ProbabilityTable.Iterator di = new ProbabilityTable.Iterator() {
			public void iterate(Map possibleWorld,
					double probability) {
				if (phi.holds(possibleWorld)) {
					probSum[0] += probability;
				}
			}
		};

		distribution.iterateOverTable(di);

		return probSum[0];
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy