Metoda eliminacji Gaussa L. zespolonych

0

No pora się wziąć za projekt na zaliczenie.
Wie ktoś z was jak zrealizować metodę eliminacji Gaussa na liczbach zespolonych ? Znalazłem w dokumentacji bibliotekę complex. No i teraz to już nie wiem w co ręce włożyć? Może ktoś z was już zajmował się tym problemem ?

0

Coś mi się zdaje, że samo algo nie różni się od liczb rzeczywistych.

0

Z tego co znalazłem wynika ze masz racje. Kumpel ma kod pod php. Jutro powinniśmy siąść i postarać się to przetłumaczyć na c++
zobaczymy jaki będzie z tego efekt.
Jak się uda :) to to tutaj podrzucę.

Trzymajcie kciuki :)

0

Zaglądałeś tutaj ? Może nie trzeba będzie tłumaczyć :)</url>

0

No właśnie próbowałem przerobić ten kod:

// Program rozwiązuje układ równań liniowych o n niewiadomych
// za pomocą metody eliminacji Gaussa.
//-----------------------------------------------------------
// (C)2006 mgr J.Wałaszek                     I LO w Tarnowie

#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>

using namespace std;

const double EPS   = 0.0000000001; // dokładność porównania z zerem
const int    MAXEQ = 100;          // maksymalna ilość równań w układzie

// Funkcja dokonująca eliminacji niewiadomych. Jeśli operacja
// się powiedzie, zwraca true. Inaczej zwraca false.

bool EliminujX(int n, double AB[][MAXEQ+1])
{
  int    i,j,k;
  double m;

  for(i = 0; i < n - 1; i++)
  {
    if(fabs(AB[i][i]) < EPS) return false;
    for(j = i + 1; j < n; j++)
    {
      m = -AB[j][i] / AB[i][i];
      for(k = i + 1; k <= n; k++) AB[j][k] += m * AB[i][k];
    }
  }
  return true;
}

// Funkcja oblicza kolejne niewiadome x z macierzy AB
// przetworzonej przez funkcję Eliminuj_X().
// Jeśli operacja się powiedzie, zwraca true. Inaczej
// zwraca false.

bool ObliczX(int n, double X[], double AB[][MAXEQ+1])
{
  int    i,j;
  double s;

  for(i = n - 1; i >= 0; i--)
  {
    if(fabs(AB[i][i]) < EPS) return false;
    s = AB[i][n];
    for(j = n - 1; j > i; j--) s -= AB[i][j] * X[j];
    X[i] = s / AB[i][i];
  }
  return true;
}

//-----------------------------------------------------
// Program główny
//-----------------------------------------------------

int main(int argc, char* argv[])
{
  ifstream fin;
  ofstream fout;
  int i,j,n;
  double AB[MAXEQ][MAXEQ+1], X[MAXEQ];

  cout.precision(5);     // 5 cyfr po przecinku
  cout.setf(ios::fixed); // format stałoprzecinkowy

  cout << "Uklad rownan liniowych  - metoda eliminacji Gaussa\n"
          "--------------------------------------------------\n"
          "(C)2006 mgr Jerzy Walaszek         I LO w Tarnowie\n\n";

// Dane dla programu odczytujemy z pliku tekstowego o nazwie in.txt,
// który musi się znajdować w tym samym katalogu co program
// Pierwszy wiersz pliku powinien zawierać liczbę n
// Następne n kolejnych wierszy powinno zawierać współczynniki ai dla
// tego wiersza, a na końcu współczynnik bi. Kolejne współczynniki
// oddzielone są od siebie przynajmniej jedną spacją.

  fin.open("in.txt");
  fin >> n;
  if(n <= MAXEQ)
  {
    for(i = 0; i < n; i++)
      for(j = 0; j <= n; j++) fin >> AB[i][j];
    fin.close();

// Dokonujemy eliminacji oraz obliczania niewiadomych x

    cout << "\n--------------------------------------------------\n"
            "Wyniki:\n\n";

    if(EliminujX(n,AB) && ObliczX(n,X,AB))
    {
      fout.open("out.txt");
      for(i = 0; i < n; i++)
      {
        cout << "x" << i + 1 << " = " << setw(12) << X[i] << endl;
        fout << X[i] << endl;
      }
      fout.close();
    }
    else cout << "Rozwiazanie ukladu rownan nie powiodlo sie\n";
  }
  else
  {
    fin.close();
    cout << "Zbyt wiele rownan!\n";
  }
  cout << "\n--------------------------------------------------\n";
  system("pause");
  return 0;
}

Na takie coś:

// Program rozwiązuje układ równań liniowych o n niewiadomych
// za pomocą metody eliminacji Gaussa.
//-----------------------------------------------------------
// (C)2006 mgr J.Wałaszek                     I LO w Tarnowie

#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
#include <complex>
using namespace std;

const double EPS   = 0.0000000001; // dokładność porównania z zerem
const int    MAXEQ = 100;          // maksymalna ilość równań w układzie

// Funkcja dokonująca eliminacji niewiadomych. Jeśli operacja
// się powiedzie, zwraca true. Inaczej zwraca false.

bool EliminujX(int n, complex<double> AB[][MAXEQ+1])
{
  int    i,j,k;
  complex<double> m;

  for(i = 0; i < n - 1; i++)
  {
    if(abs(AB[i][i]) < EPS) return false;
    for(j = i + 1; j < n; j++)
    {
      m = -AB[j][i] / AB[i][i];
      for(k = i + 1; k <= n; k++) AB[j][k] += m * AB[i][k];
    }
  }
  return true;
}

// Funkcja oblicza kolejne niewiadome x z macierzy AB
// przetworzonej przez funkcję Eliminuj_X().
// Jeśli operacja się powiedzie, zwraca true. Inaczej
// zwraca false.

bool ObliczX(int n, complex<double> X[], complex<double> AB[][MAXEQ+1])
{
  int    i,j;
  complex<double> s;

  for(i = n - 1; i >= 0; i--)
  {
    if(abs(AB[i][i]) < EPS) return false;
    s = AB[i][n];
    for(j = n - 1; j > i; j--) s -= AB[i][j] * X[j];
    X[i] = s / AB[i][i];
  }
  return true;
}

//-----------------------------------------------------
// Program główny
//-----------------------------------------------------

int main(int argc, char* argv[])
{
  ifstream fin;
  ofstream fout;
  int i,j,n;
  complex<double> AB[MAXEQ][MAXEQ+1], X[MAXEQ];

  cout.precision(5);     // 5 cyfr po przecinku
  cout.setf(ios::fixed); // format stałoprzecinkowy

  cout << "Uklad rownan liniowych  - metoda eliminacji Gaussa\n"
          "--------------------------------------------------\n"
          "(C)2006 mgr Jerzy Walaszek         I LO w Tarnowie\n\n";

// Dane dla programu odczytujemy z pliku tekstowego o nazwie in.txt,
// który musi się znajdować w tym samym katalogu co program
// Pierwszy wiersz pliku powinien zawierać liczbę n
// Następne n kolejnych wierszy powinno zawierać współczynniki ai dla
// tego wiersza, a na końcu współczynnik bi. Kolejne współczynniki
// oddzielone są od siebie przynajmniej jedną spacją.
n=2;
AB[0][0] = (2,0);
AB[0][1] = (3,-2);
AB[1][0] = (1.0,0);
AB[1][1] = (2,-1);
AB[0][2]= (3,0);
AB[1][2]= (0,1); 

// Dokonujemy eliminacji oraz obliczania niewiadomych x

    cout << "\n--------------------------------------------------\n"
            "Wyniki:\n\n";

    if(EliminujX(n,AB) && ObliczX(n,X,AB))
    {
      fout.open("out.txt");
      for(i = 0; i < n; i++)
      {
        cout << "x" << i + 1 << " = " << setw(12) << X[i] << endl;
        fout << X[i] << endl;
      }
      fout.close();
    }
    else cout << "Rozwiazanie ukladu rownan nie powiodlo sie\n";
  
  cout << "\n--------------------------------------------------\n";
  system("pause");
  return 0;
}

No ale coś nie działa wyrzuciłem z tego pierwotnego kodu odczyt z pliku i ustawiłem wartości i rozmiar macierzy na sztywno.
Pisze że jest zbyt wiele równań zero wyników, no może ze zmienię liczbę z1 tzn AB[0][0] na coś innego ale potem jak zmienię inne liczby to wynik się nie zmienia coś źle działa. Umie ktoś sobie z tym poradzić ?
Co robie źle ?

0
if(fabs(AB[i][i]) < EPS) return false;

co to ma być?

Masz szukać max w linii, a tu wyskakujesz gdy na przekątnej masz zero:
0x + y = 0
x + 0y = 0
czyli rozwiązanie: x = 0 i y = 0,
a ten algorytm pada na tym trywialnym przypadku.

http://en.wikipedia.org/wiki/Gaussian_elimination

0

Pod linkiem, który podałem wyżej znajduje się gdzieś ulepszona wersja tego algorytmu. Na pewno jest na tej stronie wystarczy tylko poszukać :)

0

Panie matek3005 to nie jest mój program ani algorytm. Wiem że ten algo działa bo stosowałem go do rozwiązywania równań gdzie liczby zespolone nie występowały. A teraz potrzebuje coś co rozwiąże mi układ wielu równań na liczach zespolonych i próbowałem to prze modyfikować na klasę complex. Ale kredki z tego wyszły. Może masz jakiś pomysł ja tego pilnie potrzebuję a sam żadnej koncepcji nie mam. Proszę o pomoc. Urok programów numerycznych nie każdy może je napisać.

1 użytkowników online, w tym zalogowanych: 0, gości: 1