[C] Eliminazione Gauss

beowulf2
Salve,
ho scritto la seguente funzione C per implementare l'algoritmo di eliminazione di Gauss. La variabile 'iterazione' sarà poi incrementata di 1 ad ogni passo, ma prima volevo testare il codice al passo iniziale. Il problema è che mi azzera solo gli elementi della prima colonna, le altre colonne rimangono invariate, e non capisco dove ho sbagliato. Potreste aiutarmi ?
void eliminazione_gauss ( tMatrice M, int m, int n, int iterazione)
{
int i, j,s;
tMatrice T;
    
      for ( j = iterazione; j < n; j++ ) {
         for ( i = iterazione; i < m; i++ ) {
            if ( M[i][j] == 0 ) { s = i+1; }
            else {
               s = 0;
               i = m;
               j = n; } } }

    printf ("\ns = %d", s);
    printf ("\n");

    printf ("%d %d %d\n", iterazione, m, n);
  
   if ( M[iterazione][iterazione] == 0 ) {
      for ( j = iterazione; j < n; j++ ) {
         T[s][j] = M[s][j];
         M[s][j] = M[0][j];
         M[0][j] = T[s][j]; } }
   else {
      for ( i = iterazione+1; i < m; i++ ) {
         for ( j = iterazione; j < n; j++ ) {
            M[i][j] = M[i][j] - M[i][iterazione]*M[iterazione][j]/M[iterazione][iterazione]; } } }

   for ( i=0; i<m; i++ ) {
      for ( j=0; j<n; j++ ) {
         printf ("%.2f\t", M[i][j] ); }
      printf("\n"); }

}

Risposte
vict85
Come è definito [inline]tMatrice[/inline]? Comunque è generalmente una cattiva idea la presenza della variabile iterazione: toglie al compilatore la capacità di riorganizzare il codice.

Comunque, ho sinceramente difficoltà a capire cosa vuoi fare con quel codice. Cosa dovrebbe fare il primo ciclo per esempio? Cercare il pivot? Perché lo cerchi anche nella altre colonne?

feddy
Non vedo come una volta eventualmente chiamata la funzione poi venga modificata la matrice. O passi una reference oppure ritorni una nuova matrice.

feddy
Ah okay stai scrivendo in C, scusami. In ogni caso non mi pare che tu stia modificando la matrice di partenza oppure ritornando una nuova matrice.

vict85
@feddy, penso che tMatrice sia definito come:
typedef double tMatrice[MAXSIZE][MAXSIZE]

o qualcosa del genere. Quindi è implicitamente un puntatore. Ma rimane il fatto che quel codice non implementa l'eliminazione di Gauss.

@beowulf: prendi una versione scritta con lo pseudocodice (wiki ne dovrebbe contenere una) e riinizia da capo.

feddy
Certo, il nome di un array decade ad un puntatore ad un primo elemento. Mi aspettavo di vedere
void eliminazione_gauss ( double* M, int m, int n)
nella signature della funzione, ti ringrazio :-)

beowulf2
Salve, questo è il codice definitivo a cui sono giunto e sembra funzionare con qualsiasi tipo di matrice. Si accettano consigli e osservazioni
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define MAX 20
#define PRECISIONE 100

typedef float tMatrice[MAX][MAX];
tMatrice M;

unsigned int validazione_input_intero ( unsigned int );
void stampa_matrice ( tMatrice, unsigned int, unsigned int );
void controllo_gradini ( tMatrice, unsigned int, unsigned int );
void scambia_righe ( tMatrice, unsigned int, unsigned int, unsigned int );
void azzera (tMatrice, unsigned int, unsigned int, unsigned int );
void eliminazione_gauss ( tMatrice, unsigned int, unsigned int );

unsigned int validazione_input_intero ( unsigned int v )
{
	int c;
	do
	    { c=scanf("%d", &v);
	      if (c==0)
	          {
	      	scanf ("%*[^\n]");
	      	printf ("Attenzione: input non valido. Inserire input valido: ");
	           }
	     } while (c==0);
	  
if(v>MAX)
	   {   printf ("%u", v);
	             printf(" viene scalato a %u", MAX);
	        v=MAX;
	    }
else
	    { printf("%u", v); }
	  
return v; }

void stampa_matrice ( tMatrice M, unsigned int rig, unsigned int col)
{
unsigned int i, j;

 for ( i=0; i<rig; i++ ) {
  for ( j=0; j<col; j++ ) {
   printf ("%.2f\t", M[i][j]); }
  printf ("\n"); }
 printf ("\n");
}

void controllo_gradini ( tMatrice M, unsigned int rig, unsigned int col )
{
 unsigned int i, j, k1 = 0, k2 = 1;

  for ( i =1; i < rig - 1; i++ ) {
    for ( j = 0; j < col; j++ ) {
      if ( (int)( M[i][j] * PRECISIONE) != 0 ) { 
        k2 = j;
          if ( k2 > k1 ) {
            unsigned int z, u;
            float coeff;

        for (z = i + 1; z < rig; z++) {
  if ( (int)( M[z][k2] * PRECISIONE) != 0 ) {
  coeff = M[z][k2] / M[i][k2] ; 
  for ( u = k2; u < col; u++) {
     M[z] = M[z] - coeff * M[i] ;
} } }
 }  
 k1 = k2; 
 j = col;
       } 
     }
  }
}

void scambia_righe ( tMatrice M, unsigned int rig, unsigned int col, unsigned int iterazione )
{
unsigned int i, j;
unsigned int rig_1, rig_2;
float temp;

rig_1 = iterazione;

for ( j=iterazione; j < col; j++ ) {
 for ( i=iterazione; i < rig; i++ ) {
  if ( (int)( M[i][j] * PRECISIONE) != 0 ) {
   rig_2 = i;
   i = rig;
   j = col; } } }

if ( rig_2 != rig_1 ) {
 for( j = iterazione; j < col; j++ )
    {
        temp = M[iterazione][j];
        M[iterazione][j] = M[rig_2][j];
        M[rig_2][j] = temp;
    } }
} 

void azzera (tMatrice M, unsigned int rig, unsigned int col, unsigned int iterazione )
{
  int i, j;
  float coeff;
  
 for (i = iterazione + 1; i < rig; i++) {
  if ( (int)( M[i][iterazione] * PRECISIONE) != 0 ) {
  coeff = M[i][iterazione] / M[iterazione][iterazione] ; 
  for ( j = iterazione; j < col; j++) {
     M[i][j] = M[i][j] - coeff * M[iterazione][j] ;
} } }

 }
     
void eliminazione_gauss ( tMatrice M, unsigned int rig, unsigned int col )
{
 unsigned int passi, iterazione;

if ( rig >= col ) { passi = col - 1; }
else { passi = rig - 1; }

for ( iterazione = 0; iterazione <= passi; iterazione++ ) {
  scambia_righe ( M, rig, col, iterazione );
  azzera ( M, rig, col, iterazione );
  stampa_matrice ( M, rig, col ); }

  controllo_gradini ( M, rig, col );
  stampa_matrice ( M, rig, col );
  
}

int main()
{
unsigned int i, j, rig, col, v;
double t;

   printf ("\nInserisci il numero di righe della matrice: ");
	rig = validazione_input_intero (v);

   printf ("\nInserisci il numero di colonne della matrice: ");
   col = validazione_input_intero (v);

   printf("\nInserisci i valori della matrice da sx a dx in ordine di riga:\n");
	 
	 for (i=0; i<rig; i++) {
	    for (j=0; j<col; j++) { 
          scanf("%f", &M[i][j]) ; }
       printf ("\n"); }

   stampa_matrice (M, rig, col);

   srand(time(NULL));

   clock_t start=clock();

   eliminazione_gauss ( M, rig, col );

   clock_t end=clock();
     t=((double)(end-start)) / CLOCKS_PER_SEC;
     printf("\nTempo di esecuzione = %f secondi\n", t) ;

   return 0;
}

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.