From 3271c57cd456fc1ac9b9bf226a341d0ebb86ad1c Mon Sep 17 00:00:00 2001 From: Max Goryunov Date: Wed, 30 Aug 2023 01:39:08 +0300 Subject: [PATCH 1/6] #24 signatures --- LinearSystemsToolkit/Matrix.h | 131 ++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 LinearSystemsToolkit/Matrix.h diff --git a/LinearSystemsToolkit/Matrix.h b/LinearSystemsToolkit/Matrix.h new file mode 100644 index 0000000..2858b94 --- /dev/null +++ b/LinearSystemsToolkit/Matrix.h @@ -0,0 +1,131 @@ +#pragma once + +#include "Vector.h" + +/** + * @brief A matrix of regular values. + * + * This struct represents a square matrix. +*/ +typedef struct Matrix { + double** data; // matrix values + int n; // matrix size +} Matrix; + +/** + * @brief Initialize a matrix. + * + * @param n The size of the matrix. + * + * @return A pointer to the matrix. +*/ +Matrix* matrixCreate(int n); + +/** + * @brief Free a matrix. + * + * @param A The matrix to free. +*/ +void matrixDestroy(Matrix* A); + +/** + * @brief Create an identity matrix. + * + * @param n The size of the matrix. + * + * @return A pointer to the matrix. +*/ +Matrix* matrixIdentity(int n); + +/** + * @brief Read a matrix from a file. + * + * @param name The name of the file. + * @param n The size of the matrix. + * + * @return A pointer to the matrix. +*/ +Matrix* matrixReadFromFile(const char* name, int n); + +/** + * @brief Print a matrix to console. + * + * @param A The matrix to print. +*/ +void matrixPrint(Matrix* A); + +/** + * @brief Sums two matrices. + * + * @param left Left term. + * @param right Right term. + * + * @return The sum. +*/ +Matrix* matrixSum(Matrix* left, Matrix* right); + +/** + * @brief Subtracts two matrices. + * + * @param left Left term. + * @param right Right term. + * + * @return The difference. +*/ +Matrix* matrixDiff(Matrix* left, Matrix* right); + +/** + * @brief Scales a matrix by some factor. + * + * @param A The matrix to scale. + * @param num The factor by which the matrix is scaled. + * + * @return The scaled matrix. +*/ +Matrix* matrixScale(Matrix* A, double num); + +/** + * @brief Multiplies a matrix by a vector. + * + * Matrix and vector dimensions must match. The result of such multiplication + * is b = A * vec. + * + * @param A The matrix to multiply. + * @param vec The vector to multiply. + * + * @return A vector containing the product. +*/ +Vector* matrixMultiplyByVector(Matrix* A, Vector* vec); + +/** + * @brief Multiplies two matrices. + * + * @param left The left term. + * @param right The right term. + * + * @return The product of the two matrices' multiplication. +*/ +Matrix* matrixMultiply(Matrix* left, Matrix* right); + +/** + * @brief Creates a normalized orthogonal matrix. + * + * Orthogonal matrix is calculated according to the formula: + * Q = I - 2 * w * w' / (w' * w), where + * I is an identity matrix, + * w is a given vector seed + * + * @param seed The seed vector. + * + * @return A normalized orthogonal matrix. +*/ +Matrix* matrixOrthogonal(Vector* seed); + +/** + * @brief Creates a diagonal matrix from a vector. + * + * @param diag Vector containing the diagonal elements. + * + * @return A diagonal matrix. +*/ +Matrix* matrixDiagonal(Vector* diag); \ No newline at end of file From c1655a30ccee499cbcdb1df41f7fb323fee6b2e8 Mon Sep 17 00:00:00 2001 From: Max Goryunov Date: Wed, 30 Aug 2023 13:25:08 +0300 Subject: [PATCH 2/6] #24 identity --- LinearSystemsToolkit/Matrix.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 LinearSystemsToolkit/Matrix.c diff --git a/LinearSystemsToolkit/Matrix.c b/LinearSystemsToolkit/Matrix.c new file mode 100644 index 0000000..55b24b9 --- /dev/null +++ b/LinearSystemsToolkit/Matrix.c @@ -0,0 +1,34 @@ +#include +#include "Matrix.h" + +Matrix* matrixCreate(int n) { + Matrix* M = malloc(sizeof(Matrix)); + M->n = n; + double** A = malloc(n * sizeof(double*) + n * n * sizeof(double)); + char* p = A; + p += n * sizeof(double*); + for (int i = 0; i < n; i++) { + A[i] = p + i * n * sizeof(double); + } + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + A[i][j] = 0; + } + } + M->data = A; + return M; +} + +void matrixDestroy(Matrix* M) { + free(M->data); + free(M); +} + +Matrix* matrixIdentity(int n) { + Matrix* M = matrixCreate(n); + for (int i = 0; i < n; ++i) { + M->data[i][i] = 1; + } + return M; +} + From f4bd1a06054a4b205247cde5ecfc34de23325a3f Mon Sep 17 00:00:00 2001 From: Max Goryunov Date: Thu, 31 Aug 2023 23:49:45 +0300 Subject: [PATCH 3/6] #24 print, sum, diff, scale --- LinearSystemsToolkit/Matrix.c | 51 +++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/LinearSystemsToolkit/Matrix.c b/LinearSystemsToolkit/Matrix.c index 55b24b9..b769d07 100644 --- a/LinearSystemsToolkit/Matrix.c +++ b/LinearSystemsToolkit/Matrix.c @@ -1,4 +1,5 @@ #include +#include #include "Matrix.h" Matrix* matrixCreate(int n) { @@ -32,3 +33,53 @@ Matrix* matrixIdentity(int n) { return M; } +Matrix* matrixReadFromFile(const char* name, int n) { + FILE* f = fopen(name, "r"); + Matrix* A = matrixCreate(n); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < n; ++j) { + fscanf(f, "%lf", &(A->data[i][j])); + } + } + fclose(f); + return A; +} + +void matrixPrint(Matrix* M) { + for (int i = 0; i < M->n; ++i) { + for (int j = 0; j < M->n; ++j) { + printf("%lf ", M->data[i][j]); + } + printf("\n"); + } +} + +Matrix* matrixSum(Matrix* left, Matrix* right) { + Matrix* S = matrixCreate(left->n); + for (int i = 0; i < left->n; ++i) { + for (int j = 0; j < right->n; ++j) { + S->data[i][j] = left->data[i][j] + right->data[i][j]; + } + } + return S; +} + +Matrix* matrixDiff(Matrix* left, Matrix* right) { + Matrix* D = matrixCreate(left->n); + for (int i = 0; i < left->n; ++i) { + for (int j = 0; j < right->n; ++j) { + D->data[i][j] = left->data[i][j] - right->data[i][j]; + } + } + return D; +} + +Matrix* matrixScale(Matrix* A, double num) { + Matrix* S = matrixCreate(A->n); + for (int i = 0; i < A->n; ++i) { + for (int j = 0; j < A->n; ++j) { + S->data[i][j] = A->data[i][j] * num; + } + } + return S; +} \ No newline at end of file From c61c444d7852c27a8bce53515d7a14e1e78b674b Mon Sep 17 00:00:00 2001 From: Max Goryunov Date: Fri, 1 Sep 2023 16:26:59 +0300 Subject: [PATCH 4/6] #24 test identity, sum --- LinearSystemsToolkit/Matrix.c | 14 +++++++++++ LinearSystemsToolkit/Matrix.h | 12 ++++++++- LinearSystemsToolkit/MatrixTest.c | 41 +++++++++++++++++++++++++++++++ LinearSystemsToolkit/MatrixTest.h | 3 +++ 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 LinearSystemsToolkit/MatrixTest.c create mode 100644 LinearSystemsToolkit/MatrixTest.h diff --git a/LinearSystemsToolkit/Matrix.c b/LinearSystemsToolkit/Matrix.c index b769d07..f41407e 100644 --- a/LinearSystemsToolkit/Matrix.c +++ b/LinearSystemsToolkit/Matrix.c @@ -82,4 +82,18 @@ Matrix* matrixScale(Matrix* A, double num) { } } return S; +} + +int matrixEqual(Matrix* left, Matrix* right) { + if (left->n != right->n) { + return 0; + } + for (int i = 0; i < left->n; ++i) { + for (int j = 0; j < left->n; ++j) { + if (left->data[i][j] != right->data[i][j]) { + return 0; + } + } + } + return 1; } \ No newline at end of file diff --git a/LinearSystemsToolkit/Matrix.h b/LinearSystemsToolkit/Matrix.h index 2858b94..ca9278c 100644 --- a/LinearSystemsToolkit/Matrix.h +++ b/LinearSystemsToolkit/Matrix.h @@ -128,4 +128,14 @@ Matrix* matrixOrthogonal(Vector* seed); * * @return A diagonal matrix. */ -Matrix* matrixDiagonal(Vector* diag); \ No newline at end of file +Matrix* matrixDiagonal(Vector* diag); + +/** + * @brief Checks if two matrices are equal. + * + * @param left The left term. + * @param right The right term. + * + * @return 1 if the two matrices are equal, 0 otherwise. +*/ +int matrixEqual(Matrix* left, Matrix* right); \ No newline at end of file diff --git a/LinearSystemsToolkit/MatrixTest.c b/LinearSystemsToolkit/MatrixTest.c new file mode 100644 index 0000000..a555bc4 --- /dev/null +++ b/LinearSystemsToolkit/MatrixTest.c @@ -0,0 +1,41 @@ +#include +#include "MatrixTest.h" +#include "Matrix.h" + +/** + * matrixIdentity can return an identity matrix. +*/ +void matrixIdentityReturnsIdentityMatrix() { + int size = 3; + Matrix* A = matrixIdentity(size); + for (int i = 0; i < size; ++i) { + assert(1 == A->data[i][i]); + } + matrixDestroy(A); +} + +/** + * matrixSum can return the sum of two matrices. +*/ +void matrixSumSumsTwoMatrices() { + int size = 3; + Matrix* A = matrixCreate(size); + Matrix* B = matrixCreate(size); + Matrix* S = matrixCreate(size); + for (int i = 0; i < size; ++i) { + for (int j = 0; j < size; ++j) { + A->data[i][j] = i; + B->data[i][j] = j; + S->data[i][j] = i + j; + } + } + assert(1 == matrixEqual(matrixSum(A, B), S)); + matrixDestroy(A); + matrixDestroy(B); + matrixDestroy(S); +} + +void matrixAllTests() { + matrixIdentityReturnsIdentityMatrix(); + matrixSumSumsTwoMatrices(); +} \ No newline at end of file diff --git a/LinearSystemsToolkit/MatrixTest.h b/LinearSystemsToolkit/MatrixTest.h new file mode 100644 index 0000000..92a006f --- /dev/null +++ b/LinearSystemsToolkit/MatrixTest.h @@ -0,0 +1,3 @@ +#pragma once + +void matrixAllTests(); \ No newline at end of file From 1e9e35378c2b2bd7deb25d91f009c80153eee7c6 Mon Sep 17 00:00:00 2001 From: Max Goryunov Date: Mon, 4 Sep 2023 08:37:17 +0300 Subject: [PATCH 5/6] #24 test diff, scale --- LinearSystemsToolkit/MatrixTest.c | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/LinearSystemsToolkit/MatrixTest.c b/LinearSystemsToolkit/MatrixTest.c index a555bc4..495fa2e 100644 --- a/LinearSystemsToolkit/MatrixTest.c +++ b/LinearSystemsToolkit/MatrixTest.c @@ -35,6 +35,46 @@ void matrixSumSumsTwoMatrices() { matrixDestroy(S); } +/** + * matrixDiff can compute the difference of two matrices. +*/ +void matrixDiffComputesDifferenceOfTwoMatrices() { + int size = 3; + Matrix* A = matrixCreate(size); + Matrix* B = matrixCreate(size); + Matrix* D = matrixCreate(size); + for (int i = 0; i < size; ++i) { + for (int j = 0; j < size; ++j) { + A->data[i][j] = i + j; + B->data[i][j] = j; + D->data[i][j] = i; + } + } + assert(1 == matrixEqual(matrixDiff(A, B), D)); + matrixDestroy(A); + matrixDestroy(B); + matrixDestroy(D); +} + +/** + * matrixScale can scale a matrix by some factor. +*/ +void matrixScaleScalesMatrixBySomeFactor() { + int size = 3; + double factor = 3; + Matrix* A = matrixCreate(size); + Matrix* S = matrixCreate(size); + for (int i = 0; i < size; ++i) { + for (int j = 0; j < size; ++j) { + A->data[i][j] = i + j; + S->data[i][j] = (i + j) * factor; + } + } + assert(1 == matrixEqual(matrixScale(A, factor), S)); + matrixDestroy(A); + matrixDestroy(S); +} + void matrixAllTests() { matrixIdentityReturnsIdentityMatrix(); matrixSumSumsTwoMatrices(); From aab3b2438c3cfa46ca92a99694dcf9e780f0ff97 Mon Sep 17 00:00:00 2001 From: Max Goryunov Date: Mon, 4 Sep 2023 09:06:27 +0300 Subject: [PATCH 6/6] #24 call tests --- LinearSystemsToolkit/AllTest.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/LinearSystemsToolkit/AllTest.c b/LinearSystemsToolkit/AllTest.c index 6438ed3..7575b16 100644 --- a/LinearSystemsToolkit/AllTest.c +++ b/LinearSystemsToolkit/AllTest.c @@ -1,5 +1,8 @@ #include "VectorTest.h" +#include "MatrixTest.h" int main() { vectorAllTests(); + matrixAllTests(); + return 0; } \ No newline at end of file