From 1cb20e364ce276aa18402b3b774ff5a6fa809afe Mon Sep 17 00:00:00 2001 From: Meysam Azad Date: Fri, 1 Dec 2017 15:18:24 +0330 Subject: [PATCH 1/6] Customized set function --- .gitignore | 1 + src/SparseMatrix/SparseMatrix.cpp | 4 ++-- src/SparseMatrix/SparseMatrix.h | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index b883f1f..05e3f0b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.exe +*.swp diff --git a/src/SparseMatrix/SparseMatrix.cpp b/src/SparseMatrix/SparseMatrix.cpp index 26f7bd3..9cc72e2 100644 --- a/src/SparseMatrix/SparseMatrix.cpp +++ b/src/SparseMatrix/SparseMatrix.cpp @@ -82,7 +82,7 @@ void SparseMatrix::construct(int rows, int columns) this->vals = NULL; this->cols = NULL; - this->rows = new vector(rows + 1, 1); + this->rows = new vector(rows + 1, 1); } @@ -139,7 +139,7 @@ T SparseMatrix::get(int row, int col) const template -SparseMatrix & SparseMatrix::set(T val, int row, int col) +SparseMatrix & SparseMatrix::set(int row, int col, T val) { this->validateCoordinates(row, col); diff --git a/src/SparseMatrix/SparseMatrix.h b/src/SparseMatrix/SparseMatrix.h index bce1769..76c9f61 100644 --- a/src/SparseMatrix/SparseMatrix.h +++ b/src/SparseMatrix/SparseMatrix.h @@ -42,7 +42,7 @@ // === VALUES ============================================== T get(int row, int col) const; - SparseMatrix & set(T val, int row, int col); + SparseMatrix & set(int row, int col, T val); // === OPERATIONS ============================================== From 2b0b52332fdf311963475144ea71ab73492cf9bf Mon Sep 17 00:00:00 2001 From: Petr Kessler Date: Sat, 17 Feb 2018 00:10:00 +0000 Subject: [PATCH 2/6] optimized vector values access - thanks to @sergiosvieira [Closes #14] This replaces calling std::vector::at() with direct operator[] access. It is somehow faster - maybe compiler-related optimization or lack of out-of-range checking when using operator[]. Out-of-range access is prevented thanks to validateCoordinates() method --- src/SparseMatrix/SparseMatrix.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/SparseMatrix/SparseMatrix.cpp b/src/SparseMatrix/SparseMatrix.cpp index 26f7bd3..71aecce 100644 --- a/src/SparseMatrix/SparseMatrix.cpp +++ b/src/SparseMatrix/SparseMatrix.cpp @@ -123,11 +123,11 @@ T SparseMatrix::get(int row, int col) const int currCol; - for (int pos = this->rows->at(row - 1) - 1; pos < this->rows->at(row) - 1; pos++) { - currCol = this->cols->at(pos); + for (int pos = (*(this->rows))[row - 1] - 1; pos < (*(this->rows))[row] - 1; ++pos) { + currCol = (*(this->cols))[pos]; if (currCol == col) { - return this->vals->at(pos); + return (*(this->vals))[pos]; } else if (currCol > col) { break; @@ -143,11 +143,11 @@ SparseMatrix & SparseMatrix::set(T val, int row, int col) { this->validateCoordinates(row, col); - int pos = this->rows->at(row - 1) - 1; + int pos = (*(this->rows))[row - 1] - 1; int currCol = 0; - for (; pos < this->rows->at(row) - 1; pos++) { - currCol = this->cols->at(pos); + for (; pos < (*(this->rows))[row] - 1; pos++) { + currCol = (*(this->cols))[pos]; if (currCol >= col) { break; @@ -163,7 +163,7 @@ SparseMatrix & SparseMatrix::set(T val, int row, int col) this->remove(pos, row); } else { - this->vals->at(pos) = val; + (*(this->vals))[pos] = val; } return *this; @@ -184,8 +184,8 @@ vector SparseMatrix::multiply(const vector & x) const if (this->vals != NULL) { // only if any value set for (int i = 0; i < this->m; i++) { T sum = T(); - for (int j = this->rows->at(i); j < this->rows->at(i + 1); j++) { - sum = sum + this->vals->at(j - 1) * x[this->cols->at(j - 1) - 1]; + for (int j = (*(this->rows))[i]; j < (*(this->rows))[i + 1]; j++) { + sum = sum + (*(this->vals))[j - 1] * x[(*(this->cols))[j - 1] - 1]; } result[i] = sum; @@ -322,7 +322,7 @@ void SparseMatrix::insert(int index, int row, int col, T val) } for (int i = row; i <= this->m; i++) { - this->rows->at(i) = this->rows->at(i) + 1; + (*(this->rows))[i] = (*(this->rows))[i] + 1; } } @@ -334,7 +334,7 @@ void SparseMatrix::remove(int index, int row) this->cols->erase(this->cols->begin() + index); for (int i = row; i <= this->m; i++) { - this->rows->at(i) = this->rows->at(i) - 1; + (*(this->rows))[i] = (*(this->rows))[i] - 1; } } From ae4ef42e23ce5423bce7bcce22c6462cb88ed77d Mon Sep 17 00:00:00 2001 From: Petr Kessler Date: Sun, 18 Feb 2018 00:52:27 +0100 Subject: [PATCH 3/6] tests: better folder structure --- tests/{tests => cases}/addition.h | 4 ++-- tests/{tests => cases}/constructor.h | 4 ++-- tests/{tests => cases}/crs-format.h | 4 ++-- tests/{tests => cases}/custom-type.h | 4 ++-- tests/{tests => cases}/get-set.h | 4 ++-- tests/{tests => cases}/multiplication.h | 4 ++-- tests/{tests => cases}/output.h | 4 ++-- tests/{tests => cases}/subtraction.h | 4 ++-- tests/{ => inc}/SparseMatrixMock.h | 2 +- tests/{ => inc}/testslib.h | 0 tests/run.cpp | 18 +++++++++--------- 11 files changed, 26 insertions(+), 26 deletions(-) rename tests/{tests => cases}/addition.h (96%) rename tests/{tests => cases}/constructor.h (94%) rename tests/{tests => cases}/crs-format.h (98%) rename tests/{tests => cases}/custom-type.h (97%) rename tests/{tests => cases}/get-set.h (93%) rename tests/{tests => cases}/multiplication.h (97%) rename tests/{tests => cases}/output.h (88%) rename tests/{tests => cases}/subtraction.h (97%) rename tests/{ => inc}/SparseMatrixMock.h (98%) rename tests/{ => inc}/testslib.h (100%) diff --git a/tests/tests/addition.h b/tests/cases/addition.h similarity index 96% rename from tests/tests/addition.h rename to tests/cases/addition.h index 07b3c98..c1361d2 100644 --- a/tests/tests/addition.h +++ b/tests/cases/addition.h @@ -6,8 +6,8 @@ * @link https://github.com/uestla/Sparse-Matrix */ -#include "../testslib.h" -#include "../SparseMatrixMock.h" +#include "../inc/testslib.h" +#include "../inc/SparseMatrixMock.h" void _additionFail1(void) diff --git a/tests/tests/constructor.h b/tests/cases/constructor.h similarity index 94% rename from tests/tests/constructor.h rename to tests/cases/constructor.h index 815c609..687be14 100644 --- a/tests/tests/constructor.h +++ b/tests/cases/constructor.h @@ -6,8 +6,8 @@ * @link https://github.com/uestla/Sparse-Matrix */ -#include "../testslib.h" -#include "../SparseMatrixMock.h" +#include "../inc/testslib.h" +#include "../inc/SparseMatrixMock.h" void _constructorFail1(void) diff --git a/tests/tests/crs-format.h b/tests/cases/crs-format.h similarity index 98% rename from tests/tests/crs-format.h rename to tests/cases/crs-format.h index 17cdcb7..ea9a8b9 100644 --- a/tests/tests/crs-format.h +++ b/tests/cases/crs-format.h @@ -6,8 +6,8 @@ * @link https://github.com/uestla/Sparse-Matrix */ -#include "../testslib.h" -#include "../SparseMatrixMock.h" +#include "../inc/testslib.h" +#include "../inc/SparseMatrixMock.h" void testInternalStorage(void) diff --git a/tests/tests/custom-type.h b/tests/cases/custom-type.h similarity index 97% rename from tests/tests/custom-type.h rename to tests/cases/custom-type.h index 6f5eae8..f37060b 100644 --- a/tests/tests/custom-type.h +++ b/tests/cases/custom-type.h @@ -8,8 +8,8 @@ #include #include -#include "../testslib.h" -#include "../SparseMatrixMock.h" +#include "../inc/testslib.h" +#include "../inc/SparseMatrixMock.h" using namespace std; diff --git a/tests/tests/get-set.h b/tests/cases/get-set.h similarity index 93% rename from tests/tests/get-set.h rename to tests/cases/get-set.h index 3e04ebc..653bde6 100644 --- a/tests/tests/get-set.h +++ b/tests/cases/get-set.h @@ -6,8 +6,8 @@ * @link https://github.com/uestla/Sparse-Matrix */ -#include "../testslib.h" -#include "../SparseMatrixMock.h" +#include "../inc/testslib.h" +#include "../inc/SparseMatrixMock.h" void _getFail(void) diff --git a/tests/tests/multiplication.h b/tests/cases/multiplication.h similarity index 97% rename from tests/tests/multiplication.h rename to tests/cases/multiplication.h index 45f9510..7527c7c 100644 --- a/tests/tests/multiplication.h +++ b/tests/cases/multiplication.h @@ -6,8 +6,8 @@ * @link https://github.com/uestla/Sparse-Matrix */ -#include "../testslib.h" -#include "../SparseMatrixMock.h" +#include "../inc/testslib.h" +#include "../inc/SparseMatrixMock.h" void _multiplicationFail1(void) diff --git a/tests/tests/output.h b/tests/cases/output.h similarity index 88% rename from tests/tests/output.h rename to tests/cases/output.h index c941436..747abbe 100644 --- a/tests/tests/output.h +++ b/tests/cases/output.h @@ -6,8 +6,8 @@ * @link https://github.com/uestla/Sparse-Matrix */ -#include "../testslib.h" -#include "../SparseMatrixMock.h" +#include "../inc/testslib.h" +#include "../inc/SparseMatrixMock.h" void testOutput(void) diff --git a/tests/tests/subtraction.h b/tests/cases/subtraction.h similarity index 97% rename from tests/tests/subtraction.h rename to tests/cases/subtraction.h index e4adf3e..f789690 100644 --- a/tests/tests/subtraction.h +++ b/tests/cases/subtraction.h @@ -6,8 +6,8 @@ * @link https://github.com/uestla/Sparse-Matrix */ -#include "../testslib.h" -#include "../SparseMatrixMock.h" +#include "../inc/testslib.h" +#include "../inc/SparseMatrixMock.h" void _subtractionFail1(void) diff --git a/tests/SparseMatrixMock.h b/tests/inc/SparseMatrixMock.h similarity index 98% rename from tests/SparseMatrixMock.h rename to tests/inc/SparseMatrixMock.h index 2db7a5c..d7bbe11 100644 --- a/tests/SparseMatrixMock.h +++ b/tests/inc/SparseMatrixMock.h @@ -11,7 +11,7 @@ #define __SPARSEMATRIX_MOCK_H__ #include - #include "../src/SparseMatrix/SparseMatrix.h" + #include "../../src/SparseMatrix/SparseMatrix.h" using namespace std; diff --git a/tests/testslib.h b/tests/inc/testslib.h similarity index 100% rename from tests/testslib.h rename to tests/inc/testslib.h diff --git a/tests/run.cpp b/tests/run.cpp index 979ec68..aad44c6 100644 --- a/tests/run.cpp +++ b/tests/run.cpp @@ -9,17 +9,17 @@ #include #include #include -#include "testslib.h" +#include "inc/testslib.h" #include "../src/SparseMatrix/SparseMatrix.cpp" -#include "tests/constructor.h" -#include "tests/get-set.h" -#include "tests/multiplication.h" -#include "tests/addition.h" -#include "tests/subtraction.h" -#include "tests/crs-format.h" -#include "tests/output.h" -#include "tests/custom-type.h" +#include "cases/constructor.h" +#include "cases/get-set.h" +#include "cases/multiplication.h" +#include "cases/addition.h" +#include "cases/subtraction.h" +#include "cases/crs-format.h" +#include "cases/output.h" +#include "cases/custom-type.h" using namespace std; From 49dfeafbf985fd7656d074bf5566c96c33345eb8 Mon Sep 17 00:00:00 2001 From: Petr Kessler Date: Sun, 18 Feb 2018 00:54:35 +0100 Subject: [PATCH 4/6] tests: separated helper functions into standalone file --- tests/inc/helpers.h | 69 ++++++++++++++++++++++++++++++++++++++++++++ tests/inc/testslib.h | 49 ------------------------------- tests/run.cpp | 1 + 3 files changed, 70 insertions(+), 49 deletions(-) create mode 100644 tests/inc/helpers.h diff --git a/tests/inc/helpers.h b/tests/inc/helpers.h new file mode 100644 index 0000000..b6af690 --- /dev/null +++ b/tests/inc/helpers.h @@ -0,0 +1,69 @@ +/** + * This file is part of the SparseMatrix library + * + * @license MIT + * @author Petr Kessler (https://kesspess.cz) + * @link https://github.com/uestla/Sparse-Matrix + */ + +#ifndef __HELPERS_H__ + + #define __HELPERS_H__ + + #include + #include + + using namespace std; + + + // === GENERATORS ========================================= + + template + vector generateRandomVector(int size) + { + vector vector(size, 0); + + for (int i = 0; i < size; i++) { + vector[i] = rand() % 101; + } + + return vector; + } + + + template + vector > generateRandomMatrix(int rows, int columns) + { + vector > matrix(rows, vector(columns, 0)); + + for (int i = 0; i < rows; i++) { + for (int j = 0; j < columns; j++) { + matrix[i][j] = rand() % 101; + } + } + + return matrix; + } + + + // === OUTPUT HELPERS ========================================= + + template + ostream & operator << (ostream & os, const vector & v) + { + os << "["; + + for (int i = 0, len = v.size(); i < len; i++) { + if (i != 0) { + os << ", "; + } + + os << v[i]; + } + + os << "]"; + + return os; + } + +#endif diff --git a/tests/inc/testslib.h b/tests/inc/testslib.h index d3bbd6e..4579571 100644 --- a/tests/inc/testslib.h +++ b/tests/inc/testslib.h @@ -104,53 +104,4 @@ } } - - template - vector generateRandomVector(int size) - { - vector vector(size, 0); - - for (int i = 0; i < size; i++) { - vector[i] = rand() % 101; - } - - return vector; - } - - - template - vector > generateRandomMatrix(int rows, int columns) - { - vector > matrix(rows, vector(columns, 0)); - - for (int i = 0; i < rows; i++) { - for (int j = 0; j < columns; j++) { - matrix[i][j] = rand() % 101; - } - } - - return matrix; - } - - - // === OUTPUT HELPERS ========================================= - - template - ostream & operator << (ostream & os, const vector & v) - { - os << "["; - - for (int i = 0, len = v.size(); i < len; i++) { - if (i != 0) { - os << ", "; - } - - os << v[i]; - } - - os << "]"; - - return os; - } - #endif diff --git a/tests/run.cpp b/tests/run.cpp index aad44c6..30a275c 100644 --- a/tests/run.cpp +++ b/tests/run.cpp @@ -10,6 +10,7 @@ #include #include #include "inc/testslib.h" +#include "inc/helpers.h" #include "../src/SparseMatrix/SparseMatrix.cpp" #include "cases/constructor.h" From 6de7bfc46f4ff035c5b9b3da0734d4b35e5c3e85 Mon Sep 17 00:00:00 2001 From: Petr Kessler Date: Sun, 18 Feb 2018 01:36:11 +0100 Subject: [PATCH 5/6] tests: moved standard operations into functions --- tests/cases/addition.h | 8 +---- tests/cases/multiplication.h | 20 ++---------- tests/inc/helpers.h | 61 ++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 25 deletions(-) diff --git a/tests/cases/addition.h b/tests/cases/addition.h index c1361d2..9573b09 100644 --- a/tests/cases/addition.h +++ b/tests/cases/addition.h @@ -71,13 +71,7 @@ void testAddition(void) SparseMatrixMock sparseMatrixB = SparseMatrixMock::fromVectors(classicMatrixB); // calculate result manually - vector > manualResult(rows, vector(cols, 0)); - - for (int i = 0; i < rows; i++) { - for (int j = 0; j < cols; j++) { - manualResult[i][j] += classicMatrixA[i][j] + classicMatrixB[i][j]; - } - } + vector > manualResult = addMatrices(classicMatrixA, classicMatrixB); // method assertEquals, vector > >( diff --git a/tests/cases/multiplication.h b/tests/cases/multiplication.h index 7527c7c..fdcfce1 100644 --- a/tests/cases/multiplication.h +++ b/tests/cases/multiplication.h @@ -56,13 +56,7 @@ void testVectorMultiplication(void) SparseMatrixMock sparseMatrix = SparseMatrixMock::fromVectors(classicMatrix); // calculate result manually - vector manualResult(rows, 0); - - for (int i = 0; i < rows; i++) { - for (int j = 0; j < cols; j++) { - manualResult[i] += classicMatrix[i][j] * vec[j]; - } - } + vector manualResult = multiplyMatrixByVector(classicMatrix, vec); // method assertEquals >(manualResult, sparseMatrix.multiply(vec), "Incorrect vector multiplication"); @@ -92,17 +86,7 @@ void testMatricesMultiplication(void) SparseMatrixMock sparseMatrixB = SparseMatrixMock::fromVectors(classicMatrixB); // calculate result manually - vector > manualResult(rowsA, vector(colsB, 0)); - - for (int i = 0; i < rowsA; i++) { - for (int j = 0; j < colsB; j++) { - manualResult[i][j] = 0; - - for (int k = 0; k < colsArowsB; k++) { // rows in B - manualResult[i][j] += classicMatrixA[i][k] * classicMatrixB[k][j]; - } - } - } + vector > manualResult = multiplyMatrices(classicMatrixA, classicMatrixB); // method assertEquals, vector > >( diff --git a/tests/inc/helpers.h b/tests/inc/helpers.h index b6af690..830f0b1 100644 --- a/tests/inc/helpers.h +++ b/tests/inc/helpers.h @@ -46,6 +46,67 @@ } + // === STANDARD OPERATIONS ========================================= + + template + vector > addMatrices(const vector > & a, const vector > & b) + { + int rows = a.size(); + int cols = a.front().size(); + + vector > result(rows, vector(cols, 0)); + + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + result[i][j] = a[i][j] + b[i][j]; + } + } + + return result; + } + + + template + vector multiplyMatrixByVector(const vector > & m, const vector & v) + { + int rows = m.size(); + int cols = v.size(); + + vector result(rows, 0); + + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + result[i] += m[i][j] * v[j]; + } + } + + return result; + } + + + template + vector > multiplyMatrices(const vector > & a, const vector > & b) + { + int rowsA = a.size(); + int colsA = a.front().size(); + int colsB = b.front().size(); + + vector > result(rowsA, vector(colsB, 0)); + + for (int i = 0; i < rowsA; i++) { + for (int j = 0; j < colsB; j++) { + result[i][j] = 0; + + for (int k = 0; k < colsA; k++) { + result[i][j] += a[i][k] * b[k][j]; + } + } + } + + return result; + } + + // === OUTPUT HELPERS ========================================= template From 93ea63188d6d0c34c615534e640a0e3348315157 Mon Sep 17 00:00:00 2001 From: Meysam Azad Date: Wed, 21 Feb 2018 15:29:40 +0330 Subject: [PATCH 6/6] commit in branch devel0 --- .gitignore | 2 +- src/SparseMatrix/SparseMatrix.cpp | 403 ++++++++++++++++++------------ src/SparseMatrix/SparseMatrix.h | 106 ++++---- src/SparseMatrix/exceptions.h | 60 ++--- 4 files changed, 334 insertions(+), 237 deletions(-) diff --git a/.gitignore b/.gitignore index 05e3f0b..31decfc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -*.exe *.swp +*.exe diff --git a/src/SparseMatrix/SparseMatrix.cpp b/src/SparseMatrix/SparseMatrix.cpp index 9cc72e2..fb456e6 100644 --- a/src/SparseMatrix/SparseMatrix.cpp +++ b/src/SparseMatrix/SparseMatrix.cpp @@ -19,69 +19,69 @@ using namespace std; template SparseMatrix::SparseMatrix(int n) { - this->construct(n, n); + this->construct(n, n); } template SparseMatrix::SparseMatrix(int rows, int columns) { - this->construct(rows, columns); + this->construct(rows, columns); } template SparseMatrix::SparseMatrix(const SparseMatrix & matrix) { - this->deepCopy(matrix); + this->deepCopy(matrix); } template SparseMatrix & SparseMatrix::operator = (const SparseMatrix & matrix) { - if (&matrix != this) { - this->destruct(); - this->deepCopy(matrix); - } + if (&matrix != this) { + this->destruct(); + this->deepCopy(matrix); + } - return *this; + return *this; } template void SparseMatrix::deepCopy(const SparseMatrix & matrix) { - this->m = matrix.m; - this->n = matrix.n; - this->rows = new vector(*(matrix.rows)); - - if (matrix.vals != NULL) { - this->cols = new vector(*(matrix.cols)); - this->vals = new vector(*(matrix.vals)); - } + this->m = matrix.m; + this->n = matrix.n; + this->rows = new vector(*(matrix.rows)); + + if (matrix.vals != NULL) { + this->cols = new vector(*(matrix.cols)); + this->vals = new vector(*(matrix.vals)); + } } template SparseMatrix::~SparseMatrix(void) { - this->destruct(); + this->destruct(); } template void SparseMatrix::construct(int rows, int columns) { - if (rows < 1 || columns < 1) { - throw InvalidDimensionsException("Matrix dimensions cannot be zero or negative."); - } + if (rows < 1 || columns < 1) { + throw InvalidDimensionsException("Matrix dimensions cannot be zero or negative."); + } - this->m = rows; - this->n = columns; + this->m = rows; + this->n = columns; - this->vals = NULL; - this->cols = NULL; + this->vals = NULL; + this->cols = NULL; this->rows = new vector(rows + 1, 1); } @@ -89,12 +89,12 @@ void SparseMatrix::construct(int rows, int columns) template void SparseMatrix::destruct(void) { - if (this->vals != NULL) { - delete this->vals; - delete this->cols; - } + if (this->vals != NULL) { + delete this->vals; + delete this->cols; + } - delete this->rows; + delete this->rows; } @@ -103,14 +103,14 @@ void SparseMatrix::destruct(void) template int SparseMatrix::getRowCount(void) const { - return this->m; + return this->m; } template int SparseMatrix::getColumnCount(void) const { - return this->n; + return this->n; } @@ -119,54 +119,131 @@ int SparseMatrix::getColumnCount(void) const template T SparseMatrix::get(int row, int col) const { - this->validateCoordinates(row, col); + this->validateCoordinates(row, col); - int currCol; + int currCol; - for (int pos = this->rows->at(row - 1) - 1; pos < this->rows->at(row) - 1; pos++) { - currCol = this->cols->at(pos); + for (int pos = this->rows->at(row - 1) - 1; pos < this->rows->at(row) - 1; pos++) + { + currCol = this->cols->at(pos); - if (currCol == col) { - return this->vals->at(pos); + if (currCol == col) { + return this->vals->at(pos); - } else if (currCol > col) { - break; - } - } + } else if (currCol > col) { + break; + } + } - return T(); + return T(); } +template +bool SparseMatrix::removeAnyEdge(int row, int& col) +{ + for (col = 1; col <= this->n; ++col) + { + this->validateCoordinates(row, col); + + int pos = this->rows->at(row - 1) - 1; + int currCol = 0; + + for (; pos < this->rows->at(row) - 1; pos++) + { + currCol = this->cols->at(pos); + if (currCol >= col) + break; + } + + if (currCol == col) + { + this->remove(pos, row); + + return true; + } + } + return false; +} +template +bool SparseMatrix::removeEdge(int row, int col) +{ + this->validateCoordinates(row, col); + + int currCol; + + for (int pos = this->rows->at(row - 1) - 1; pos < this->rows->at(row) - 1; pos++) + { + currCol = this->cols->at(pos); + + if (currCol == col) + { + remove(pos, row); + return true; + } + else if (currCol > col) + { + break; + } + } + + return false; +} + +template +vector SparseMatrix::getNeighbors(int row) +{ + vector neighbors; + for (int col = 1; col <= this->n; ++col) + + { + this->validateCoordinates(row, col); + + int currCol; + + + for (int pos = this->rows->at(row - 1) - 1; pos < this->rows->at(row) - 1; pos++) + { + currCol = this->cols->at(pos); + + if (currCol == col) + neighbors.push_back(this->vals->at(pos)); + else if (currCol > col) + break; + } + } + + return neighbors; +} template SparseMatrix & SparseMatrix::set(int row, int col, T val) { - this->validateCoordinates(row, col); + this->validateCoordinates(row, col); - int pos = this->rows->at(row - 1) - 1; - int currCol = 0; + int pos = this->rows->at(row - 1) - 1; + int currCol = 0; - for (; pos < this->rows->at(row) - 1; pos++) { - currCol = this->cols->at(pos); + for (; pos < this->rows->at(row) - 1; pos++) { + currCol = this->cols->at(pos); - if (currCol >= col) { - break; - } - } + if (currCol >= col) { + break; + } + } - if (currCol != col) { - if (!(val == T())) { - this->insert(pos, row, col, val); - } + if (currCol != col) { + if (!(val == T())) { + this->insert(pos, row, col, val); + } - } else if (val == T()) { - this->remove(pos, row); + } else if (val == T()) { + this->remove(pos, row); - } else { - this->vals->at(pos) = val; - } + } else { + this->vals->at(pos) = val; + } - return *this; + return *this; } @@ -175,167 +252,177 @@ SparseMatrix & SparseMatrix::set(int row, int col, T val) template vector SparseMatrix::multiply(const vector & x) const { - if (this->n != (int) x.size()) { - throw InvalidDimensionsException("Cannot multiply: Matrix column count and vector size don't match."); - } + if (this->n != (int) x.size()) { + throw InvalidDimensionsException("Cannot multiply: Matrix column count and vector size don't match."); + } - vector result(this->m, T()); + vector result(this->m, T()); - if (this->vals != NULL) { // only if any value set - for (int i = 0; i < this->m; i++) { - T sum = T(); - for (int j = this->rows->at(i); j < this->rows->at(i + 1); j++) { - sum = sum + this->vals->at(j - 1) * x[this->cols->at(j - 1) - 1]; - } + if (this->vals != NULL) { // only if any value set + for (int i = 0; i < this->m; i++) { + T sum = T(); + for (int j = this->rows->at(i); j < this->rows->at(i + 1); j++) { + sum = sum + this->vals->at(j - 1) * x[this->cols->at(j - 1) - 1]; + } - result[i] = sum; - } - } + result[i] = sum; + } + } - return result; + return result; } template vector SparseMatrix::operator * (const vector & x) const { - return this->multiply(x); + return this->multiply(x); } template SparseMatrix SparseMatrix::multiply(const SparseMatrix & m) const { - if (this->n != m.m) { - throw InvalidDimensionsException("Cannot multiply: Left matrix column count and right matrix row count don't match."); - } + if (this->n != m.m) { + throw InvalidDimensionsException("Cannot multiply: Left matrix column count and right matrix row count don't match."); + } - SparseMatrix result(this->m, m.n); + SparseMatrix result(this->m, m.n); - T a; + T a; - // TODO: more efficient? - // @see http://www.math.tamu.edu/~srobertp/Courses/Math639_2014_Sp/CRSDescription/CRSStuff.pdf + // TODO: more efficient? + // @see http://www.math.tamu.edu/~srobertp/Courses/Math639_2014_Sp/CRSDescription/CRSStuff.pdf - for (int i = 1; i <= this->m; i++) { - for (int j = 1; j <= m.n; j++) { - a = T(); + for (int i = 1; i <= this->m; i++) { + for (int j = 1; j <= m.n; j++) { + a = T(); - for (int k = 1; k <= this->n; k++) { - a = a + this->get(i, k) * m.get(k, j); - } + for (int k = 1; k <= this->n; k++) { + a = a + this->get(i, k) * m.get(k, j); + } - result.set(a, i, j); - } - } + result.set(a, i, j); + } + } - return result; + return result; } template SparseMatrix SparseMatrix::operator * (const SparseMatrix & m) const { - return this->multiply(m); + return this->multiply(m); } template SparseMatrix SparseMatrix::add(const SparseMatrix & m) const { - if (this->m != m.m || this->n != m.n) { - throw InvalidDimensionsException("Cannot add: matrices dimensions don't match."); - } + if (this->m != m.m || this->n != m.n) { + throw InvalidDimensionsException("Cannot add: matrices dimensions don't match."); + } - SparseMatrix result(this->m, this->n); + SparseMatrix result(this->m, this->n); - // TODO: more efficient? - // @see http://www.math.tamu.edu/~srobertp/Courses/Math639_2014_Sp/CRSDescription/CRSStuff.pdf + // TODO: more efficient? + // @see http://www.math.tamu.edu/~srobertp/Courses/Math639_2014_Sp/CRSDescription/CRSStuff.pdf - for (int i = 1; i <= this->m; i++) { - for (int j = 1; j <= this->n; j++) { - result.set(this->get(i, j) + m.get(i, j), i, j); - } - } + for (int i = 1; i <= this->m; i++) { + for (int j = 1; j <= this->n; j++) { + result.set(this->get(i, j) + m.get(i, j), i, j); + } + } - return result; + return result; } template SparseMatrix SparseMatrix::operator + (const SparseMatrix & m) const { - return this->add(m); + return this->add(m); } template SparseMatrix SparseMatrix::subtract(const SparseMatrix & m) const { - if (this->m != m.m || this->n != m.n) { - throw InvalidDimensionsException("Cannot subtract: matrices dimensions don't match."); - } + if (this->m != m.m || this->n != m.n) { + throw InvalidDimensionsException("Cannot subtract: matrices dimensions don't match."); + } - SparseMatrix result(this->m, this->n); + SparseMatrix result(this->m, this->n); - // TODO: more efficient? - // @see http://www.math.tamu.edu/~srobertp/Courses/Math639_2014_Sp/CRSDescription/CRSStuff.pdf + // TODO: more efficient? + // @see http://www.math.tamu.edu/~srobertp/Courses/Math639_2014_Sp/CRSDescription/CRSStuff.pdf - for (int i = 1; i <= this->m; i++) { - for (int j = 1; j <= this->n; j++) { - result.set(this->get(i, j) - m.get(i, j), i, j); - } - } + for (int i = 1; i <= this->m; i++) { + for (int j = 1; j <= this->n; j++) { + result.set(this->get(i, j) - m.get(i, j), i, j); + } + } - return result; + return result; } template SparseMatrix SparseMatrix::operator - (const SparseMatrix & m) const { - return this->subtract(m); + return this->subtract(m); } +template +int SparseMatrix::numberOfRowElement(int row) const +{ + validateCoordinates(row, 1); + return this->rows->at(row) - this->rows->at(row - 1); + +} + + + // === HELPERS / VALIDATORS ============================================== template void SparseMatrix::validateCoordinates(int row, int col) const { - if (row < 1 || col < 1 || row > this->m || col > this->n) { - throw InvalidCoordinatesException("Coordinates out of range."); - } + if (row < 1 || col < 1 || row > this->m || col > this->n) { + throw InvalidCoordinatesException("Coordinates out of range."); + } } template void SparseMatrix::insert(int index, int row, int col, T val) { - if (this->vals == NULL) { - this->vals = new vector(1, val); - this->cols = new vector(1, col); - - } else { - this->vals->insert(this->vals->begin() + index, val); - this->cols->insert(this->cols->begin() + index, col); - } - - for (int i = row; i <= this->m; i++) { - this->rows->at(i) = this->rows->at(i) + 1; - } + if (this->vals == NULL) { + this->vals = new vector(1, val); + this->cols = new vector(1, col); + + } else { + this->vals->insert(this->vals->begin() + index, val); + this->cols->insert(this->cols->begin() + index, col); + } + + for (int i = row; i <= this->m; i++) { + this->rows->at(i) = this->rows->at(i) + 1; + } } template void SparseMatrix::remove(int index, int row) { - this->vals->erase(this->vals->begin() + index); - this->cols->erase(this->cols->begin() + index); + this->vals->erase(this->vals->begin() + index); + this->cols->erase(this->cols->begin() + index); - for (int i = row; i <= this->m; i++) { - this->rows->at(i) = this->rows->at(i) - 1; - } + for (int i = row; i <= this->m; i++) { + this->rows->at(i) = this->rows->at(i) - 1; + } } @@ -344,37 +431,37 @@ void SparseMatrix::remove(int index, int row) template bool operator == (const SparseMatrix & a, const SparseMatrix & b) { - return ((a.vals == NULL && b.vals == NULL) - || (a.vals != NULL && b.vals != NULL && *(a.vals) == *(b.vals))) - && ((a.cols == NULL && b.cols == NULL) - || (a.cols != NULL && b.cols != NULL && *(a.cols) == *(b.cols))) - && *(a.rows) == *(b.rows); + return ((a.vals == NULL && b.vals == NULL) + || (a.vals != NULL && b.vals != NULL && *(a.vals) == *(b.vals))) + && ((a.cols == NULL && b.cols == NULL) + || (a.cols != NULL && b.cols != NULL && *(a.cols) == *(b.cols))) + && *(a.rows) == *(b.rows); } template bool operator != (const SparseMatrix & a, const SparseMatrix & b) { - return !(a == b); + return !(a == b); } template ostream & operator << (ostream & os, const SparseMatrix & matrix) { - for (int i = 1; i <= matrix.m; i++) { - for (int j = 1; j <= matrix.n; j++) { - if (j != 1) { - os << " "; - } + for (int i = 1; i <= matrix.m; i++) { + for (int j = 1; j <= matrix.n; j++) { + if (j != 1) { + os << " "; + } - os << matrix.get(i, j); - } + os << matrix.get(i, j); + } - if (i < matrix.m) { - os << endl; - } - } + if (i < matrix.m) { + os << endl; + } + } - return os; + return os; } diff --git a/src/SparseMatrix/SparseMatrix.h b/src/SparseMatrix/SparseMatrix.h index 76c9f61..6e06233 100644 --- a/src/SparseMatrix/SparseMatrix.h +++ b/src/SparseMatrix/SparseMatrix.h @@ -8,87 +8,97 @@ #ifndef __SPARSEMATRIX_H__ - #define __SPARSEMATRIX_H__ +#define __SPARSEMATRIX_H__ - #include - #include +#include +#include - using namespace std; +using namespace std; - template - class SparseMatrix - { +template +class SparseMatrix +{ - public: +public: - // === CREATION ============================================== + // === CREATION ============================================== - SparseMatrix(int n); // square matrix n×n - SparseMatrix(int rows, int columns); // general matrix + SparseMatrix(int n); // square matrix n×n + SparseMatrix(int rows, int columns); // general matrix - SparseMatrix(const SparseMatrix & m); // copy constructor - SparseMatrix & operator = (const SparseMatrix & m); + SparseMatrix(const SparseMatrix & m); // copy constructor + SparseMatrix & operator = (const SparseMatrix & m); - ~SparseMatrix(void); + ~SparseMatrix(void); - // === GETTERS / SETTERS ============================================== + // === GETTERS / SETTERS ============================================== - int getRowCount(void) const; - int getColumnCount(void) const; + int getRowCount(void) const; + int getColumnCount(void) const; - // === VALUES ============================================== + // === VALUES ============================================== - T get(int row, int col) const; - SparseMatrix & set(int row, int col, T val); + T get(int row, int col) const; + SparseMatrix & set(int row, int col, T val); - // === OPERATIONS ============================================== + // === OPERATIONS ============================================== - vector multiply(const vector & x) const; - vector operator * (const vector & x) const; + vector multiply(const vector & x) const; + vector operator * (const vector & x) const; - SparseMatrix multiply(const SparseMatrix & m) const; - SparseMatrix operator * (const SparseMatrix & m) const; + SparseMatrix multiply(const SparseMatrix & m) const; + SparseMatrix operator * (const SparseMatrix & m) const; - SparseMatrix add(const SparseMatrix & m) const; - SparseMatrix operator + (const SparseMatrix & m) const; + SparseMatrix add(const SparseMatrix & m) const; + SparseMatrix operator + (const SparseMatrix & m) const; - SparseMatrix subtract(const SparseMatrix & m) const; - SparseMatrix operator - (const SparseMatrix & m) const; + SparseMatrix subtract(const SparseMatrix & m) const; + SparseMatrix operator - (const SparseMatrix & m) const; - // === FRIEND FUNCTIONS ========================================= + // === FRIEND FUNCTIONS ========================================= - template - friend bool operator == (const SparseMatrix & a, const SparseMatrix & b); + template + friend bool operator == (const SparseMatrix & a, const SparseMatrix & b); - template - friend bool operator != (const SparseMatrix & a, const SparseMatrix & b); + template + friend bool operator != (const SparseMatrix & a, const SparseMatrix & b); - template - friend ostream & operator << (ostream & os, const SparseMatrix & matrix); + template + friend ostream & operator << (ostream & os, const SparseMatrix & matrix); + // === Number of row elements ========================================= - protected: + int numberOfRowElement(int row) const; - int m, n; - vector * vals; - vector * rows, * cols; + bool removeAnyEdge(int row, int& col); + bool removeEdge(int row, int col); - // === HELPERS / VALIDATORS ============================================== + vector getNeighbors(int row); +private: - void construct(int m, int n); - void destruct(void); - void deepCopy(const SparseMatrix & m); - void validateCoordinates(int row, int col) const; - void insert(int index, int row, int col, T val); - void remove(int index, int row); + int m, n; - }; + vector * vals; + vector * rows, * cols; + + + // === HELPERS / VALIDATORS ============================================== + + void construct(int m, int n); + void destruct(void); + void deepCopy(const SparseMatrix & m); + void validateCoordinates(int row, int col) const; + void insert(int index, int row, int col, T val); + void remove(int index, int row); + + +}; #endif diff --git a/src/SparseMatrix/exceptions.h b/src/SparseMatrix/exceptions.h index c05663a..378ed46 100644 --- a/src/SparseMatrix/exceptions.h +++ b/src/SparseMatrix/exceptions.h @@ -8,58 +8,58 @@ #ifndef __SPARSEMATRIX_EXCEPTIONS_H__ - #define __SPARSEMATRIX_EXCEPTIONS_H__ +#define __SPARSEMATRIX_EXCEPTIONS_H__ - #include +#include - using namespace std; +using namespace std; - class Exception : public exception - { +class Exception : public exception +{ - public: +public: - explicit Exception(const string & message) : exception(), message(message) - {} + explicit Exception(const string & message) : exception(), message(message) + {} - virtual ~Exception(void) throw () - {} + virtual ~Exception(void) throw () + {} - inline string getMessage(void) const - { - return this->message; - } + inline string getMessage(void) const + { + return this->message; + } - protected: +protected: - string message; + string message; - }; +}; - class InvalidDimensionsException : public Exception - { +class InvalidDimensionsException : public Exception +{ - public: +public: - InvalidDimensionsException(const string & message) : Exception(message) - {} + InvalidDimensionsException(const string & message) : Exception(message) + {} - }; +}; - class InvalidCoordinatesException : public Exception - { +class InvalidCoordinatesException : public Exception +{ - public: +public: - InvalidCoordinatesException(const string & message) : Exception(message) - {} + InvalidCoordinatesException(const string & message) : Exception(message) + {} - }; +}; -#endif \ No newline at end of file +#endif