狄利克雷分布代码实现

public sealed class DirichletDistribution : MultivariateContinuousDistribution
    {
        private Vector alpha;

        private double sum = double.NaN;

        private double scale;

        private Vector mean;

        private SymmetricMatrix covarianceMatrix;

        private void DoPrecomputations()
        {
            if (double.IsNaN(this.sum))
            {
                this.sum = this.alpha.GetSum();
                this.scale = 0.0 - GammaFunctions.LogGamma(this.sum);
                this.mean = Vector.Create(this.alpha.Length);
                for (int i = 0; i < this.alpha.Length; i++)
                {
                    this.scale += GammaFunctions.LogGamma(this.alpha.GetValue(i));
                    this.mean[i] = this.alpha[i] / this.sum;
                }
            }
        }

        protected override void FillRandomVariateCore(System.Random random, Vector sample)
        {
            for (int i = 0; i < base.Order; i++)
            {
                sample[i] = GammaDistribution.GetRandomVariate(random, this.alpha[i]);
            }
            sample.Multiply(1.0 / sample.GetSum());
        }

        public DirichletDistribution(Vector parameters)
            : base(Vector.SafeLength(parameters))
        {
            if (parameters == null)
            {
                ThrowException.ArgumentNull("parameters");
            }
            if (parameters.Length == 0)
            {
                ThrowException.ArgumentOutOfRange("parameters");
            }
            this.alpha = parameters;
        }

        public DirichletDistribution(Matrix data)
            : base((!(data == null)) ? data.RowCount : 0)
        {
            if (data == null)
            {
                ThrowException.ArgumentNull("variable");
            }
            this.alpha = data.ApplyToColumns(Stats.Mean);
        }

        public DirichletDistribution(NumericalVariable[] variables)
            : base((variables != null) ? variables.Length : 0)
        {
            if (variables == null)
            {
                ThrowException.ArgumentNull("variable");
            }
            for (int i = 0; i < variables.Length; i++)
            {
                if (variables[i] == null)
                {
                    throw new ArgumentException();
                }
            }
            if (variables.Length == 0)
            {
                ThrowException.ArgumentOutOfRange("variables");
            }
            this.alpha = new GeneralVector(Array.ConvertAll(variables, Stats.Mean), reuseComponentArray: true);
        }

        public override double LogProbabilityDensityFunction(Vector x)
        {
            if (x == null)
            {
                ThrowException.ArgumentNull("x");
            }
            bool flag;
            flag = x.Length == this.alpha.Length - 1;
            if (x.Length != this.alpha.Length && !flag)
            {
                ThrowException.LengthMismatch("x");
            }
            this.DoPrecomputations();
            double num;
            num = 0.0;
            double num2;
            num2 = 0.0;
            for (int i = 0; i < x.Length; i++)
            {
                double value;
                value = x.GetValue(i);
                if (value <= 0.0 || value >= 1.0)
                {
                    return 0.0;
                }
                num += (this.alpha[i] - 1.0) * Math.Log(value);
                num2 += value;
            }
            if (flag)
            {
                if (num2 >= 1.0)
                {
                    return 0.0;
                }
                num += (this.alpha[this.alpha.Length - 1] - 1.0) * Math.Log(1.0 - num2);
            }
            else if (Math.Abs(num2 - 1.0) > 1.4901161193847656E-08)
            {
                return 0.0;
            }
            return this.scale + num;
        }

        public Vector GetParameters()
        {
            return this.alpha.ToGeneralVector();
        }

        public override Vector GetMeans()
        {
            if (this.mean == null)
            {
                this.DoPrecomputations();
                this.mean = this.alpha.ToGeneralVector().Multiply(1.0 / this.sum);
            }
            return this.mean;
        }

        public override SymmetricMatrix GetVarianceCovarianceMatrix()
        {
            if (this.covarianceMatrix == null)
            {
                this.DoPrecomputations();
                this.covarianceMatrix = Matrix.CreateSymmetric(this.alpha.Length);
                double num;
                num = 1.0 / (this.sum * this.sum * (this.sum + 1.0));
                this.covarianceMatrix.AddOuterProduct(0.0 - num, this.alpha);
                this.covarianceMatrix.GetDiagonal().Add(this.sum * num, this.alpha);
            }
            return this.covarianceMatrix;
        }
    }

 如果对您有帮忙,非常感谢您支持一下创造者的付出!

 感谢支持技术分享,请扫码点赞支持:

技术合作交流qq:2401315930

狄克分布是一种概率分布,常用于多元变量和概率向量的建模。对于一个具有K个维度的随机向量,狄利克雷分布的参数是一个长度为K的向量α=[α1, α2, ..., αK],其中每个αi>0。狄利克雷分布的概率密度函数定义如下: f(x|α) = (1/B(α)) * ∏(x^αi-1) (0<=xi<=1, ∑xi=1) 其中,B(α)是多元贝塔函数,∏表示对于所有i的连乘。狄利克雷分布的随机变量服从于一个概率向量,在每个维度上的取值范围是0到1之间,并且各维度的取值之和为1。 在Matlab中没有现成的工具函数可以直接使用狄利克雷分布。但是你可以根据引用提供的代码实现一个狄利克雷分布的随机数生成函数drchrnd(a,n),其中a是参数向量,n是生成样本的数量。这个函数利用了gamma分布和狄利克雷分布之间的关系,通过生成多个gamma随机变量,并按一定的规则进行归一化,实现狄利克雷分布的随机数生成。 需要注意的是,生成的随机数是符合狄利克雷分布的概率向量,每个维度的取值范围是0到1之间,并且各维度的取值之和为1。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [狄利克雷分布的matlab代码实现和R语言函数调用](https://blog.csdn.net/sacainiao/article/details/54866385)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

合抱阴阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值