prob Determinante matrice

Stato
Discussione chiusa ad ulteriori risposte.

Cynical

Utente Silver
10 Febbraio 2011
2
1
0
51
Salve a tutti :)
ho scritto un programma che calcola il determinante di una matrice...per ora riempita con scalari pseudocasualmente generati....

ecco il sorgente :

Codice:
#include<stdio.h>
#include<stdlib.h>
#include <time.h>

#define PULIZIA printf("\n\n")

int leggiOrdine(void);
void inizializzaMatrice(int**, int);
void estraiMinore(int**, int**,int, int, int);
int detLaplace(int**, int, int); 
void outputRisultati(int**,int , int);

int main(void)
{
 int n; //ordine della matrice...
 
 n = leggiOrdine();
 int mat[n][n];
  
 inizializzaMatrice(mat, n); 

 outputRisultati(mat, n, detLaplace(mat, n , -1));
 PULIZIA;
 system("PAUSE");
}

int leggiOrdine()
{ int n; // ordine della matrice...
  do { printf("Inserisci l'ordine della matrice :\n");
       scanf("%d",&n);
       if(n<=0)
       {
        PULIZIA;
        printf("l'ordine deve essere maggiore di 0.");
        PULIZIA;
       }
   }while(n<=0);
 
 return n;        
}

void inizializzaMatrice(int **m, int dim)
{ int i,j;
  srand(time(NULL));     
  
  /*inizializzo la matrice con valori casuali 
    compresi tra 1 e 6 */
  for(i=0;i<dim;i++)
     for(j=0;j<dim;j++)
          m[i][j] = rand()%6 + 1;
}

void estraiMinore(int **s, int **d,int dimS, int r, int c)
{ int i,j;
 
  for(i=0; i<dimS; i++)
    if(i!=r)  
      for(j=0;j<dimS;j++)
         if(j!=c)
           d[i][j] = s[i][j];
}

int detLaplace(int **m, int dim, int dont)
{ int j,par; int min[dim-1][dim-1], det;
 
  if(dim >1)
  {
    det = 0;
    par = 1;
    for(j=0;j<dim;j++)
       if(j!=dont) 
       { 
          par *= par;
          estraiMinore(m, min, dim, 1, j);
          det += m[1][j]*par*detLaplace(min, dim-1,j);
          par *= -1;
       }
    return det;
  }
  else
    return m[0][0];
}

void outputRisultati(int **m,int n, int det)
{ int i,j;
  
  for(i=0;i<n;i++)
  { 
    printf("|");      
    for(j=0;j<n;j++)
      printf("%d", m[i][j]);
    printf("|"); 
    if(i == (int)n/2)
      printf("  =  %d", det);
    printf("\n");
  }
}

ogni volta che passo una matrice come parametro mi dice Wrong passing argument from incompatible pointer type.

come mai?
grazie in anticipo?
 
Così su 2 piedi non ho dato un' occhiata veloce al codice e non ho notato nulla. L' unica cosa che ho notato è che tu sicuramente utilizzi un compilatore sotto windows e al 90% usi dev c. Io ti consiglio di compilare il tuo codice sotto linux perchè dev c ha non pochi problemi di compilazione e magari dopo ci posti il risultato.
 
Vero XD ero su vm con xp. Ma ora su ubuntu con Code::Blocks mi da lo stesso problema.
uff....mi da solo sti warning invalid argument quando passo le matrici...uff....0 errori 5 warning -.-"


ho modificato la funzione estraiMinore()
Codice:
void estraiMinore(int **s, int **d,int dimS, int r, int c)
{ int i,j;

  for(i=0; i<r; i++)
     for(j=0; j<c; j++)
         d[i][j] = s[i][j];

  for(i=r+1; i<dimS; i++)
     for(j=c+1; j<dimS; j++)
         d[i-1][j-1] = s[i][j];
}

era sbagliata....ma non era quel problema che mi dava i warning....
 
Se parla di incompatible pointer type forse dovresti provare a controllare tutti i puntatori del programma se ritornano correttamente l' indirizzo di memoria. O forse dovresti fare un cast ad alcune variabili. E' da qualche anno che non rispolvero il C, non saprei dirti ora come ora.
 
(tralasciando il fatto che tu ti occupi nello specifico di sole matrici quadrate :asd: )

ma, tralasciando i warning, il programmino funziona?
 
d[j] = s[j];

vorrei sapere come fa il compilatore a calcolarti d[j] oppure s[j] non sapendo quante "colonne" ha.
 
lo dovrebbe sapere perchè le matrici che passo come parametro hanno una dimensione prestabilita, non dovrebbe essere così?
 
Malex ha detto:
(tralasciando il fatto che tu ti occupi nello specifico di sole matrici quadrate :asd: )

beh la vedo dura calcolare il determinante o l'inversa di una matrice non quadrata :)

ma quindi il tuo problema sta nel passare
int mat[n][n];
come
int **m
??

comunque dichiarare la dimensione dell'array tramite variabile non sarebbe standard c89 quindi se devi farlo per un test all'università potresti avere dei problemi, almeno a me rompevano le palle per robe del genere
 
non tanto quello, più che altro fare x[j]....

la soluzione è o fare un cast esplicito del tipo ((int[dim][])x)[j] (ma non so se si può fare passando una variabile), oppure la cosa più corretta è:
*(x + i * dim + j) = valore
 
prova un cast tipo
(int**)mat
ad ogni passaggio
oppure definisci mat usando malloc..
Codice:
int i;
int **mat;
mat=(int*)malloc(n*sizeof(int*));
for(i=0;i<n;i++)
	mat[i]=(int*)malloc(sizeof(int));
 
scusate, ma proprio non volete capire che il compilatore non è onnisciente?
come fa a trasformare un "array" di int (così è la matrice in memoria) in una matrice, se non conosce quante sono le colonne?

lo stesso per malloc... come fa il compilatore a sapere quanto spazio riservi? sfera di cristallo?
 
Correggetemi se sbaglio:
se tipo vet[n] è un array allora vet è un puntatore che punta alla prima locazione.
*(vet + i ) equivale a vet

una matrice è un array di array in pratica quindi dovrebbe essere vero questo per quanto detto fin'ora
se tipo mat[n][m]; è una matrice

*(*(mat +i)+j) equivale a mat[j]

perciò l'unico problema che dovrebbe presentarsi è se io provo a dereferenziare una locazione di memoria non preservata dal compilatore, ma poichè io a quelle funzioni passo matrici dichiarate in altri ambienti non dovrei avere problemi. Almeno questo è il ragionamento che ho fatto....
Mi sta venendo il dubbio che una matrice non sia esattamente un puntatore a puntatore. Ma mi sembra illogico. scusate l'ignoranza è da un pò che non mi capita di programmare con matrici :) hehe
 
una matrice NxM è un array di N*M celle.

int m[5][7];

il compilatore riserverà 5*7 locazioni di memoria, ognuno di dimensione sizeof(int), tutte contigue.

void funzione(int **val, int col, row)
{
}

qui richiedo che val sia un indirizzo di un puntatore.

la chiamata funzione(&m, 5, 7)
non rende onnisciente il compilatore facendo capire che val è una matrice 5x7, quindi tentare di fare val[j] porterà ad un errore:
il compilatore convertirà in (val + i*?+j), dove ? sarebbe il numero di colonne (che il compilatore non conosce).
 
Codice:
#include<stdio.h>
#include<stdlib.h>
#include <time.h>

#define PULIZIA printf("\n\n")

int leggiOrdine(void);
void inizializzaMatrice(unsigned int dim, int m[dim][dim]);
void estraiMinoreComplementare(unsigned int dimS, int s[dimS][dimS], int d[dimS][dimS], int r, int c);
int detLaplace(unsigned int dim, int m[dim][dim]);
void outputRisultati(unsigned int n,int m[n][n], int det);

int main(void)
{
  unsigned int n; //ordine della matrice...

  n = leggiOrdine();
  int mat[n][n];

  inizializzaMatrice(n, mat);

  outputRisultati(n, mat, detLaplace(n, mat));
  PULIZIA;
  scanf("%d",&n);

  return 0;
}

int leggiOrdine()
{ unsigned int n; // ordine della matrice...
  do { printf("Inserisci l'ordine della matrice :\n");
       scanf("%d",&n);
       if(n<=0)
       {
        PULIZIA;
        printf("l'ordine deve essere maggiore di 0.");
        PULIZIA;
       }
   }while(n<=0);

return n;
}

void inizializzaMatrice(unsigned int dim, int m[dim][dim])
{ int i,j;
  srand(time(NULL));

  /*inizializzo la matrice con valori casuali
    compresi tra 1 e 6 */
  for(i=0;i<dim;i++)
     for(j=0;j<dim;j++)
          m[i][j] = (int) rand()%5;
}

void estraiMinoreComplementare(unsigned int dimS, int s[dimS][dimS], int d[dimS-1][dimS-1], int r, int c)
{ int i,j,p,q;

  for(i=0; i<dimS; i++)
    if(i!=r)  
      for(j=0;j<dimS;j++)
         if(j!=c)
            {
              p = (i<r)? i : i-1;
              q = (j<c)? j : j-1;

              d[p][q] = s[i][j]; 
            }
}

int detLaplace(unsigned int dim, int m[dim][dim])
{ int j,par; int min[dim-1][dim-1], det;

  if(dim > 1)
  {
    det = 0;
    par = 1;
    for(j=0;j<dim;j++)
    {
        estraiMinoreComplementare(dim,m, min, 0, j);
        det += m[0][j]*par*detLaplace(dim-1, min);
        par *= -1;
    }
    return det;
  }
  else
    return m[0][0];
}

void outputRisultati(unsigned int n,int m[n][n], int det)
{ int i,j;

  for(i=0;i<n;i++)
  {
    printf("|");
    for(j=0;j<n;j++)
      printf("%d", m[i][j]);
    printf("|");
    if(i == n/2)
      printf("  =  %d", det);
    printf("\n");
  }
}

ecco il programma sistemato, non erano le dimensioni variabili il problema, ma in ogni funzione dovevo esplicitare le variabili in funzione delle quali calcolare le dimensioni, è vero non è onniscente il compilatore xDDDDD


(per quanto riguarda i concetti sulle matrici :
grazie Whivel ora ricordo :) dovevo rispolverare xD infatti ora che ci penso usavo *(mat+i+j) hehe....)
 
Stato
Discussione chiusa ad ulteriori risposte.