PDA

View Full Version : [c++] Problema con funzione ricorsiva


Gervasoni
21-03-2004, 15:42
Devo scrivere un programma che calcoli il determinante di una matrice al max 6*6 mediante una funzione ricorsiva.

Il codice della funzione che calcola il determinante che ho scritto è questo:


float determinante(float x[IMAX][IMAX], int n_rig)
{
float min_estratto[IMAX][IMAX];
float det;
int h=n_rig-1;

if (n_rig>2)
{

for (int n_col=0; n_col<IMAX; n_col++)
{
matrice_minore(x,min_estratto,n_col,h+1);
det=det+(x[n_rig][n_col]*pow(-1,n_col+n_rig)*determinante(min_estratto,h));
printf("\t\t%d\n",h);
}
h=h-1;
}
if (n_rig==2) return (x[0][0]*x[1][1]-x[0][1]*x[1][0]);
return det;
}


matrice_minore è il nome della funzione che calcola la matrice ottenuta cancellando una determinata riga e colonna.

Il problema non è della funzione matrice_minore che mediante dei printf ho visto che funziona correttamente quanto della funzione determinante che mi restituisce sempre e comunque un valore del determinante uguale a zero.

Cosa c'è che non va?

/\/\@®¢Ø
21-03-2004, 18:20
attento che non inizializzi det a zero.

Gervasoni
21-03-2004, 19:07
Una variabile locale viene automaticamente inizializzata a zero.
Il problema è che non funge proprio la ricorsione...

Perchè a det non viene assegnato questo valore?

det=det+(x[n_rig][n_col]*pow(-1,n_col+n_rig)*determinante(min_estratto,h));

Help please! :cry:

cionci
21-03-2004, 19:49
Originariamente inviato da Gervasoni
Una variabile locale viene automaticamente inizializzata a zero.

Questo non è assoultamente vero...

ri
21-03-2004, 20:25
Originariamente inviato da Gervasoni
Una variabile locale viene automaticamente inizializzata a zero.


:rotfl:

ommiodio :rotfl:

scusa sa rotflo ma l'hai detto troppo convinto per non farmi ridere :rotfl:

/\/\@®¢Ø
21-03-2004, 20:56
Originariamente inviato da Gervasoni
Una variabile locale viene automaticamente inizializzata a zero.
Il problema è che non funge proprio la ricorsione...


non e' garantito, anche se probabilmente alcuni compilatori permettono di impostare tale opzione.
Infatti il seguente codice


void foo()
{
float f;
cout << f;
}

stampa

1.#QNAN

sul mio compilatore.

/\/\@®¢Ø
21-03-2004, 21:10
if (n_rig>2)
{
for (int n_col=0; n_col<IMAX; n_col++)
{
matrice_minore(x,min_estratto,n_col,h+1);
det=det+(x[n_rig][n_col]*pow(-1,n_col+n_rig)*determinante(min_estratto,h));
printf("\t\t%d\n",h);
}
h=h-1;
}

h a cosa serve ? Non dovrebbe bastarti n_col e n_rig ?
Ancora piu' dubbio quel pow(-1,...) , dovrebbe bastare qualcosa del tipo

det = det + x[n_rig][n_col]*determinante(min_estratto);

/\/\@®¢Ø
21-03-2004, 21:41
Originariamente inviato da /\/\@®¢Ø
non e' garantito, anche se probabilmente alcuni compilatori permettono di impostare tale opzione.
Infatti il seguente codice


void foo()
{
float f;
cout << f;
}

stampa

1.#QNAN

sul mio compilatore.
Dimenticavo di dire che invece sono le variabili globali quelle che vengono inizializzate a 0.

Gervasoni
22-03-2004, 15:16
l'h la passo a n_rig

Il pow serve perchè x[n_rig][n_col] deve essere alternativamente positiva e negativa.

Cmq Marco grazie per l'aiuto.

cionci
22-03-2004, 16:55
Al posto di pow(-1,n_col+n_rig) metti:

inline float pow_minus1(const int riga, const int colonna)
{
return (float)((riga+colonna)&0x1)?-1:1;
}

Direi 5 o 6 volte + veloce... Pensa che il pow era l'operazione + lenta del tuo programma ;)

/\/\@®¢Ø
22-03-2004, 18:44
Originariamente inviato da Gervasoni
l'h la passo a n_rig

Ok, ma allora che serve decrementarlo dopo il ciclo for visto che non lo usi piu' ? :confused:


Il pow serve perchè x[n_rig][n_col] deve essere alternativamente positiva e negativa.

Cmq Marco grazie per l'aiuto.
Hai ragione :eek: avevo l'avevo letto come x^-1 invece che -1^x

Gervasoni
22-03-2004, 22:34
Ok, ma allora che serve decrementarlo dopo il ciclo for visto che non lo usi piu' ?

Già! Sarebbe quindi giusto levare

int h=n_rig-1;
e
h=h-1;

e chiamare la funzione direttamente come
determinante(min_estratto,n_rig-1)?

angelica
23-03-2004, 13:29
Originariamente inviato da cionci
Direi 5 o 6 volte + veloce... Pensa che il pow era l'operazione + lenta del tuo programma ;)

Mi son sempre chiesta come si faccia a sapere quanto più veloce giri il proprio prog post-modifiche, e la velocità/lentezza delle singole operazioni...

/\/\@®¢Ø
23-03-2004, 13:58
Originariamente inviato da cionci
Al posto di pow(-1,n_col+n_rig) metti:

inline float pow_minus1(const int riga, const int colonna)
{
return (float)((riga+colonna)&0x1)?-1:1;
}

Direi 5 o 6 volte + veloce... Pensa che il pow era l'operazione + lenta del tuo programma ;)
In teoria trasformando l'if in operazioni artimetiche ne dovrebbe trar giovamento la pipeline giusto ? :confused:
(pensavo a qualcosa del tipo ((riga+colonna)&0x1)*2-1))

verloc
23-03-2004, 17:10
Originariamente inviato da angelica
Mi son sempre chiesta come si faccia a sapere quanto più veloce giri il proprio prog post-modifiche, e la velocità/lentezza delle singole operazioni...


Con un "profiler".
:)

Mi ricordo che ne esisteva uno gratise.

cionci
23-03-2004, 17:33
Originariamente inviato da /\/\@®¢Ø
In teoria trasformando l'if in operazioni artimetiche ne dovrebbe trar giovamento la pipeline giusto ? :confused:
(pensavo a qualcosa del tipo ((riga+colonna)&0x1)*2-1))
Certo....ma ti sei dimenticato un - davanti (dispari: 1*2-1 dovrebbe rendere -1; pari: 0*2-1, ma dovrebbe rendere 1)... Non avevo pensato a farlo in questo modo ;) Anche se allora sarebbe più veloce così: -((riga+colonna)&0x1)<<1 - 1)

Gervasoni
27-03-2004, 20:55
C'è l'ho fatta!!! :yeah:

Grazie per l'aiuto!

/\/\@®¢Ø
27-03-2004, 21:26
Originariamente inviato da Gervasoni
C'è l'ho fatta!!! :yeah:

Grazie per l'aiuto!
Eh, ma adesso devi dirci come, altrimenti non vale :p

Gervasoni
29-03-2004, 23:43
Ho riscritto il programma da zero.
C'erano vari errori cmq non grossolani...

Ti allego il file .cpp così mi dai un parere ;)

Gervasoni
29-03-2004, 23:45
Ecco il file :p