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