//Autor: Artur Czekalski (Sator) www.epokaY.net/artur artur@epokaY.net Wer. 2007-08-04 //Liczenie ukladu rownan - wersja z wyborem max. wyrazu do dzielenia import std.c.windows.windows; //GetTickCount import std.stdio; //writefln import std.math; ///fabs //--------------------------------------------------------------------------- const double MinEpsilon = 1.0E-9; //dla spr czy == 0, bo bledy zaokraglen !!!WAZNE!!! const int MAXWymiar = 2000; //2000 dla 995 double gM[]; //macierz wspolczynnikow double gB[MAXWymiar]; //wektor wyrazow wolnych double gX[MAXWymiar]; //dla wyniku double gOdpX[MAXWymiar]; //Odpowiedni wynik //--------------------------------------------------------------------------- int EliminacjaGaussaMax(int Wymiar, double A[], double B[], double X[]) //zmienia A[] ! {//Rozwiazuje uklad rownan liniowych metoda eliminacji Gaussa -wsz. przypadki //A[Wymiar*Wymiar] - macierz kwadratowa stopnia Wymiar; A[i,j] = A[i*Wymiar+j] //B[Wymiar] - wektor wyrazow wolnych //X[Wymiar] - tablica wynikow int i, j, k, nr_max; double w, max; //---Przeksztalcam macierz A na trojkatna gorna z jedynkami na przekatnej--- for (k=0; k < Wymiar-1; ++k) //wiersze (k) (bez ostatniego) { //Znajdz najwiekszy element != 0 w kolumnie k (bo mniejsze beda bledy przy dzieleniu przez mala liczbe) 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 bede dzielil) if (max < MinEpsilon) return -1; //nie ma takiego -kolumna (k) jest linowa kombinacja innej kolumny (ma same zera) if (k != nr_max) //Jesli nie jest to elem. z k-tego wiersza, to zamien wiersz k-ty z nr_max { for (j=k; j MinEpsilon) //Dziele przez 'pierwszy' tzn. k-ty wyraz wszystkie elementy tego wiersza {A[k*Wymiar+k] = 1.0; //juz nie dziele; wiadomo ma byc =1.0 for (i=k+1; i MinEpsilon) //tylko te rozne od 0.0 (niezredukowane) {for (i=k; i=0; --k) //wiersze k {X[k] = B[k]; for (j=k+1; j