/// <summary> /// Обратная матрица по Гауссу /// </summary> /// <returns></returns> public CSqMatrix Invert(bool correct = false) { CSqMatrix mResult = SqMatrix.E(this.ColCount); CSqMatrix mCur = new CSqMatrix(this); CVectors rTmp, eTmp; for (int i = 0; i < this.ColCount; i++) //Цикл по строкам сверху-вниз { int max = MaxLine(i, i); if (max != i) { rTmp = mCur.GetLine(max); eTmp = mResult.GetLine(max); mCur.MinusVector(i, rTmp * (-1)); mResult.MinusVector(i, eTmp * (-1)); //Complex y = new Complex(mCur[i, max]); //mCur.DivByLine(i, y); //mResult.DivByLine(i, y); } //Заединичить вервую строку Complex dItem = new Complex(mCur[i, i]); mCur.DivByLine(i, dItem); mResult.DivByLine(i, dItem); rTmp = mCur.GetLine(i); eTmp = mResult.GetLine(i); //Забить нулями вертикаль for (int j = 0; j < this.ColCount; j++) { if (i != j) { Complex con = new Complex(mCur[j, i]); mCur.MinusVector(j, rTmp * con); mResult.MinusVector(j, eTmp * con); } } //mCur.PrintMatrix(); Console.WriteLine(); //mResult.PrintMatrix(); Console.WriteLine(); } if (!correct) { return(mResult); } return(ReverseCorrect(this, mResult, 1e-16, 100)); }
/// <summary> /// Уточнение обратной матрицы /// </summary> /// <param name="A">Исходная матрица</param> /// <param name="Reverse">Обратная марица</param> /// <param name="eps">Точность</param> /// <returns></returns> public static SqMatrix ReverseCorrect(SqMatrix A, SqMatrix Reverse, double eps = 0.001, int stepcount = 1000, bool existnorm = false) { SqMatrix E = SqMatrix.E(A.RowCount), R = new SqMatrix(Reverse); int i = 0; if ((E - A * R).CubeNorm < 1 || existnorm) { while ((E - A * R).CubeNorm > eps && i < stepcount) { R *= (2 * E - A * R); //(E - A * R).CubeNorm.Show(); i++; } } return(R); }
/// <summary> /// Обратная матрица по Гауссу /// </summary> /// <returns></returns> public SqMatrix Invert() { SqMatrix mResult = SqMatrix.E(this.ColCount); /* * Получать "1" на элементе главной диагонали, а потом * Занулять оставшиеся элементы * */ SqMatrix mCur = new SqMatrix(this); //mCur.PrintMatrix(); Console.WriteLine(); //mResult.PrintMatrix(); Console.WriteLine(); for (int i = 0; i < this.ColCount; i++) //Цикл по строкам сверху-вниз { //Заединичить вервую строку double dItem = mCur[i, i]; mCur.DivByLine(i, dItem); mResult.DivByLine(i, dItem); //mCur.PrintMatrix(); Console.WriteLine(); //mResult.PrintMatrix(); Console.WriteLine(); Vectors rTmp = mCur.GetLine(i); Vectors eTmp = mResult.GetLine(i); //Забить нулями вертикаль for (int j = 0; j < this.ColCount; j++) { if (i != j) { double con = mCur[j, i]; mCur.MinusVector(j, rTmp * con); mResult.MinusVector(j, eTmp * con); } } //mCur.PrintMatrix(); Console.WriteLine(); //mResult.PrintMatrix(); Console.WriteLine(); } return(mResult); }
/// <summary> /// Уточнение обратной матрицы /// </summary> /// <param name="A">Исходная матрица</param> /// <param name="Reverse">Обратная марица</param> /// <param name="eps">Точность</param> /// <returns></returns> public static CSqMatrix ReverseCorrect(CSqMatrix A, CSqMatrix Reverse, double eps = 0.001, int stepcount = 1000, bool existnorm = false) { CSqMatrix E = new CSqMatrix(SqMatrix.E(A.RowCount)), E2 = E * 2, R = new CSqMatrix(Reverse), Rold = new CSqMatrix(Reverse); int i = 0;//i.Show(); double epsold = (E - A * R).CubeNorm, epsnew = epsold; //if (epsold < 1 || existnorm) while (epsnew > eps && i < stepcount) { R *= (E2 - A * R);//epsold.Show(); //(E - A * R).CubeNorm.Show(); epsold = epsnew; epsnew = (E - A * R).CubeNorm; if (epsnew >= epsold) /*$"{epsold} {epsnew}".Show();*/ return { (Rold); } Rold = new CSqMatrix(R); i++; } return(R); }