Skip to content

Commit 2a358ec

Browse files
committed
Added Sparse Matrix multiplication implementation (TheAlgorithms#2903)
1 parent 77b9f39 commit 2a358ec

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/**
2+
* @file
3+
* @brief Implementation of Sparse Matrix Compression (Row-Major and
4+
* Column-Major) with efficient retrieval and decompression.
5+
*
6+
* @details
7+
* This program provides:
8+
* - Compression: Stores only non-zero elements in both row-major and
9+
* column-major formats.
10+
* - Retrieval: Allows efficient retrieval of original matrix values.
11+
* - Decompression: Reconstructs the original matrix from compressed data.
12+
*
13+
* @author: [vrtarimala](https://github.com/vrtarimala)
14+
*/
15+
16+
#include <cassert>
17+
#include <iostream>
18+
#include <map>
19+
#include <vector>
20+
21+
using namespace std;
22+
23+
class SparseMatrix {
24+
private:
25+
int rows; ///< Number of rows in the original matrix.
26+
int cols; ///< Number of columns in the original matrix.
27+
28+
// Map to store non-zero elements as key-value pairs
29+
// Key: (row, col) pair; Value: non-zero element
30+
map<pair<int, int>, int> data;
31+
32+
public:
33+
SparseMatrix(int r, int c) : rows(r), cols(c) {}
34+
35+
/**
36+
* @brief Compresses a given sparse matrix in row-major order.
37+
* @param matrix 2D vector representing the sparse matrix.
38+
*/
39+
void compressRowMajor(const vector<vector<int> > &matrix) {
40+
data.clear();
41+
for (int i = 0; i < rows; i++) {
42+
for (int j = 0; j < cols; j++) {
43+
if (matrix[i][j] != 0) {
44+
data[{i, j}] = matrix[i][j];
45+
}
46+
}
47+
}
48+
}
49+
50+
/**
51+
* @brief Compresses a given sparse matrix in column-major order.
52+
* @param matrix 2D vector representing the sparse matrix.
53+
*/
54+
void compressColumnMajor(const vector<vector<int> > &matrix) {
55+
data.clear();
56+
for (int j = 0; j < cols; j++) {
57+
for (int i = 0; i < rows; i++) {
58+
if (matrix[i][j] != 0) {
59+
data[{i, j}] = matrix[i][j];
60+
}
61+
}
62+
}
63+
}
64+
65+
/**
66+
* @brief Decompresses the sparse matrix to its original form.
67+
* @return 2D vector representing the original matrix.
68+
*/
69+
vector<vector<int> > decompress() const {
70+
vector<vector<int> > matrix(rows, vector<int>(cols, 0));
71+
for (const auto &[key, value] : data) {
72+
matrix[key.first][key.second] = value;
73+
}
74+
return matrix;
75+
}
76+
77+
/**
78+
* @brief Retrieves the value at a given row and column.
79+
* @param row Row index of the element.
80+
* @param col Column index of the element.
81+
* @return Value at the specified position (0 if not present).
82+
*/
83+
int getValue(int row, int col) const {
84+
auto it = data.find({row, col});
85+
if (it != data.end()) {
86+
return it->second;
87+
}
88+
return 0; // Default to 0 if the value is not stored.
89+
}
90+
91+
/**
92+
* @brief Prints the compressed representation of the matrix.
93+
*/
94+
void printCompressed() const {
95+
cout << "Compressed Representation:\n";
96+
for (const auto &[key, value] : data) {
97+
cout << "(" << key.first << ", " << key.second << ", " << value
98+
<< ")\n";
99+
}
100+
}
101+
};
102+
103+
void runTests() {
104+
cout << "\nTest Case 1: Basic Row-Major Compression\n";
105+
vector<vector<int> > matrix1 = {{5, 0, 0}, {0, 8, 0}, {0, 0, 3}};
106+
107+
SparseMatrix sparseMatrix1(3, 3);
108+
sparseMatrix1.compressRowMajor(matrix1);
109+
sparseMatrix1.printCompressed();
110+
111+
// Test decompression
112+
auto decompressedMatrix1 = sparseMatrix1.decompress();
113+
assert(matrix1 == decompressedMatrix1);
114+
115+
// Test retrieval
116+
assert(sparseMatrix1.getValue(0, 0) == 5);
117+
assert(sparseMatrix1.getValue(1, 1) == 8);
118+
assert(sparseMatrix1.getValue(2, 2) == 3);
119+
assert(sparseMatrix1.getValue(1, 2) == 0);
120+
121+
cout << "Passed Test Case 1.\n";
122+
123+
cout << "\nTest Case 2: Basic Column-Major Compression\n";
124+
SparseMatrix sparseMatrix2(3, 3);
125+
sparseMatrix2.compressColumnMajor(matrix1);
126+
sparseMatrix2.printCompressed();
127+
128+
// Test decompression
129+
auto decompressedMatrix2 = sparseMatrix2.decompress();
130+
assert(matrix1 == decompressedMatrix2);
131+
132+
// Test retrieval
133+
assert(sparseMatrix2.getValue(0, 0) == 5);
134+
assert(sparseMatrix2.getValue(1, 1) == 8);
135+
assert(sparseMatrix2.getValue(2, 2) == 3);
136+
assert(sparseMatrix2.getValue(1, 2) == 0);
137+
138+
cout << "Passed Test Case 2.\n";
139+
140+
cout << "\nTest Case 3: Matrix with All Zeros\n";
141+
vector<vector<int> > matrix2 = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
142+
143+
SparseMatrix sparseMatrix3(3, 3);
144+
sparseMatrix3.compressRowMajor(matrix2);
145+
sparseMatrix3.printCompressed();
146+
147+
auto decompressedMatrix3 = sparseMatrix3.decompress();
148+
assert(matrix2 == decompressedMatrix3);
149+
150+
assert(sparseMatrix3.getValue(0, 0) == 0);
151+
assert(sparseMatrix3.getValue(1, 1) == 0);
152+
153+
cout << "Passed Test Case 3.\n";
154+
155+
cout << "\nTest Case 4: Large Sparse Matrix\n";
156+
vector<vector<int> > matrix3(10, vector<int>(10, 0));
157+
matrix3[1][2] = 10;
158+
matrix3[3][4] = 20;
159+
matrix3[5][6] = 30;
160+
161+
SparseMatrix sparseMatrix4(10, 10);
162+
sparseMatrix4.compressRowMajor(matrix3);
163+
sparseMatrix4.printCompressed();
164+
165+
auto decompressedMatrix4 = sparseMatrix4.decompress();
166+
assert(matrix3 == decompressedMatrix4);
167+
168+
assert(sparseMatrix4.getValue(1, 2) == 10);
169+
assert(sparseMatrix4.getValue(3, 4) == 20);
170+
assert(sparseMatrix4.getValue(5, 6) == 30);
171+
assert(sparseMatrix4.getValue(0, 0) == 0);
172+
173+
cout << "Passed Test Case 4.\n";
174+
175+
cout << "\nAll Test Cases Passed.\n";
176+
}
177+
178+
int main() {
179+
runTests();
180+
return 0;
181+
}

0 commit comments

Comments
 (0)