Re: Sparse Matrix Operations
Quote:
Originally Posted by
euclid2016
Hello !
I want to implement some operations with sparse matrix: addition, substraction, multiplication, multiplication with vector.
I have two matrix in Matrix Market format, namely two *.mtx files( "A.mtx", "B.mtx").
Till now, I am able to read matrix, to print and to write in text files.
I use this library:
http://math.nist.gov/MatrixMarket/mmio/c/mmio.c
...
So, please help me with addition(A+B) implementation.
All the best !
Do you know how to "implement" the addition(A+B) using a piece of paper and a pencil?
Re: Sparse Matrix Operations
I guess this is not your personal forum, it's public.
So what the **** do you want ?
If you don't want to help me, ok...let's them other to help me.
And **** Windows !..you ****ink comunist !
Linux Rules !!!
Re: Sparse Matrix Operations
euclid2016: err... that would entirely uncalled for. By asking that question, VictorN presumably intended to establish that you do know an algorithm for computing addition(A+B). If you did not know that, then that would be the first step, i.e., to think about and research an algorithm to solve the problem, even before you implement it as code. If you did know that, then you only need to answer "yes" and provide an outline of the algorithm that you intend to implement, e.g., in pseudocode.
Cursing Windows, insulting VictorN for being a Microsoft MVP, and praising Linux is entirely out of point... and no, before you accuse me of saying this because I use Windows: I am using Linux right now, and I do sysadmin work on Linux servers as part of my job.
Re: Sparse Matrix Operations
Quote:
Originally Posted by
euclid2016
I guess this is not your personal forum, it's public.
So what the **** do you want ?
If you don't want to help me, ok...let's them other to help me.
And **** Windows !..you ****ink comunist !
Linux Rules !!!
I guess Euklid has rolled over in his grave "reading" your post. :(
So either do something useful in direction "solve the problem" or get back!
Re: Sparse Matrix Operations
Yes, I have an algorithm for sparse matrix addition and I write a function Sum(), but the function give me many errors.
I have two functions: Read() for read a sparse matrix from a mtx file; Sum() for addition.
My code:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
struct MatriceRara
{
int Linie, Coloana; //row, column
double Valoare; //value
//number of elements != 0 ; rows number; columns number
int nrElemente, nrLinii, nrColoane;
};
MatriceRara Read(const char* mtx) {
const char * mtx_file = mtx;
// open file
ifstream fin(mtx_file);
MatriceRara matR;
int nrElemente, nrLinii, nrColoane;
// skip header:
while (fin.peek() == '%') fin.ignore(2048, '\n');
// read parameters:
fin >> nrLinii >> nrColoane >> nrElemente;
matR.nrElemente = nrElemente;
matR.nrLinii = nrLinii;
matR.nrColoane = nrColoane;
cout << "Rows number: " << matR.nrLinii <<endl;
cout << "Columns number: " << matR.nrColoane << endl;
cout << "Number of not null elements: " << matR.nrElemente << endl;
for (int i = 0; i< nrElemente; i++)
{
int m ,n;
double data;
fin >> m >> n >> data;
matR.Linie = m;
matR.Coloana = n;
matR.Valoare = data;
}
return matR;
}
// Addition two sparse matrix
MatriceRara Sum(const MatriceRara& M1, const MatriceRara& M2)
{
MatriceRara R;
if (M1.nrLinii != M2.nrLinii && M1.nrColoane != M2.nrColoane)
{
cout << "Erorr: Matrix don't have the same dim." << endl;
return R;
}
// number of elements in result matrix
int i = 0, j = 0, nr = 0;
while (i < M1.nrElemente && j < M2.nrElemente)
{
if (M1.Linie[i] < M2.Linie[j])
i++;
else if (M1.Linie[i] > M2.Linie[j])
j++;
else
{
if (M1.Coloana[i] < M2.Coloana[j])
i++;
else if (M1.Coloana[i] > M2.Coloana[j])
j++;
else
{
if (M1.Valoare[i] + M2.Valoare[j] == 0)
nr = nr + 2; // common element(null)
else
nr = nr + 1; // common element(not null)
i++; j++;
}
}
}
// number of elements for result
nr = M1.nrElemente + M2.nrElemente - nr ;
// initialization result
R.Linie = new int[nr];
R.Coloana = new int[nr];
R.Valoare = new double[nr];
R.nrElemente = nr;
R.nrLinii = M1.nrLinii;
R.nrColoane = M1.nrColoane;
// calculation
int k = 0; // index in result matrix
i = 0; j = 0;
while (k < R.nrElemente)
{
if (M1.Linie[i] < M2.Linie[j])
{
R.Linie[k] = M2.Linie[i];
R.Coloana[k] = M2.Coloana[i];
R.Valoare[k] = M2.Valoare[i];
i++; k++;
}
else if (M1.Linie[i] > M2.Linie[j])
{
R.Linie[k] = M1.Linie[j];
R.Coloana[k] = M1.Coloana[j];
R.Valoare[k] = M1.Valoare[j];
j++; k++;
}
else
{
if (M1.Coloana[i] < M2.Coloana[j])
{
R.Linie[k] = M2.Linie[i];
R.Coloana[k] = M2.Coloana[i];
R.Valoare[k] = M2.Valoare[i];
i++; k++;
}
else if (M1.Coloana[i] > M2.Coloana[j])
{
R.Linie[k] = M1.Linie[j];
R.Coloana[k] = M1.Coloana[j];
R.Valoare[k] = M1.Valoare[j];
j++; k++;
}
else
{
if (M1.Valoare[i] + M2.Valoare[j] == 0)
{
i++; j++; // common element( null)
}
else
{
R.Linie[k] = M1.Linie[i];;
R.Coloana[k] = M1.Coloana[i];
R.Valoare[k] = M1.Valoare[i] + M2.Valoare[j];
i++; j++; k++; // common element(not null)
}
}
}
}
return R;
}
int main () {
cout << "Matrix A " << endl;
MatriceRara a = Read("Amica.mtx");
cout << "Matrix B " << endl;
MatriceRara b = Read("Bmica.mtx");
MatriceRara suma = Sum(a,b);
cout << "Sum A + B" << endl;
for (int i = 0; i< suma.nrElemente; i++)
{
cout << suma.Linie<< " " << suma.Coloana << " " << suma.Valoare << endl;
}
}
Output:
In function ‘MatriceRara Adunare(const MatriceRara&, const MatriceRara&)’:
adunare.cpp:96:29: error: invalid types ‘const int[int]’ for array subscript
if (M1.Linie[i] < M2.Linie[j])
^
adunare.cpp:96:43: error: invalid types ‘const int[int]’ for array subscript
if (M1.Linie[i] < M2.Linie[j])
^
adunare.cpp:100:34: error: invalid types ‘const int[int]’ for array subscript
else if (M1.Linie[i] > M2.Linie[j])
^
adunare.cpp:100:48: error: invalid types ‘const int[int]’ for array subscript
else if (M1.Linie[i] > M2.Linie[j])
^
adunare.cpp:108:38: error: invalid types ‘const int[int]’ for array subscript
if (M1.Coloana[i] < M2.Coloana[j])
.............................................
adunare.cpp:251:12: error: invalid types ‘double[int]’ for array subscript
R.Valoare[k] = M1.Valoare[i] + M2.Valoare[j];
^
adunare.cpp:251:28: error: invalid types ‘const double[int]’ for array subscript
R.Valoare[k] = M1.Valoare[i] + M2.Valoare[j];
Re: Sparse Matrix Operations
MatriceRara struct has 6 elements - none of which are an array. So trying
Code:
if (M1.Linie[i] < M2.Linie[j])
is not correct as Linie is not an array, just a variable of type int.
Note in Read(), you are overwriting the same values in MatR for every elements read in the for loop.
Re: Sparse Matrix Operations
Well, I make some change in struct MatriceRara and in function Read().
Code:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
struct MatriceRara
{
int Linie[], Coloana[];
double Valoare[];
int nrElemente, nrLinii, nrColoane;
};
MatriceRara Read(const char* mtx) {
const char * mtx_file = mtx;
ifstream fin(mtx_file);
MatriceRara matR;
int nrElemente, nrLinii, nrColoane;
// skip header:
while (fin.peek() == '%') fin.ignore(2048, '\n');
// read parameters:
fin >> nrLinii >> nrColoane >> nrElemente;
matR.nrElemente = nrElemente;
matR.nrLinii = nrLinii;
matR.nrColoane = nrColoane;
cout << "Number of rows: " << matR.nrLinii <<endl;
cout << "Number of columns: " << matR.nrColoane << endl;
cout << "Number of not null values: " << matR.nrElemente << endl;
for (int i = 0; i< nrElemente; i++)
{
int m[nrElemente] ,n[nrElemente];
double data[nrElemente];
fin >> m[i] >> n[i] >> data[i];
matR.Linie[i] = m[i];
matR.Coloana[i] = n[i];
matR.Valoare[i] = data[i];
}
return matR;
}
int main () {
MatriceRara a = Read("Amica.mtx");
for (int i = 0; i< a.nrElemente; i++)
{
cout << a.Linie[i] << " " << a.Coloana[i] << " " << a.Valoare[i] << endl;
}
}
Output:
Number of rows: 5
Number of columns: 5
Number of not null values: 8
Segmentation fault (core dumped)
Re: Sparse Matrix Operations
Code:
int Linie[], Coloana[];
...
int m[nrElemente] ,n[nrElemente];
This is not valid standard c++. In c++ the number of elements of an array has to be determined at compile time, not run time. If you don't know the number of elements in an array at compile time, then you'll need to use dynamic arrays. Why not use a vector? Consider (not tried)
Code:
struct Elems {
int Linie;
int Coloana;
double Valoare;
};
struct MatriceRara {
vector<Elems> elems;
int nrElemente, nrLinii, nrColoane;
};
...
for (int i = 0; i < nrElemente; ++i) {
Elems el;
fin >> el.Linie >> el.Coloana >> el.Valoare;
MatR.elems.push_back(el);
}
Re: Sparse Matrix Operations
Thank you very much !
When I try to display the matrix, I get some strange values.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
struct Elems {
int Linie;
int Coloana;
double Valoare;
};
struct MatriceRara {
vector<Elems> elems;
int nrElemente, nrLinii, nrColoane;
};
MatriceRara Read(const char* mtx) {
const char * mtx_file = mtx;
ifstream fin(mtx_file);
MatriceRara matR;
int nrElemente, nrLinii, nrColoane;
// skip header:
while (fin.peek() == '%') fin.ignore(2048, '\n');
// read parameters:
fin >> nrLinii >> nrColoane >> nrElemente;
matR.nrElemente = nrElemente;
matR.nrLinii = nrLinii;
matR.nrColoane = nrColoane;
cout << "Number of rows: " << matR.nrLinii <<endl;
cout << "Number of columns: " << matR.nrColoane << endl;
cout << "Number of not null values: " << matR.nrElemente << endl;
for (int i = 0; i < nrElemente; ++i) {
Elems el;
fin >> el.Linie >> el.Coloana >> el.Valoare;
matR.elems.push_back(el);
}
return matR;
}
int main () {
MatriceRara a = Read("Amica.mtx");
for (int i = 0; i< a.nrElemente; i++)
{
Elems el;
cout << el.Linie << " " << el.Coloana << " " << el.Valoare << endl;
}
}
Output:
Number of rows: 5
Number of columns: 5
Number of not null values: 8
1354166784 32767 2.07462e-317
1354166784 32767 2.07462e-317
1354166784 32767 2.07462e-317
1354166784 32767 2.07462e-317
1354166784 32767 2.07462e-317
1354166784 32767 2.07462e-317
1354166784 32767 2.07462e-317
1354166784 32767 2.07462e-317
My real matrix from file "Amica.mtx":
1 1 1.000e+00
2 2 1.050e+01
3 3 1.500e-02
1 4 6.000e+00
4 2 2.505e+02
4 4 -2.800e+02
4 5 3.332e+01
5 5 1.200e+01
Re: Sparse Matrix Operations
You have:
Code:
for (int i = 0; i< a.nrElemente; i++)
{
Elems el;
cout << el.Linie << " " << el.Coloana << " " << el.Valoare << endl;
}
The variable "el" has no relationship to the sparse matrix variable "a".
It should be:
Code:
for (int i = 0; i< a.nrElemente; i++)
{
cout << a.elems[i].Linie << " " << a.elems[i].Coloana << " " << a.elems[i].Valoare << endl;
}
Re: Sparse Matrix Operations
By the way, the member variable nrElemente is redundant. Just get the size from the vector.
Re: Sparse Matrix Operations
Yeah, thanks ! :)
Now my function Read() work ok, but the function for addition two sparse matrix, give me some errors.
My full code:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <iomanip>
using namespace std;
struct Elems {
int Linie;
int Coloana;
double Valoare;
};
struct MatriceRara {
vector<Elems> elems;
int nrElemente, nrLinii, nrColoane;
};
MatriceRara Read(string mtx) {
string mtx_file = mtx;
char *c = (char *) mtx_file.c_str();
ifstream fin(c);
MatriceRara matR;
int nrElemente, nrLinii, nrColoane;
// skip header:
while (fin.peek() == '%') fin.ignore(2048, '\n');
// read parameters:
fin >> nrLinii >> nrColoane >> nrElemente;
matR.nrElemente = nrElemente;
matR.nrLinii = nrLinii;
matR.nrColoane = nrColoane;
string nume_matrice = mtx_file.substr (0,1);//nume matrice
cout << "*************************************************" << endl;
cout << "* MATRICEA RARA " << nume_matrice <<" : " << " *" << endl;
cout << "*************************************************" << endl;
cout << "Numar randuri: " << matR.nrLinii <<endl;
cout << "Numar coloane: " << matR.nrColoane << endl;
cout << "Numar valori nenule: " << matR.nrElemente << endl;
for (int i = 0; i < nrElemente; ++i) {
Elems el;
fin >> el.Linie >> el.Coloana >> el.Valoare;
matR.elems.push_back(el);
}
return matR;
}
// ADDITION A + B
MatriceRara Sum(const MatriceRara& M1, const MatriceRara& M2)
{
MatriceRara R;
if (M1.nrLinii != M2.nrLinii && M1.nrColoane != M2.nrColoane)
{
cout << "Eroare: Matricele trebuie sa aiba dimensiuni egale." << endl;
return R;
}
// determinarea numarului de elemente al matricei rezultat
int i = 0, j = 0, nr = 0;
while (i < M1.nrElemente && j < M2.nrElemente)
{
if (M1.elems[i].Linie < M2.elems[j].Linie)
i++;
else if (M1.elems[i].Linie > M2.elems[j].Linie)
j++;
else
{
if (M1.elems[i].Coloana < M2.elems[j].Coloana)
i++;
else if (M1.elems[i].Coloana > M2.elems[j].Coloana)
j++;
else
{
if (M1.elems[i].Valoare + M2.elems[j].Valoare == 0)
nr = nr + 2; // element comun nul
else
nr = nr + 1; // element comun nenul
i++; j++;
}
}
}
// number of elements for results
nr = M1.nrElemente + M2.nrElemente - nr ;
// result initialization
// ERRORS LINES !!!
R.elems[nr].Linie = new int[nr];
R.elems[nr].Coloana = new int[nr];
R.elems[nr].Valoare = new double[nr];
R.nrElemente = nr;
R.nrLinii = M1.nrLinii;
R.nrColoane = M1.nrColoane;
// calculare rezultat
int k = 0; // index in result matrix
i = 0; j = 0;
while (k < R.nrElemente)
{
if (M1.elems[i].Linie < M2.elems[j].Linie)
{
R.elems[k].Linie = M2.elems[i].Linie;
R.elems[k].Coloana= M2.elems[i].Coloana;
R.elems[k].Valoare = M2.elems[i].Valoare;
i++; k++;
}
else if (M1.elems[i].Linie > M2.elems[j].Linie)
{
R.elems[k].Linie = M1.elems[j].Linie;
R.elems[k].Coloana = M1.elems[j].Coloana;
R.elems[k].Valoare = M1.elems[j].Valoare;
j++; k++;
}
else
{
if (M1.elems[i].Coloana < M2.elems[j].Coloana)
{
R.elems[k].Linie = M2.elems[i].Linie;
R.elems[k].Coloana = M2.elems[i].Coloana;
R.elems[k].Valoare = M2.elems[i].Valoare;
i++; k++;
}
else if (M1.elems[i].Coloana > M2.elems[j].Coloana)
{
R.elems[k].Linie = M1.elems[j].Linie;
R.elems[k].Coloana = M1.elems[j].Coloana;
R.elems[k].Valoare = M1.elems[j].Valoare;
j++; k++;
}
else
{
if (M1.elems[i].Valoare + M2.elems[j].Valoare == 0)
{
i++; j++; // element comun nul
}
else
{
R.elems[k].Linie = M1.elems[i].Linie;
R.elems[k].Coloana = M1.elems[i].Coloana;
R.elems[k].Valoare= M1.elems[i].Valoare + M2.elems[j].Valoare;
i++; j++; k++; // element comun nenul
}
}
}
}
return R;
}
int main () {
// MATRIX A
MatriceRara a = Read("Amica.mtx");
// 1) DISPLAY
// 2) SAVE IN TXT FILE
ofstream output("Amica.txt");
for (int i = 0; i< a.elems.size(); i++)
{
cout << a.elems[i].Linie << " " << a.elems[i].Coloana << " " << a.elems[i].Valoare << endl;
output << a.elems[i].Linie << " " << a.elems[i].Coloana << " " << a.elems[i].Valoare << endl;
}
output.close();
cout << "Matricea rara A" << " a fost salvata in fisierul " << "\"Amica.txt\"" << endl;
// 3) SPARSE MATRIX ----> FULL MATRIX
int mat[a.nrLinii][a.nrColoane];
//umple cu zero
for (int i = 0; i < a.nrLinii; i++)
{
for (int j = 0; j < a.nrColoane; j++)
{
mat[i][j] = 0;
}
}
// copiere elemente nenule
for (int i = 0; i < a.elems.size(); i++) {
mat[a.elems[i].Linie][a.elems[i].Coloana] = a.elems[i].Valoare;
}
// 4) DISPLAY FULL MATRIX
cout << "Matricea densa A :" << endl;
for (int i=0;i<a.nrLinii;i++)
{
for (int j=0;j<a.nrColoane;j++)
{
cout<<mat[i][j]<<' ';
}
cout << endl;
}
///////////////
// MATRICEA B //
///////////////
MatriceRara b = Read("Bmica.mtx");
// 1) DISPLAY
// 2) SAVE IN TXT FILE
ofstream outputb("Bmica.txt");
for (int i = 0; i< b.elems.size(); i++)
{
cout << b.elems[i].Linie << " " << b.elems[i].Coloana << " " << b.elems[i].Valoare << endl;
outputb << b.elems[i].Linie << " " << b.elems[i].Coloana << " " << b.elems[i].Valoare << endl;
}
outputb.close();
cout << "Matricea rara B" << " a fost salvata in fisierul " << "\"Bmica.txt\"" << endl;
// 3) SPARSE ----> FULL
int matb[b.nrLinii][b.nrColoane];
//add zeros
for (int i = 0; i < b.nrLinii; i++)
{
for (int j = 0; j < b.nrColoane; j++)
{
matb[i][j] = 0;
}
}
// copy not null elements
for (int i = 0; i < b.elems.size(); i++) {
matb[b.elems[i].Linie][b.elems[i].Coloana] = b.elems[i].Valoare;
}
// 4) AFISARE MATRICEA DENSA
cout << "Matricea densa B :" << endl;
for (int i=0;i<b.nrLinii;i++)
{
for (int j=0;j<b.nrColoane;j++)
{
cout<<matb[i][j]<<' ';
}
cout << endl;
}
//SUM A + B
MatriceRara suma = Sum(a,b);
cout << "Sum A + B" << endl;
for (int i = 0; i< suma.nrElemente; i++)
{
cout << suma.elems[i].Linie<< " " << suma.elems[i].Coloana << " " << suma.elems[i].Valoare << endl;
}
}
My output:
In function ‘MatriceRara Sum(const MatriceRara&, const MatriceRara&)’:
TEST-READ.cpp:139:27: error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
R.elems[nr].Linie = new int[nr];
^
TEST-READ.cpp:140:29: error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
R.elems[nr].Coloana = new int[nr];
^
TEST-READ.cpp:141:29: error: cannot convert ‘double*’ to ‘double’ in assignment
R.elems[nr].Valoare = new double[nr];
Re: Sparse Matrix Operations
Code:
// ERRORS LINES !!!
R.elems[nr].Linie = new int[nr];
R.elems[nr].Coloana = new int[nr];
R.elems[nr].Valoare = new double[nr];
Yes, because Linie, Coloana and Valoare are of type int/double, not of type int*/double* - so cannot be assigned a memory address of allocated memory.
What are you trying to achieve?
Also
Code:
int mat[a.nrLinii][a.nrColoane];
as discussed in post #9, this is not valid standard c++. In standard c++ the number of elements in an array needs to be determined at compile time. If they cannot be, then use a container such as a vector.
Re: Sparse Matrix Operations
Code:
// ERRORS LINES !!!
R.elems[nr].Linie = new int[nr];
R.elems[nr].Coloana = new int[nr];
R.elems[nr].Valoare = new double[nr];
In the above code, I want to initialize the result matrix R( R = A + B).
If I delete that lines of code, I got error "Segmentation fault".
Regarding the other issue:
Code:
int mat[a.nrLinii][a.nrColoane];
I will write a function for convert sparse matrix to full matrix.
Re: Sparse Matrix Operations
Code:
R.elems[nr].Linie = new int[nr];
R.elems[nr].Coloana = new int[nr];
R.elems[nr].Valoare = new double[nr];
I think you require
Code:
R.elems.resize(nr);
since elems is a vector.
Re: Sparse Matrix Operations
Unless I've misunderstood what you are trying to achieve, you seem to be making very heavy weather of doing this. Consider the code below which reads in 2 files in the .mtx format, displays their contents, produces a new matrix which is their sum and displays this matrix. Various improvements could be made to this code which I'll leave to you.
Code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const string fa = "mata.mtx";
const string fb = "matb.mtx";
class matrix {
public:
matrix(int col, int row) : cols(col), rows(row), elems(new double[col * row])
{
memset(elems, 0, sizeof(double) * col * row);
}
~matrix() {
delete[] elems;
}
matrix(const string& fn)
{
ifstream fma(fn);
if (!fma.is_open()) {
cout << "Cannot open " << fn << endl;
return;
}
string tmp;
while (fma.peek() == '%')
getline(fma, tmp);
int noelems;
fma >> rows >> cols >> noelems;
elems = new double[cols * rows];
memset(elems, 0, sizeof(double) * cols * rows);
int r, c;
double v;
while (fma >> r >> c >> v)
operator()(c - 1, r - 1) = v;
fma.close();
}
matrix(const matrix& ma)
{
cols = ma.cols;
rows = ma.rows;
elems = new double[cols * rows];
memcpy(elems, ma.elems, sizeof(double) * cols * rows);
}
matrix(matrix&& ma)
{
cols = ma.cols;
rows = ma.rows;
elems = ma.elems;
ma.elems = nullptr;
}
double& operator()(int c, int r)
{
return elems[c * cols + r];
}
const double& operator()(int c, int r) const
{
return elems[c * cols + r];
}
int noRows() const
{
return rows;
}
int noCols() const
{
return cols;
}
matrix operator=(matrix&&) = delete;
matrix operator=(const matrix&) = delete;
private:
int cols = 0;
int rows = 0;
double *elems = nullptr;
};
ostream& operator<<(ostream& os, const matrix& ma)
{
for (int r = 0; r < ma.noRows(); ++r) {
for (int c = 0; c < ma.noCols(); ++c)
os << ma(c, r) << " ";
os << endl;
}
return os;
}
matrix operator+(const matrix& ma, const matrix& mb)
{
if ((ma.noCols() != mb.noCols()) || (ma.noRows() != mb.noRows())) {
cout << "cols/rows don't match" << endl;
return matrix(0, 0);
}
matrix s(ma.noCols(), ma.noRows());
for (int r = 0; r < ma.noRows(); ++r)
for (int c = 0; c < ma.noCols(); ++c)
s(c, r) = ma(c, r) + mb(c, r);
return s;
}
int main()
{
matrix A(fa);
if (A.noCols() == 0)
return 1;
cout << "Matrix A" << endl;
cout << A;
matrix B(fb);
if (B.noCols() == 0)
return 2;
cout << endl << "Matrix B" << endl;
cout << B;
matrix S = A + B;
if (S.noCols() != 0) {
cout << endl << "Matrix sum" << endl;
cout << S;
}
}
Re: Sparse Matrix Operations
1) Since you are using std::vector, you will not need to
do a "new" to increase the size of sum matrix. You can
simply push_back() the element.
2) As a first pass, I would choose a simple method:
a) set the sum matrix equal to the first matrix.
b) loop thru the second matrix ... for each (i,j) combination
in the second matrix, see if the combination is in the first
matrix. If it is, add the values. If it is not, create a
new element and do a push_back() to the sum matrix. There
are other containers besides std::vector that would make this
step faster.
Code:
// ADDITION A + B
MatriceRara Sum(const MatriceRara& M1, const MatriceRara& M2)
{
MatriceRara R;
if (M1.nrLinii != M2.nrLinii || M1.nrColoane != M2.nrColoane)
{
cout << "Eroare: Matricele trebuie sa aiba dimensiuni egale." << endl;
return R;
}
R = M1; // set the sum equal to the first matrix
// loop thru the second matrix ... if the element exists
// in the first matrix, add it to the sum. If it does
// not exist, create a new element in the sum.
for (int j = 0; j<M2.nrElemente; ++j)
{
bool found = false;
for (int i = 0; i<M1.nrElemente; ++i)
{
if (M1.elems[i].Linie == M2.elems[j].Linie &&
M1.elems[i].Coloana == M2.elems[j].Coloana)
{
found = true;
R.elems[i].Valoare += M2.elems[j].Valoare;
break;
}
}
if (!found) // element is in M2, but not in M1
{
Elems el;
el.Linie = M2.elems[j].Linie;
el.Coloana = M2.elems[j].Coloana;
el.Valoare = M2.elems[j].Valoare;
R.elems.push_back(el);
}
}
// remove elements that equal 0.0
auto value_0 = [](const Elems & el) { return el.Valoare == 0.0; };
R.elems.erase(remove_if(R.elems.begin(), R.elems.end(), value_0), R.elems.end());
R.nrElemente = R.elems.size();
return R;
}
Re: Sparse Matrix Operations
Thank you very much !
Now, work OK :)
Re: Sparse Matrix Operations
Quote:
Originally Posted by
2kaud
Unless I've misunderstood what you are trying to achieve, you seem to be making very heavy weather of doing this.
I believe the original goal was to get this working for sparse matrix implementations?
Re: Sparse Matrix Operations
Quote:
Originally Posted by
monarch_dodra
I believe the original goal was to get this working for sparse matrix implementations?
Yes, but the OP's post #15 mentions converting sparse matrix to full matrix. If the full matrices can be held in memory and depending upon the size of the matrices and the number of used elements, the operations on a full matrix may be more efficient than on a sparse matrix structure. The best method in a particular situation will depend upon the size of the matrices and number of used elements.