/// <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])); }
/// <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); }