internal CPT PointWiseProduct(CPT other) { IEnumerable <RandomVariable> commonVars = this.vars.Intersect(other.vars); HashSet <RandomVariable> rightVars = new HashSet <RandomVariable>(other.vars); rightVars.ExceptWith(commonVars); int[] commVarsIndicesInLeft = commonVars.Select <RandomVariable, int>(v => keyPosMap[v]).ToArray(); int[] commVarsIndicesInRight = commonVars.Select <RandomVariable, int>(v => other.keyPosMap[v]).ToArray(); List <RandomVariable> varsInResultCPT = new List <RandomVariable>(this.vars); List <RandomVariable> rightVarsInResult = new List <RandomVariable>(other.vars); rightVarsInResult.RemoveAll(v => commonVars.Contains(v)); varsInResultCPT.AddRange(rightVarsInResult); Dictionary <RandomVariable, int> newKeyPosMap = new Dictionary <RandomVariable, int>(); for (int i = 0; i < varsInResultCPT.Count(); i++) { newKeyPosMap.Add(varsInResultCPT[i], i); } int newCptSize = varsInResultCPT.Aggregate <RandomVariable, int>(1, (acc, v) => acc * v.tokens.Length); CptEntry[] newCptEntries = new CptEntry[newCptSize]; Dictionary <CptKey, List <CptEntry> > mapping = new Dictionary <CptKey, List <CptEntry> >(); CategoriseEntries(other, commVarsIndicesInRight, mapping); int cptIndex = 0; foreach (CptEntry leftEntry in this.cpt) { CptKey key = leftEntry.key.Extract(commVarsIndicesInLeft); List <CptEntry> right = mapping[key]; foreach (CptEntry rightEntry in right) { CptKey newKey = leftEntry.key.Concat(rightEntry.key.Remove(commVarsIndicesInRight)); newCptEntries[cptIndex] = new CptEntry(newKey, leftEntry.value * rightEntry.value); cptIndex++; } } return(new CPT(varsInResultCPT.ToArray(), newKeyPosMap, newCptEntries)); }
internal CPT(RandomVariable[] vars, double[] values) { this.vars = vars; this.keyPosMap = new Dictionary <RandomVariable, int>(); this.cpt = new CptEntry[values.Length]; for (int i = 0; i < vars.Length; i++) { keyPosMap.Add(vars[i], i); } CptKey[] keys = Enumerable.Range(1, values.Length).Select(_ => new CptKey(vars.Length)).ToArray(); SetKeys(new ArraySegment <CptKey>(keys), new ArraySegment <RandomVariable>(vars)); for (int i = 0; i < cpt.Length; i++) { cpt[i] = new CptEntry(keys[i], values[i]); } }