-
May 3rd, 2016, 11:49 AM
#16
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.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
May 3rd, 2016, 03:43 PM
#17
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;
}
}
Last edited by 2kaud; May 3rd, 2016 at 04:36 PM.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
May 3rd, 2016, 06:59 PM
#18
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;
}
-
May 4th, 2016, 04:25 AM
#19
Re: Sparse Matrix Operations
Thank you very much !
Now, work OK
-
May 4th, 2016, 07:04 AM
#20
Re: Sparse Matrix Operations
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?
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
May 4th, 2016, 08:46 AM
#21
Re: Sparse Matrix Operations
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.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|