From d5466ae1fd26de0ec434a5f85c1287cefcd8a4ed Mon Sep 17 00:00:00 2001 From: "AD005\\z004z3ez" Date: Thu, 13 Nov 2025 11:13:40 +0100 Subject: [PATCH] Verbesserungen nach Informatik-Stunde --- matrix.c | 341 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 184 insertions(+), 157 deletions(-) diff --git a/matrix.c b/matrix.c index 4b63542..1d3509f 100644 --- a/matrix.c +++ b/matrix.c @@ -2,35 +2,32 @@ #include #include #include "matrix.h" - + // TODO Matrix-Funktionen implementieren - -Matrix createMatrix(unsigned int rows, unsigned int cols) // Ergebnismatrix erstellen + +enum addModes{sameDimensions, colVec, rowVec}; + +Matrix createMatrix(unsigned int rows, unsigned int cols) { - //Matrix-Struktur initialisieren - Matrix m; m.rows = rows; m.cols = cols; m.buffer = NULL; - - //Prüfen auf 0-Zeilen oder Spalten -> wenn ja, Rückgabe leerer Matrix if(rows == 0 || cols == 0) { - + m.rows = 0; m.cols = 0; m.buffer = NULL; return m; } - - //Speicher für Matrix reservieren -> wenn calloc fehlschlägt, wird wieder leere Matrix zurückgegeben m.buffer = calloc(rows * cols, sizeof(MatrixType)); + if (m.buffer == NULL) { - + m.rows = 0; m.cols = 0; m.buffer = NULL; @@ -39,208 +36,238 @@ Matrix createMatrix(unsigned int rows, unsigned int cols) // Ergebnismatrix erst return m; } - -void clearMatrix(Matrix *matrix) //dynamisch angelegte Matrix wird freigegeben + +void clearMatrix(Matrix *matrix) { + if (matrix->buffer == NULL) + { + matrix->rows = 0; + matrix->cols = 0; + matrix->buffer = NULL; + return matrix; + } + else + { + free(matrix->buffer); - + matrix->rows = 0; matrix->cols = 0; matrix->buffer = NULL; + + } } - -void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx) //dient dazu einen Wert in der Matrix an bestimmte Position zu setzen + +void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx) { - - matrix.buffer[(rowIdx * matrix.cols) + colIdx] = value; //wir setzen den data-Wert an der Stelle (rowIdx*Spalten + colIdx) auf den Wert von value + + if(matrix.buffer == NULL || rowIdx >= matrix.rows || colIdx >= matrix.cols) + { + return; + } + else + { + matrix.buffer[(rowIdx * matrix.cols) + colIdx] = value; //wir setzen den data-Wert an der Stelle (rowIdx*Spalten + colIdx) auf den Wert von value + } } - -MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx) //liest einen Wert an einer bestimmten Position aus der Matrix aus + +MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx) { - //Prüfen, ob ein Buffer existiert & ob Zeilen- und Spaltenindex innerhalb der Grenzen ist - if(matrix.buffer == NULL || rowIdx >= matrix.rows || colIdx >= matrix.cols) { return UNDEFINED_MATRIX_VALUE; } - + return matrix.buffer[(rowIdx * matrix.cols) + colIdx]; } - - - - -static int can_add(Matrix matrix1, Matrix matrix2) //Prüft, ob und wie zwei Matrizen addiert werden können -{ - - int can_add; - + +static int get_add_mode(Matrix matrix1, Matrix matrix2) { + + int get_add_mode; + if(matrix1.cols == matrix2.cols && matrix1.rows == matrix2.rows){ - - can_add = 1; - + + get_add_mode = sameDimensions; + } else if(matrix1.cols == 1 && matrix1.rows == matrix2.rows){ - - can_add = 2; - + + get_add_mode = colVec; + } else if(matrix2.cols == 1 && matrix1.rows == matrix2.rows){ - - can_add = 3; - + + get_add_mode = colVec; + } else if(matrix1.rows == 1 && matrix1.cols == matrix2.cols){ - - can_add = 4; - + + get_add_mode = rowVec; + } else if(matrix2.rows == 1 && matrix1.cols == matrix2.cols){ - - can_add = 5; - + + get_add_mode = rowVec; + } - else{ - - can_add = 0; - + return get_add_mode; + +} + + + Matrix addSameDim(Matrix matrix1, Matrix matrix2) + { + Matrix matrix_erg = createMatrix(matrix1.rows, matrix1.cols); + + for(int i = 0; i < (matrix1.rows * matrix1.cols); i++) + + matrix_erg.buffer[i] = matrix1.buffer[i] + matrix2.buffer[i]; + + return matrix_erg; + } - - return can_add; + + Matrix addColVec(Matrix matrix1, Matrix matrix2) + { + Matrix matrix_erg; + if(matrix1.cols == 1) + { + matrix_erg = createMatrix(matrix2.rows, matrix2.cols); + + for(int i = 0; i < matrix2.rows; i++) + { + for(int j = 0; j < matrix2.cols; j++) + + matrix_erg.buffer[i * matrix2.cols + j] = matrix1.buffer[i * matrix2.cols + j] + matrix2.buffer[i]; + } + + + } + if(matrix2.cols == 1) + { + matrix_erg = createMatrix(matrix1.rows, matrix1.cols); + + for(int i = 0; i < matrix1.rows; i++) + { + for(int j = 0; j < matrix1.cols; j++) + + matrix_erg.buffer[i * matrix1.cols + j] = matrix1.buffer[i] + matrix2.buffer[i * matrix1.cols + j]; + } + } + return matrix_erg; + + } - -Matrix add(const Matrix matrix1, const Matrix matrix2) //wir addieren nur wenn beide Matrizen gleich groß sind oder eine von beiden eine Zeile oder eine Spalte besitzt -{ - - //Anlegen einer Variable für die Fallunterscheidung der Addition - - int ok = can_add(matrix1,matrix2); - - //Gibt die Größe der Ergebnismatrix an - - unsigned int erg_rows = (matrix1.rows == matrix2.rows) ? matrix1.rows : (matrix1.rows == 1 ? matrix2.rows : matrix1.rows); - unsigned int erg_cols = (matrix1.cols == matrix2.cols) ? matrix1.cols : (matrix1.cols == 1 ? matrix2.cols : matrix1.cols); - - //Ergebnis-Matrix anlegen - - Matrix matrix_erg = createMatrix(erg_rows, erg_cols); - - - + + Matrix addRowVec(Matrix matrix1, Matrix matrix2) + { + Matrix matrix_erg; + if(matrix1.rows == 1) + { + matrix_erg = createMatrix(matrix2.rows, matrix2.cols); + + for(int i = 0; i < matrix2.rows; i++) + { + for(int j = 0; j < matrix2.cols; j++) + + matrix_erg.buffer[i * matrix2.cols + j] = matrix1.buffer[i * matrix2.cols + j] + matrix2.buffer[j]; + } + + + } + if(matrix2.rows == 1) + { + matrix_erg = createMatrix(matrix1.rows, matrix1.cols); + + for(int i = 0; i < matrix1.rows; i++) + { + for(int j = 0; j < matrix1.cols; j++) + + matrix_erg.buffer[i * matrix1.cols + j] = matrix1.buffer[j] + matrix2.buffer[i * matrix1.cols + j]; + } + } + return matrix_erg; + } + + + + + Matrix add(const Matrix matrix1, const Matrix matrix2) + { + int ok = get_add_mode(matrix1,matrix2); + + Matrix matrix_erg = createMatrix(0, 0); + + switch(ok) { - case 1: - - for(int i = 0; i < (matrix1.rows * matrix1.cols); i++) - - matrix_erg.buffer[i] = matrix1.buffer[i] + matrix2.buffer[i]; - + + + case sameDimensions: + + addSameDim(matrix1, matrix2); + break; - - case 2: - - for(int i = 0; i < erg_rows; i++){ - for(int j = 0; j < erg_cols; j++) - - matrix_erg.buffer[i * erg_cols + j] = matrix1.buffer[i * erg_cols + j] + matrix2.buffer[i]; - } + + case colVec: + + addColVec(matrix1, matrix2); + break; - - case 3: - - for(int i = 0; i < erg_rows; i++){ - for(int j = 0; j < erg_cols; j++) - - matrix_erg.buffer[i * erg_cols + j] = matrix1.buffer[i] + matrix2.buffer[i * erg_cols + j]; - } + + case rowVec: + + addRowVec(matrix1, matrix2); + break; - - case 4: - - for(int i = 0; i < erg_rows; i++){ - for(int j = 0; j < erg_cols; j++) - - matrix_erg.buffer[i * erg_cols + j] = matrix1.buffer[i * erg_cols + j] + matrix2.buffer[j]; - } - break; - - case 5: - - for(int i = 0; i < erg_rows; i++){ - for(int j = 0; j < erg_cols; j++) - - matrix_erg.buffer[i * erg_cols + j] = matrix1.buffer[j] + matrix2.buffer[i * erg_cols + j]; - } - break; - - default: - - matrix_erg.rows = 0; - matrix_erg.cols = 0; - matrix_erg.buffer = NULL; - return matrix_erg; - - + } - -return matrix_erg; - - - + + return matrix_erg; + + + } - - -static int can_multiply (Matrix matrix1, Matrix matrix2) //Test, ob Matrixmultiplikation möglich +static int can_multiply (Matrix matrix1, Matrix matrix2) { int can_multiply = 0; - + if(matrix1.cols == matrix2.rows) can_multiply = 1; - + return can_multiply; } - - + + Matrix multiply(const Matrix matrix1, const Matrix matrix2) { - //Prüft, ob Matrixmultiplikation möglich -> Übergabe an Hilfsvariable - - int ok = can_multiply(matrix1,matrix2); - - //Größe der Matrix festlegen und an Ergebnismatrix übergeben - + int ok = can_multiply(matrix1,matrix2); unsigned int erg_rows = matrix1.rows; unsigned int erg_cols = matrix2.cols; - Matrix matrix_erg = createMatrix(erg_rows, erg_cols); - - + Matrix matrix_erg = createMatrix(0, 0); + if (ok == 1) { - + Matrix matrix_erg = createMatrix(erg_rows, erg_cols); + for (int i = 0; i < erg_rows; i++) { for (int j = 0; j < erg_cols; j++) { MatrixType sum = 0; - + for (int k = 0; k < matrix1.cols; k++) { - sum += matrix1.buffer[i * matrix1.cols + k] * matrix2.buffer[k * matrix2.cols + j]; + sum += getMatrixAt(matrix1, k, j) * getMatrixAt(matrix2, j, k); } - - matrix_erg.buffer [i * erg_cols + j] = sum; + + setMatrixAt(sum, matrix_erg, i, j); } } - + return matrix_erg; } - else - { - - matrix_erg.rows = 0; - matrix_erg.cols = 0; - matrix_erg.buffer = NULL; - return matrix_erg; - } -} \ No newline at end of file + +} + \ No newline at end of file