using System;
|
using System;
|
using System;
|
using System.Collections.Generic;
|
using System.Collections.Generic;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Linq;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
|
|
namespace CloudWaterNetwork
|
{
|
public class Math_Expect
|
{
|
public List<double> _datas = null;
|
public Math_Expect(List<double> datas)
|
{
|
_datas = datas.Select(p => Math.Round(p, 1)).Distinct().ToList();
|
|
}
|
|
public double Average()
|
{
|
return _datas.Average();
|
}
|
|
|
|
/// <summary>
|
/// 返回置信区间的上下限值
|
/// </summary>
|
/// <param name="x_percentile">用户指定的置信水平,假设是90%</param>
|
/// <returns></returns>
|
public double[] GetExpect(double x_percentile)
|
{
|
//List<double> datas = _datas;
|
|
//double mean = datas.Average(); // 求期望值
|
|
//double std_err = StdErr(datas); // 计算标准误差
|
|
|
|
//double x_percentile_z_score = ZScore(x_percentile / 100.0); // 根据置信水平计算分位点
|
|
//double x_percentile_CI_lower = mean - x_percentile_z_score * std_err; // 下限
|
|
//double x_percentile_CI_upper = mean + x_percentile_z_score * std_err; // 上限
|
|
//return new double[] {x_percentile_CI_lower,x_percentile_CI_upper };
|
|
|
|
//List<double> datas = new List<double>() { 2.0, 3.5, 1.2, 4.6, 5.2, 6.8, 7.5, 8.1, 9.0, 10.5 };
|
List<double> datas = _datas;
|
|
// 计算期望值
|
double mean = datas.Average();
|
|
// 计算95%置信区间范围
|
//double alpha = 0.05; // 置信水平
|
double alpha = x_percentile;
|
double z = InvNormal(1 - alpha / 2); // 根据正态分布求出z值
|
double stdDev = Math.Sqrt(datas.Select(x => Math.Pow((x - mean), 2)).Sum() / (datas.Count - 1)); // 计算标准差
|
double marginOfError = z * stdDev / Math.Sqrt(datas.Count); // 计算误差范围
|
double lowerBound = mean - marginOfError; // 下限范围
|
double upperBound = mean + marginOfError; // 上限范围
|
|
return new double[] { lowerBound, upperBound };
|
//// 计算x%置信区间范围,如80%置信区间范围
|
//double xAlpha = 0.8; // 置信水平
|
//double xZ = InvNormal(1 - xAlpha / 2); // 根据正态分布求出z值
|
//double xMarginOfError = xZ * stdDev / Math.Sqrt(datas.Count); // 计算误差范围
|
//double xLowerBound = mean - xMarginOfError; // 下限范围
|
//double xUpperBound = mean + xMarginOfError; // 上限范围
|
|
|
}
|
|
|
public double[] GetPercent(double x_percentile)
|
{
|
return new double[] { GetPercent_single(x_percentile), GetPercent_single(1 - x_percentile) };
|
}
|
|
public double GetPercent_single(double x_percentile)
|
{
|
_datas.Sort();
|
int n = _datas.Count;
|
double index = x_percentile * (n - 1);
|
double frac = index % 1;
|
if (frac == 0)
|
{
|
return _datas[(int)index];
|
}
|
else
|
{
|
int lowIndex = (int)index;
|
int highIndex = lowIndex + 1;
|
|
double lowValue = _datas[lowIndex];
|
double highValue = _datas[highIndex];
|
|
return lowValue + (highValue - lowValue) * frac;
|
}
|
}
|
public static double InvNormal(double p)
|
{
|
double a0 = 2.50662823884;
|
double a1 = -18.61500062529;
|
double a2 = 41.39119773534;
|
double a3 = -25.44106049637;
|
double b1 = -8.47351093090;
|
double b2 = 23.08336743743;
|
double b3 = -21.06224101826;
|
double b4 = 3.13082909833;
|
double c0 = -2.78718931138;
|
double c1 = -2.29796479134;
|
double c2 = 4.85014127135;
|
double c3 = 2.32121276858;
|
double d1 = 3.54388924762;
|
double d2 = 1.63706781897;
|
double p_low = 0.02425;
|
double p_high = 1.0 - p_low;
|
double q, r;
|
|
if ((p < 0) || (p > 1))
|
{
|
throw new ArgumentOutOfRangeException("Probability p must be between 0 and 1.");
|
}
|
|
if (p < p_low)
|
{
|
q = Math.Sqrt(-2 * Math.Log(p));
|
return (((((c3 * q + c2) * q + c1) * q) + c0) / ((((d2 * q + d1) * q) + 1) * q + 0.0));
|
}
|
else if (p <= p_high)
|
{
|
q = p - 0.5;
|
r = q * q;
|
return (((((a3 * r + a2) * r + a1) * r) + a0) * q) /
|
((((b4 * r + b3) * r + b2) * r + b1) * r + 1);
|
}
|
else
|
{
|
q = Math.Sqrt(-2 * Math.Log(1 - p));
|
return -((((((c3 * q + c2) * q) + c1) * q) + c0) / ((((d2 * q + d1) * q) + 1) * q + 0.0));
|
}
|
}
|
double StdErr(List<double> datas)
|
{
|
double mean = datas.Average();
|
double sum_squares = datas.Sum(d => Math.Pow(d - mean, 2));
|
int n = datas.Count;
|
return Math.Sqrt(sum_squares / (n - 1)) / Math.Sqrt(n);
|
}
|
|
double ZScore(double confidence_level)
|
{
|
double z_score = 0;
|
|
if (confidence_level > 0 && confidence_level < 1)
|
{
|
double tail_area = (1 - confidence_level) / 2;
|
|
z_score = Math.Abs(NormSInv(tail_area));
|
}
|
|
return z_score;
|
}
|
|
double NormSInv(double p)
|
{
|
if (p < 0 || p > 1)
|
{
|
throw new ArgumentOutOfRangeException("Argument out of range: " + nameof(p));
|
}
|
else if (p == 0)
|
{
|
return double.NegativeInfinity;
|
}
|
else if (p == 1)
|
{
|
return double.PositiveInfinity;
|
}
|
|
// Abramowitz and Stegun formula 26.2.23.
|
// The absolute value of the error should be less than 4.5 e-4.
|
double[] a = new double[]
|
{
|
-3.969683028665376e+01,
|
2.209460984245205e+02,
|
-2.759285104469687e+02,
|
1.383577518672690e+02,
|
-3.066479806614716e+01,
|
2.506628277459239e+00
|
};
|
|
double[] b = new double[]
|
{
|
-5.447609879822406e+01,
|
1.615858368580409e+02,
|
-1.556989798598866e+02,
|
6.680131188771972e+01,
|
-1.328068155288572e+01
|
};
|
|
double[] c = new double[]
|
{
|
-7.784894002430293e-03,
|
-3.223964580411365e-01,
|
-2.400758277161838e+00,
|
-2.549732539343734e+00,
|
4.374664141464968e+00,
|
2.938163982698783e+00
|
};
|
|
double[] d = new double[]
|
{
|
7.784695709041462e-03,
|
3.224671290700398e-01,
|
2.445134137142996e+00,
|
3.754408661907416e+00
|
};
|
|
// Define break-points.
|
double p_low = 0.02425;
|
double p_high = 1 - p_low;
|
|
// Rational approximation for lower region:
|
if (p < p_low)
|
{
|
double q = Math.Sqrt(-2 * Math.Log(p));
|
return (((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5]) / ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);
|
}
|
// Rational approximation for upper region:
|
else if (p > p_high)
|
{
|
double q = Math.Sqrt(-2 * Math.Log(1 - p));
|
return -(((((c[0] * q + c[1]) * q + c[2]) * q + c[3]) * q + c[4]) * q + c[5]) / ((((d[0] * q + d[1]) * q + d[2]) * q + d[3]) * q + 1);
|
}
|
// Rational approximation for central region:
|
else
|
{
|
double q = p - 0.5;
|
double r = q * q;
|
return (((((a[0] * r + a[1]) * r + a[2]) * r + a[3]) * r + a[4]) * r + a[5]) * q / (((((b[0] * r + b[1]) * r + b[2]) * r + b[3]) * r + b[4]) * r + 1);
|
}
|
}
|
}
|
}
|