public T Sample(IRNG random) { while (true) { var sample = this.helper.Sample(random); var helperWeight = this.helper.Weight(sample) * this.factor; var weight = this.Weight(sample); if (Flip.Boolean(weight / helperWeight).Sample(random)) { return(sample); } } }
public static Metropolis <T> Distribution( Func <T, float> target, IDistribution <T> initial, Func <T, IDistribution <T> > proposal, IRNG random) { var markov = Markov <T> .Distribution(initial, Transition); var chain = markov.Sample(random); return(new Metropolis <T>(target, chain.GetEnumerator())); IDistribution <T> Transition(T item) { T candidate = proposal(item).Sample(random); float probability = target(candidate) / target(candidate); return(Flip <T> .Distribution(candidate, item, probability)); } }
public static IWeightedDistribution <T> Distribution(IDictionary <T, float> weights) { var weightArray = weights.ToArray(); switch (weightArray.Length) { case 0: return(Empty <T> .Distribution()); case 1: var item = weights.Keys.First(); return(Singleton <T> .Distribution(item)); case 2: var item1 = weights.First(); var item2 = weights.Last(); var probability = item1.Value / (item1.Value + item2.Value); return(Flip <T> .Distribution(item1.Key, item2.Key, probability)); default: return(new FloatWeighted <T>(weights)); } }