Mnożenie macierzy

0
 
/*A - macierz o wymiarach Am, An; B - macierz o wymiarach Bm, Bn; C = A * B*/

int *mult(int *A, int *B, int Am, int Bn, int An) {
	int i, j, k, l = 0;
	int *C;
	
	C = malloc(sizeof(int) * Am * Bn);
	for (i = 0; i < Am * Bn; ++i) C[i] = 0;
	
	for (i = 0; i < Am; ++i)
		for (j = 0; j < Bn; ++j) {
			for (k = 0; k < An; ++k) C[l] += A[Bn * i + k] * B[Bn * k + j];	
			++l;
		}
	
	return C;
}

Algorytm wydaje się być poprawny, debuggowanie na kartce mi nie pomogło a zagmatwania dodaje też to, że chcę traktować macierz jako tablicę jednowymiarową. Może ktoś z was zauważy błąd i oszcżędzi mi nerwów?
Z góry bardzo dziękuję.

0

Algorytm jest nie poprawny. Ponieważ ponazywałeś zmienne bez sensu. Zamień nazwy Ay,Ax - wymiary A; By,Bx - wymiary B. Zamiast i,y,k - użyj ay,axby,bx.
Jak tylko pozamieniasz natychmiast zobaczysz błąd.

0
int *mult(int *A, int *B, int Ay, int Bx, int Ax) {
	int i, ay, bx, ax;
	int *C;
	
	C = malloc(sizeof(int) * Ay * Bx);
	for (i = 0; i < Ay * Bx; ++i) C[i] = 0;
	
	i = 0;
	for (ay = 0; ay < Ay; ++ay)
		for (bx = 0; bx < Bx; ++bx) {
			for (ax = 0; ax < Ax; ++ax) C[i] += A[Bx * ay + ax] * B[Bx * ax + bx];	
			++i;
		}
	
	return C;
}
 

zgodnie z radą, tym razem pierwszy wiersz jest ok, niestety nastepne to losowe wartosci

0

I nie widzisz? Ok: A[Bx * ay + ax], naprawdę nie widzisz?

0

Poprawiłem na Ax i cholerstwo dalej nie działa, a na kartce jak rozpisałem to niby się teraz zgadza

int *mult(int *A, int *B, int Ay, int Bx, int Ax) {
	int i, ay, bx, ax;
	int *C;
	
	C = malloc(sizeof(int) * Ay * Bx);
	for (i = 0; i < Ay * Bx; ++i) C[i] = 0;
	
	i = 0;
	for (ay = 0; ay < Ay; ++ay)
		for (bx = 0; bx < Bx; ++bx) {
			for (ax = 0; ax < Ax; ++ax) C[i] += A[Ax * ay + ax] * B[Bx * ax + bx];	
			++i;
		}
	
	return C;
}
 
0

Parametry dobrze przekazuje, oto cały kod:

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

int *mult(int *A, int *B, int Ay, int Bx, int Ax);
int *addSub(int *A, int *B, int Ay, int Ax, int sign);

int main() {
	int *A, *B, *C;
	int Ay, Ax, By, Bx, i, j;
	srand(time(NULL));
	
	Ay = rand() % 10 + 1;
	Ax = rand() % 10 + 1;
	By = Ax;
	Bx = rand() % 10 + 1;
	
	A = (int*) malloc(sizeof(int) * Ay * Ax);
	B = (int*) malloc(sizeof(int) * By * Bx);
		
	printf("Macierz A:\n");
	for (i = 0; i < Ay; ++i)
		for (j = 0; j < Ax; ++j) {
			A[Ax * i + j] = rand() % 100;
			printf("%3d ", A[Ax * i + j]);
			if (j == Ax - 1) printf("\n");	
		}
	printf("\n");
	
	printf("Macierz B:\n");
	for (i = 0; i < By; ++i)
		for (j = 0; j < Bx; ++j) {
			B[Bx * i + j] = rand() % 100;
			printf("%3d ", B[Bx * i + j]);
			if (j == Bx - 1) printf("\n");
		}
	printf("\n");
	
	C = mult(A, B, Ay, Bx, Ax);
	printf("Macierz C = A * B:\n");
	for (i = 0; i < Ay; ++i)
		for (j = 0; j < Bx; ++j) {
			printf("%8d ", C[Ax * i + j]);
			if (j == Bx - 1) printf("\n");
		}
	
	free(A);
	free(B);
	free(C);
	return 0;
}

int *mult(int *A, int *B, int Ay, int Bx, int Ax) {
	int i, ay, bx, ax;
	int *C;
	
	C = malloc(sizeof(int) * Ay * Bx);
	for (i = 0; i < Ay * Bx; ++i) C[i] = 0;
	
	i = 0;
	for (ay = 0; ay < Ay; ++ay)
		for (bx = 0; bx < Bx; ++bx) {
			for (ax = 0; ax < Ax; ++ax) C[i] += A[Ax * ay + ax] * B[Bx * ax + bx];	
			++i;
		}
	
	return C;
}

int *addSub(int *A, int *B, int Ay, int Ax, int sign) {
	int i;
	int *C;
	
	C = malloc(sizeof(int) * Ay * Ax);
	for (i = 0; i < Ay * Ax; ++i) C[i] = A[i] + B[i] * sign;
	
	return C;
} 
0

A jakie wymiary ma macierz C?

0

C ma wymiary Ay i Bx

0

Ajj widzę: C[Ax * i + j]); powinno być Bx * i, dzięki za cierpliwość :)

0

Dokładnie :D
Tak a propos przemyśl sobie takie rozwiązanie:

typedef struct { unsigned Y,X; double *T; } Matrix;
Matrix CreateMatrix(unsigned Y,unsigned X);
void RandMatrix(Matrix *M);
void FreeMatrix(Matrix *M);
void PrintMatrix(const Matrix *M);
Matrix MulMatrix(const Matrix *A,const Matrix *B);

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