C#,数值计算——对数正态分布(logarithmic normal distribution)的计算方法与源程序

对数正态分布(logarithmic normal distribution)是指一个随机变量的对数服从正态分布,则该随机变量服从对数正态分布。对数正态分布从短期来看,与正态分布非常接近。但长期来看,对数正态分布向上分布的数值更多一些。

有些量本身就是不对称的。例如,试想,人们完成某项特定任务需要的时间:因为每个人都是不同的,我们会得到一个分布。然而,所有的值都必然是正数(因为时间不可能为负数)。而且,我们还能预测到该分布可能的形状:有一个无人可及的最小时间,然后是少数一些非常快的“冠军”,接下来就是普通人的最具代表性的完成时间形成一个高峰,最后是尾部一长串的“掉队者”。显然,高斯分布不会很好地描述这样的分布,因为高斯分布中x可以定义为正值,也可定义为负值,它是对称的且尾部很短。
在很多应用中,特别是在可靠性和维修性方面,数据可能不符合正态分布。可是,随机变量的对数可能符合正态分布,对此情况称为对数正态分布。如果应用对数正态分布,在对数正态图纸上数据的图形将是一条直线。绘图的过程与其他分布是相同的。其分析的过程包括计算对数值的平均值和标准差,以及对最终结果取反对数。
对数正态分布与正态分布很类似,除了它的概率分布向右进行了移动。对数正态分布从短期来看,与正态分布非常接近。但长期来看,对数正态分布向上分布的数值更多一些。更准确地说,对数正态分布中,有更大向上波动的可能,更小向下波动的可能。
对数正态分布用于半导体器件的可靠性分析和某些种类的机械零件的疲劳寿命。其主要用途是在维修性分析中对修理时间数据进行确切的分析。
已知对数正态分布的密度函数,就可以根据可靠度与不可靠度函数的定义计算出该分布的可靠度函数和不可靠度函数的表达式。

对数正态分布具有如下性质:
(1)正态分布经指数变换后即为对数正态分布;对数正态分布经对数变换后即为正态分布。
(2)γ,t是正实数,X是参数为(μ,σ)的对数正态分布,则仍是对数正态分布,参数为。
(3)对数正态总是右偏的。
(4)对数正态分布的均值和方差是其参数(μ,σ)的增函数。
(5)对给定的参数μ,当σ趋于零时,对数正态分布的均值趋于exp(μ),方差趋于零。
 

using System;

namespace Legalsoft.Truffer
{
    public class Lognormaldist : Erf
    {
        private double mu { get; set; }
        private double sig { get; set; }

        public Lognormaldist(double mmu = 0.0, double ssig = 1.0)
        {
            this.mu = mmu;
            this.sig = ssig;
            if (sig <= 0.0)
            {
                throw new Exception("bad sig in Lognormaldist");
            }
        }

        public double p(double x)
        {
            if (x < 0.0)
            {
                throw new Exception("bad x in Lognormaldist");
            }
            //if (x == 0.0)
            if (Math.Abs(x) <= float.Epsilon)
            {
                return 0.0;
            }
            return (0.398942280401432678 / (sig * x)) * Math.Exp(-0.5 * Globals.SQR((Math.Log(x) - mu) / sig));
        }

        public double cdf(double x)
        {
            if (x < 0.0)
            {
                throw new Exception("bad x in Lognormaldist");
            }
            //if (x == 0.0)
            if (Math.Abs(x) <= float.Epsilon)
            {
                return 0.0;
            }
            return 0.5 * erfc(-0.707106781186547524 * (Math.Log(x) - mu) / sig);
        }

        public double invcdf(double p)
        {
            if (p <= 0.0 || p >= 1.0)
            {
                throw new Exception("bad p in Lognormaldist");
            }
            return Math.Exp(-1.41421356237309505 * sig * inverfc(2.0 * p) + mu);
        }
    }
}
 

猜你喜欢

转载自blog.csdn.net/beijinghorn/article/details/131894187