private void WybierzElemGlowny(ref SparseMatrix y) { for (int i = 0; i < rows; i++) { if(Get(i, i)==0) { for (int j = 0; j < rows; j++) { if (Get(j, i) != 0 && Get(j, i) != 0) { Vector temp = this.wektor[i]; this.wektor[i] = wektor[j]; wektor[j] = temp; temp = y.wektor[i]; y.wektor[i] = y.wektor[j]; y.wektor[j] = temp; } } } } }
private void Decompose(out SparseMatrix L) { SparseMatrix A = this; if (A.rows != A.columns) { Console.WriteLine("Macierz nie jest kwadratowa, niemożliwa dekompozycja"); } L = new SparseMatrix(A.rows, A.columns);//dolnotrójkątna z diagonalą niezerową //U = new SparseMatrix(A.rows, A.columns);//górnotrójkątna z diagonalą zerową int temp; for (int i = 0; i < L.rows; i++)//uzupełniam diagonalę L jedynkami { L.Insert(i, i, 1); } //Gauss int k; for (int m = 0; m < A.rows; m++) { for (int i = m + 1; i < A.rows; i++)//redukcja i-tych wierszy za pomocą m-tego wiersza { k = A.Get(i, m) / A.Get(m, m); for (int j = 0; j < A.columns; j++)//redukcja dwóch konkretnych wierszy { temp = A.Get(i, j) - k * A.Get(m, j); A.Insert(i, j, temp); } L.Insert(i, m, k); //odejmij wiersze //zapisz współczynnik } } }
public static SparseMatrix operator -(SparseMatrix m1, SparseMatrix m2) { if (m1.rows != m2.rows || m1.columns != m2.columns) throw new ZlyRozmiarException("Zły rozmiar macierzy, odejmowanie niemożliwe"); SparseMatrix c = new SparseMatrix(m1.rows, m1.columns); int[] avaibleIndexes; for (int i = 0; i < m1.rows; i++) { c.wektor[i] = new Vector(); avaibleIndexes = m1.wektor[i].avaibleIndex;//wektor niepustych indeksów rzędu i-tego macierzy m1 for (int j = 0; j < m1.wektor[i].numberOfElements; j++) { c.wektor[i].Insert(avaibleIndexes[j], m1.wektor[i].GetAt(avaibleIndexes[j]) - m2.wektor[i].GetAt(avaibleIndexes[j])); //w odpowiednią komórkę macierzy c wstawiam różnicę tych samych komórek m1 i m2 } avaibleIndexes = m2.wektor[i].avaibleIndex;//wektor niepustych indeksów rzędu i-tego macierzy m2 for (int j = 0; j < m2.wektor[i].numberOfElements; j++) { if (c.wektor[i].GetAt(avaibleIndexes[j]) != 0) // sprawdzam czy w poprzedniej pętli nie było już wykonywane działanie continue; else c.wektor[i].Insert(avaibleIndexes[j], m1.wektor[i].GetAt(avaibleIndexes[j]) - m2.wektor[i].GetAt(avaibleIndexes[j])); } } return c; }
public SparseMatrix ObliczUklad(SparseMatrix y) { SparseMatrix L; WybierzElemGlowny( ref y); Decompose(out L); //czas obliczyć wektor Z SparseMatrix Z= new SparseMatrix(rows, 1); int temp = y.Get(0, 0); Z.Insert(0, 0, temp); //pierwszy element zawsze równy temu z wektora y for (int i = 1; i < L.rows; i++)//licze elementy wektora z { temp = y.Get(i, 0); for (int j = 0 ; j < i+1; j++)//licze wartosc i-tego elementu wektora z { temp -= Z.Get(j ,0) * L.Get(i, j); } Z.Insert(i, 0, temp); } //obliczam ostatni wektor X SparseMatrix X = new SparseMatrix(rows, 1); temp = Z.Get(rows-1, 0); X.Insert(rows-1, 0 , temp/this.Get(rows-1, columns-1)); for (int i = this.rows-2; i >= 0; i--)//licze elementy od dołu "this" { temp = Z.Get(i, 0); for (int j = columns-1 ; j >= i ; j--) { temp -= X.Get(j, 0) * this.Get(i, j); } temp/=this.Get(i,i); X.Insert(i, 0, temp); } this.DoPliku("U.txt"); L.DoPliku("L.txt"); X.DoPliku("X.txt"); Console.WriteLine("Macierz U:"); PrintMatrix(); Console.WriteLine("\nMacierz L:"); L.PrintMatrix(); return X; }
public static SparseMatrix operator *(SparseMatrix m1, SparseMatrix m2) { if (m1.columns != m2.rows) throw new ZlyRozmiarException("Zły rozmiar macierzy, mnożenie niemożliwe"); SparseMatrix c = new SparseMatrix(m1.rows, m2.columns); int []avaibleIndexes; int temp; for (int i = 0; i < m1.rows; i++) //pętla po rzędach { c.wektor[i] = new Vector(); avaibleIndexes=m1.wektor[i].avaibleIndex; for (int k = 0; k < m2.columns; k++)//pętla po kolumnach { for (int j = 0; j < m1.wektor[i].numberOfElements; j++) //pętla mnożąca m1[i][j] przez m2[j][k] { temp = m1.wektor[i].GetAt(avaibleIndexes[j]) * m2.wektor[avaibleIndexes[j]].GetAt(k); //if (i == 2) //{ // Console.WriteLine("trzecia linia" + temp); //} c.wektor[i].Insert(k, c.wektor[i].GetAt(k) + temp); } } } return c; }