/** * Calculate the indexes for X[i] into a vector representing the enumeration * of the value assignments for the variables X and their corresponding * assignment in x. For example the Random Variables:<br> * Q::{true, false}, R::{'A', 'B','C'}, and T::{true, false}, would be * enumerated in a Vector as follows: * * <pre> * Index Q R T * ----- - - - * 00: true, A, true * 01: true, A, false * 02: true, B, true * 03: true, B, false * 04: true, C, true * 05: true, C, false * 06: false, A, true * 07: false, A, false * 08: false, B, true * 09: false, B, false * 10: false, C, true * 11: false, C, false * </pre> * * if X[i] = R and x = {..., R='C', ...} then the indexes returned would be * [4, 5, 10, 11]. * * @param X * a list of the Random Variables that would comprise the vector. * @param idx * the index into X for the Random Variable whose assignment we * wish to retrieve its indexes for. * @param x * an assignment for the Random Variables in X. * @return the indexes into a vector that would represent the enumeration of * the values for X[i] in x. */ public static int[] indexesOfValue(IRandomVariable[] X, int idx, IMap <IRandomVariable, object> x) { int csize = ProbUtil.expectedSizeOfCategoricalDistribution(X); IFiniteDomain fd = (IFiniteDomain)X[idx].getDomain(); int vdoffset = fd.GetOffset(x.Get(X[idx])); int vdosize = fd.Size(); int[] indexes = new int[csize / vdosize]; int blocksize = csize; for (int i = 0; i < X.Length; ++i) { blocksize = blocksize / X[i].getDomain().Size(); if (i == idx) { break; } } for (int i = 0; i < indexes.Length; i += blocksize) { int offset = ((i / blocksize) * vdosize * blocksize) + (blocksize * vdoffset); for (int b = 0; b < blocksize; b++) { indexes[i + b] = offset + b; } } return(indexes); }
/** * Calculate the index into a vector representing the enumeration of the * value assignments for the variables X and their corresponding assignment * in x. For example the Random Variables:<br> * Q::{true, false}, R::{'A', 'B','C'}, and T::{true, false}, would be * enumerated in a Vector as follows: * * <pre> * Index Q R T * ----- - - - * 00: true, A, true * 01: true, A, false * 02: true, B, true * 03: true, B, false * 04: true, C, true * 05: true, C, false * 06: false, A, true * 07: false, A, false * 08: false, B, true * 09: false, B, false * 10: false, C, true * 11: false, C, false * </pre> * * if x = {Q=true, R='C', T=false} the index returned would be 5. * * @param X * a list of the Random Variables that would comprise the vector. * @param x * an assignment for the Random Variables in X. * @return an index into a vector that would represent the enumeration of * the values for X. */ public static int indexOf(IRandomVariable[] X, IMap <IRandomVariable, object> x) { if (0 == X.Length) { return(((IFiniteDomain)X[0].getDomain()).GetOffset(x.Get(X[0]))); } // X.Length > 1 then calculate using a mixed radix number // // Note: Create radices in reverse order so that the enumeration // through the distributions is of the following // order using a MixedRadixNumber, e.g. for two Booleans: // X Y // true true // true false // false true // false false // which corresponds with how displayed in book. int[] radixValues = new int[X.Length]; int[] radices = new int[X.Length]; int j = X.Length - 1; for (int i = 0; i < X.Length; ++i) { IFiniteDomain fd = (IFiniteDomain)X[i].getDomain(); radixValues[j] = fd.GetOffset(x.Get(X[i])); radices[j] = fd.Size(); j--; } return(new MixedRadixNumber(radixValues, radices).IntValue()); }
public SubsetProposition(string name, IFiniteDomain subsetDomain, IRandomVariable ofVar) : base(name) { if (null == subsetDomain) { throw new IllegalArgumentException("Sum Domain must be specified."); } this.subsetDomain = subsetDomain; this.varSubsetOf = ofVar; addScope(this.varSubsetOf); }
/** * Calculate the probability distribution for <b>P</b>(X<sub>i</sub> | * mb(X<sub>i</sub>)), where mb(X<sub>i</sub>) is the Markov Blanket of * X<sub>i</sub>. The probability of a variable given its Markov blanket is * proportional to the probability of the variable given its parents times * the probability of each child given its respective parents (see equation * 14.12 pg. 538 AIMA3e):<br> * <br> * P(x'<sub>i</sub>|mb(Xi)) = * αP(x'<sub>i</sub>|parents(X<sub>i</sub>)) * * ∏<sub>Y<sub>j</sub> ∈ Children(X<sub>i</sub>)</sub> * P(y<sub>j</sub>|parents(Y<sub>j</sub>)) * * @param Xi * a Node from a Bayesian network for the Random Variable * X<sub>i</sub>. * @param event * comprising assignments for the Markov Blanket X<sub>i</sub>. * @return a random sample from <b>P</b>(X<sub>i</sub> | mb(X<sub>i</sub>)) */ public static double[] mbDistribution(INode Xi, IMap <IRandomVariable, object> even) { IFiniteDomain fd = (IFiniteDomain)Xi.GetRandomVariable().getDomain(); double[] X = new double[fd.Size()]; /** * As we iterate over the domain of a ramdom variable corresponding to Xi * it is necessary to make the modified values of the variable visible * to the child nodes of Xi in the computation of the markov blanket * probabilities. */ //Copy contents of event to generatedEvent so as to leave event untouched IMap <IRandomVariable, object> generatedEvent = CollectionFactory.CreateInsertionOrderedMap <IRandomVariable, object>(); foreach (var entry in even) { generatedEvent.Put(entry.GetKey(), entry.GetValue()); } for (int i = 0; i < fd.Size(); ++i) { /** P(x'<sub>i</sub>|mb(Xi)) = * αP(x'<sub>i</sub>|parents(X<sub>i</sub>)) * * ∏<sub>Y<sub>j</sub> ∈ Children(X<sub>i</sub>)</sub> * P(y<sub>j</sub>|parents(Y<sub>j</sub>)) */ generatedEvent.Put(Xi.GetRandomVariable(), fd.GetValueAt(i)); double cprob = 1.0; foreach (INode Yj in Xi.GetChildren()) { cprob *= Yj.GetCPD().GetValue( getEventValuesForXiGivenParents(Yj, generatedEvent)); } X[i] = Xi.GetCPD() .GetValue( getEventValuesForXiGivenParents(Xi, fd.GetValueAt(i), even)) * cprob; } return(Util.normalize(X)); }
/** * * @param probabilityChoice * a probability choice for the sample * @param Xi * a Random Variable with a finite domain from which a random * sample is to be chosen based on the probability choice. * @param distribution * Xi's distribution. * @return a Random Sample from Xi's domain. */ public static object sample(double probabilityChoice, IRandomVariable Xi, double[] distribution) { IFiniteDomain fd = (IFiniteDomain)Xi.getDomain(); if (fd.Size() != distribution.Length) { throw new IllegalArgumentException("Size of domain Xi " + fd.Size() + " is not equal to the size of the distribution " + distribution.Length); } int i = 0; double total = distribution[0]; while (probabilityChoice > total) { ++i; total += distribution[i]; } return(fd.GetValueAt(i)); }
/** * Calculated the expected size of a ProbabilityTable for the provided * random variables. * * @param vars * null, 0 or more random variables that are to be used to * construct a CategoricalDistribution. * @return the size (i.e. getValues().Length) that the * CategoricalDistribution will need to be in order to represent the * specified random variables. * * @see CategoricalDistribution#getValues() */ public static int expectedSizeOfProbabilityTable(params IRandomVariable[] vars) { // initially 1, as this will represent constant assignments // e.g. Dice1 = 1. int expectedSizeOfDistribution = 1; if (null != vars) { foreach (IRandomVariable rv in vars) { // Create ordered domains for each variable if (!(rv.getDomain() is IFiniteDomain)) { throw new IllegalArgumentException("Cannot have an infinite domain for a variable in this calculation:" + rv); } IFiniteDomain d = (IFiniteDomain)rv.getDomain(); expectedSizeOfDistribution *= d.Size(); } } return(expectedSizeOfDistribution); }
/// <summary> /// Instantiate a Hidden Markov Model. /// </summary> /// <param name="stateVariable"> /// the single discrete random variable used to describe the process states 1,...,S. /// </param> /// <param name="transitionModel"> /// the transition model:<para /> /// P(Xt | Xt-1)<para /> /// is represented by an S * S matrix T where /// Tij= P(Xt = j | Xt-1 = i). /// </param> /// <param name="sensorModel"> /// the sensor model in matrix form:<para /> /// P(et | Xt = i) for each state i. For /// mathematical convenience we place each of these values into an /// S * S diagonal matrix. /// </param> /// <param name="prior">the prior distribution represented as a column vector in Matrix form.</param> public HiddenMarkovModel(IRandomVariable stateVariable, Matrix transitionModel, IMap <object, Matrix> sensorModel, Matrix prior) { if (!stateVariable.getDomain().IsFinite()) { throw new IllegalArgumentException("State Variable for HHM must be finite."); } this.stateVariable = stateVariable; stateVariableDomain = (IFiniteDomain)stateVariable.getDomain(); if (transitionModel.GetRowDimension() != transitionModel .GetColumnDimension()) { throw new IllegalArgumentException("Transition Model row and column dimensions must match."); } if (stateVariableDomain.Size() != transitionModel.GetRowDimension()) { throw new IllegalArgumentException("Transition Model Matrix does not map correctly to the HMM's State Variable."); } this.transitionModel = transitionModel; foreach (Matrix smVal in sensorModel.GetValues()) { if (smVal.GetRowDimension() != smVal.GetColumnDimension()) { throw new IllegalArgumentException("Sensor Model row and column dimensions must match."); } if (stateVariableDomain.Size() != smVal.GetRowDimension()) { throw new IllegalArgumentException("Sensor Model Matrix does not map correctly to the HMM's State Variable."); } } this.sensorModel = sensorModel; if (transitionModel.GetRowDimension() != prior.GetRowDimension() && prior.GetColumnDimension() != 1) { throw new IllegalArgumentException("Prior is not of the correct dimensions."); } this.prior = prior; }
public RVInfo(IRandomVariable rv) { variable = rv; varDomain = (IFiniteDomain)variable.getDomain(); }