AIUTO PROGRAMMA MATRICExMATRICE

fra0128
ho un problema con la funzione prodotto di matrici.. mi dice che float non va bene per prodAxA.. ma cosa devo mettere? la nostra professoressa negli appunti ha messo matrice, ma non lo riconosce proprio. da quel che ho capito float non va bene perchè la funzione restituisce un array e non un valore. metto il programma che ho provato a scrivere. spero che qualcuno possa aiutarmi.
#include
#include
#include
#include

using namespace std;
const int size=100;
typedef float matrice[size][size];
typedef float vettore[size];

int leggidimensione();
int legginumeroe();
void leggiA(matrice,int);
void stampaA(matrice,int);
void leggiu(vettore,int);
void stampau(vettore,int);
float prodAxA(matrice,int);
void stampaAxA(matrice,int);

main()
{
int m,e; matrice A; matrice C; vettore u;

m=leggidimensione();
e=legginumeroe();
leggiA(A,m);
stampaA(A,m);
leggiu(u,m);
stampau(u,m);
C=prodAxA(A,m);
stampaAxA(C,m);

system("PAUSE");
return 0;
}

int leggidimensione(){int m;
do{
printf("inserisci dimensione 2<=m<20, m=");
scanf("%d",&m);}
while ((m<2)||(m>=20));
return m;}

int legginumeroe(){int e;
printf("inserisci 0 return e;}

void leggiA(matrice A,int m){
for (int i=1;i<=m;i++){for(int j=1;j<=m;j++){
printf("a[%d][%d]=",i,j);
scanf("%f",&A[j]);}}
return;}

void stampaA(matrice A,int m){
for (int i=1;i<=m;i++){printf("\n");
for(int j=1;j<=m;j++){
printf("%f ",A[j]);}}
return;}

void leggiu(vettore u,int m){
for (int j=1;j<=m;j++){
printf("u[%d]=",j);
scanf("%f",&u[j]);}
return;}

void stampau(vettore u,int m){
for (int i=1;i<=m;i++){
printf("%f\n",&u);}
return;}

float prodAxA(matrice A,int m){
k=1;
for (int i=1;i<=m;i++){
for (int j=1;j<=m;j++){
float d=1;
for (k=1;k<=m;k++){ d=d+A[k]*B[k][j];
C[j]=d;}
d++}}
return C;}

Risposte
vict85
Quello è C : gli array partono da 0 e arrivano a n-1. Quindi tutti i tuoi cicli sono sbagliati.

fra0128
si lo so che partono da zero, ma la professoressa ci aveva detto che scrivendo così in pratica era come se lasciassimo sempre vuota la prima componente. cmq ora sono riuscita a farlo partire. ora però devo aggiustare la moltiplicazione.. non so se sto scrivendo bene.. girare gira..
#include
#include
#include
#include

using namespace std;
const int size=100;
typedef float matrice[size][size];
typedef float vettore[size];

int leggidimensione();
int legginumeroe();
void leggiA(matrice,int);
void stampaA(matrice,int);
void leggiu(vettore,int);
void stampau(vettore,int);
float prodAxA(matrice,int);
void stampaAxA(matrice,int);
void leggix0(vettore,int,vettore);
void stampax0(vettore,int);

main()
{
int m,e; matrice A; matrice C; vettore u; vettore x0;

m=leggidimensione();
//e=legginumeroe();
leggiA(A,m);
stampaA(A,m);
leggiu(u,m);
stampau(u,m);
C[m][m]=prodAxA(A,m);
stampaAxA(C,m);
leggix0(x0,m,u);
stampax0(x0,m);

system("PAUSE");
return 0;
}

int leggidimensione(){int m;
do{
printf("inserisci dimensione 2<=m<20, m=");
scanf("%d",&m);}
while ((m<2)||(m>=20));
return m;}

int legginumeroe(){int e;
printf("inserisci 0 return e;}

void leggiA(matrice A,int m){
for (int i=1;i<=m;i++){for(int j=1;j<=m;j++){
printf("a[%d][%d]=",i,j);
scanf("%f",&A[j]);}}
return;}

void stampaA(matrice A,int m){
for (int i=1;i<=m;i++){printf("\n");
for(int j=1;j<=m;j++){
printf("%f ",A[j]);}}
return;}

void leggiu(vettore u,int m){printf("\n");
for (int j=1;j<=m;j++){
printf("u[%d]=",j);
scanf("%f",&u[j]);}
return;}

void stampau(vettore u,int m){
for (int i=1;i<=m;i++){
printf("%f\n",u);}
return;}

float prodAxA(matrice A,int m){ matrice C;
for (int i=1;i<=m;i++){
for (int j=1;j<=m;j++){
float d=1;
for (int k=1;k<=m;k++){ float d=d+A[k]*A[k][j];
C[j]=d;}
}}
return C[m][m];}

void stampaAxA(matrice C,int m){
for (int i=1;i<=m;i++){ printf("\n");
for(int j=1;j<=m;j++){
printf("%f ",C[j]);}}
return;}

vict85
Questo forum permette di inserire il codice in un tag specifico. Esempio:
[code]scrivi il codice qui...
[/code]
Ti suggerisco di usarlo. Il tuo codice comunque è piuttosto discutibile in varie parti.

Se la tua professoressa ha davvero detto quello allora sbaglia doppiamente. Supponi per comodità di avere una matrice allocata 20x20. Il primo errore è che A[19][20] e tutta la righa A[20] è al di fuori della zona allocata e quindi potrebbe produrre una marea di errori (sempre che non vai in segmentation fault). Il secondo è che se tu allochi un 20x20 per lavorare su una 20x20 allora rimane vuota la intera prima riga e il primo elemento della successiva perché se scrivi A[20] in realtà accedi all'elemento A[i+1][0]. Se tu invece allochi più memoria, per esempio una 21x21, allora risolvi il problema del potenziale seg. fault ma lasci libera tutta la prima riga e tutta la prima colonna (cioè in questo caso \(\displaystyle 21 + 21 - 1 = 41 \) elementi).

Detto questo ritengo che non sia più difficile iniziare gli array da 0 rispetto a 1. Se non ti piace questa caratteristica usa un altro linguaggio :roll: .

Detto questo in leggidimensione imponi la matrice come al massimo una 20x20 ma la matrice è staticamente allocata come una 100x100. Quindi non c'è certo pericolo di seg. fault: hai allocato almeno 25 volte la memoria di cui hai bisogno.

Ovviamente prodAxA è senza senso.

Questa è una mia versione in standard C (post iso99). Mi compila, funziona e non è basata su idee senza senso. Per il prodotto ho usato un ciclo ikj invece di un ciclo ijk. È equivalente e potenzialmente più efficiente (per matrici grandi). Ho anche ripulito da vario codice inutile. Ho curato un minimo la visualizzazione su schermo.
#include <stdio.h>

#define SIZE 20
typedef float matrice[SIZE][SIZE];

int LeggiDimensione();

void LeggiMatrice(matrice, int const, char const * const);
void StampaMatrice(matrice, int const, char const * const);

void QuadratoMatrice(matrice, matrice, int const);

int main()
{
    int const m = LeggiDimensione();

    matrice A;
    LeggiMatrice(A, m, "A");
    StampaMatrice(A, m, "A");

    matrice C;
    QuadratoMatrice(A, C, m);
    StampaMatrice(C, m, "C");
}

int LeggiDimensione()
{
    int d = SIZE;
    do
    {
        if(d != SIZE)
            puts("Il valore inserito non e' nell'intervallo richiesto");

        fputs("inserisci dimensione 2 <= dim <= 20, dim =", stdout);
        scanf("%d", &d);
    }
    while ((d <= 2)||(d >= 20));
    printf("Valore accettato: la dimensione e' dim = %d\n", d);
    return d;
}

void LeggiMatrice(matrice M, int const m, char const * const nome)
{
    printf("\nInserisci i valori della matrice %s:\n", nome);
    for(int i = 0; i < m; ++i)
    {
        for(int j = 0; j < m; ++j)
        {
            printf("%s[%d][%d]=",nome,i+1,j+1);
            scanf("%f",&M[i][j]);
        }
    }
}

void StampaMatrice(matrice M, int const m, char const * const nome)
{
    printf("\n%s:\n", nome);
    for (int i=0; i < m; ++i)
    {
        printf("[ %f", M[i][0] );
        for(int j=1; j < m; ++j)
        {
            printf(", %f",M[i][j]);
        }
        puts(" ]");
    }
}


void QuadratoMatrice(matrice A, matrice A2, int const m)
{
    for(int i = 0; i < m; ++i)
        for(int j = 0; j < m; ++j)
            A2[i][j] = 0.f;

    for(int i = 0; i < m; ++i)
        for(int k = 0; k < m; ++k)
            for(int j = 0; j < m; ++j)
                A2[i][j] += A[i][k] * A[k][j];
}

fra0128
grazie mille per l'aiuto! immaginavo fosse pieno di scemenze. purtroppo alcuni particolari della tua versione non li conosco bene, non li so usare.. la professoressa non è stata un granché purtroppo, i programmi che ci faceva vedere a lezione provati funzionano 1 volta su 3. cmq le altre cose le avevo messe perché richieste dal compito, ma non so bene come continuare dopo il prodotto. per calcolare la successione non so come far variare x^k, come scriverlo, perchè cmq è già un vettore x[m].

Esercizio 1. Scrivere un programma C++ strutturato in funzioni che
1. legge da tastiera un numero intero m con 2 <= m < 20 e un numero reale
positivo e < 1;
2. legge da tastiera una matrice quadrata A mxm e un vettore u mx1 ad elementi
reali di tipo float;
3. calcola la matrice C = A^2;
4. posto x^0 = u, calcola la successione
x^(k) = Cx^(k-1) per k = 1; 2; 3; : : :
5. esce dal ciclo quando la norma norm del massimo della di fferenza delle ultime
due iterazioni è minore di e, oppure quando k supera 20;
6. stampa sullo schermo l’ultimo vettore della successione riordinato in senso
crescente, oltre ai valori finali di norm e k.

fra0128
anche se probabilmente non avrò scritto un programma molto bello sono riuscita a fare tutti i punti. grazie per il tuo aiuto :D

vict85
"fra0128":
Esercizio [...]
4. posto x^0 = u, calcola la successione
x^(k) = Cx^(k-1) per k = 1; 2; 3; : : :
5. esce dal ciclo quando la norma norm del massimo della di fferenza delle ultime
due iterazioni è minore di e, oppure quando k supera 20;


La tua incomprensione su questo punto è assolutamente matematica.

Sia \(\displaystyle \mathbf{x}^0\in \mathbb{R}^n \) e sia \(\displaystyle C = A^2 \). Allora definisce, induttivamente, il vettore \(\displaystyle \mathbf{x}^k\in \mathbb{R}^n \) come \(\displaystyle \mathbf{x}^k = C\mathbf{x}^{k-1} = C^k\mathbf{x}^0 = A^{2k}\mathbf{x}^0 \). Ovviamente ti chiede di trovare gli elementi in ordine quindi userai la formula \(\displaystyle \mathbf{x}^k = C\mathbf{x}^{k-1} \). Ti chiede di fermarti quando \(\displaystyle \lVert \mathbf{x}^k - \mathbf{x}^{k-1} \rVert_{\infty} \le \varepsilon \) cioè \(\displaystyle \max_{0\le i < n} \lvert x_i^k - x_i^{k-1} \vert \le \varepsilon \).

In sostanza ti sta chiedendo di implementare un metodo del punto fisso.

"fra0128":
6. stampa sullo schermo l’ultimo vettore della successione riordinato in senso
crescente, oltre ai valori finali di norm e k.


Riordinare gli elementi del vettore sinceramente la trovo una operazione senza alcun senso, matematicamente parlando.

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