public FourParentNodes(ModelNode node) { this.node = node; Range parent1States = node.parents[0].states; Range parent2States = node.parents[1].states; Range parent3States = node.parents[2].states; Range parent4States = node.parents[3].states; CPTPrior = Variable.Array(Variable.Array <Dirichlet>(parent1States), parent2States, parent3States, parent4States).Named("Prob" + node.name + "Prior"); Dirichlet[, , ][] priorObserved = new Dirichlet[parent2States.SizeAsInt, parent3States.SizeAsInt, parent4States.SizeAsInt][]; for (int p2 = 0; p2 < parent2States.SizeAsInt; p2++) { for (int p3 = 0; p3 < parent3States.SizeAsInt; p3++) { for (int p4 = 0; p4 < parent3States.SizeAsInt; p4++) { priorObserved[p2, p3, p4] = Enumerable.Repeat(Dirichlet.Uniform(node.states.SizeAsInt), parent1States.SizeAsInt).ToArray(); } } } CPTPrior.ObservedValue = priorObserved; CPT = Variable.Array(Variable.Array <Vector>(parent1States), parent2States, parent3States, parent4States).Named("Prob" + node.name); CPT[parent2States, parent3States, parent4States][parent1States] = Variable <Vector> .Random(CPTPrior[parent2States, parent3States, parent4States][parent1States]); CPT.SetValueRange(node.states); }
/// <summary> /// Helper method to add a child from two parents /// </summary> /// <param name="parent1">First parent (a variable array over a range of examples)</param> /// <param name="parent2">Second parent (a variable array over the same range)</param> /// <param name="cpt">Conditional probability table</param> /// <returns></returns> public static VariableArray <int> AddChildFromFourParents( VariableArray <int> parent1, VariableArray <int> parent2, VariableArray <int> parent3, VariableArray <int> parent4, VariableArray3D <VariableArray <Vector>, Vector[, , ][]> cpt) { var n = parent1.Range; var child = Variable.Array <int>(n); using (Variable.ForEach(n)) using (Variable.Switch(parent1[n])) using (Variable.Switch(parent2[n])) using (Variable.Switch(parent3[n])) child[n] = Variable.Discrete(cpt[parent2[n], parent3[n], parent4[n]][parent1[n]]); return(child); }