internal CPT SumOut(RandomVariable varToSumOut) { int varToSumOutIndex = keyPosMap[varToSumOut]; RandomVariable[] remainingVars = vars.Where(v => !v.Equals(varToSumOut)).ToArray(); Dictionary <RandomVariable, int> newStartPosMap = keyPosMap .Where(kvp => !kvp.Key.Equals(varToSumOut)) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value > varToSumOutIndex ? kvp.Value - 1 : kvp.Value); Dictionary <CptKey, List <CptEntry> > mapping = new Dictionary <CptKey, List <CptEntry> >(); foreach (CptEntry entry in cpt) { CptKey key = entry.key.Remove(varToSumOutIndex); if (!mapping.ContainsKey(key)) { mapping.Add(key, new List <CptEntry>()); } mapping[key].Add(entry); } List <CptEntry> newEntries = new List <CptEntry>(); foreach (KeyValuePair <CptKey, List <CptEntry> > entry in mapping) { double value = entry.Value.Aggregate <CptEntry, double>(0, (acc, e) => acc + e.value); newEntries.Add(new CptEntry(entry.Key, value)); } return(new CPT(remainingVars, newStartPosMap, newEntries.ToArray())); }
private CptEntry[] FilterCptByEvidence(Proposition[] evidence) { CptKey searchKey = EvidenceToKey(evidence); return(cpt .Where(entry => entry.key.Match(searchKey)) .ToArray()); }
internal CptKey Concat(CptKey other) { CptKey newKey = new CptKey(this.size + other.size); Array.Copy(key, 0, newKey.key, 0, this.size); Array.Copy(other.key, 0, newKey.key, this.size, other.size); return(newKey); }
public override bool Equals(object obj) { if (obj == null || GetType() != obj.GetType()) { return(false); } CptKey otherKey = (CptKey)obj; return(this.ToString().Equals(otherKey.ToString())); }
private CptKey EvidenceToKey(Proposition[] evidence) { CptKey searchKey = new CptKey(GetKeySize(), true); foreach (Proposition e in evidence) { RandomVariable var = this.vars.Single(d => d.name.Equals(e.name)); searchKey.Set(keyPosMap[var], (char)e.valueIndex); } return(searchKey); }
private void CategoriseEntries(CPT factor, int[] commVarsIndices, Dictionary <CptKey, List <CptEntry> > mapping) { foreach (CptEntry entry in factor.cpt) { CptKey key = entry.key.Extract(commVarsIndices); if (!mapping.ContainsKey(key)) { mapping.Add(key, new List <CptEntry>()); } mapping[key].Add(entry); } }
internal CptKey Extract(params int[] indices) { if (indices.Any(i => i >= this.size)) { throw new ArgumentOutOfRangeException(); } CptKey newKey = new CptKey(indices.Length); for (int i = 0; i < indices.Length; i++) { newKey.key[i] = this.key[indices[i]]; } return(newKey); }
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 bool Match(CptKey searchKey) { if (searchKey.size != this.size) { throw new ArgumentException(string.Format("This key has length {0} but the key to match has length {1}", this.size, searchKey.size)); } bool match = true; for (int i = 0; i < size; i++) { char c1 = key[i]; char c2 = searchKey.key[i]; if (c1 != WILDCARD && c2 != WILDCARD && c1 != c2) { match = false; break; } } return(match); }
private void SetKeys(ArraySegment <CptKey> keys, ArraySegment <RandomVariable> remainingVars) { if (remainingVars.Count == 0) { return; } RandomVariable var = remainingVars.Array[remainingVars.Offset]; remainingVars = new ArraySegment <RandomVariable>(remainingVars.Array, remainingVars.Offset + 1, remainingVars.Count - 1); ArraySegment <CptKey>[] tokenSegments = DivideIntoNSegments(keys, var.tokens.Length); for (int i = 0; i < tokenSegments.Length; i++) { ArraySegment <CptKey> segment = tokenSegments[i]; for (int index = segment.Offset; index < segment.Offset + segment.Count; index++) { CptKey key = segment.Array[index]; key.Set(keyPosMap[var], (char)i); } SetKeys(tokenSegments[i], remainingVars); } }
internal CptKey Remove(params int[] indices) { if (indices.Any(i => i >= this.size)) { throw new ArgumentOutOfRangeException(); } CptKey newKey = new CptKey(size - indices.Length); int newIndex = 0; for (int i = 0; i < size; i++) { if (Array.IndexOf(indices, i) != -1) { continue; } newKey.key[newIndex] = this.key[i]; newIndex++; } return(newKey); }
internal CptEntry(CptKey key, double value) { this.key = key; this.value = value; }