Пример #1
0
        public OutData PowerRegression()
        {
            OutData res = new OutData {
                name = "степенная регрессия"
            };
            bool indata_valid = true;

            for (int i = 0; i < x.Length; i++)
            {
                if (x[i] <= 0 || y[i] <= 0)
                {
                    indata_valid = false;
                }
            }
            if (indata_valid)
            {
                double lnx = 0, ln2x = 0, lny = 0, lnxlny = 0;
                float  sumy = 0;
                for (int i = 0; i < x.Length; i++)
                {
                    lnx    += Math.Log(x[i]);
                    ln2x   += Math.Pow(Math.Log(x[i]), 2);
                    lny    += Math.Log(y[i]);
                    lnxlny += Math.Log(x[i]) * Math.Log(y[i]);
                    sumy   += y[i];
                }
                float   b = (float)((x.Length * lnxlny - lnx * lny) / (x.Length * ln2x - lnx * lnx)), a = (float)(Math.Exp(lny / (x.Length) - (b / x.Length) * lnx));
                float[] yd = new float[y.Length];
                float   ym = sumy / y.Length, difyyd = 0, difyym = 0;
                for (int i = 0; i < x.Length; i++)
                {
                    yd[i]   = (float)(a * Math.Pow(x[i], b));
                    difyyd += (y[i] - yd[i]) * (y[i] - yd[i]);
                    difyym += (y[i] - ym) * (y[i] - ym);
                }
                double r = Math.Sqrt(1 - (difyyd / difyym)), index = Math.Pow(r, 2);
                //заполнение выходного результата
                res.a        = a;
                res.b        = b;
                res.equation = $"y = {Math.Round(a, 4)} * x ^ {(b > 0 ? "" : "(")}{Math.Round(b, 4)}{(b > 0 ? "" : ")")}";
                res.R2       = (float)index;
            }
            else
            {
                //(0, 0, -1);
                res.equation = "Error: Уравнение степенной регрессии не может быть построено для " +
                               "выборки, содержащей значения X или Y меньшие либо равные нулю";
                res.R2 = -1;
            }

            return(res);
        }
Пример #2
0
        public OutData ExponentialRegression()
        {
            OutData res = new OutData {
                name = "экспоненциальная регрессия"
            };
            bool indata_valid = true;

            for (int i = 0; i < x.Length; i++)
            {
                if (y[i] <= 0)
                {
                    indata_valid = false;
                }
            }
            if (indata_valid)
            {
                double sumx = 0, sumx2 = 0, lny = 0, xlny = 0, sumy = 0;
                for (int i = 0; i < x.Length; i++)
                {
                    sumx  += x[i];
                    sumx2 += x[i] * x[i];
                    lny   += Math.Log(y[i]);
                    xlny  += x[i] * Math.Log(y[i]);
                    sumy  += y[i];
                }
                float    b = (float)((x.Length * xlny - sumx * lny) / (x.Length * sumx2 - sumx * sumx)), a = (float)(lny / (x.Length) - (b / x.Length) * sumx);
                double[] yd = new double[y.Length];
                double   ym = sumy / y.Length, difyyd = 0, difyym = 0;
                for (int i = 0; i < x.Length; i++)
                {
                    yd[i]   = Math.Exp(a + b * x[i]);
                    difyyd += (y[i] - yd[i]) * (y[i] - yd[i]);
                    difyym += (y[i] - ym) * (y[i] - ym);
                }
                double r = Math.Sqrt(1 - (difyyd / difyym)), index = Math.Pow(r, 2);
                //заполнение выходного результата
                res.a        = a;
                res.b        = b;
                res.equation = $"y = e ^ ({Math.Round(a, 4)} {(b > 0 ? "+ " : "")}{Math.Round(b, 4)}";
                res.R2       = (float)index;
            }
            else
            {
                //(0, 0, -1);
                res.equation = "Error: Уравнение экспоненциальной регрессии не может быть построено для " +
                               "выборки, содержащей значения Y меньшие либо равные нулю";
                res.R2 = -1;
            }
            return(res);
        }
Пример #3
0
        public OutData LogarithmicRegression()
        {
            OutData res = new OutData {
                name = "логарифмическая регрессия"
            };
            bool indata_valid = true;

            for (int i = 0; i < x.Length; i++)
            {
                if (x[i] <= 0)
                {
                    indata_valid = false;
                }
            }
            if (indata_valid)
            {
                double lnx = 0, ln2x = 0, ylnx = 0, sumy = 0;
                for (int i = 0; i < x.Length; i++)
                {
                    lnx  += Math.Log(x[i]);
                    ln2x += Math.Pow(Math.Log(x[i]), 2);
                    ylnx += y[i] * Math.Log(x[i]);
                    sumy += y[i];
                }
                float    b = (float)((x.Length * ylnx - lnx * sumy) / (x.Length * ln2x - lnx * lnx)), a = (float)(sumy / (x.Length) - (b / x.Length) * lnx);
                double[] yd = new double[y.Length];
                double   ym = sumy / y.Length, difyyd = 0, difyym = 0;
                for (int i = 0; i < x.Length; i++)
                {
                    yd[i]   = a + b * Math.Log(x[i]);
                    difyyd += (y[i] - yd[i]) * (y[i] - yd[i]);
                    difyym += (y[i] - ym) * (y[i] - ym);
                }
                double r = Math.Sqrt(1 - (difyyd / difyym)), index = Math.Pow(r, 2);
                //заполнение выходного результата
                res.a        = a;
                res.b        = b;
                res.equation = $"y = {Math.Round(a, 4)} {(b > 0 ? "+ " : "")}{Math.Round(b, 4)} * ln x";
                res.R2       = (float)index;
            }
            else
            {
                //(0, 0, -1);
                res.equation = "Error: Уравнение логарифмической регрессии не может быть построено для " +
                               "выборки, содержащей значения X меньшие либо равные нулю";
                res.R2 = -1;
            }
            return(res);
        }
Пример #4
0
        public OutData HyperbolicRegression()
        {
            OutData res = new OutData {
                name = "гиперболическая регрессия"
            };
            bool indata_valid = true;

            for (int i = 0; i < x.Length; i++)
            {
                if (x[i] == 0)
                {
                    indata_valid = false;
                }
            }
            if (indata_valid)
            {
                float ydivx = 0, ldivx = 0, ldivx2 = 0, sumy = 0;
                for (int i = 0; i < x.Length; i++)
                {
                    ydivx  += y[i] / x[i];
                    ldivx  += 1 / x[i];
                    ldivx2 += 1 / (x[i] * x[i]);
                    sumy   += y[i];
                }
                float   b = (x.Length * ydivx - ldivx * sumy) / (x.Length * ldivx2 - ldivx * ldivx), a = sumy / (x.Length) - (b / x.Length) * ldivx;
                float[] yd = new float[y.Length];
                float   ym = sumy / y.Length, difyyd = 0, difyym = 0;
                for (int i = 0; i < x.Length; i++)
                {
                    yd[i]   = a + b / x[i];
                    difyyd += (y[i] - yd[i]) * (y[i] - yd[i]);
                    difyym += (y[i] - ym) * (y[i] - ym);
                }
                double r = Math.Sqrt(1 - (difyyd / difyym)), index = Math.Pow(r, 2);
                //заполнение результата
                res.a        = a;
                res.b        = b;
                res.equation = $"y = {Math.Round(a, 4)} {(b > 0 ? "+ " : "")}{Math.Round(b, 4)} /x";
                res.R2       = (float)index;
            }
            else
            {
                //(0, 0, -1);
                res.equation = "Error: Уравнение гиперболической регрессии не может быть построено для" +
                               "выборки, содержащей значения X равные нулю";
                res.R2 = -1;
            }
            return(res);
        }
Пример #5
0
        public OutData Run()
        {
            OutData data = new OutData();

            if (x.Length == y.Length)
            {
                if (!(x.Length < 3))
                {
                    Dictionary <int, OutData> result = new Dictionary <int, OutData>();
                    //запуск по очереди функций:
                    // 1 - степенная регрессия
                    // 2 - квадратичная
                    // 3 - кубическая
                    // 4 - гиперболическая
                    // 5 - показательная
                    // 6 - логарифмическая
                    // 7 - экспоненциальная
                    result.Add(1, PowerRegression());
                    result.Add(2, QuadraticRegression());
                    result.Add(3, CubicRegression());
                    result.Add(4, HyperbolicRegression());
                    result.Add(5, DemonstrativeRegression());
                    result.Add(6, LogarithmicRegression());
                    result.Add(7, ExponentialRegression());
                    float maxR2 = 0;
                    int   regr  = 0;
                    foreach (var pair in result)
                    {
                        Write($"{pair.Value.name} - R2 = {Math.Round(pair.Value.R2, 15)}");
                        if (pair.Value.R2 > maxR2)
                        {
                            maxR2 = pair.Value.R2;
                            regr  = pair.Key;
                            data  = pair.Value;
                        }
                    }
                    string outstr = $"\nНаилучший результат выдала '{data.name}'" +
                                    $"\nc уравнением {data.equation}" +
                                    $"\nи индексом детерминации R2 = {Math.Round(data.R2, 4)}";
                    Write(outstr);
                }
                else
                {
                    Write("Error: Количество элементов X и Y не может быть меньше трёх");
                }
            }
            return(data);
        }
Пример #6
0
        public OutData QuadraticRegression()
        {
            double sumx = 0, sumx2 = 0, sumx3 = 0, sumx4 = 0, sumxy = 0, sumx2y = 0, sumy = 0;

            for (int i = 0; i < x.Length; i++)
            {
                sumx   += x[i];
                sumx2  += x[i] * x[i];
                sumx3  += x[i] * x[i] * x[i];
                sumx4  += x[i] * x[i] * x[i] * x[i];
                sumxy  += x[i] * y[i];
                sumx2y += x[i] * x[i] * y[i];
                sumy   += y[i];
            }
            double det = sumx2 * (sumx2 * sumx2 - sumx * sumx3) - sumx * (sumx3 * sumx2 - sumx * sumx4) + x.Length * (sumx3 * sumx3 - sumx2 * sumx4),
                   detA = sumy * (sumx2 * sumx2 - sumx * sumx3) - sumx * (sumxy * sumx2 - sumx * sumx2y) + x.Length * (sumxy * sumx3 - sumx2 * sumx2y),
                   detB = sumx2 * (sumxy * sumx2 - sumx * sumx2y) - sumy * (sumx3 * sumx2 - sumx * sumx4) + x.Length * (sumx3 * sumx2y - sumxy * sumx4),
                   detC = sumx2 * (sumx2 * sumx2y - sumxy * sumx3) - sumx * (sumx3 * sumx2y - sumxy * sumx4) + sumy * (sumx3 * sumx3 - sumx2 * sumx4);
            double a = detA / det, b = detB / det, c = detC / det;

            double[] yd = new double[y.Length];
            double   ym = sumy / y.Length, difyyd = 0, difyym = 0;

            for (int i = 0; i < x.Length; i++)
            {
                yd[i]   = a * x[i] * x[i] + b * x[i] + c;
                difyyd += (y[i] - yd[i]) * (y[i] - yd[i]);
                difyym += (y[i] - ym) * (y[i] - ym);
            }
            double  r = Math.Sqrt(1 - (difyyd / difyym)), index = Math.Pow(r, 2);
            OutData res = new OutData {
                a        = (float)a, b = (float)b, c = (float)c, R2 = (float)index,
                name     = "квадратичная регрессия",
                equation = $"{Math.Round(a, 4)}*x2 {(b > 0 ? "+ " : "")}{Math.Round(b, 4)} * x " +
                           $"{(c > 0 ? "+ " : "")}{Math.Round(c, 4)}"
            };

            return(res);
        }
Пример #7
0
        public OutData CubicRegression()
        {
            OutData res = new OutData {
                name = "кубическая регрессия"
            };

            if (!(N < 4))
            {
                int[]      n    = new int[N];
                double[][] t    = new double[11][]; //вспомогательная таблица
                double[]   sumc = new double[11];   //суммы столбцов вспомогательной таблицы

                //инициализация вспомогательной таблицы
                for (int i = 0; i < 11; i++)
                {
                    t[i] = new double[N];
                }

                // 0 - номера строк: 1..N
                // 1 - x
                // 2 - x2
                // 3 - x3
                // 4 - x4
                // 5 - x5
                // 6 - x6
                // 7 - y
                // 8 - xy
                // 9 - x2y
                // 10 - x3y
                for (int j = 0; j < N; j++)
                {
                    double x = this.x[j];
                    double y = this.y[j];

                    t[0][j]  = j + 1;
                    t[1][j]  = x;
                    t[6][j]  = (t[5][j] = (t[4][j] = (t[3][j] = (t[2][j] = x * x) * x) * x) * x) * x;
                    t[7][j]  = y;
                    t[8][j]  = x * y;
                    t[9][j]  = t[2][j] * y; //x2y
                    t[10][j] = t[3][j] * y; //x3y
                }
                sumc[0] = N;
                //суммирование значений в столобцах
                for (int i = 1; i < 11; i++)
                {
                    sumc[i] = SumVector(t[i]);
                }

                var matrix_k = new Matrix(4, 4);
                int offset   = 3;
                for (int i = 0; i < 4; i++)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        matrix_k[i, j] = sumc[offset + j];
                    }
                    offset--;
                }
                double det_k = matrix_k.CalculateDeterminant();
                //Write($"Определитель системы уравнений = {Math.Round(det_k,4)}");
                //a
                var matrix = new Matrix(4, 4);
                matrix = CopySquareMatrix(matrix_k);
                for (int j = 0; j < 4; j++)
                {
                    matrix[0, j] = sumc[7 + j];
                }
                double det = matrix.CalculateDeterminant();
                double a   = det / det_k;
                //Write($"Определитель а = {Math.Round(det,4)}, коэффициент a = {Math.Round(a,4)}");
                //b
                matrix = CopySquareMatrix(matrix_k);
                for (int j = 0; j < 4; j++)
                {
                    matrix[1, j] = sumc[7 + j];
                }
                det = matrix.CalculateDeterminant();
                double b = det / det_k;
                //Write($"Определитель b = {Math.Round(det,4)}, коэффициент b = {Math.Round(b,4)}");
                //c
                matrix = CopySquareMatrix(matrix_k);
                for (int j = 0; j < 4; j++)
                {
                    matrix[2, j] = sumc[7 + j];
                }
                det = matrix.CalculateDeterminant();
                double c = det / det_k;
                //Write($"Определитель c = {Math.Round(det,4)}, коэффициент c = {Math.Round(c, 4)}");
                //d
                matrix = CopySquareMatrix(matrix_k);
                for (int j = 0; j < 4; j++)
                {
                    matrix[3, j] = sumc[7 + j];
                }
                det = matrix.CalculateDeterminant();
                double d = det / det_k;
                //Write($"Определитель d = {Math.Round(det,4)}, коэффициент d = {Math.Round(d, 4)}");
                //считаем индексы
                double y_cp = sumc[7] / sumc[0]; //  y среднее
                                                 //Write($"y среднее = {Math.Round(y_cp,4)}");

                sumc[5] = (sumc[6] = (sumc[10] = 0));
                for (int j = 0; j < N; j++)
                {
                    double y = t[7][j];
                    t[8][j]   = a * t[3][j] + b * t[2][j] + c * t[1][j] + d; // y'
                    t[4][j]   = y - y_cp;                                    // y-(y среднее)
                    sumc[5]  += (t[5][j] = t[4][j] * t[4][j]);               // (4) в квадрате и сумма
                    t[9][j]   = y - t[8][j];                                 // y-y'
                    sumc[10] += (t[10][j] = t[9][j] * t[9][j]);              // (y-y')2 и сумма
                                                                             //sumc[6] += (t[6][j] = Math.Abs(t[9][j] / y));           // Ai и сумма
                }
                double R  = Math.Sqrt(1 - sumc[10] / sumc[5]);
                double R2 = R * R;
                //Write($"Индекс корреляции R = {Math.Round(R, 4)}");
                //Write($"Индекс детерминации R² = {Math.Round(R2,4)}");

                res = new OutData
                {
                    a        = (float)a,
                    b        = (float)b,
                    c        = (float)c,
                    d        = (float)d,
                    R2       = (float)R2,
                    name     = "кубическая регрессия",
                    equation = $"y = {Math.Round(a, 4)} * x3 {(b > 0 ? "+ " : "")}{Math.Round(b, 4)} * x2 " +
                               $"{(c > 0 ? "+ " : "")}{Math.Round(c, 4)}*x {(d > 0 ? "+ " : "")}{Math.Round(d, 4)}"
                };
            }
            else
            {
                //(0, 0, 0, 0, -1);
                res.equation = "Error: Уравнение кубической регрессии не может быть построено для " +
                               "выборки с количеством элементов X и Y менше четырёх";
                res.R2 = -1;
            }
            return(res);
        }