diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..789a385 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "makefile.launchConfigurations": [ + { + "cwd": "c:\\Users\\z004w66a\\projects\\Info2\\Praktikum_Aufgabe2\\I2_NeuronalesNetz", + "binaryPath": "c:\\Users\\z004w66a\\projects\\Info2\\Praktikum_Aufgabe2\\I2_NeuronalesNetz\\mnist", + "binaryArgs": [] + } + ] +} \ No newline at end of file diff --git a/NeuronalesNetz_Aufgabenstellung.pdf b/NeuronalesNetz_Aufgabenstellung.pdf index dcb354a..b4c6ce5 100644 Binary files a/NeuronalesNetz_Aufgabenstellung.pdf and b/NeuronalesNetz_Aufgabenstellung.pdf differ diff --git a/imageInputTests.c b/imageInputTests.c index c704271..03240ab 100644 --- a/imageInputTests.c +++ b/imageInputTests.c @@ -54,7 +54,7 @@ void test_readImagesReturnsCorrectImageWidth(void) GrayScaleImageSeries *series = NULL; const unsigned short expectedWidth = 10; const char *path = "testFile.info2"; - prepareImageFile(path, 8, expectedWidth, 2, 1); + prepareImageFile(path, expectedWidth, 8, 2, 1); series = readImages(path); TEST_ASSERT_NOT_NULL(series); TEST_ASSERT_NOT_NULL(series->images); @@ -70,7 +70,7 @@ void test_readImagesReturnsCorrectImageHeight(void) GrayScaleImageSeries *series = NULL; const unsigned short expectedHeight = 10; const char *path = "testFile.info2"; - prepareImageFile(path, expectedHeight, 8, 2, 1); + prepareImageFile(path, 8, expectedHeight, 2, 1); series = readImages(path); TEST_ASSERT_NOT_NULL(series); TEST_ASSERT_NOT_NULL(series->images); diff --git a/matrix.c b/matrix.c index ad00628..09aebe6 100644 --- a/matrix.c +++ b/matrix.c @@ -1,35 +1,224 @@ #include #include +#include #include "matrix.h" // TODO Matrix-Funktionen implementieren Matrix createMatrix(unsigned int rows, unsigned int cols) { + if (rows != 0 && cols != 0) + { + Matrix m = {rows, cols}; + + size_t total = (size_t)rows * (size_t)cols; + + MatrixType *block = calloc(total, sizeof(MatrixType)); + + if (block == NULL) + { + printf("Fehler bei der Speicherreservierung!\n"); + + } + + m.buffer = block; + return m; + + } + + else + { + printf("Fehler! Die Anzahl der Reihen und Spalten der Matrix darf nicht null sein!\n"); + + } } void clearMatrix(Matrix *matrix) { + if (matrix != NULL) + { + if (matrix->buffer != NULL) + { + free(matrix->buffer); + matrix->buffer = NULL; + } + + else + { + printf("Die Matrixgröße darf nicht NULL sein!\n"); + + } + + + matrix->rows = 0; + matrix->cols = 0; + } + + else + { + printf("Keine gültige Matrix zum Leeren!\n"); + + } } void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx) { - + if (matrix.buffer != NULL) + { + if (rowIdx < matrix.rows && colIdx < matrix.cols) + { + size_t index = rowIdx * matrix.cols + colIdx; + + matrix.buffer[index] = value; + } + else + { + printf("Fehler, Zeile bzw Spalte außerhalb der Matrixdimensionen!\n"); + + } + + } + else + { + printf("Fehler! Matrix nicht initialisier oder leer\n"); + + } } MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx) { + if (matrix.buffer != NULL) + { + if (rowIdx < matrix.rows && colIdx < matrix.cols) + { + size_t index = rowIdx * matrix.cols + colIdx; + + MatrixType value = matrix.buffer[index]; + + return value; + } + else + { + printf("Fehler! Zeile oder Spalte ausserhalb der Matrixdimensionen!\n"); + + } + + } + else + { + printf("Fehler! Matrix nicht initialisiert oder leer!\n"); + + } } Matrix add(const Matrix matrix1, const Matrix matrix2) { + if (matrix1.cols == matrix2.cols && matrix1.rows == matrix2.rows) + { + Matrix matrixAdd = createMatrix(matrix1.rows, matrix1.cols); + + for (size_t i = 0; i < matrix1.rows; i++) + { + for (size_t j = 0; j < matrix1.cols; j++) + { + MatrixType value1 = getMatrixAt(matrix1, i, j); + MatrixType value2 = getMatrixAt(matrix2, i, j); + + MatrixType sum = value1 + value2; + + size_t index = i * matrix1.cols + j; + + matrixAdd.buffer[index] = sum; + } + + } + return matrixAdd; + } + + else if (matrix1.rows == matrix2.rows && matrix2.cols == 1) + { + Matrix matrixAdd = createMatrix(matrix1.rows, matrix1.cols); + + for (size_t i = 0; i < matrix1.rows; i++) + { + for (size_t j = 0; j < matrix1.cols; j++) + { + MatrixType value1 = getMatrixAt(matrix1, i, j); + MatrixType value2 = getMatrixAt(matrix2, i, 1); + + MatrixType sum = value1 + value2; + size_t index = i * matrix1.cols + j; + + matrixAdd.buffer[index] = sum; + } + + } + return matrixAdd; + } + + else if (matrix1.rows == matrix2.rows && matrix1.cols == 1) + { + Matrix matrixAdd = createMatrix(matrix2.rows, matrix2.cols); + + for (size_t i = 0; i < matrix2.rows; i++) + { + for (size_t j = 0; j < matrix2.cols; j++) + { + MatrixType value1 = getMatrixAt(matrix1, i, 1); + MatrixType value2 = getMatrixAt(matrix2, i, j); + + MatrixType sum = value1 + value2; + size_t index = i * matrix1.cols + j; + + matrixAdd.buffer[index] = sum; + } + + } + return matrixAdd; + } + + else + { + printf("Fehler bei der Matrixaddition! Die Matritzen sind nicht gleich gross!\n"); + + } + } Matrix multiply(const Matrix matrix1, const Matrix matrix2) { + if (matrix1.cols == matrix2.rows) + { + Matrix matrixMult = createMatrix(matrix1.rows, matrix2.cols); + MatrixType sum = 0.0; + + for (size_t i = 0; i < matrix1.rows; i++) + { + for (size_t j = 0; j < matrix2.cols; j++) + { + for (size_t k = 0; k < matrix1.cols; k++) + { + MatrixType value1 = getMatrixAt(matrix1, i, k); + MatrixType value2 = getMatrixAt(matrix2, k, j); + + sum += value1 * value2; + } + size_t index = i * matrixMult.cols + j; + matrixMult.buffer[index] = sum; + } + + } + return matrixMult; + } + else + { + printf("Fehler bei der Matrixmultiplikation! Die Anzahl an Zeilen der ersten Matrix entspricht nicht der Anzahl an Spalten der zweiten Matrix!\n"); + + } + } \ No newline at end of file diff --git a/matrix.h b/matrix.h index cc640d1..aea3ee0 100644 --- a/matrix.h +++ b/matrix.h @@ -5,7 +5,14 @@ typedef float MatrixType; -// TODO Matrixtyp definieren +// Matrixtyp definieren +typedef struct +{ + unsigned int rows; + unsigned int cols; + MatrixType *buffer; +}Matrix; + Matrix createMatrix(unsigned int rows, unsigned int cols); diff --git a/matrixTests.c b/matrixTests.c index 686db1e..80b1daa 100644 --- a/matrixTests.c +++ b/matrixTests.c @@ -71,6 +71,32 @@ void test_addFailsOnDifferentInputDimensions(void) TEST_ASSERT_EQUAL_UINT32(0, result.cols); } +void test_addSupportsBroadcasting(void) +{ + MatrixType buffer1[] = {1, 2, 3, 4, 5, 6}; + MatrixType buffer2[] = {7, 8}; + Matrix matrix1 = {.rows=2, .cols=3, .buffer=buffer1}; + Matrix matrix2 = {.rows=2, .cols=1, .buffer=buffer2}; + + Matrix result1 = add(matrix1, matrix2); + Matrix result2 = add(matrix2, matrix1); + + float expectedResults[] = {8, 9, 10, 12, 13, 14}; + + TEST_ASSERT_EQUAL_UINT32(matrix1.rows, result1.rows); + TEST_ASSERT_EQUAL_UINT32(matrix1.cols, result1.cols); + TEST_ASSERT_EQUAL_UINT32(matrix1.rows, result2.rows); + TEST_ASSERT_EQUAL_UINT32(matrix1.cols, result2.cols); + + TEST_ASSERT_EQUAL_INT(sizeof(expectedResults)/sizeof(expectedResults[0]), result1.rows * result1.cols); + TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, result1.buffer, result1.cols * result1.rows); + TEST_ASSERT_EQUAL_INT(sizeof(expectedResults)/sizeof(expectedResults[0]), result2.rows * result2.cols); + TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, result2.buffer, result2.cols * result2.rows); + + free(result1.buffer); + free(result2.buffer); +} + void test_multiplyReturnsCorrectResults(void) { MatrixType buffer1[] = {1, 2, 3, 4, 5, 6}; @@ -159,6 +185,7 @@ int main() RUN_TEST(test_clearMatrixSetsMembersToNull); RUN_TEST(test_addReturnsCorrectResult); RUN_TEST(test_addFailsOnDifferentInputDimensions); + RUN_TEST(test_addSupportsBroadcasting); RUN_TEST(test_multiplyReturnsCorrectResults); RUN_TEST(test_multiplyFailsOnWrongInputDimensions); RUN_TEST(test_getMatrixAtReturnsCorrectResult);