diff --git a/src/matrix.h b/src/matrix.h index 1765479..f0d5fd0 100644 --- a/src/matrix.h +++ b/src/matrix.h @@ -9,6 +9,9 @@ #include #endif +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + // represents user-supplied training data typedef struct DataSet_ { size_t rows; @@ -92,6 +95,30 @@ static Matrix* hadamard(Matrix* A, Matrix* B); // places values of hadamard product of $A and $B into $into static void hadamardInto(Matrix* A, Matrix* B, Matrix* into); +// returns a Matrix with the mean by row of $A +static Matrix* meanByRow(Matrix* A); + +// returns a Matrix with the mean by collumn of $A +static Matrix* meanByCol(Matrix* A); + +// returns a Matrix with the max element by row of $A +static Matrix* maxByRow(Matrix* A); + +// returns a Matrix with the max element by collumn of $A +static Matrix* maxByCol(Matrix* A); + +// returns a Matrix with the min element by row of $A +static Matrix* minByRow(Matrix* A); + +// returns a Matrix with the min element by collumn of $A +static Matrix* minByCol(Matrix* A); + +// returns a normalized Matrix per row of $A by a $min_bound and a $max_bound +static Matrix* normalizeByRow(Matrix* A, int min_bound, int max_bound); + +// returns a normalized Matrix per col of $A by a $min_bound and a $max_bound +static Matrix* normalizeByCol(Matrix* A, int min_bound, int max_bound); + // returns a shallow copy of input matrix static Matrix* copy(Matrix* orig); @@ -367,6 +394,120 @@ Matrix* copy(Matrix* orig){ return createMatrix(orig->rows, orig->cols, data); } +Matrix* meanByRow(Matrix* A){ + float* data = (float*)malloc(sizeof(float) * A->rows); + Matrix* result = createMatrix(A->rows, 1, data); + int i, j; + for (i = 0; i < A->rows; i++){ + float sum = 0.0; + for (j = 0; j < A->cols; j++){ + sum += getMatrix(A, i, j); + } + setMatrix(result, i, 0, sum/(float)A->cols); + } + return result; +} + +Matrix* meanByCol(Matrix* A){ + float* data = (float*)malloc(sizeof(float) * A->cols); + Matrix* result = createMatrix(1, A->cols, data); + int i, j; + for (j = 0; j < A->cols; j++){ + float sum = 0.0; + for (i = 0; i < A->rows; i++){ + sum += getMatrix(A, i, j); + } + setMatrix(result, 0, j, sum/(float)A->rows); + } + return result; +} + +Matrix* maxByRow(Matrix* A){ + float* data = (float*)malloc(sizeof(float) * A->rows); + Matrix* result = createMatrix(A->rows, 1, data); + int i, j; + for (i = 0; i < A->rows; i++){ + float max = FLT_MIN; + for (j = 0; j < A->cols; j++){ + max = MAX(getMatrix(A, i, j), max); + } + setMatrix(result, i, 0, max); + } + return result; +} + +Matrix* maxByCol(Matrix* A){ + float* data = (float*)malloc(sizeof(float) * A->cols); + Matrix* result = createMatrix(1, A->cols, data); + int i, j; + for (j = 0; j < A->cols; j++){ + float max = FLT_MIN; + for (i = 0; i < A->rows; i++){ + max = MAX(getMatrix(A, i, j), max); + } + setMatrix(result, 0, j, max); + } + return result; +} + +Matrix* minByRow(Matrix* A){ + float* data = (float*)malloc(sizeof(float) * A->rows); + Matrix* result = createMatrix(A->rows, 1, data); + int i, j; + for (i = 0; i < A->rows; i++){ + float min = FLT_MAX; + for (j = 0; j < A->cols; j++){ + min = MIN(getMatrix(A, i, j), min); + } + setMatrix(result, i, 0, min); + } + return result; +} + +Matrix* minByCol(Matrix* A){ + float* data = (float*)malloc(sizeof(float) * A->cols); + Matrix* result = createMatrix(1, A->cols, data); + int i, j; + for (j = 0; j < A->cols; j++){ + float min = FLT_MAX; + for (i = 0; i < A->rows; i++){ + min = MIN(getMatrix(A, i, j), min); + } + setMatrix(result, 0, j, min); + } + return result; +} + +Matrix* normalizeByRow(Matrix* A, int min_bound, int max_bound){ + float* data = (float*)malloc(sizeof(float) * A->rows * A->cols); + Matrix* result = createMatrix(A->rows, A->cols, data); + int i, j; + for (i = 0; i < A->rows; i++){ + float max = getMatrix(maxByRow(A),i,0); + float min = getMatrix(minByRow(A),i,0); + for (j = 0; j < A->cols; j++){ + float normalized_value = (max_bound - min_bound)*(getMatrix(A,i,j)-min)/(max-min) + min_bound; + setMatrix(result, i, j, normalized_value); + } + } + return result; +} + +Matrix* normalizeByCol(Matrix* A, int min_bound, int max_bound){ + float* data = (float*)malloc(sizeof(float) * A->rows * A->cols); + Matrix* result = createMatrix(A->rows, A->cols, data); + int i, j; + for (j = 0; j < A->cols; j++){ + float max = getMatrix(maxByCol(A),0,j); + float min = getMatrix(minByCol(A),0,j); + for (i = 0; i < A->rows; i++){ + float normalized_value = (max_bound - min_bound)*(getMatrix(A,i,j)-min)/(max-min) + min_bound; + setMatrix(result, i, j, normalized_value); + } + } + return result; +} + int equals(Matrix* A, Matrix* B){ if (A->rows != B->rows){ return 0; @@ -390,4 +531,4 @@ void destroyMatrix(Matrix* matrix){ free(matrix); } -#endif \ No newline at end of file +#endif diff --git a/src/network.h b/src/network.h index 82259cd..5220d3e 100644 --- a/src/network.h +++ b/src/network.h @@ -42,7 +42,7 @@ static float crossEntropyLoss(Network* network, Matrix* prediction, DataSet* act static float meanSquaredError(Network* network, Matrix* prediction, DataSet* actual, float regularizationStrength); // return matrix of network output -static Matrix* getOuput(Network* network); +static Matrix* getOutput(Network* network); // returns indices corresponding to highest-probability classes for each // example previously inputted @@ -178,7 +178,7 @@ float meanSquaredError(Network* network, Matrix* prediction, DataSet* actual, fl return ((0.5 / actual->rows) * total_err) + (regularizationStrength * .5 * reg_err); } -Matrix* getOuput(Network* network){ +Matrix* getOutput(Network* network){ return network->layers[network->numLayers - 1]->input; } @@ -342,4 +342,4 @@ Network* readNetwork(char* path){ return network; } -#endif \ No newline at end of file +#endif diff --git a/tests/matrix_tests.c b/tests/matrix_tests.c index 6d58483..5d697df 100644 --- a/tests/matrix_tests.c +++ b/tests/matrix_tests.c @@ -84,6 +84,26 @@ int main(){ } } + //test mean, max, min by row + Matrix *matrixMeanRow = meanByRow(A); + Matrix *matrixMaxRow = maxByRow(A); + Matrix *matrixMinRow = minByRow(A); + for (i = 0; i < 3; i++){ + assert(getMatrix(A,i,1) == getMatrix(matrixMeanRow,i,0)); + assert(getMatrix(A,i,2) == getMatrix(matrixMaxRow,i,0)); + assert(getMatrix(A,i,0) == getMatrix(matrixMinRow,i,0)); + } + + //test mean, max, min by col + Matrix *matrixMeanCol = meanByCol(A); + Matrix *matrixMaxCol = maxByCol(A); + Matrix *matrixMinCol = minByCol(A); + for (j = 0; j < 3; j++){ + assert(getMatrix(A,1,j) == getMatrix(matrixMeanCol,0,j)); + assert(getMatrix(A,2,j) == getMatrix(matrixMaxCol,0,j)); + assert(getMatrix(A,0,j) == getMatrix(matrixMinCol,0,j)); + } + // test destroy destroyMatrix(A); destroyMatrix(B); @@ -101,4 +121,4 @@ int main(){ destroyMatrix(copied); return 0; -} \ No newline at end of file +}