public void DrawGraph3(ZedGraphControl control, PirsonContainer data ,int type)
        {
            GraphPane pane = control.GraphPane;// Получим панель для рисования
            // Очистим список кривых
            pane.CurveList.Clear();

            pane.Title.Text = "Плотность распределения";  // Название панели и осей
            pane.XAxis.Title.Text = "Х";
            pane.YAxis.Title.Text = "f(x)";

            IDistributionFunction function1 = null;
            IDensityFunction function2 = null;
            switch (type)
            {
                case 0:
                    function1 = UniversalDistributionFunction.Create();
                    function2 = UniversalDistributionFunction.Create();
                    break;

                case 1:
                    function1 = InverseDistributionFunction.Create();
                    function2 = InverseDistributionFunction.Create();
                    break;

                case 2:
                    function1 = DiscreteDistributionFunction.Create();
                    function2 = DiscreteDistributionFunction.Create();
                    break;

                default:
                    throw new Exception("Неизвестная функция");
            }
            double min = function1.GetInverseFunctionValue(0);
            double max = function1.GetInverseFunctionValue(1);

            PointPairList list = new PointPairList();  // Создадим список точек
            PointPairList list3 = new PointPairList();  // Создадим список точек

            double step = (max - min) / 100000;  // Заполняем список точек
            list.Add(min, 0);
            if (type == 2)
            {
                for (int i = 0; i < ((DiscreteDistributionFunction)function1).GetNumberOfPoints(); i++)
                {
                    RandomGenerator.Model.Point point = ((DiscreteDistributionFunction)function1).GetPoint(i);
                    // добавим в список точку
                    list.Add(point.GetX, 0);
                    list.Add(point.GetX, point.GetP);
                    list.Add(point.GetX, 0);

                    list3.Add(point.GetX + 400 * step, 0);
                    list3.Add(point.GetX + 400 * step,(double) data.Nj[i]/data.N);//гистограмма для дискретной
                    list3.Add(point.GetX + 400 * step, 0);
                }
            }
            else
            {
                for (double i = min; i < max; i += step)
                {
                    list.Add(i, function2.GetDensityFunctionValue(i));// добавим в список точку
                }
            }
            list.Add(max, 0);
            LineItem myCurve = null;
            LineItem myCurve2 = null;
            double[] x = new double[data.Intervals];
            double[] list2 = new double[data.Intervals];
            for (int i = 0; i <data.Intervals; i++)
            {
                if(type==2)
                {
                    //list2[i] = (double)data.Nj[i] / data.N;
                }
                else
                {
                    x[i] = (data.Border.GetPoint(i) + data.Border.GetPoint(i + 1)) / 2;
                    list2[i] = (double)data.Intervals * data.Nj[i] / (data.N * (max - min));
                }
            }
            // Создадим кривую с названием "Sinc",
            // которая будет рисоваться голубым цветом (Color.Blue),
            // Опорные точки выделяться не будут (SymbolType.None)

            if(type == 2)
            {
                myCurve = pane.AddCurve("ряд распределения", list, Color.DarkGreen, SymbolType.None);
                myCurve2 = pane.AddCurve("практический ряд распределения", list3, Color.DarkOrange, SymbolType.None);
                myCurve2.Line.Width = 2.0F;  // Толщина графиков

            }
            else
            {
                myCurve = pane.AddCurve("функция плотности", list, Color.Orange, SymbolType.None);
                // Создадим кривую с названием "Sinc",
                // которая будет рисоваться голубым цветом (Color.Blue),
                // Опорные точки выделяться не будут (SymbolType.None)
                BarItem myBar = pane.AddBar("гистограмма ", x, list2, Color.Empty);
                myBar.Bar.Fill = new Fill(Color.Empty, Color.Empty, Color.Empty);
                myBar.Bar.Border.Color = Color.BlueViolet;
                pane.BarSettings.MinClusterGap = 0;
            }

            // Устанавливаем интересующий нас интервал по оси X
            pane.XAxis.Scale.Min = min - 5000 * step;
            pane.XAxis.Scale.Max = max + 5000 * step;
            // Устанавливаем интересующий нас интервал по оси Y
            switch (type)
            {
                case 0:
                    pane.YAxis.Scale.Max = 3.5;
                    break;
                case 1:
                    pane.YAxis.Scale.Max = 1.6;
                    break;
                case 2:
                    pane.YAxis.Scale.Max = 0.16;
                    break;
                default:
                    throw new Exception("Неизвестная функция");
            }
            pane.YAxis.Scale.Min = 0;

            myCurve.Line.Width = 2.0F;  // Толщина графиков

            // Включаем отображение сетки напротив крупных рисок по оси X
            pane.XAxis.MajorGrid.IsVisible = true;

            // Задаем вид пунктирной линии для крупных рисок по оси X:
            // Длина штрихов равна 10 пикселям, ...
            pane.XAxis.MajorGrid.DashOn = 10;

            // затем 5 пикселей - пропуск
            pane.XAxis.MajorGrid.DashOff = 5;

            // Включаем отображение сетки напротив крупных рисок по оси Y
            pane.YAxis.MajorGrid.IsVisible = true;

            // Аналогично задаем вид пунктирной линии для крупных рисок по оси Y
            pane.YAxis.MajorGrid.DashOn = 10;
            pane.YAxis.MajorGrid.DashOff = 5;

            // Включаем отображение сетки напротив мелких рисок по оси X
            pane.YAxis.MinorGrid.IsVisible = true;

            // Задаем вид пунктирной линии для крупных рисок по оси Y:
            // Длина штрихов равна одному пикселю, ...
            pane.YAxis.MinorGrid.DashOn = 1;

            // затем 2 пикселя - пропуск
            pane.YAxis.MinorGrid.DashOff = 2;

            // Включаем отображение сетки напротив мелких рисок по оси Y
            pane.XAxis.MinorGrid.IsVisible = true;

            // Аналогично задаем вид пунктирной линии для крупных рисок по оси Y
            pane.XAxis.MinorGrid.DashOn = 1;
            pane.XAxis.MinorGrid.DashOff = 2;

            //Цвет сетки
            pane.XAxis.MajorGrid.Color = Color.LightGray;
            pane.YAxis.MajorGrid.Color = Color.LightGray;

            //Оси
            pane.XAxis.MajorGrid.IsZeroLine = true;
            pane.YAxis.MajorGrid.IsZeroLine = true;

            // Вызываем метод AxisChange (), чтобы обновить данные об осях.
            // В противном случае на рисунке будет показана только часть графика,
            // которая умещается в интервалы по осям, установленные по умолчанию
            control.AxisChange();

            control.Invalidate(); // Обновляем график
        }
        public PirsonContainer Calculate(int type)
        {
            PirsonTable table = new PirsonTable();// хранит таблицу для критерия Пирсона
            ArrayOfPoints borders = new ArrayOfPoints();//массив границ гистограмм
            List<int> m =new List<int>();//массив практических частот
            List<double> np= new List<double>();//массив теоретических частот
            int r = Intervals - 3;//количество степеней свободы (количество интервалов-количество ограничений)
            double χ = 0; //Хи
            Volume = ranged.GetVolume();
            PirsonContainer Result = new PirsonContainer();// создаём контейнер для результатов
            IDistributionFunction function1 = null;
            switch (type)
            {
                case 0:
                    function1 = UniversalDistributionFunction.Create();
                    break;

                case 1:
                    function1 = InverseDistributionFunction.Create();
                    break;

                case 2:
                    function1 = DiscreteDistributionFunction.Create();
                    break;

                default:
                    throw new Exception("Неизвестная функция");
            }
            if(type!=2)//вычисление Хи если функция непрерывная
            {
                Min = function1.Xmin();//минимальное значение СВ
                Max = function1.Xmax();//максимальное значение СВ
                step = (Max - Min) / Intervals;//длина интервала
                for (double i = Min; i < Max; i =/* Math.Floor(*/ i /* * 10000000000000) / 10000000000000 */+ step)
                {
                    borders.SetPoint(i);//добавляем границу
                    //вычисляем теоретическую частоту интервала
                    np.Add(Volume * (function1.GetFunctionValue(i + step) - function1.GetFunctionValue(i)));
                    //вычисляем практическую частоту интервала
                    m.Add(this.GetM(i));
                }
                borders.SetPoint(Max);
                for (int l = 0; l < Intervals; l++)
                {
                    if (np[l] != 0)
                    {
                        χ += Math.Pow((m[l] - np[l]), 2) / np[l];//вычисление Хи
                    }
                }
                Result.Border = borders;//сохраняем в контейнер с результатами
            }
            else//вычисление Хи если функция дискретная
            {
                //вычисление частот для каждой точки дискретной функции
                int n = 0;//номер значения в упорядоченной выборке
                Point p = null;//точка ряда распределения
                //для всех точек дискретной функции
                for (int j = 0; j < ((DiscreteDistributionFunction)function1).GetNumberOfPoints(); j++)
                {
                    m.Add(0);
                    p = ((DiscreteDistributionFunction)function1).GetPoint(j);//получаем очередную точку
                    np.Add(Volume * p.GetP);//вычисляем теоретическую частоту
                    //пока значения выборки совпадают с значением точки
                    while ((n < ranged.GetVolume()) && (p.GetX == ranged.GetValue(n)))
                    {
                        m[j]++;
                        n++;//переходим к следующей точке
                    }
                    χ += Math.Pow((m[j] - np[j]), 2) / np[j];//вычисление Хи
                }
            }

            double P = table.GetP(χ, r);//получение из таблицы значения критерия пирсона
            // сохраненение результатов в конетейнер
            Result.P = P;
            Result.Intervals = Intervals;
            Result.N = ranged.GetVolume();
            Result.Nj = m;
            Result.NP = np;
            Result.χ = χ;
            Result.r = r;
            return Result;
        }
 public void DrawGraph3(ZedGraphControl control, PirsonContainer data ,int type, List<double> borders)
 {
     DrawGraph3(control, data, type);
     GraphPane pane = control.GraphPane; // Получим панель для рисования
     PointPairList list4 = new PointPairList();// Создадим список точек
     UniversalDistributionFunction function = UniversalDistributionFunction.Create();
     //границы равновероятных интервалов универсального метода
     for(int i=0;i<borders.Count;i++)
     {
         list4.Add(borders[i], 0);
         list4.Add(borders[i], function.GetDensityFunctionValue(borders[i]));
         list4.Add(borders[i], 0);
     }
     LineItem curve = pane.AddCurve("границы равновероятных интервалов", list4, Color.Green, SymbolType.None);
     curve.Line.Width = 2.0F;
 }