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());
            });
        }
Exemple #2
0
        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();
        }