diff --git a/.gitignore b/.gitignore index 4f907f8..15d0ea4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ mnist runTests *.o -*.exe \ No newline at end of file +*.exe +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/settings.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..cb8d469 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "windows-gcc-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "C:/ProgramData/mingw64/mingw64/bin/gcc.exe", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "windows-gcc-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..7583c69 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "externalConsole": true, + "cwd": "c:/Users/Max-R/I2Pr/repoKachelto/I2-Pr_neuronalesNetz/info2Praktikum-NeuronalesNetz", + "program": "c:/Users/Max-R/I2Pr/repoKachelto/I2-Pr_neuronalesNetz/info2Praktikum-NeuronalesNetz/build/Debug/outDebug", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 082b194..bb879da 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,59 @@ { - "makefile.configureOnOpen": false + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false } \ No newline at end of file diff --git a/makefile b/makefile index 376d643..444bd21 100644 --- a/makefile +++ b/makefile @@ -62,4 +62,5 @@ ifeq ($(OS),Windows_NT) del /f *.o *.exe else rm -f *.o mnist runMatrixTests runNeuralNetworkTests runImageInputTests -endif \ No newline at end of file +endif + \ No newline at end of file diff --git a/matrix.c b/matrix.c index bcbf07c..bc4b8ae 100644 --- a/matrix.c +++ b/matrix.c @@ -10,34 +10,15 @@ } Matrix;*/ Matrix createMatrix(unsigned int rows, unsigned int cols) { - - Matrix matrix; // neue Metrix Struktur erstellen - - Matrix errorMatrix = {0, 0, NULL}; // Fehlermatrix zum zurückgeben - - if (rows == 0 || cols == 0) { // fehlerhafte Parameter übergeben - + if (cols == 0 || rows == 0) { + Matrix errorMatrix = {0, 0, NULL}; return errorMatrix; } - - matrix.rows = rows; // nach dem Prüfen auf unmögliche Angaben kann die Matrix - // erstellt werden - matrix.cols = cols; - - matrix.buffer = - malloc(rows * cols * sizeof(MatrixType)); // Speicher reservieren - if (matrix.buffer == NULL) { // Prüfen, ob Speicher reserviert werden konnte - matrix.rows = 0; - matrix.cols = 0; - return matrix; - } - - for (int r = 0; r < rows; r++) { - for (int c = 0; c < cols; c++) { - matrix.buffer[r * matrix.cols + c] = UNDEFINED_MATRIX_VALUE; - } - } - return matrix; + 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) { @@ -53,14 +34,13 @@ 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 || - matrix.buffer == NULL) { // Speichergröße nicht überschreiten + 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 + 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 @@ -74,187 +54,131 @@ MatrixType getMatrixAt(const Matrix matrix, return value; } - -Matrix broadCastCols(const Matrix matrix, const unsigned int rows, - const unsigned int cols) { - - Matrix copy = createMatrix( - rows, cols); // Matrix 1 Kopie erstellen mit Dimensionen von Matrix2 - for (int r = 0; r < rows; r++) { - - MatrixType value = getMatrixAt(matrix, r, 0); +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(value, copy, r, c); + setMatrixAt(valueMatrix1, copy1, r, c); } } - - return copy; + return copy1; } -Matrix broadCastRows(const Matrix matrix, const unsigned int rows, - const unsigned int cols) { - - Matrix copy = createMatrix(rows, cols); - - for (int c = 0; c < cols; c++) { - MatrixType value = getMatrixAt(matrix, 0, c); - +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(value, copy, r, c); + setMatrixAt(valueMatrix1, copy1, r, c); } } - - return copy; + return copy1; } - Matrix add(const Matrix matrix1, const Matrix matrix2) { - const unsigned int rows1 = matrix1.rows; - const unsigned int rows2 = matrix2.rows; - const unsigned int cols1 = matrix1.cols; - const unsigned int cols2 = matrix2.cols; + // 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 = ((rows1 == rows2) ? 1 : 0); + const int rowsEqual = (matrix1.rows == matrix2.rows) ? 1 : 0; + const int colsEqual = (matrix1.cols == matrix2.cols) ? 1 : 0; - const int colsEqual = ((cols1 == cols2) ? 1 : 0); - - if (rowsEqual && colsEqual) // addieren - - { - Matrix result = createMatrix(rows1, cols1); // Speicher reservieren + // Broadcasting nur bei Vektor und Matrix, Fehlermeldung bei zwei unpassender + // Matrix + if (rowsEqual == 1 && colsEqual == 1) { + Matrix result = createMatrix(matrix1.rows, matrix1.cols); if (result.buffer == NULL) { return (Matrix){0, 0, NULL}; } - - for (int i = 0; i < (rows1 * cols1); i++) { // addieren - - result.buffer[i] = - (matrix1.buffer[i] + - matrix2.buffer[i]); // buffer[i] ⇔ *(buffer + i) Adresse = - // Startadresse + (i * sizeof(MatrixType)) + 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; // zurückgeben - } - - else if (rowsEqual && !colsEqual) { - - if (cols1 == 1) { - - Matrix result = createMatrix(rows2, cols2); + 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); if (result.buffer == NULL) { return (Matrix){0, 0, NULL}; } - - Matrix copy1 = broadCastCols(matrix1, rows2, cols2); - if (!copy1.buffer) { - clearMatrix(&result); + 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); + if (result.buffer == NULL) { return (Matrix){0, 0, NULL}; } - - for (unsigned int i = 0; i < rows2 * cols2; i++) { - result.buffer[i] = copy1.buffer[i] + matrix2.buffer[i]; + 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); + } } - - /* freigeben, weil nicht mehr benötigt */ - clearMatrix(©1); - return result; - - // add und return - - } else if (cols2 == 1) { - - Matrix result = createMatrix(rows1, cols1); - if (result.buffer == NULL) { - Matrix error = {0, 0, NULL}; - return error; - } - - // Matrix2 hat nur eine Spalte -> horizontal broadcasten - Matrix copy2 = broadCastCols(matrix2, rows1, cols1); - - for (unsigned int i = 0; i < rows1 * cols1; i++) { - result.buffer[i] = matrix1.buffer[i] + copy2.buffer[i]; - } - - // Optional: Speicher von copy2 freigeben - clearMatrix(©2); - return result; } - - else { - - printf("Fehlermeldung"); // vielleicht Fehlermeldung ändern zu - // Programmabbruch - Matrix error = {0, 0, NULL}; - return error; - } - } - else if (!rowsEqual && colsEqual) { - + else if ((rows1 == 1 || rows2 == 1) && colsEqual == 1) { if (rows1 == 1) { - - Matrix result = createMatrix(rows2, cols2); + Matrix newMatrix = broadcastingRows(matrix1, rows2); + // add + Matrix result = createMatrix(newMatrix.rows, newMatrix.cols); if (result.buffer == NULL) { return (Matrix){0, 0, NULL}; } - - Matrix copy1 = broadCastRows(matrix1, rows2, cols2); - - for (int i = 0; i < (rows2 * cols2); i++) { // addieren - - result.buffer[i] = - (copy1.buffer[i] + - matrix2.buffer[i]); // buffer[i] ⇔ *(buffer + i) Adresse = - // Startadresse + (i * sizeof(MatrixType)) + 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; - - // add und return - - } else if (rows2 == 1) { - - Matrix result = createMatrix(rows1, cols1); + } else { + Matrix newMatrix2 = broadcastingRows(matrix2, rows1); + // add + Matrix result = createMatrix(newMatrix2.rows, newMatrix2.cols); if (result.buffer == NULL) { return (Matrix){0, 0, NULL}; } - - Matrix copy2 = broadCastRows(matrix2, rows1, cols1); - - // add und return - - for (int i = 0; i < (rows1 * cols1); i++) { // addieren - - result.buffer[i] = - (matrix1.buffer[i] + - copy2.buffer[i]); // buffer[i] ⇔ *(buffer + i) Adresse = - // Startadresse + (i * sizeof(MatrixType)) + 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 { - - printf("Fehlermeldung"); // vielleicht Fehlermeldung ändern zu - // Programmabbruch - Matrix error = {0, 0, NULL}; - return error; } + } else { + // kein add möglich + Matrix errorMatrix = {0, 0, NULL}; + return errorMatrix; } - - else { - printf("Fehlermeldung"); // vielleicht Fehlermeldung ändern zu - // Programmabbruch - Matrix error = {0, 0, NULL}; - return error; - } + return result; } - Matrix multiply(const Matrix matrix1, const Matrix matrix2) { // Spalten1 müssen gleich zeilen2 sein! dann multiplizieren if (matrix1.cols == matrix2.rows) {