Merge branch 'RMax' matrix.c voll

This commit is contained in:
Max-R 2025-11-25 09:58:03 +01:00
commit 8e518a3bdd
12 changed files with 360 additions and 32 deletions

18
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -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
}

24
.vscode/launch.json vendored Normal file
View File

@ -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
}
]
}
]
}

59
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,59 @@
{
"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
}

Binary file not shown.

2
README.md Normal file
View File

@ -0,0 +1,2 @@
# Projekt 2 für Informatik 2 Praktikum

View File

@ -7,16 +7,23 @@
#define FILE_HEADER_STRING "__info2_image_file_format__"
// TODO Implementieren Sie geeignete Hilfsfunktionen für das Lesen der Bildserie aus einer Datei
GrayScaleImage readImage()
{
}
// TODO Vervollständigen Sie die Funktion readImages unter Benutzung Ihrer Hilfsfunktionen
GrayScaleImageSeries *readImages(const char *path)
{
GrayScaleImageSeries *series = NULL;
FILE *file = fopen("mnist_test.info2","rb");
char headOfFile;
series = malloc();
return series;
}
// TODO Vervollständigen Sie die Funktion clearSeries, welche eine Bildserie vollständig aus dem Speicher freigibt
void clearSeries(GrayScaleImageSeries *series)
{
}

View File

@ -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);

196
matrix.c
View File

@ -1,35 +1,191 @@
#include "matrix.h"
#include <stdlib.h>
#include <string.h>
#include "matrix.h"
// 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) {
Matrix createMatrix(unsigned int rows, unsigned int cols)
{
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;
}
void clearMatrix(Matrix *matrix)
{
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) {
void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx)
{
// 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;
}
}
MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx)
{
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);
}
Matrix add(const Matrix matrix1, const Matrix matrix2)
{
}
Matrix multiply(const Matrix matrix1, const Matrix matrix2)
{
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);
//durch neue matrix iterieren
for (int r=0; r< matrix1.rows; r++){
for (int c=0; c< matrix2.cols; c++){
MatrixType sum = 0.0;
//skalarprodukte berechnen, k damit die ganze zeile mal die ganze spalte genommen wird quasi
for (int k=0; k< matrix1.cols; k++){
//sum+= matrix1.buffer[r*matrix1.cols+k]*matrix2.buffer[k*matrix2.cols+c];
sum += getMatrixAt(matrix1, r, k)*getMatrixAt(matrix2, k, c);
}
//Ergebnisse in neue matrix speichern
setMatrixAt(sum, multMatrix, r, c);
}
}
return multMatrix;
}
//sonst fehler, kein multiply möglich
else{
Matrix errorMatrix = {0, 0, NULL};
return errorMatrix;
}
}

View File

@ -6,14 +6,20 @@
typedef float MatrixType;
// TODO Matrixtyp definieren
typedef struct {
unsigned int rows;
unsigned int cols;
MatrixType *buffer;
} Matrix;
Matrix createMatrix(unsigned int rows, unsigned int cols);
void clearMatrix(Matrix *matrix);
void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx);
MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx);
void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx,
unsigned int colIdx);
MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx,
unsigned int colIdx);
Matrix add(const Matrix matrix1, const Matrix matrix2);
Matrix multiply(const Matrix matrix1, const Matrix matrix2);
#endif

View File

@ -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};
@ -138,7 +164,7 @@ void test_setMatrixAtFailsOnIndicesOutOfRange(void)
Matrix matrixToTest = {.rows=2, .cols=3, .buffer=buffer};
setMatrixAt(-1, matrixToTest, 2, 3);
TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, matrixToTest.buffer, matrixToTest.cols * matrixToTest.rows);
TEST_ASSERT_EQUAL_FLOAT_ARRAY(expectedResults, matrixToTest.buffer, sizeof(buffer)/sizeof(MatrixType));
}
void setUp(void) {
@ -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);

29
neuralN_readFiles Normal file
View File

@ -0,0 +1,29 @@
Inhalte: Dynamische Speicherverwaltung, Strukturen, Dateien lesen.
Ziel: Die Bilder aus mnist_test.info 2 auslesen
Struktur für einlesen des Strings am Anfang der Datei:
int AnzahlBilder
int breiteBilder
int LaengeBilder
Struktur für Bilder:
unsinged int array Breite * Höhe
unsigned int Klasse (Label 0 - 9)
Speicher für Bilder dynamisch allokieren
GrayScaleImageSeries:
datei einlesen
header String aus der Datei lesen
mit header String den benötigten Speicher freigeben
in den Speicher die Datei einschreiben (mit Hilfsfunktion)
Hilfsfunktion (saveFile)
gehe zum Anfang des Strings
speicher alles der Reihe nach ein
clearSeries:
pointer der be malloc kommt nehemen
free()