#include "matrix.h" #include #include // TODO Matrix-Funktionen implementieren /*typedef struct { unsigned int rows; //Zeilen unsigned int cols; //Spalten MatrixType *buffer; //Zeiger auf Speicherbereich Reihen*Spalten } Matrix;*/ Matrix createMatrix(unsigned int rows, unsigned int cols) { if (cols == 0 || rows == 0){ Matrix errorMatrix = {0, 0, NULL}; return errorMatrix; } MatrixType *buffer = malloc(rows * cols * sizeof(MatrixType)); // Speicher reservieren, malloc // liefert Zeiger auf Speicher Matrix newMatrix = {rows, cols, buffer}; // neue Matrix nach struct return newMatrix; } void clearMatrix(Matrix *matrix) { matrix->buffer = UNDEFINED_MATRIX_VALUE; matrix->rows = UNDEFINED_MATRIX_VALUE; matrix->cols = UNDEFINED_MATRIX_VALUE; free((*matrix).buffer); // Speicher freigeben } void setMatrixAt(const MatrixType value, Matrix matrix, const unsigned int rowIdx, // Kopie der Matrix wird übergeben const unsigned int colIdx) { if (rowIdx >= matrix.rows || colIdx >= matrix.cols) { // Speichergröße nicht überschreiten return; } matrix.buffer[rowIdx * matrix.cols + colIdx] = value; // rowIdx * matrix.cols -> Beginn der Zeile colIdx ->Spalte // innerhalb der Zeile } MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, // Kopie der Matrix wird übergeben unsigned int colIdx) { if (rowIdx >= matrix.rows || colIdx >= matrix.cols) { // Speichergröße nicht überschreiten return 0; } MatrixType value = matrix.buffer[rowIdx * matrix.cols + colIdx]; return value; } Matrix broadcastingCols(const Matrix matrix, const unsigned int cols){ Matrix copy1 = createMatrix(matrix.rows, cols); for (int r= 0; r < matrix.rows; r++){ MatrixType valueMatrix1 = getMatrixAt(matrix, r, 0); for (int c=0; c < cols; c++){ setMatrixAt(valueMatrix1, copy1,r,c); } } return copy1; } Matrix broadcastingRows(const Matrix matrix, const unsigned int rows){ Matrix copy1 = createMatrix(rows, matrix.cols); for (int c= 0; c < matrix.cols; c++){ MatrixType valueMatrix1 = getMatrixAt(matrix, 0, c); for (int r=0; r < rows; r++){ setMatrixAt(valueMatrix1, copy1,r,c); } } return copy1; } Matrix add(const Matrix matrix1, const Matrix matrix2) { // Ergebnismatrix Matrix result; const int cols1 = matrix1.cols; const int rows1 = matrix1.rows; const int cols2 = matrix2.cols; const int rows2 = matrix2.rows; const int rowsEqual = (matrix1.rows==matrix2.rows) ? 1: 0; const int colsEqual = (matrix1.cols==matrix2.cols) ? 1: 0; // Broadcasting nur bei Vektor und Matrix, Fehlermeldung bei zwei unpassender // Matrix if (rowsEqual == 1 && colsEqual == 1){ Matrix result = createMatrix(matrix1.rows, matrix1.cols); for (int i = 0; i< rows1; i++) { for (int j= 0; j< cols1; j++){ int valueM1= getMatrixAt(matrix1, i, j); int valueM2= getMatrixAt(matrix2, i, j); int sum = valueM1 + valueM2; setMatrixAt(sum, result, i, j); } } return result; } else if (rowsEqual ==1 && (cols1 ==1 || cols2 ==1)){ if (cols1==1){ //broadcasting von vektor 1 zu matrix 1, add Matrix newMatrix = broadcastingCols(matrix1, cols2); //add Matrix result = createMatrix(newMatrix.rows, newMatrix.cols); for (int i = 0; i< rows1; i++) { for (int j= 0; j< cols2; j++){ int valueM1= getMatrixAt(newMatrix, i, j); int valueM2= getMatrixAt(matrix2, i, j); int sum = valueM1 + valueM2; setMatrixAt(sum, result, i, j); } } return result; } else{ Matrix newMatrix2 = broadcastingCols(matrix2, cols1); //add Matrix result = createMatrix(newMatrix2.rows, newMatrix2.cols); for (int i = 0; i< rows1; i++) { for (int j= 0; j< cols1; j++){ int valueM1= getMatrixAt(matrix1, i, j); int valueM2= getMatrixAt(newMatrix2, i, j); int sum = valueM1 + valueM2; setMatrixAt(sum, result, i, j); } } return result; } } else if ((rows1 ==1 || rows2 ==1) && colsEqual == 1){ if (rows1==1){ Matrix newMatrix = broadcastingRows(matrix1, rows2); //add Matrix result = createMatrix(newMatrix.rows, newMatrix.cols); for (int i = 0; i< rows2; i++) { for (int j= 0; j< cols1; j++){ int valueM1= getMatrixAt(newMatrix, i, j); int valueM2= getMatrixAt(matrix2, i, j); int sum = valueM1 + valueM2; setMatrixAt(sum, result, i, j); } } return result; } else{ Matrix newMatrix2 = broadcastingRows(matrix2, rows1); //add Matrix result = createMatrix(newMatrix2.rows, newMatrix2.cols); for (int i = 0; i< rows1; i++) { for (int j= 0; j< cols1; j++){ int valueM1= getMatrixAt(matrix1, i, j); int valueM2= getMatrixAt(newMatrix2, i, j); int sum = valueM1 + valueM2; setMatrixAt(sum, result, i, j); } } return result; } } else { // kein add möglich Matrix errorMatrix = {0, 0, NULL}; return errorMatrix; } return result; } Matrix multiply(const Matrix matrix1, const Matrix matrix2) { //Spalten1 müssen gleich zeilen2 sein! dann multiplizieren if (matrix1.cols == matrix2.rows){ Matrix multMatrix = createMatrix(matrix1.rows,matrix2.cols); for (int r=0; r< matrix1.rows; r++){ for (int c=0; c< matrix2.cols; c++){ MatrixType sum = 0.0; for (int k=0; k< matrix1.cols; k++){ sum+= matrix1.buffer[r*matrix1.cols+k]*matrix2.buffer[k*matrix2.cols+c]; } multMatrix.buffer[r*multMatrix.cols+c] = sum; } } return multMatrix; } //sonst fehler else{ Matrix errorMatrix = {0, 0, NULL}; return errorMatrix; } //return matrix1; }