I'm trying to implement matrix class to handle sparse matrices. Basically I store matrix as two vectors of vectors: the first one stores values (of type double
) row-wise and the second one stores respective column indices (thus type is int
) of these values. For example, matrix A = {{5,0,0},{0,0,7},{3,1,0}}
is stored as entries_ = {{5},{7},{3,1}}
and columnIndices_ = {{1},{3},{1,2}}
.
My code so far is as follows:
class SparseMatrix
{
private:
vector<vector<double> > entries_;
vector<vector<int> > columnIndices_;
public:
SparseMatrix();
SparseMatrix(vector<vector<double> >,vector<vector<int> >);
~SparseMatrix();
// getters
vector<vector<double> > getEntries();
vector<vector<int> > getColIndices();
vector<int> size();
void add_entry(double,unsigned int,unsigned int);
};
Method add_entry(double value, unsigned int i, unsigned int j)
is supposed to put value
on (i,j)
coordinate of the matrix. I want this method to be able to extend the matrix if given coordinates are beyond its scope. I (partially) wrote it, but extension does not seem to work (causes segmentation fault). This is the code I came up with:
void SparseMatrix::add_entry(double value, unsigned int i, unsigned int j)
{
int M = (*this).size()[0]; // current number of rows
int N = (*this).size()[1]; // current number of columns
if(i>M || j>N)
{
int diff_rows = i-M;
int diff_cols = j-N;
if(diff_rows > 0) // extend by adding rows
{
entries_.resize(i); // resize current entries_ so it can store more elements
columnIndices_.resize(i); // same for columnIndices_
vector<vector<double> >::iterator iterVal;
iterVal = entries_.begin() + i;
vector<vector<int> >::iterator iterInd;
iterInd = columnIndices_.begin() + i;
entries_.insert(iterVal,{value});
columnIndices_.insert(iterInd,{j});
}
if(diff_cols > 0) // extend by adding columns
{
entries_[i].push_back(value);
columnIndices_[i].push_back(j);
}
}
else
{
if(find(columnIndices_[i].begin(),columnIndices_[i].end(), j) != columnIndices_[i].end())
/* check if index j is in columnIndices_[i]; if it is, then there is a non-zero value there,
if it is NOT there, it means that on (i,j) position is zero
*/
{
char choice;
cout << "There is a non-zero element on (" << i << ", " << j << ") position." << endl;
cout << "Would you like to replace it by " << value << "? [Y/n]: ";
do
{
cin >> choice;
if(choice == 'n' || choice == 'N')
{
cout << "Element was not replaced." << endl;
return;
}
if(choice == 'y' || choice == 'Y')
{
// how to get (i,j) element from existing representation??...
return;
}
else
cout << "Invalid choice. Try again..." << endl;
}
while(choice == 'n' || choice == 'N' || choice == 'y' || choice == 'Y');
}
else
{
entries_[i].push_back(value); // push value at the end of i-th vector (row)
columnIndices_[i].push_back(j); // store index of newly added value at the end of i-th row
cout << "Matrix has been updated." << endl;
}
}
}
And main()
function:
int main(int argc, char const *argv[])
{
vector<vector<double> > values {{3.0, 1.0}, {2.0}, {5.0, 4.0}};
vector<vector<int> > columns {{1,3}, {1}, {2,3}};
SparseMatrix A(values,columns);
cout << "Matrix A has dimensions " << A.size()[0] << "x" << A.size()[1] << "." << endl;
A.add_entry(7.0,8,0); // segmentation fault happens here...
cout << "Matrix A has dimensions " << A.size()[0] << "x" << A.size()[1] << "." << endl;
return 0;
}
My compiler is g++
with flag -std=c++11
and I'm writing my code on Ubuntu 14.04.
Thanks for any help.
Aucun commentaire:
Enregistrer un commentaire