Mnożenie macierzy przez wektor

0

Z losowymi liczbami sobie poradziłam. Problemem pozostaje mnożenie wektora przez macierz (wektor wielkości 1xN, a macierz wielkości NxM). Próbowałam to zrobić na zasadzie mnożenia macierzy i owszem, coś wyświetla. Ale wynik jest błędny.

void mnozenie(double **macierz, double *wektor, double *wynik, int wier, int k)
{ int o, p;

 for(o=0;o<wier;o++)
 {
 	for(p=0;p<k;p++)
 	{
 		wynik[p] =+ wektor[o] * macierz[o][p];
 		printf("[%d]=%.1f\t", p, wynik[p]);
 	}
 }
  }
0
  1. Wkleisz cały kod? Może będzie prościej.
  2. Na pewno =+ , a nie +=? Może czegoś już nie pamiętam, ale wydaje mi się, że powinno być +=?
0

Zamień kolejność pętli, w drugiej macierzy musisz lecieć po wierszach, a nie kolumnach. I zmień nazwy zmiennych, bo mylą strasznie.

for (p = 0; p < k; ++p)
    for (o = 0; o < wier; ++o)
0
kmph napisał(a):

Wkleisz cały kod? Może będzie prościej.

Na pewno =+ , a nie +=? Może czegoś już nie pamiętam, ale wydaje mi się, że powinno być +=?

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

double **macierzDouble(int iloscWierszy, int iloscKolumn){
 double **tab;
	int i;
 tab=(double **) malloc( iloscWierszy*sizeof(double *) );
 if(tab==NULL) { 
 fprintf(stderr,"Brak pamieci !\n");
 exit(1); }
 tab[0]=(double *) malloc( iloscWierszy*iloscKolumn*sizeof(double) );
 if(tab[0]==NULL) { 
 fprintf(stderr,"Brak pamieci !\n");
 free(tab); 
 exit(1); }
 for(i=1; i<iloscWierszy; i++)
 tab[i]=tab[i-1]+iloscKolumn;
 return tab;
}




void zwolnijMacierzDouble(double **tablica){
 free(tablica[0]); 
 free(tablica);
}

void wyswietlMacierzDouble(double **t, int w_Max, int k_Max){

 int wiersz, kolumna;
 for(wiersz=0; wiersz<w_Max; wiersz++)
 for(kolumna=0; kolumna<k_Max; kolumna++)
 printf("[%d][%d]=%.1f%c", wiersz, kolumna, t[wiersz][kolumna],
 kolumna==k_Max-1 ? '\n' : '\t');

 
} 

void wyswietlWektorDouble(double *t, int k_Max){

 int wiersz, kolumna;
 for(kolumna=0; kolumna<k_Max; kolumna++)
 printf("[%d]=%.1f%c", kolumna, t[kolumna]+wiersz*k_Max+kolumna,
 kolumna==k_Max-1 ? '\n' : '\t');
 }

void mnozenie(double **macierz, double *wektor, double *wynik, int wier, int k)
{ int o, p;

 for(p=0;p<k;p++)
 {
 	for(o=0;o<wier;o++)
 	{
 		wynik[p] = wynik[p] + wektor[o] * macierz[o][p];
 		
 	}
 	printf("[%d]=%.1f\t", p, wynik[p]);
 }
  }

void main()
{

double *wektor, **macierz, *wynik;
  int kol, k, m, n, i;
 double x; 

 wektor =(double *) malloc( kol*sizeof(double *) );
 if(wektor==NULL) { 
 fprintf(stderr,"Brak pamieci !\n");
 exit(1); }
  
 wynik =(double *) malloc( k*sizeof(double *) );
 if(wynik==NULL) { 
 fprintf(stderr,"Brak pamieci !\n");
 exit(1); }
  
  printf("Wektor * macierz\n\n");
  
  printf("podaj ilosc kolumn wektora i ilosc kolumn mnozonej macierzy: \n");
  scanf("%d\n %d", &kol, &k);
  
 
 printf("\nwektor\n");
srand( time( NULL ) );
 for (i=0; i<kol; i++)
 {
 wektor[i]=(double)rand();
 }
 wyswietlWektorDouble(wektor,kol);
 
 printf("\n");
 
printf("\nmacierz\n");
 macierz=macierzDouble(kol,k);
 srand( time( NULL ) );
 for(m=0; m<kol; m++)
 {
	for(n=0; n<k; n++) 
	{
	macierz[m][n] = (double)rand();
	}
 }
 wyswietlMacierzDouble(macierz,kol,k);
 
 printf("\n");

 
 

 
 printf("\n");
 
mnozenie(macierz, wektor, wynik, kol,k);
 
 zwolnijMacierzDouble(macierz);
 free(wektor);

 }
twonek napisał(a):

Zamień kolejność pętli, w drugiej macierzy musisz lecieć po wierszach, a nie kolumnach. I zmień nazwy zmiennych, bo mylą strasznie.

for (p = 0; p < k; ++p)
    for (o = 0; o < wier; ++o)

To niestety niezbyt pomogło.

0
void wyswietlWektorDouble(double* t, int k_Max)
{
    int wiersz, kolumna;
    for (kolumna = 0; kolumna < k_Max; kolumna++)
        printf("[%d]=%.1f%c", kolumna, t[kolumna] + wiersz * k_Max + kolumna,
               kolumna == k_Max - 1 ? '\n' : '\t');
}

Co to jest wiersz? I dlaczego jest tam (pomijając fakt, że ma niezdefiniowaną wartość)?

0
twonek napisał(a):
void wyswietlWektorDouble(double* t, int k_Max)
{
    int wiersz, kolumna;
    for (kolumna = 0; kolumna < k_Max; kolumna++)
        printf("[%d]=%.1f%c", kolumna, t[kolumna] + wiersz * k_Max + kolumna,
               kolumna == k_Max - 1 ? '\n' : '\t');
}

Co to jest wiersz? I dlaczego jest tam (pomijając fakt, że ma niezdefiniowaną wartość)?

Przerabiałam tę funkcję z funkcji wyswietlMacierzDouble. Usunęłam ten wiersz i teraz zdaje się, że działa trochę lepiej, ale pierwszy wyraz w wektorze jest zawsze zerem...

0

Nie mam tego problemu: http://melpon.org/wandbox/permlink/olwYv4t16s0q7btZ
Ograniczyłem wartości do 5, żeby dało się sprawdzić poprawność "ręcznie".

0

Dziękuję ci i w ogóle, ale teraz pojawia się problem, że przy wpisaniu ilości kolumn wektora większej niż 3, program się nagle się kończy. Nie jestem pewna czy jest sposób na ominięcie tego...

0
void zwolnijMacierzDouble(double** tablica)
{
    free(tablica[0]);
    //free(tablica);
}

Zakomentowanie tej linijki free(tablica) "pomaga". Tzn. program już się nie wywala. Natomiast oczywiście nie jest to do końca poprawne (tak samo nie zwalniasz wyniku). Nie znam C na tyle, żeby Ci powiedzieć, czemu ta linijka powoduje błąd, na oko niby jest w porządku.

0

free() wywali program tylko jeśli naruszysz pamięć wokół, więc gdzieś pewnie wychodzisz za zakres.

1 użytkowników online, w tym zalogowanych: 0, gości: 1