aboutsummaryrefslogtreecommitdiff
path: root/matrix-operations.c
diff options
context:
space:
mode:
Diffstat (limited to 'matrix-operations.c')
-rw-r--r--matrix-operations.c243
1 files changed, 243 insertions, 0 deletions
diff --git a/matrix-operations.c b/matrix-operations.c
new file mode 100644
index 0000000..ae253f7
--- /dev/null
+++ b/matrix-operations.c
@@ -0,0 +1,243 @@
+#include "matrix-operations.h"
+
+
+matrix_t matrixError(error_t error){
+ switch(error){
+ case NOT_EQUAL:
+ perror("Matrices are not of the same dimensions\n");
+ break;
+ case NOT_MULTIPLIABLE:
+ perror("Matrix A's number of columns is different to matrix B's number of rows\n");
+ break;
+ case NOT_SQUARE:
+ perror("Matrix is not square");
+ break;
+ case ZERO_DET:
+ perror("Determinant of the matrix should be 0\n");
+ break;
+ case UNKNOWN:
+ default:
+ perror("Unknown error\n");
+ }
+ return createMatrix(0, 0);
+}
+// Creates a rows x columns matrix;
+matrix_t createMatrix(size_t rows, size_t columns){
+ matrix_t newmatrix;
+ newmatrix.rows = rows;
+ newmatrix.columns = columns;
+ newmatrix.matrix = malloc(rows*sizeof(float*));
+ for(size_t i = 0; i < rows; ++i)
+ newmatrix.matrix[i] = calloc(columns,sizeof(float));
+ return newmatrix;
+}
+
+// Fills the matrix with values provided by the user
+void initializeMatrix(matrix_t *m){
+ printf("Initializing %dx%d matrix\n", m->rows, m->columns);
+ for(size_t r = 0; r < m->rows; ++r){
+ printf("Please insert %d numbers for each of the columns of the %d%s row\n",
+ m->columns, r+1, (r+1==1)?("st"):((r+1==2)?("nd"):((r+1==3)?("rd"):("th"))));
+ for(size_t c = 0; c < m->columns; ++c){
+ scanf("%f", &m->matrix[r][c]);
+ }
+ }
+}
+
+// Returns true if the matrix is square, false otherwise
+int isSquare(matrix_t m){
+ return m.rows == m.columns;
+}
+
+// Displays the given matrix
+void displayMatrix(matrix_t m){
+ for(size_t r = 0; r < m.rows; ++r){
+ for(size_t c = 0; c < m.columns; ++c)
+ printf("%3.3g ", m.matrix[r][c]);
+ printf("\n");
+ }
+}
+
+// Returns the identity matrix n x n
+matrix_t identityMatrix(size_t n){
+ matrix_t identityMatrix = createMatrix(n, n);
+ for(size_t r = 0; r < n; ++r)
+ for(size_t c = 0; c < n; ++c)
+ if(r == c)
+ identityMatrix.matrix[r][c] = 1;
+ return identityMatrix;
+}
+
+// Returns a matrix of the same size as "m" filled with the number "n"
+matrix_t fillN(matrix_t m, float n){
+ matrix_t filledmatrix = createMatrix(m.rows, m.columns);
+ for(size_t r = 0; r < m.rows; ++r)
+ for(size_t c = 0; c < m.columns; ++c)
+ filledmatrix.matrix[r][c] = n;
+ return filledmatrix;
+}
+
+// Adds a number to all the positions of the matrix and returns the result
+matrix_t addN(matrix_t m, float n){
+ matrix_t addedmatrix = createMatrix(m.rows, m.columns);
+ for(size_t r = 0; r < m.rows; ++r)
+ for(size_t c = 0; c < m.columns; ++c)
+ addedmatrix.matrix[r][c] = m.matrix[r][c]+n;
+ return addedmatrix;
+}
+
+// Substracts a number from all the positions of the matrix and returns the result
+matrix_t substractN(matrix_t m, float n){
+ matrix_t substractedmatrix = createMatrix(m.rows, m.columns);
+ for(size_t r = 0; r < m.rows; ++r)
+ for(size_t c = 0; c < m.columns; ++c)
+ substractedmatrix.matrix[r][c] = m.matrix[r][c]-n;
+ return substractedmatrix;
+}
+
+// Adds two matrices together and returns the result
+matrix_t addMatrices(matrix_t a, matrix_t b){
+ if(a.rows != b.rows || a.columns != b.columns)
+ return matrixError(NOT_EQUAL);
+ matrix_t addedmatrices = createMatrix(a.rows, b.columns);
+ for(size_t r = 0; r < a.rows; ++r)
+ for(size_t c = 0; c < a.columns; ++c)
+ addedmatrices.matrix[r][c] = a.matrix[r][c] + b.matrix[r][c];
+ return addedmatrices;
+}
+
+// Negates all of the positions of the matrix and returns the result
+matrix_t negateMatrix(matrix_t m){
+ matrix_t negatedmatrix = createMatrix(m.rows, m.columns);
+ for(size_t r = 0; r < m.rows; ++r)
+ for(size_t c = 0; c < m.columns; ++c)
+ negatedmatrix.matrix[r][c] = -m.matrix[r][c];
+ return negatedmatrix;
+}
+
+// Substracts matrix "b" from "a" and returns the result
+matrix_t substractMatrices(matrix_t a, matrix_t b){
+ return addMatrices(a, negateMatrix(b));
+}
+
+// Multiplies all of the positions of the matrix by "n" and returns the result
+matrix_t multiplyByN(matrix_t m, float n){
+ matrix_t multipliedmatrix = createMatrix(m.rows, m.columns);
+ for(size_t r = 0; r < m.rows; ++r)
+ for(size_t c = 0; c < m.columns; ++c)
+ multipliedmatrix.matrix[r][c] = m.matrix[r][c]*n;
+ return multipliedmatrix;
+}
+
+// Divides all of the positions of the matrix by "n" and returns the result
+matrix_t divideByN(matrix_t m, float n){
+ return multiplyByN(m, (float)1/n);
+}
+
+// Multiplies matrix "a" by "b" and returns the result
+matrix_t multiplyMatrices(matrix_t a, matrix_t b){
+ if(a.columns != b.rows)
+ return matrixError(NOT_MULTIPLIABLE);
+ matrix_t multipliedmatrices = createMatrix(a.rows, b.columns);
+ for(size_t r = 0; r < multipliedmatrices.rows; ++r)
+ for(size_t c = 0; c < multipliedmatrices.columns; ++c)
+ for(size_t n = 0; n < a.columns; ++n)
+ multipliedmatrices.matrix[r][c] += a.matrix[r][n]*b.matrix[n][c];
+ return multipliedmatrices;
+}
+
+// Divides matrix "a" by "b" and returns the result
+matrix_t divideMatrices(matrix_t a, matrix_t b){
+ return multiplyMatrices(a, inverse(b));
+}
+
+// Raises the matrix to the nth power and returns the result
+matrix_t raiseMatrixToN(matrix_t m, int n){
+ if(!isSquare(m))
+ return matrixError(NOT_SQUARE);
+ // TODO: only accepts positive values of n
+ matrix_t raisedmatrix = identityMatrix(m.rows);
+ for(int i = 0; i < n; ++i)
+ raisedmatrix = multiplyMatrices(raisedmatrix, m);
+ return raisedmatrix;
+}
+
+// Creates a submatrix from "matrix" without the column "column" and row "row" of "matrix"
+matrix_t createSubmatrix(matrix_t m, size_t row, size_t column){
+ int mod = m.rows, nmod = mod-1, sr = 0, sc = 0;
+ matrix_t submatrix = createMatrix(nmod, nmod);
+ for(size_t r = 0; r < mod; ++r){
+ sc = 0;
+ if(r != row){
+ for(size_t c = 0; c < mod; ++c){
+ if(c != column){
+ submatrix.matrix[sr][sc] = m.matrix[r][c];
+ ++sc;
+ }
+ }
+ ++sr;
+ }
+ }
+ return submatrix;
+}
+
+// Returns the determinant of the given (square) matrix
+int determinant(matrix_t m){
+ if(!isSquare(m)){
+ matrixError(NOT_SQUARE);
+ return (int)NULL;
+ }
+ int det = 0;
+ if(m.rows == 1)
+ return m.matrix[0][0];
+ else{
+ int count = 0, nmod = m.rows-1;
+ for(size_t r = 0; r < m.rows; ++r){
+ matrix_t submatrix = createSubmatrix(m, 0, r);
+ int subdeterminant = determinant(submatrix);
+ int step = m.matrix[0][r]*subdeterminant;
+ if((count++)%2 == 0)
+ det += step;
+ else
+ det -= step;
+ }
+ return det;
+ }
+}
+
+// Returns the cofactor matrix of the given matrix
+matrix_t cofactor(matrix_t m){
+ if(!isSquare(m))
+ return matrixError(NOT_SQUARE);
+ matrix_t cofactormatrix = createMatrix(m.rows, m.columns);
+ for(size_t r = 0; r < m.rows; ++r){
+ for(size_t c = 0; c < m.columns; ++c){
+ matrix_t submatrix = createSubmatrix(m, r, c);
+ int d = determinant(submatrix);
+ cofactormatrix.matrix[r][c] = (r+c)%2?-d:d;
+ }
+ }
+ return cofactormatrix;
+}
+
+// Returns the transpose matrix of the given matrix
+matrix_t transpose(matrix_t m){
+ matrix_t transposematrix = createMatrix(m.columns, m.rows);
+ for(size_t r = 0; r < m.columns; ++r)
+ for(size_t c = 0; c < m.rows; ++c)
+ transposematrix.matrix[r][c] = m.matrix[c][r];
+ return transposematrix;
+}
+
+// Returns the adjugate matrix of the given matrix
+matrix_t adjugate(matrix_t m){
+ return transpose(cofactor(m));
+}
+
+// Returns the inverse matrix of the given matrix
+matrix_t inverse(matrix_t m){
+ int det = determinant(m);
+ if(det == 0)
+ return matrixError(ZERO_DET);
+ return multiplyByN(adjugate(m), (float)1/det);
+} \ No newline at end of file