Witam,
Mam problem z projektem dotyczącym obliczania układów liniowych przy pomocy metody Gaussa.
W projekcie mamy utworzyć 4 różne funkcje obliczające wartości niewiadomych różniące się sposobem wybrania elementu stojącym w lewym górnym rogu (chodzi o to żeby np. nigdy nie stało tam zero). Jednak w zależności jaką funkcję wybiorę w niektórych wypadkach otrzymuje różne wyniki i nie wiem co jest tego przyczyną.
Przykładowe dane w których widać ten problem:
ilość niewiadomych: 3
macierz:
2 3 -4 9
1 2 -2 7
4 -2 5 -5
#include <iostream>
#include <cmath>
using namespace std;
void wczytywanie_macierzy(float **macierz,int rozmiar)
{
for (int i=0; i<rozmiar; i++)
{
cout<<"\nPodaj " << i+1 << " wiersz:\n";
for (int j=0; j<rozmiar+1; j++)
{
cin>>macierz[i][j];
}
}
}
void wyswietl(float **macierz,int rozmiar)
{
for (int i=0; i<rozmiar; i++)
{
cout<<endl;
for (int j=0; j<rozmiar+1; j++)
{
cout<<macierz[i][j]<<" ";
}
}
}
void Gauss(float **macierz,int rozmiar, int a)
{
float w;
for(int i=a+1; i<rozmiar; i++)
{
w=macierz[i][a]/macierz[a][a];
for(int j=a; j<rozmiar+i; j++)
{
macierz[i][j]-=w*macierz[a][j];
}
}
}
void wyznaczanie_wartosci(float *wyniki,float **macierz,int rozmiar,bool &flaga)
{
wyniki[rozmiar-1]=macierz[rozmiar-1][rozmiar] / macierz[rozmiar-1][rozmiar-1];
float suma;
for(int i=rozmiar-2; i>=0 && flaga==1; i--)
{
suma=0;
for(int j=rozmiar-1; j>i; j--)
{
suma+=wyniki[j]*macierz[i][j];
}
if(macierz[i][i]!=0)
{
wyniki[i]=(macierz[i][rozmiar]-suma)/macierz[i][i];
if(fabs(wyniki[i]<0.0000001)) wyniki[i]=0;
}
else
{
flaga=0;
}
}
}
void redukcja_bledow(float **macierz,int rozmiar)
{
for (int i=0; i<rozmiar; i++)
{
for (int j=0; j<rozmiar+1; j++) //tutaj zmiana
{
if(fabs(macierz[i][j]) < 0.0000001)
macierz[i][j]=0;
}
}
}
void wiersz_swap(float **macierz,int rozmiar, int a, int b)
{
for(int i=0; i<rozmiar+1; i++)
{
swap(macierz[a][i],macierz[b][i]);
}
}
void kolumna_swap(float **macierz,int rozmiar, int a, int b,int *kolejnosc)
{
for(int i=0; i<rozmiar; i++)
{
swap(macierz[i][a],macierz[i][b]);
}
swap(kolejnosc[a],kolejnosc[b]);
}
void najwiekszy_w_kolumnie(float **macierz,int rozmiar, int &najwiekszyKolumna, int a)
{
for(int i=a; i<rozmiar; i++)
{
if(fabs(macierz[najwiekszyKolumna][a]) < fabs(macierz[i][a])) najwiekszyKolumna=i;
}
}
void najwiekszy_w_wierszu(float **macierz,int rozmiar, int &najwiekszyWiersz, int a)
{
for(int i=a; i<rozmiar; i++)
{
if(fabs(macierz[a][najwiekszyWiersz]) < fabs(macierz[a][i])) najwiekszyWiersz=i;
}
}
void najwiekszy_w_macierzy(float **macierz,int rozmiar, int &najwiekszyWiersz,int &najwiekszyKolumna, int a)
{
for(int i=a; i<rozmiar; i++)
{
for(int j=a; j<rozmiar; j++)
{
if(fabs(macierz[najwiekszyKolumna][najwiekszyWiersz])<fabs(macierz[i][j]))
{
najwiekszyKolumna=i;
najwiekszyWiersz=j;
}
}
}
}
void wyswietl_wyniki(float wyniki[],int rozmiar) //w przypadku podstawowego Gaussai w przypadku szukania w kolumnie
{
cout<<"\nWyniki:";
for(int i=0; i<rozmiar; i++)
{
cout<<"\nX"<<i<<" ="<<wyniki[i];
}
cout<<endl;
}
void wyswietl_kolejnosc(float wyniki[],int kolejnosc[],int rozmiar)
{
cout<<"\nWyniki:";
for(int i=0; i<rozmiar; i++)
{
cout<<"\nX"<<kolejnosc[i]<<" ="<<wyniki[i];
}
}
void Gauss_podstawowy(float **macierz,int rozmiar, float *wyniki)
{
bool flaga=1;
for(int i=0; i<rozmiar; i++)
{
Gauss(macierz,rozmiar,i);
redukcja_bledow(macierz,rozmiar);
}
wyznaczanie_wartosci(wyniki,macierz,rozmiar,flaga);
if(flaga==1)
{
wyswietl(macierz,rozmiar);
wyswietl_wyniki(wyniki,rozmiar);
}
else
{
cout<<"Nie mozna obliczyc wartosci niewiadomych ta metoda";
}
}
void Gauss_w_wierszu (float **macierz,int rozmiar, float *wyniki) //w zrodle jest to "w kolumnie"
{
int maksI;
bool flaga=1;
for(int i=0; i<rozmiar; i++)
{
maksI=i;
najwiekszy_w_kolumnie(macierz,rozmiar,maksI,i);
wiersz_swap(macierz,rozmiar,maksI,i);
redukcja_bledow(macierz,rozmiar);
Gauss(macierz,rozmiar,i);
redukcja_bledow(macierz,rozmiar);
}
wyznaczanie_wartosci(wyniki,macierz,rozmiar,flaga);
if(flaga==1)
{
wyswietl(macierz,rozmiar);
wyswietl_wyniki(wyniki,rozmiar);
}
else
{
cout<<"Nie mozna obliczyc wartosci niewiadomych ta metoda";
}
}
void Gauss_w_kolumnie( float **macierz,int rozmiar, float *wyniki, int *kolejnosc)
{
int maksJ;
bool flaga=1;
for(int i=0; i<rozmiar; i++)
{
maksJ=i;
najwiekszy_w_wierszu(macierz,rozmiar,maksJ,i);
kolumna_swap(macierz,rozmiar,maksJ,i,kolejnosc);
redukcja_bledow(macierz,rozmiar);
Gauss(macierz,rozmiar,i);
wyswietl(macierz,rozmiar);
redukcja_bledow(macierz,rozmiar);
}
wyznaczanie_wartosci(wyniki,macierz,rozmiar,flaga);
if(flaga==1)
{
wyswietl(macierz,rozmiar);
wyswietl_kolejnosc(wyniki,kolejnosc,rozmiar);
}
else
{
cout<<"Nie mozna obliczyc wartosci niewiadomych ta metoda";
}
}
void Gauss_pelny(float **macierz,int rozmiar, float *wyniki, int *kolejnosc)
{
int maksJ;
int maksI;
bool flaga=1;
for(int i=0; i<rozmiar; i++)
{
maksJ=i;
maksI=i;
najwiekszy_w_macierzy(macierz,rozmiar,maksJ,maksI,i);
wiersz_swap(macierz,rozmiar,maksI,i);
kolumna_swap(macierz,rozmiar,maksJ,i,kolejnosc);
Gauss(macierz,rozmiar,i);
redukcja_bledow(macierz,rozmiar);
}
wyznaczanie_wartosci(wyniki,macierz,rozmiar,flaga);
if(flaga==1)
{
wyswietl(macierz,rozmiar);
wyswietl_kolejnosc(wyniki,kolejnosc,rozmiar);
}
else
{
cout<<"Nie mozna obliczyc wartosci niewiadomych ta metoda";
}
}
void kolejnosc_zerowanie(int *kolejnosc,int rozmiar)
{
for(int i=0; i<rozmiar; i++)
{
kolejnosc[i]=i+1;
}
}
void przepisanie(float **skad, float **dokad,int rozmiar)
{
for (int i=0; i<rozmiar; i++)
{
for (int j=0; j<rozmiar+1; j++)
{
dokad[i][j]=skad[i][j];
}
}
}
int main()
{
int n;
int wybor;
bool warunek=1;
cout << "Podaj ilosc zmiennych: ";
cin >> n;
int kolejnosc[n];
float wyniki[n];
float **tab = new float *[n];
for(int i=0; i<n; i++)
{
tab[i] = new float [n+1];
}
wczytywanie_macierzy(tab,n);
float **badana=new float *[n];
for(int i=0; i<n; i++)
{
badana[i] = new float [n+1];
}
przepisanie(tab,badana,n);
while(warunek==1)
{
cout<<"\n1.Podstawowy:\n21.Wybor w wierszu\n22.Wybor w kolumnie \n3.Pelny Gauss\n4.Wyjscie\n";
cin>>wybor;
switch(wybor)
{
case 1:
{
przepisanie(tab,badana,n);
Gauss_podstawowy(badana,n,wyniki);
break;
}
case 21:
{
przepisanie(tab,badana,n);
Gauss_w_wierszu(badana,n,wyniki);
break;
}
case 22:
{
przepisanie(tab,badana,n);
kolejnosc_zerowanie(kolejnosc,n);
Gauss_w_kolumnie(badana,n,wyniki,kolejnosc);
break;
}
case 3:
{
przepisanie(tab,badana,n);
kolejnosc_zerowanie(kolejnosc,n);
Gauss_pelny(badana,n,wyniki,kolejnosc);
break;
}
case 4:
{
cout<<"\n*******************************************************\nKONIEC\n";
warunek=0;
}
default:
{
cout<<"\nNieprawidlowa funkcja\n";
break;
}
}
}
for(int i=0; i<n; i++)
{
delete tab[i];
}
delete tab;
for(int i=0; i<n; i++)
{
delete badana[i];
}
delete badana;
return 0;
}