广义帕累托分布代码实现

public class GeneralizedParetoDistribution : ContinuousDistribution
    {
        private double location;

        private double shape;

        private double scale;

        public override double Mean
        {
            get
            {
                if (this.shape < 1.0)
                {
                    return this.location + this.scale / (1.0 - this.shape);
                }
                return double.NaN;
            }
        }

        public override double Variance
        {
            get
            {
                if (2.0 * this.shape >= 1.0)
                {
                    return double.NaN;
                }
                return this.scale * this.scale / ((1.0 - this.shape) * (1.0 - this.shape) * (1.0 - 2.0 * this.shape));
            }
        }

        public override double Skewness
        {
            get
            {
                if (3.0 * this.shape >= 1.0)
                {
                    return double.NaN;
                }
                return 2.0 * (1.0 + this.shape) / (1.0 - 3.0 * this.shape) * Math.Sqrt(1.0 - 2.0 * this.shape);
            }
        }

        public override double Kurtosis
        {
            get
            {
                if (4.0 * this.shape >= 1.0)
                {
                    return double.NaN;
                }
                return 3.0 * (1.0 - 2.0 * this.shape) * (3.0 + this.shape + 2.0 * this.shape * this.shape) / ((3.0 * this.shape - 1.0) * (4.0 * this.shape - 1.0)) - 3.0;
            }
        }

        public double LocationParameter => this.location;

        public double ScaleParameter => this.scale;

        public double ShapeParameter => this.shape;

        private void Initialize(double shape, double scale, double location)
        {
            this.shape = shape;
            this.scale = scale;
            this.location = location;
        }

        public static double GetRandomVariate(System.Random random, double shape, double scale, double location)
        {
            if (scale <= 0.0)
            {
                ThrowException.ArgumentOutOfRange("shape");
            }
            if (shape == 0.0)
            {
                return location + ExponentialDistribution.GetRandomVariate(random, scale);
            }
            return location + scale / shape * (Math.Pow(random.NextDouble(), 0.0 - shape) - 1.0);
        }

        public static double GetRandomVariate(System.Random random, double shape, double scale)
        {
            return GeneralizedParetoDistribution.GetRandomVariate(random, shape, scale, 0.0);
        }

        public GeneralizedParetoDistribution(double shape, double scale, double location)
        {
            if (scale <= 0.0)
            {
                ThrowException.ArgumentOutOfRange("scale");
            }
            this.Initialize(shape, scale, location);
        }

        public override double ProbabilityDensityFunction(double x)
        {
            if (x < this.location)
            {
                return 0.0;
            }
            if (this.shape < 0.0 && x >= this.location - this.scale / this.shape)
            {
                return 0.0;
            }
            double num;
            num = (x - this.location) / this.scale;
            if (this.shape == 0.0)
            {
                return Math.Exp(0.0 - num) / this.scale;
            }
            return Math.Pow(1.0 + this.shape * num, -1.0 - 1.0 / this.shape) / this.scale;
        }

        public override double MomentFunction(int order, double x)
        {
            if (x < this.location)
            {
                return 0.0;
            }
            if (this.shape == 0.0)
            {
                return Math.Exp(this.location / this.scale) * ElementaryFunctions.Pow(this.scale, order) * (GammaFunctions.IncompleteGamma(1 + order, this.location / this.scale) - GammaFunctions.IncompleteGamma(1 + order, x / this.scale));
            }
            return order switch
            {
                1 => Math.Pow(1.0 + this.shape * (x - this.location) / this.scale, -1.0 / this.shape) * (this.scale + x - this.location * this.shape) / (this.shape - 1.0) - (this.scale + this.location - this.location * this.shape) / (this.shape - 1.0), 
                2 => (-2.0 * this.scale * this.scale + x * x * (this.shape - 1.0) + 2.0 * this.location * x * this.shape - 2.0 * this.location * this.location * this.shape * this.shape - 2.0 * this.scale * (x - 2.0 * this.location * this.shape)) / Math.Pow(1.0 + this.shape * (x - this.location) / this.scale, 1.0 / this.shape) / (1.0 - 3.0 * this.shape + 2.0 * this.shape * this.shape) - (2.0 * (this.location - this.scale) * this.scale / (this.shape - 1.0) + 4.0 * this.scale * this.scale / (2.0 * this.shape - 1.0) - this.location * this.location), 
                _ => base.MomentFunction(order, x), 
            };
        }

        public override double DistributionFunction(double x)
        {
            if (x < this.location)
            {
                return 0.0;
            }
            if (this.shape < 0.0 && x >= this.location - this.scale / this.shape)
            {
                return 1.0;
            }
            if (this.shape == 0.0)
            {
                return 0.0 - ElementaryFunctions.ExpMinus1((0.0 - (x - this.location)) / this.scale);
            }
            return 1.0 - Math.Pow(1.0 + this.shape * (x - this.location) / this.scale, -1.0 / this.shape);
        }

        public override double InverseDistributionFunction(double probability)
        {
            if (probability < 0.0 || probability > 1.0)
            {
                ThrowException.ArgumentOutOfRange("probability");
            }
            if (this.shape == 0.0)
            {
                return this.location - this.scale * ElementaryFunctions.Log1PlusX(0.0 - probability);
            }
            return this.location + this.scale / this.shape * (Math.Pow(1.0 - probability, 0.0 - this.shape) - 1.0);
        }

        public override double SurvivorDistributionFunction(double x)
        {
            if (x < this.location)
            {
                return 1.0;
            }
            if (this.shape < 0.0 && x >= this.location - this.scale / this.shape)
            {
                return 0.0;
            }
            if (this.shape == 0.0)
            {
                return Math.Exp((0.0 - (x - this.location)) / this.scale);
            }
            return Math.Pow(1.0 + this.shape * (x - this.location) / this.scale, -1.0 / this.shape);
        }

        public override double GetRandomVariate(System.Random random)
        {
            if (random == null)
            {
                ThrowException.ArgumentNull("random");
            }
            if (this.shape == 0.0)
            {
                return this.location - this.scale * Math.Log(random.NextDouble());
            }
            return this.location + this.scale / this.shape * (Math.Pow(random.NextDouble(), 0.0 - this.shape) - 1.0);
        }
    }

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

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

技术合作交流qq:2401315930

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

合抱阴阳

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

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

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

打赏作者

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

抵扣说明:

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

余额充值