[C]Successione di matrici
Salve a tutti!
Devo scrivere un programma in C che fa le seguenti cose:
Richiede in input una matrice quadrata di ordine n: $A^0$ e la stampa.Calcola $w_max$=$max_{j=1,...,n}$ $\sum_{i=1}^n$ $a_{i,j}$ .Calcola la matrice A=$A^0$/10$w_max$.E fino a qui va bene! Il problema viene dopo quando mi chiede di calcolare a partire da $B^0$=A la successione $B^k$= $B^{k-1}$A (per k>=1).Stampa $B^k$ a ogni iterazione. Se sono state eseguite 10 iterazioni si arresta e stampa un opportuno messaggio.
Il programma viene compilato però non itera la successione..calcola solo il prodotto AxA.
Qualcuno può controllare dove sono gli errori??Grazie anticipatamente
Devo scrivere un programma in C che fa le seguenti cose:
Richiede in input una matrice quadrata di ordine n: $A^0$ e la stampa.Calcola $w_max$=$max_{j=1,...,n}$ $\sum_{i=1}^n$ $a_{i,j}$ .Calcola la matrice A=$A^0$/10$w_max$.E fino a qui va bene! Il problema viene dopo quando mi chiede di calcolare a partire da $B^0$=A la successione $B^k$= $B^{k-1}$A (per k>=1).Stampa $B^k$ a ogni iterazione. Se sono state eseguite 10 iterazioni si arresta e stampa un opportuno messaggio.
Il programma viene compilato però non itera la successione..calcola solo il prodotto AxA.
Qualcuno può controllare dove sono gli errori??Grazie anticipatamente

#include <stdio.h> #include <stdlib.h> #include <math.h> #include <conio.h> const int size=3; typedef float matrice[size][size]; void ins_int(int &); void ins_matrice(int*,matrice); void stampa_matrice(int ,matrice); void costruisci_matrice(int,matrice,matrice,double); void prod(int,matrice,matrice,matrice); main() { int n,i,j,max_ind; double wmax,somma; matrice A0; ins_int(n); printf("\nInserire gli elementi della matrice A0\n"); ins_matrice(&n,A0); stampa_matrice(n,A0); wmax = 0; max_ind = 0; for (j=0; j<n; j++) { somma = 0; for (i=0; i<n; i++) { somma += A0[i][j];} if (somma > wmax) { wmax = somma; max_ind = j; } } printf("La colonna di somma massima (wmax= (%f)) e' quella di indice %d.\n", wmax, max_ind); matrice A; costruisci_matrice(n,A,A0,wmax); stampa_matrice(n,A); matrice Bk; matrice Bkm1; int cont=0; do { prod(n,A,Bk,Bkm1); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) {Bkm1[i][j]=Bk[i][j]; cont ++; printf("La matrice della successione dopo (%d) iterazioni e':\n",cont); stampa_matrice(n,Bk);} } } while (cont<4); system("PAUSE"); return 0;} void ins_int(int &a) {do { printf("\nInserire un intero n tale che 0<n<=3 n="); scanf("%d",&a);} while((a<=0)||(a>3));} void ins_matrice(int *n,matrice A0) { for(int i=0;i<*n;i++) for(int j=0;j<*n;j++) scanf("%f",&A0[i][j]); } void stampa_matrice(int n,matrice A0) { printf("La matrice e':\n"); for(int i=0;i<n;i++) { for(int j=0;j<n;j++) printf("%16f",A0[i][j]); printf("\n");} } void costruisci_matrice(int n, matrice A, matrice A0,double wmax) { int i,j; for(i=0;i<n;i++) for(j=0;j<n;j++) { A[i][j]=A0[i][j]/(10*wmax);} } void prod(int n,matrice A,matrice b2,matrice b1) { int i,j,k; { for (i=0;i<n;i++) { for (j=0;j<n;j++) { b2[i][j]=0; for (k=0;k<n;k++) b2[i][j]=b2[i][j]+A[i][k]*A[k][j];} } } }
Risposte
Prima di tutto ti consiglio di usare sempre le parentesi anche quando non sono del tutto necessarie perché rendono più semplice la lettura. La chiusura delle parentesi graffe dovrebbe inoltre essere allineata con la riga in cui sono state aperte, quindi in particolare non dovrebbero esserci parentesi chiuse una dopo l'altra. Usa il tag code per inserire il codice. Ovviamente non sei obbligato a fare nessuna di queste cose ma semplifica molto il lavoro a chi deve leggere il tuo codice e lo conosce meno di te.
Noto subito che visualizzi la matrice solo dopo aver completato il ciclo di 10 iterazioni. Nel testo dell'esercizio la matrice doveva invece essere stampata ad ogni iterazione e quindi immagino che le righe seguenti dovevano essere inserite nel ciclo.
C'è inoltre un grave errore nell'uso delle matrici in C... Gli indici partono da 0 e non da 1!!! Immagino che tu non abbia mai provato ad inserire una matrice di ordine 10. In questo caso il tuo codice molto probabilmente sarebbe crashato perché avrebbe cercato di avvedere ad elementi oltre i limiti.
Noto subito che visualizzi la matrice solo dopo aver completato il ciclo di 10 iterazioni. Nel testo dell'esercizio la matrice doveva invece essere stampata ad ogni iterazione e quindi immagino che le righe seguenti dovevano essere inserite nel ciclo.
printf("La matrice della successione dopo (%d) iterazioni e':\n",cont); stampa_matriceB(n,Bk);
C'è inoltre un grave errore nell'uso delle matrici in C... Gli indici partono da 0 e non da 1!!! Immagino che tu non abbia mai provato ad inserire una matrice di ordine 10. In questo caso il tuo codice molto probabilmente sarebbe crashato perché avrebbe cercato di avvedere ad elementi oltre i limiti.
"apatriarca":
Prima di tutto ti consiglio di usare sempre le parentesi anche quando non sono del tutto necessarie perché rendono più semplice la lettura. La chiusura delle parentesi graffe dovrebbe inoltre essere allineata con la riga in cui sono state aperte, quindi in particolare non dovrebbero esserci parentesi chiuse una dopo l'altra. Usa il tag code per inserire il codice.
C'è inoltre un grave errore nell'uso delle matrici in C... Gli indici partono da 0 e non da 1!!!
Grazie!!!Ho migliorato qualcosa!Mi sono iscritta un anno fa sul forum ma questo è il primo messaggio che scrivo(diciamo da quando inizio ad avere problemi con l'informatica!)...dunque su tuo consiglio ora ho usato anche il tag code!
Il fatto che gli indici partano da 0 e non da 1 per le matrici e i vettori lo sapevo..Le ho fatte partire da 1 perché nel testo dell'esercizio la sommatoria partiva da 1.
Comunque grazie molto per i consigli utilisssimi

Spesso in matematica o negli pseudocodici le sommatorie partono da 1, ma in C devi sempre iniziare da 0. Che senso ha lasciare un elemento all'inizio dell'array (o un intera riga e colonna nel tuo caso) inutilizzata?! In questo genere di cose ci si dovrebbe basare sempre sulla sintassi del linguaggio.
Ho notato un'altra cosa, che differenza c'è tra stampa_matrice, stampa_matriceA e stampa_matriceB? Cambia solo il nome del parametro ma per il resto la funzione è del tutto identica, potresti quindi usare stampa_matriceA per stampare le matrici B e viceversa. Basta solo una delle tre funzioni.
Ma scrivi normalmente senza indentare il codice oppure hai solo sbagliato a copiarlo dentro il tag code? Stai attenta alla chiusura dei tag...
Ho notato un'altra cosa, che differenza c'è tra stampa_matrice, stampa_matriceA e stampa_matriceB? Cambia solo il nome del parametro ma per il resto la funzione è del tutto identica, potresti quindi usare stampa_matriceA per stampare le matrici B e viceversa. Basta solo una delle tre funzioni.
Ma scrivi normalmente senza indentare il codice oppure hai solo sbagliato a copiarlo dentro il tag code? Stai attenta alla chiusura dei tag...
Ah si.. funzione è la stessa..basta usarne una! Grazie ancora!
Comunque ho sicuramente sbagliato qualcosa nel definire la successione perché comunque non la itera!
Ah un'altra cosa: perdona l'ignoranza ma non so cosa significhi indentare il codice!
Comunque ho sicuramente sbagliato qualcosa nel definire la successione perché comunque non la itera!
Ah un'altra cosa: perdona l'ignoranza ma non so cosa significhi indentare il codice!
http://it.wikipedia.org/wiki/Indentazione
Scusa ma non ho tempo di controllarti quel codice in questo momento. Appena ho tempo vedo se riesco a correggertelo.
Scusa ma non ho tempo di controllarti quel codice in questo momento. Appena ho tempo vedo se riesco a correggertelo.
Ah..ho capito l'indentazione..a volte non la uso..però sicuramente sarebbe più leggibile con l'indentazione!grazie!
Bk e Bkm1 non sono inizializzate. prod non sembra calcolare il prodotto ma $A^2$. Visto che A rimane fisso e $B_1 = A^2$ il risultato è sempre il primo valore della successione. Io scriverei qualcosa come il seguente:
Nel codice seguente B è $B_{2i}$ e C è $B_{2i+1}$.
void mul(int n, matrice ret, matrice a, matrice b) { int i, j, k; for (i = 0; i < n; ++i) { for (j = 0; j < n; ++j) { ret[i][j] = 0.0f; for (k = 0; k < n; ++k) { ret[i][j] += a[i][k]*a[k][j]; } } } }
Nel codice seguente B è $B_{2i}$ e C è $B_{2i+1}$.
matrice B, C; memcpy(B, A, sizeof(matrice)); for (i = 0; i < 5; ++i) { mul(n, C, B, A); mul(n, B, C, A); }
Fantastico!Funziona questa funzione!...(gioco di parole non voluto!)grazie grazie grazie!!!
Non ero a conoscenza della funzione memcpy...Ho imparato un sacco di cose in questa discussione...Credo che prossimamente mi affiderò a questo forum con più frequenza!!!
Non ero a conoscenza della funzione memcpy...Ho imparato un sacco di cose in questa discussione...Credo che prossimamente mi affiderò a questo forum con più frequenza!!!