qin
2024-06-04 9490957edfc694a0378ee52af47e921b8ac44e7a
Hydraulic/Hydro.CommonBase/Helper/CurveFitHelper.cs
@@ -7,6 +7,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms.DataVisualization.Charting;
namespace Hydro.CommonBase
{
@@ -71,7 +72,7 @@
                var list = data.FindAll(p => x - (xMax - xMin) / count / 2 <= p.X && p.X < x + (xMax - xMin) / count/2).Select(p => (double)p.Y).ToList();
                if (list.Count >= 3)
                {
                    var Bounds = ConfidenceRangeHelper.GetConfidenceRange(list, 95);
                    var Bounds = GetConfidenceRange(list, 95);
                    var x_avg = x;
                    if (Bounds[0] == double.NaN || Bounds[1] == double.NaN) continue;
                    down_list.Add(new PointF((float)x_avg, (float)Bounds[0]));
@@ -115,33 +116,29 @@
            //var curve1 = h1.GetFitCurve(count);
            return new List<List<PointF>> { down_list, up_list, avg_list };
        }
    }
    public static class ConfidenceRangeHelper
    {
        public static double[] GetConfidenceRange(List<double> data, double confidenceLevel = 90,bool mode=true)//true是中位数,置信区间是false
        public static double[] GetConfidenceRange(List<double> data, double confidenceLevel = 90, bool mode = true)//true是中位数,置信区间是false
        {
            //如果model==true,这计算中位数,比例为confidenceLevel
            if (mode)
            {
                data.Sort();
                double lowerBound = 0;
                double upperBound = 0;
                //取百分位confidenceLevel/100和1-confidenceLevel/100.0的数
                int upperIndex = (int)Math.Round( data.Count*confidenceLevel/100.0);
                int lowerIndex = (int)Math.Round(data.Count * (1-confidenceLevel / 100.0));
                int upperIndex = (int)Math.Round(data.Count * confidenceLevel / 100.0);
                int lowerIndex = (int)Math.Round(data.Count * (1 - confidenceLevel / 100.0));
                if (upperIndex == data.Count)
                {
                    upperIndex = data.Count - 1;
                }
                if (lowerIndex <0)
                if (lowerIndex < 0)
                {
                    lowerIndex = 0;
                }
                return new double[] { data[lowerIndex], data[upperIndex] };
            }
@@ -162,35 +159,35 @@
                    }
                }
            // 使用循环计算样本均值
            double sum = 0;
            foreach (double value in data)
            {
                sum += value;
            }
            double mean = sum / data.Count;
                // 使用循环计算样本均值
                double sum = 0;
                foreach (double value in data)
                {
                    sum += value;
                }
                double mean = sum / data.Count;
            // 使用循环计算标准差
            double sumOfSquares = 0;
            foreach (double value in data)
            {
                sumOfSquares += Math.Pow(value - mean, 2);
            }
            double stdDev = Math.Sqrt(sumOfSquares / (data.Count - 1));
                // 使用循环计算标准差
                double sumOfSquares = 0;
                foreach (double value in data)
                {
                    sumOfSquares += Math.Pow(value - mean, 2);
                }
                double stdDev = Math.Sqrt(sumOfSquares / (data.Count - 1));
            double zValue = 0;
            double alpha = 1 - confidenceLevel / 100.0;
                double zValue = 0;
                double alpha = 1 - confidenceLevel / 100.0;
            double zValueOneTail = GetZValueOneTail(alpha / 2);
            double marginOfError = zValueOneTail * stdDev;
            double lowerBound = mean - marginOfError;
            double upperBound = mean + marginOfError;
                double zValueOneTail = GetZValueOneTail(alpha / 2);
                double marginOfError = zValueOneTail * stdDev;
                double lowerBound = mean - marginOfError;
                double upperBound = mean + marginOfError;
                return new double[] { lowerBound, upperBound };
            }
        }
        static double[,] zTable = {
      {0.0000, 0.0039, 0.0078, 0.0117, 0.0156, 0.0195, 0.0234, 0.0274, 0.0314, 0.0353},
@@ -243,6 +240,115 @@
            return zValue;
        }
        //数据频率分布图的英文怎么说,
        /// <summary>
        /// 获取数据频率的分布图
        /// </summary>
        /// <param name="data"></param>
        /// <param name="numIntervals"></param>
        /// <param name="filterNum">以最小值作为过滤的系数</param>
        /// <returns></returns>
        public static List<DataPoint> GetFrequencyDistribution(List<double> data, out List<double>[] datapoints, int numIntervals = 10,double filterNum=5 )
        {
            List<DataPoint> resultPoints = new List<DataPoint>();
            datapoints= new List<double>[numIntervals];
            for(int i=0;i<numIntervals;i++)
            {
                datapoints[i]= new List<double>();
            }
            // 设置置信水平
            // 设置区间数量
            ////在data中过滤和最大的5%的数据
            //data = data.Where(d => d <= data.Min() * filterNum).ToList();
            // 计算数据的最小值和最大值
            double minValue = data.Min();
            double maxValue = data.Max();
            // 计算区间宽度
            double intervalWidth = (maxValue - minValue) / numIntervals;
            // 初始化频率分布数组
            int[] freqDist = new int[numIntervals];
            // 计算各个区间的频率
            foreach (double x in data)
            {
                int index = (int)((x - minValue) / intervalWidth);
                if (index < 0) // 数据小于最小值
                {
                    freqDist[0]++;
                    datapoints[0].Add(x);
                }
                else if (index >= numIntervals) // 数据大于最大值
                {
                    freqDist[numIntervals - 1]++;
                    datapoints[numIntervals - 1].Add(x);
                }
                else // 数据在区间内
                {
                    freqDist[index]++;
                    datapoints[index].Add(x);
                }
            }
            double[] freqDistPersent =new double[numIntervals];
            double sum = freqDist.Sum();
            //计算freqDist的频率百分比
            for (int i = 0; i < numIntervals; i++)
            {
                freqDistPersent[i] = (freqDist[i] / (double)sum );
            }
            //// 计算样本均值和标准差
            //double mean = data.Average();
            //double stdDev = Math.Sqrt(data.Select(x => (x - mean) * (x - mean)).Sum() / (data.Length - 1));
            //double zValue = 0;
            //double alpha = 1 - confidenceLevel / 100.0;
            //double zValueOneTail = GetZValueOneTail(alpha / 2);
            ////zValue = mean + zValueOneTail * stdDev / Math.Sqrt(data.Length);
            //// 计算置信区间的范围
            ////double z = GetZValue(confidenceLevel); //chart1.DataManipulator.Statistics.InverseNormalDistribution(1 - confidenceLevel / 200.0); // 根据置信水平查找标准正态分布的临界值
            //double marginOfError = zValueOneTail * stdDev;/// Math.Sqrt(data.Length);
            //double lowerBound = mean - marginOfError;
            //double upperBound = mean + marginOfError;
            for (int i = 0; i < numIntervals; i++)
            {
                double xValue = minValue + i * intervalWidth + intervalWidth / 2;
                double yValue = freqDistPersent[i];
                if (isValid(xValue) && isValid(yValue))
                    resultPoints.Add(new DataPoint(xValue, yValue));
            }
            return resultPoints;
        }
        static bool isValid(double value)
        {
            if (value == (int)value && value < 0) return false;
            return !Double.IsNaN(value) && !Double.IsInfinity(value);
        }
    }
    //public static class ConfidenceRangeHelper
    //{
    //}
}