10 Commits
6 changed files with 185 additions and 71 deletions

No files matched your search

+3 -3
View File
@@ -1,6 +1,6 @@
# Neuronales Netz
## To-Dos
* Matrixtyp definieren in `matrix.h`
* `Matrix.c` implementieren
* `imageInput.c` implementieren
* [ ] Matrixtyp definieren in `matrix.h`
* [ ] `Matrix.c` implementieren
* [ ] `imageInput.c` implementieren
+73 -2
View File
@@ -7,12 +7,83 @@
#define FILE_HEADER_STRING "__info2_image_file_format__"
// TODO Implementieren Sie geeignete Hilfsfunktionen für das Lesen der Bildserie aus einer Datei
static unsigned short readNumberOfImages(FILE *file)
{
unsigned short numberOfImages = 0;
fseek(file, strlen(FILE_HEADER_STRING), SEEK_SET);
fread(&numberOfImages, sizeof(unsigned short), 1, file);
return numberOfImages;
}
static unsigned short readImageWidth(FILE *file)
{
unsigned short ImageWidth = 0;
fseek(file, sizeof(unsigned short), SEEK_CUR);
fread(&ImageWidth, sizeof(unsigned short), 1, file);
return ImageWidth;
}
static unsigned short readImageHeight(FILE *file)
{
unsigned short ImageHeight = 0;
fseek(file, sizeof(unsigned short), SEEK_CUR);
fread(&ImageHeight, sizeof(unsigned short), 1, file);
return ImageHeight;
}
static GrayScalePixelType *readImage(FILE *file, unsigned short ImageWidth, unsigned short ImageHeight)
{
GrayScalePixelType *image = malloc(ImageHeight*ImageWidth*sizeof(GrayScalePixelType));
fseek(file, sizeof(unsigned short), SEEK_CUR);
fread(image, sizeof(char), ImageHeight*ImageWidth, file);
return image;
}
static GrayScalePixelType readLabel(FILE *file)
{
unsigned char label;
fseek(file, sizeof(unsigned short), SEEK_CUR);
fread(&label, sizeof(unsigned char), 1, file);
return label;
}
// TODO Vervollständigen Sie die Funktion readImages unter Benutzung Ihrer Hilfsfunktionen
GrayScaleImageSeries *readImages(const char *path)
{
GrayScaleImageSeries *series = NULL;
FILE *file = fopen(path, "rb");
if (file == NULL)
{
return NULL;
}
unsigned short numberOfImages = readNumberOfImages(file);
unsigned short imageWidth = readImageWidth(file);
unsigned short imageHeight = readImageHeight(file);
GrayScaleImageSeries *series = malloc(sizeof(GrayScaleImageSeries));
if(series == NULL)
{
fclose(file);
return NULL;
}
series->count = numberOfImages;
series->images = malloc(numberOfImages * sizeof(GrayScaleImage));
series->labels = malloc(numberOfImages * sizeof(unsigned char));
for(int i = 0; i < numberOfImages; i++)
{
series->images[i].width = imageWidth;
series->images[i].height = imageHeight;
series->images[i].buffer = readImage(file, imageWidth, imageHeight);
series->labels[i] = readLabel(file);
}
fclose(file);
return series;
}
+2
View File
@@ -54,6 +54,8 @@ neuralNetworkTests: neuralNetwork.o matrix.o neuralNetworkTests.c $(unityfolder)
imageInputTests: imageInput.o imageInputTests.c $(unityfolder)/unity.c
$(CC) $(CFLAGS) -I$(unityfolder) -o runImageInputTests imageInputTests.c imageInput.o $(unityfolder)/unity.c
# --------------------------
# Clean
# --------------------------
+102 -61
View File
@@ -2,94 +2,135 @@
#include <string.h>
#include "matrix.h"
// TODO Matrix-Funktionen implementieren
Matrix createMatrix(unsigned int rows, unsigned int cols)
{
Matrix matrix = {NULL, 0, 0}; // NUll init
Matrix m;
if(rows > 0 && cols > 0)
if (rows == 0 || cols == 0) //Ueberprüfen, ob ungültige Werte für Matrix vorhanden
{
matrix.buffer = (MatrixType *)calloc((size_t)rows * cols, sizeof(MatrixType));
if(matrix.buffer != NULL) //sichergehn das Buffer holen geklappt hat, dann setzen
{
matrix.rows = rows;
matrix.cols = cols;
}
m.rows = 0;
m.cols = 0;
m.buffer = NULL;
return m;
}
return matrix;
m.rows = rows;
m.cols = cols;
m.buffer = (MatrixType*)calloc(rows*cols, sizeof(MatrixType)); //Bei Fehlschalg gibt calloc entweder NULL oder Zeiger verschieden von NULL aus
return m;
}
void clearMatrix(Matrix *matrix)
{
if(matrix != NULL) //Check ob die Matrix nicht eh schon leer ist
{
free(matrix->buffer); //memory freen
matrix->buffer = NULL; // buffer entfernen
matrix->rows = 0;
matrix->cols = 0;
}
}
// Helper Function, um zuschauen ob Index zugriff valide ist.
static int isValidIndex(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx){
return matrix.buffer != NULL && rowIdx < matrix.rows && colIdx < matrix.cols;
matrix->buffer = 0;
matrix->rows = 0;
matrix->cols = 0;
}
void setMatrixAt(MatrixType value, Matrix matrix, unsigned int rowIdx, unsigned int colIdx)
{
if(isValidIndex(matrix, rowIdx, colIdx))
if((rowIdx * matrix.cols + colIdx) < (matrix.rows*matrix.cols))
{
matrix.buffer[rowIdx * matrix.cols + colIdx] = value;
}
}
MatrixType getMatrixAt(const Matrix matrix, unsigned int rowIdx, unsigned int colIdx)
{
// Für Zugriff auf Row2, Col2, also m6, muss man im Buffer Die Positionen um 1 row +
MatrixType value;
if(isValidIndex(matrix, rowIdx, colIdx))
value = matrix.buffer[rowIdx * matrix.cols + colIdx];
return value;
MatrixType value = 0;
if((rowIdx * matrix.cols + colIdx) < (matrix.rows*matrix.cols))
{
value = matrix.buffer[rowIdx * matrix.cols + colIdx];
}
return value;
}
static int haveSameDimensions(const Matrix matrix1, const Matrix matrix2)
{
return matrix1.rows == matrix2.rows && matrix1.cols == matrix2.cols;
}
Matrix addBroadcast(const Matrix matrix, const Matrix vector){
// Broadcasting Add von Matrix + Vector
Matrix result = createMatrix(0, 0);
}
static int isBroadcastable(const Matrix matrix1, const Matrix matrix2){
// Check Broadcastable
}
Matrix addElementwise(const Matrix matrix1, const Matrix matrix2){
// addieren der Matrizen
Matrix result = createMatrix(0, 0);
}
Matrix add(const Matrix matrix1, const Matrix matrix2)
{
Matrix result = {NULL, 0, 0};
typedef enum {elemt_add, broadcast} Addiermodi;
Addiermodi modus;
if(matrix1.buffer != NULL && matrix2.buffer != NULL){
if(haveSameDimensions(matrix1, matrix2)){
// result = NULL; //addElementwise
} else if(isBroadcastable(matrix1, matrix2)) { // Check ob Matrix2 ein Vector ist
// result = NULL; //addBroadcast
} else if(isBroadcastable(matrix1, matrix2)) { // Check ob Matrix2 ein Vector ist
// result = NULL; //addBroadcast
if((matrix1.cols == 1 || matrix2.cols ==1) && (matrix1.rows == matrix2.rows))
{
modus = broadcast;
}
else if((matrix1.rows == matrix2.rows) && (matrix1.cols == matrix2.cols))
{
modus = elemt_add;
}
else
{
Matrix failure = {NULL, 0, 0};
return failure;
}
Matrix m;
if(modus == elemt_add)
{
m = createMatrix(matrix1.rows, matrix1.cols);
for(int i = 0; i< matrix1.rows; i++)
{
for(int j = 0; j < matrix1.cols ; j++)
{
m.buffer[i*matrix1.cols+j] = matrix1.buffer[i*matrix1.cols+j] + matrix2.buffer[i*matrix1.cols+j];
}
}
return m;
}
else if(modus == broadcast)
{
if(matrix1.cols == 1)
{
m = createMatrix(matrix2.rows, matrix2.cols);
for(int i = 0; i< matrix2.rows; i++)
{
for(int j = 0; j < matrix2.cols ; j++)
{
m.buffer[i*matrix2.cols+j] = matrix2.buffer[i*matrix2.cols+j] + matrix1.buffer[i*matrix1.cols];
}
}
}
else
{
m = createMatrix(matrix1.rows, matrix1.cols);
for(int i = 0; i< matrix1.rows; i++)
{
for(int j = 0; j < matrix1.cols ; j++)
{
m.buffer[i*matrix1.cols+j] = matrix1.buffer[i*matrix1.cols+j] + matrix2.buffer[i*matrix2.cols];
}
}
}
}
return result;
return m;
}
Matrix multiply(const Matrix matrix1, const Matrix matrix2)
{
//kann man Matrizen multiplizieren, größen Check
}
if(matrix1.cols != matrix2.rows)
{
Matrix failure = {NULL, 0, 0};
return failure;
}
Matrix m = createMatrix(matrix1.rows, matrix2.cols);
for(int i = 0; i < matrix1.rows; i++)
{
for(int j = 0; j < matrix2.cols ; j++)
{
int value = 0;
for(int k = 0; k < matrix1.cols; k++)
{
value += getMatrixAt(matrix1, i, k) * getMatrixAt(matrix2, k , j);
}
m.buffer[i*matrix2.cols+j] = value;
}
}
return m;
}
+4 -5
View File
@@ -2,16 +2,15 @@
#define MATRIX_H
#define UNDEFINED_MATRIX_VALUE 0
#define MATRIX_COLS 4
#define MATRIX_ROWS 4
typedef float MatrixType;
typedef struct {
MatrixType *buffer;
// TODO Matrixtyp definieren
typedef struct Matrix{
MatrixType *buffer;
unsigned int rows;
unsigned int cols;
} Matrix;
}Matrix;
Matrix createMatrix(unsigned int rows, unsigned int cols);
void clearMatrix(Matrix *matrix);
+1
View File
@@ -0,0 +1 @@
some_tag