//Autor: Artur Czekalski (Sator) www.epokaY.net/artur artur@epokaY.net Wer. 2007-08-04 //Liczenie układu równań - wersja z wyborem max. wyrazu do dzielenia #include //printf #include //GetTickCount() #include //fabs //--------------------------------------------------------------------------- typedef double typwyr; const typwyr MinEpsilon = 1.0e-9; //dla spr czy == 0, bo błędy zaokrągleń !!!WAŻNE!!! const int MAXWymiar = 2000; //2000 dla 995 typwyr gM[MAXWymiar*MAXWymiar]; //macierz współczynników typwyr gB[MAXWymiar]; //wektor wyrazów wolnych typwyr gX[MAXWymiar]; //dla wyniku typwyr gOdpX[MAXWymiar]; //Odpowiedni wynik //--------------------------------------------------------------------------- int EliminacjaGaussaMax(const int Wymiar, typwyr *A, typwyr *B, typwyr *X) //zmienia A[] ! {//Rozwiązuje układ równań liniowych metodą eliminacji Gaussa -wsz. przypadki //A[Wymiar*Wymiar] - macierz kwadratowa stopnia Wymiar; A[i,j] = A[i*Wymiar+j] //B[Wymiar] - wektor wyrazów wolnych //X[Wymiar] - tablica wyników int i, j, k, nr_max; typwyr w, max; //---Przekształcam macierz A na trójkątną górną z jedynkami na przekątnej--- for (k=0; k < Wymiar-1; ++k) //wiersze (k) (bez ostatniego) { //Znajdź największy element != 0 w kolumnie k (bo mniejsze będą błędy przy dzieleniu przez małą liczbę) i = k; max = fabs(A[i*Wymiar+k]); nr_max = i; while (++i < Wymiar) if (fabs(A[i*Wymiar+k]) > max) {max = fabs(A[i*Wymiar+k]); nr_max = i;} //Musi to być wiersz z NIEZEROWYM elementem w kolumnie k (bo nim będę dzielił) if (max < MinEpsilon) return -1; //nie ma takiego -kolumna (k) jest linową kombinacją innej kolumny (ma same zera) if (k != nr_max) //Jeśli nie jest to elem. z k-tego wiersza, to zamień wiersz k-ty z nr_max { for (j=k; j MinEpsilon) //Dzielę przez 'pierwszy' tzn. k-ty wyraz wszystkie elementy tego wiersza {A[k*Wymiar+k] = 1.0; //już nie dzielę; wiadomo ma być =1.0 for (i=k+1; i MinEpsilon) //tylko te różne od 0.0 (niezredukowane) {for (i=k; i=0; --k) //wiersze k {X[k] = B[k]; for (j=k+1; j