public MixtureDistribution([NotNull, ItemNotNull] IReadOnlyList <IContinuousDistribution> distributions, [CanBeNull] IReadOnlyList <double> weights = null) { Assertion.NotNullOrEmpty(nameof(distributions), distributions); Assertion.ItemNotNull(nameof(distributions), distributions); bool isWeighted = weights != null; weights ??= GetDefaultWeights(distributions); Assertion.NotNullOrEmpty(nameof(weights), weights); Assertion.Equal($"{nameof(distributions)}.Length", distributions.Count, $"{nameof(weights)}.Length", weights.Count); Assertion.Positive(nameof(weights), weights); double totalWeight = weights.Sum(); if (Math.Abs(totalWeight - 1) < 1e-9) { weights = weights.Select(w => w / totalWeight).ToArray(); } n = distributions.Count; this.distributions = distributions; this.weights = weights; inverseCdf = new InverseMonotonousFunction(Cdf); Median = Quantile(0.5); Mean = Aggregate(d => d.Mean); Variance = Aggregate(d => d.Variance + d.Mean.Sqr()) - Mean * Mean; StandardDeviation = Variance.Sqrt(); lazyToString = new Lazy <string>(() => { var builder = new StringBuilder(); builder.Append("Mix("); for (int i = 0; i < distributions.Count; i++) { if (i != 0) { builder.Append(";"); } builder.Append(distributions[i]); if (isWeighted) { builder.Append("|"); builder.Append(weights[i].ToStringInvariant()); } } builder.Append(")"); return(builder.ToString()); }); }
public MixtureDistribution([NotNull, ItemNotNull] IReadOnlyList <IDistribution> distributions, [CanBeNull] IReadOnlyList <double> weights = null) { Assertion.NotNullOrEmpty(nameof(distributions), distributions); Assertion.ItemNotNull(nameof(distributions), distributions); weights ??= GetDefaultWeights(distributions); Assertion.NotNullOrEmpty(nameof(weights), weights); Assertion.Equal($"{nameof(distributions)}.Length", distributions.Count, $"{nameof(weights)}.Length", weights.Count); Assertion.Equal($"sum({nameof(weights)})", weights.Sum(), 1); n = distributions.Count; this.distributions = distributions; this.weights = weights; inverseCdf = new InverseMonotonousFunction(Cdf); Median = Quantile(0.5); Mean = Aggregate(d => d.Mean); Variance = Aggregate(d => d.Variance + d.Mean.Sqr()) - Mean * Mean; StandardDeviation = Variance.Sqrt(); }