#include #include #include "matrix.h" Matrix createMatrix(unsigned int rows, unsigned int cols) { Matrix matrix = {NULL, 0, 0}; //Initialwerte, da unsicher ob allocierung funktioniert if(rows > 0 && cols > 0) { MatrixType *buffer = (MatrixType *)calloc(rows * cols, sizeof(MatrixType)); if(buffer != NULL) { matrix.buffer = buffer; matrix.rows = rows; matrix.cols = cols; } } return matrix; } void clearMatrix(Matrix *matrix) { if(matrix != NULL) { free(matrix->buffer); matrix->buffer = NULL; matrix->rows = 0; matrix->cols = 0; } } void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx) { if(rowIdx < matrix.rows && colIdx < matrix.cols) { matrix.buffer[rowIdx * matrix.cols + colIdx] = value; } } MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx) { MatrixType value = UNDEFINED_MATRIX_VALUE; if(rowIdx < matrix.rows && colIdx < matrix.cols) { value = matrix.buffer[rowIdx * matrix.cols + colIdx]; } return value; } static int isValidMatrix(const Matrix matrix) { return matrix.buffer != NULL && matrix.rows > 0 && matrix.cols > 0; } static int hasSameDimensions(const Matrix matrix1, const Matrix matrix2) { return matrix1.rows == matrix2.rows && matrix1.cols == matrix2.cols; } static int isColumnVector(const Matrix matrix) { return matrix.cols == 1; } static Matrix addElementWise(const Matrix matrix1, const Matrix matrix2) { Matrix result = createMatrix(matrix1.rows, matrix1.cols); if(isValidMatrix(result)) { for(unsigned int i = 0; i < matrix1.rows * matrix1.cols; i++) { result.buffer[i] = matrix1.buffer[i] + matrix2.buffer[i]; } } return result; } static Matrix addBroadcast(const Matrix matrix, const Matrix vector) { Matrix result = createMatrix(matrix.rows, matrix.cols); if(isValidMatrix(result)) { for(unsigned int rowIdx = 0; rowIdx < matrix.rows; rowIdx++) { for(unsigned int colIdx = 0; colIdx < matrix.cols; colIdx++) { unsigned int index = rowIdx * matrix.cols + colIdx; result.buffer[index] = matrix.buffer[index] + getMatrixAt(vector, rowIdx, 0); } } } return result; } Matrix add(const Matrix matrix1, const Matrix matrix2) { Matrix result = {NULL, 0, 0}; //leere Matrix als Fehlerfall if(isValidMatrix(matrix1) && isValidMatrix(matrix2)) { //normal add if(hasSameDimensions(matrix1, matrix2)) { result = addElementWise(matrix1, matrix2); } //add Broadcast matrix2 = vektor and matrix1 = matrix else if(isColumnVector(matrix2) && matrix1.rows == matrix2.rows) { result = addBroadcast(matrix1, matrix2); } //add Broadcast matrix1 = vektor and matrix2 = matrix else if(isColumnVector(matrix1) && matrix1.rows == matrix2.rows) { result = addBroadcast(matrix2, matrix1); } } return result; } /* (Bedingung: matrix1.cols == matrix2.rows) * | 1 2 3 | | 7 8 | | 1*7+2*9+3*11 1*8+2*10+3*12 | | 58 64 | * | 4 5 6 | * | 9 10 | = | 4*7+5*9+6*11 4*8+5*10+6*12 | = | 139 154 | * | 11 12 | */ Matrix multiply(const Matrix matrix1, const Matrix matrix2) { Matrix result = {NULL, 0, 0}; //leere Matrix als Fehlerfall if(isValidMatrix(matrix1) && isValidMatrix(matrix2) && matrix1.cols == matrix2.rows) { result = createMatrix(matrix1.rows, matrix2.cols); if(isValidMatrix(result)) { for(unsigned int rowIdx = 0; rowIdx < matrix1.rows; rowIdx++) { for(unsigned int colIdx = 0; colIdx < matrix2.cols; colIdx++) { MatrixType sum = 0; for(unsigned int k = 0; k < matrix1.cols; k++) { sum += getMatrixAt(matrix1, rowIdx, k) * getMatrixAt(matrix2, k, colIdx); } setMatrixAt(sum, result, rowIdx, colIdx); } } } } return result; }