コード例 #1
0
ファイル: DataBase.cs プロジェクト: leoonsy/MSOsu
        /// <summary>
        /// Получить значение F-критерия Фишера
        /// </summary>
        /// <param name="n"></param>
        /// <param name="k"></param>
        /// <returns></returns>
        public static double GetFCrit(int v1, int v2) //альфа = 0.05
        {
            if (v1 > Fv1.Last())
            {
                v1 = Fv1.Length;
            }
            if (v2 > Fv2.Last())
            {
                v2 = Fv2.Length;
            }
            int vv1 = Fv1.ToList().FindIndex(x => x == v1);
            int vv2 = Fv2.ToList().FindIndex(x => x == v2);

            if (vv1 != -1 && vv2 != -1)
            {
                return(FFisherСrit[vv1][vv2]);
            }

            int y, w;

            if (vv1 != -1)
            {
                double[] fLine = FFisherСrit[vv1];
                y = 0;
                while (Fv2[y] < v2)
                {
                    y++;
                }
                return(fLine[y - 1] + (fLine[y] - fLine[y - 1]) * (v2 - Fv2[y - 1]) / (Fv2[y] - Fv2[y - 1]));
            }
            if (vv2 != -1)
            {
                double[] fline = MatrixOperations.Transpose(FFisherСrit)[vv2];
                y = 0;
                while (Fv1[y] < v1)
                {
                    y++;
                }
                return(fline[y - 1] + (fline[y] - fline[y - 1]) * (v1 - Fv1[y - 1]) / (Fv1[y] - Fv1[y - 1]));
            }
            y = 0; w = 0;
            while (Fv1[y] < v1)
            {
                y++;
            }
            while (Fv2[w] < v2)
            {
                w++;
            }
            double t1 = FFisherСrit[y - 1][w - 1] + (FFisherСrit[y - 1][w] - FFisherСrit[y - 1][w - 1]) * (v2 - Fv2[w - 1]) / (Fv2[w] - Fv2[w - 1]);
            double t2 = FFisherСrit[y][w - 1] + (FFisherСrit[y][w] - FFisherСrit[y][w - 1]) * (v2 - Fv2[w - 1]) / (Fv2[w] - Fv2[w - 1]);

            return(t1 + (t2 - t1) * (v1 - Fv1[y - 1]) / (Fv1[y] - Fv1[y - 1]));
        }
コード例 #2
0
        /// <summary>
        /// Установить решение СЛАУ
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public static double[] GetSLAUResolve(double[][] a, double[] b, GaussMethod type)
        {
            a = MatrixOperations.Copy(a);
            b = MatrixOperations.Copy(b);
            int varCount = a.Length;

            const double epsilon = 0.00000000000001; //точность нуля

            int[] perm = null;
            if (type == GaussMethod.Rows || type == GaussMethod.All)
            {
                perm = Enumerable.Range(0, b.Length).ToArray(); //перестановка
            }
            for (int k = 0; k < varCount; k++)
            {
                switch (type)
                {
                //выбор ведущего (максимального) элемента по столбцу
                case GaussMethod.Cols:
                    int    index = k;
                    double max   = Math.Abs(a[k][k]);
                    for (int i = k + 1; i < varCount; i++)
                    {
                        if (Math.Abs(a[i][k]) > max)
                        {
                            max   = Math.Abs(a[i][k]);
                            index = i;
                        }
                    }

                    if (max < epsilon)
                    {
                        throw new Exception("Нет ненулевых диагональных элементов");
                    }

                    Swap(ref a[k], ref a[index]);
                    Swap(ref b[k], ref b[index]);
                    break;

                //выбор ведущего (максимального) элемента по строке
                case GaussMethod.Rows:
                    index = k;
                    max   = Math.Abs(a[k][k]);
                    for (int i = k + 1; i < varCount; i++)
                    {
                        if (Math.Abs(a[k][i]) > max)
                        {
                            max   = Math.Abs(a[k][i]);
                            index = i;
                        }
                    }

                    if (max < epsilon)
                    {
                        throw new Exception("Нет ненулевых диагональных элементов");
                    }

                    SwapCols(ref a, k, index);
                    Swap(ref perm[k], ref perm[index]);
                    break;

                //выбор ведущего (максимального) элемента по всей матрице
                case GaussMethod.All:
                    int nRow = k, nCol = k;
                    max = Math.Abs(a[k][k]);
                    for (int i = k; i < varCount; i++)
                    {
                        for (int j = k; j < varCount; j++)
                        {
                            if (Math.Abs(a[i][j]) > max)
                            {
                                max  = Math.Abs(a[i][j]);
                                nRow = i;
                                nCol = j;
                            }
                        }
                    }

                    if (max < epsilon)
                    {
                        throw new Exception("Нет ненулевых диагональных элементов");
                    }

                    Swap(ref a[k], ref a[nRow]);
                    Swap(ref b[k], ref b[nRow]);
                    SwapCols(ref a, k, nCol);
                    Swap(ref perm[k], ref perm[nCol]);
                    break;
                }


                //Приведение к треугольному виду
                double temp = a[k][k];
                for (int j = k; j < varCount; j++)
                {
                    a[k][j] = a[k][j] / temp;
                }
                b[k] = b[k] / temp;

                for (int i = k + 1; i < varCount; i++)
                {
                    temp = a[i][k];
                    if (Math.Abs(a[i][k]) < epsilon)
                    {
                        continue;                              // для нулевого коэффициента пропустить
                    }
                    for (int j = k; j < varCount; j++)
                    {
                        a[i][j] = a[k][j] * temp - a[i][j];
                    }
                    b[i] = b[k] * temp - b[i];
                }
            }

            //нахождение x

            double[] x = new double[varCount];
            for (int k = varCount - 1; k >= 0; k--)
            {
                x[k] = b[k];
                for (int i = 0; i < k; i++) //пробег по столбцам до k-1
                {
                    b[i] = b[i] - a[i][k] * x[k];
                }
            }


            //Учитываем перестановку вектора x
            if (type == GaussMethod.Rows || type == GaussMethod.All)
            {
                double[] temp = new double[x.Length];
                for (int i = 0; i < perm.Length; i++)
                {
                    temp[perm[i]] = x[i];
                }
                x = temp;
            }

            return(x);
        }