public override BaseMatrix LLt() { var new_al = al.Clone() as double[]; var matrixLLt = new SparseMatrix(ia, ja, new_al, new_al, di.Clone() as double[]); for (int i = 0; i < matrixLLt.Size; i++) { int i0 = matrixLLt.ia[i]; int i1 = matrixLLt.ia[i + 1]; int k; double S = 0; for (k = i0; k < i1; k++) { double Sl = 0; int iind = i0; int j = matrixLLt.ja[k]; int j0 = matrixLLt.ia[j]; int j1 = matrixLLt.ia[j + 1]; if (j1 - j0 != 0) { int jind = j0; while (iind < k) { if (matrixLLt.ja[jind] > matrixLLt.ja[iind]) iind++; else if (matrixLLt.ja[jind] < matrixLLt.ja[iind]) jind++; else { Sl += matrixLLt.al[iind] * matrixLLt.al[jind]; iind++; jind++; } } } matrixLLt.al[k] = (matrixLLt.al[k] - Sl) / matrixLLt.di[j]; if (double.IsInfinity(matrixLLt.al[k])) throw new Exception(String.Concat("Предобусловливание LU : деление на 0 для расчёта элемента (", i + 1, ",", j + 1, ")")); if (double.IsNaN(matrixLLt.al[k])) throw new Exception(String.Concat("Предобусловливание LUsq : неопределённость 0/0 для элемента (", i + 1, ",", j + 1, ")")); S += matrixLLt.al[k] * matrixLLt.al[k]; } matrixLLt.di[i] = Math.Sqrt(matrixLLt.di[i] - S); if (!(matrixLLt.di[i] == matrixLLt.di[i])) throw new Exception(String.Concat("Предобусловливание LLt : NaN для элемента диагонали №", i)); } return matrixLLt; }
public override BaseMatrix LU() { var matrixILU = new SparseMatrix (ia, ja, al.Clone() as double[], au.Clone() as double[], di.Clone() as double[]); for (int i = 0; i < matrixILU.Size; i++) { int i0 = matrixILU.ia[i]; int i1 = matrixILU.ia[i + 1]; double S = 0; for (int k = i0; k < i1; k++) { double Sl = 0, Su = 0; int iind = i0; int j = matrixILU.ja[k]; int j0 = matrixILU.ia[j]; int j1 = matrixILU.ia[j + 1]; if (j1 - j0 != 0) { int jind = j0; while (iind < k) { if (matrixILU.ja[jind] > matrixILU.ja[iind]) iind++; else if (matrixILU.ja[jind] < matrixILU.ja[iind]) jind++; else { Sl += matrixILU.al[iind] * matrixILU.au[jind]; Su += matrixILU.au[iind] * matrixILU.al[jind]; iind++; jind++; } } } matrixILU.au[k] = (matrixILU.au[k] - Su) / matrixILU.di[j]; matrixILU.al[k] = (matrixILU.al[k] - Sl); if (double.IsInfinity(matrixILU.au[k])) throw new Exception(String.Concat("Предобусловливание LU : деление на 0 для расчёта элемента (", j + 1, ",", i + 1, ")")); if (double.IsNaN(matrixILU.au[k])) throw new Exception(String.Concat("Предобусловливание LU : неопределённость 0/0 для элемента (", j+1, ",", i+1,")")); S += matrixILU.au[k] * matrixILU.al[k]; // диагональ в U!!!!! } matrixILU.di[i] = matrixILU.di[i] - S; } return matrixILU; }
public static BaseMatrix InputGenericSparseMatrix(string fileName, int _n) { Logger log = Logger.Instance; BaseMatrix matrix; int n; if (_n == 0) { n = InputGenericN(fileName); } else { n = _n; } int m; int[] ia; double[] di; List<int> ja = new List<int>(); List<double> al = new List<double>(); List<double> au = new List<double>(); try { using (StreamReader streamReader = new StreamReader(fileName)) { log.Info("Чтение информации о матрице из файла " + fileName + "..."); log.Info("Ввод размерности матрицы..."); m = ReadInt(streamReader); if (m < 0) { throw new Exception("Некорректно введена размерность матрицы (Не должна быть меньше 1)."); } log.Info("Ввод размерности матрицы завершен."); ia = new int[n + 1]; di = new double[n]; log.Info("Ввод элементов матрицы..."); for (int i = 0; i < m; i++) { int row = ReadInt(streamReader); int col = ReadInt(streamReader); if (row < 0 || col < 0 || row > n - 1 || col > n - 1) { throw new Exception("Некорректно введено расположение " + (i + 1).ToString() + " элемента (индексы не должны быть меньше 0 / больше n - 1)."); } double a = ReadDouble(streamReader); if (col == row) { di[row] = a; } else { int rRow; int rCol; List<double> a1; List<double> a2; if (row > col) { a1 = al; a2 = au; rRow = row; rCol = col; } else { a1 = au; a2 = al; rRow = col; rCol = row; } int k; int i0 = ia[rRow]; int i1 = ia[rRow + 1]; bool isExisting = false; for (k = i1; k > i0; k--) { if (rCol == ja[k - 1]) { a1[k - 1] = a; isExisting = true; break; } if (rCol > ja[k - 1]) { break; } } if (!isExisting) { ja.Insert(k, rCol); a1.Insert(k, a); a2.Insert(k, 0); for (int j = rRow + 1; j < n + 1; j++) { ia[j]++; } } } } log.Info("Ввод элементов матрицы завершен."); } matrix = new SparseMatrix(ia, ja.ToArray<int>(), al.ToArray<double>(), au.ToArray<double>(), di); } catch (Exception e) { log.Error(e.Message); log.Error("Аварийное завершение ввода матрицы."); return null; } return matrix; }