C + + template class implements sparse matrix (transpose operation and fast transpose operation)

There are two problems in the realization of sparse matrix

  1. In general, the pass parameter of copy constructor should be const reference type. Otherwise, there will be problems in the case of sparsematrix < T > b (a.post()). It is the same when overloading assignment symbols. The parameter should be set to const reference type. (seems to be related to left and right values? To be further studied)
  2. In the transpose function and the fast transpose function, the rows and columns in the array element triple are all the values we input, starting from 1, while in the array they start from 0, which should be noted.

1,SparseMatrix.h

#ifndef SparseMatrix_h
#define SparseMatrix_h
#include <iostream>
using std::ostream;
using std::istream;
const int DefaultSize = 100;

template <class T>
struct Trituple{
    int row, col;
    T value;
    Trituple<T>& operator=(Trituple<T>& x){
        row = x.row;
        col = x.col;
        value = x.value;
        return *this;
    }
};

template <class T>
class SparseMatrix{
private:
    int Rows, Cols, Terms;
    Trituple<T>* smArray;
    int maxTerms;
public:
    SparseMatrix(int maxSz = DefaultSize);
    SparseMatrix(const SparseMatrix<T>& x);
    ~SparseMatrix(){delete []smArray;}
    SparseMatrix<T>& operator=(const SparseMatrix<T>& x);
    SparseMatrix<T> Transpose();
    SparseMatrix<T> FastTranspose();
    //SparseMatrix<T> Add(SparseMatrix<T>& b);
    //SparseMatrix<T> Multiply(SparseMatrix<T>& b);
    template <class U> friend ostream& operator<<(ostream& out, SparseMatrix<U>& M);
    template <class U> friend istream& operator>>(istream& in, SparseMatrix<U>& M);
};

#endif /* SparseMatrix_h */

2,SparseMatrix.cpp

#include <stdio.h>
#include "SparseMatrix.h"
using std::endl;
using std::cerr;
using std::cout;

template <class T>
SparseMatrix<T>::SparseMatrix(int maxSz) : maxTerms(maxSz){
    if(maxSz < 1){cerr << "Matrix initialization value is wrong!" << endl; exit(1);}
    smArray = new Trituple<T>[maxSz];
    if(smArray == NULL){cerr << "Wrong storage allocation!" << endl; exit(1);}
    Rows = Cols = Terms = 0;
}

template <class T>
SparseMatrix<T>::SparseMatrix(const SparseMatrix<T>& x){
    Rows = x.Rows;
    Cols = x.Cols;
    Terms = x.Terms;
    maxTerms = x.maxTerms;
    smArray = new Trituple<T>[maxTerms];
    if(smArray == NULL){cerr << "Storage allocation error!" << endl; exit(1);}
    for(int i = 0; i < Terms; i++)
        smArray[i] = x.smArray[i];
}

template <class T>
SparseMatrix<T>& SparseMatrix<T>::operator=(const SparseMatrix<T>& x){
    Rows = x.Rows;
    Cols = x.Cols;
    Terms = x.Terms;
    maxTerms = x.maxTerms;
    for(int i = 0; i < Terms; i++)
        smArray[i] = x.smArray[i];
    return *this;
}

template <class T>
ostream& operator<<(ostream& out, SparseMatrix<T>& M){
    out << "row = " << M.Rows << endl;
    out << "cols = " << M.Cols << endl;
    out << "Nozero terms = " << M.Terms << endl;
    for(int i = 0; i < M.Terms; i ++)
        out << "M[" << M.smArray[i].row << "][" << M.smArray[i].col << "] = " << M.smArray[i].value << endl;
    return out;
}

template <class T>
istream& operator>>(istream& in, SparseMatrix<T>& M){
    cout << "Enter number of rows, columns, and terms" << endl;
    in >> M.Rows >> M.Cols >> M.Terms;
    if(M.Terms > M.maxTerms){cerr << "Number of terms overflow!" << endl; exit(1);}
    for(int i = 0; i < M.Terms; i++){
        cout << "Enter row, column, and value of term:" << i+1 << endl;
        in >> M.smArray[i].row >> M.smArray[i].col >> M.smArray[i].value;
    }
    return in;
}

//Sparse matrix transpose algorithm
template <class T>
SparseMatrix<T> SparseMatrix<T>::Transpose(){
    SparseMatrix<T> b(maxTerms);
    b.Rows = Cols;
    b.Cols = Rows;
    b.Terms = Terms;
    if(Terms > 0){
        int k, i, CurrentB = 0;
        for(k = 0; k < Cols; k ++)
            for(i = 0; i < Terms; i ++)
                if(smArray[i].col == k+1){
                    b.smArray[CurrentB].row = k;
                    b.smArray[CurrentB].col = smArray[i].row;
                    b.smArray[CurrentB].value = smArray[i].value;
                    CurrentB ++;
                }
    }
    return b;
}

//Fast transpose algorithm of sparse matrix
template <class T>
SparseMatrix<T> SparseMatrix<T>::FastTranspose(){
    int* rowSize = new int[Cols];
    int* rowStart = new int[Cols];
    SparseMatrix<T> b(maxTerms);
    b.Rows = Cols;
    b.Cols = Rows;
    b.Terms = Terms;
    if(Terms > 0){
        int i, j;
        for(i = 0; i < Cols; i ++) rowSize[i] = 0;
        for(i = 0; i < Terms; i ++) rowSize[--smArray[i].col]++;
        rowStart[0] = 0;
        for(i = 1; i < Cols; i++)
            rowStart[i] = rowStart[i-1] + rowSize[i-1];
        for(i = 0; i < Terms; i ++){
            j = rowStart[smArray[i].col];
            b.smArray[j].row = smArray[i].col;
            b.smArray[j].col = smArray[i].row;
            b.smArray[j].value = smArray[i].value;
            rowStart[smArray[i].col]++;
        }
    }
    delete []rowStart;
    delete []rowSize;
    return b;
}

3,main.cpp

#include <iostream>
#include "SparseMatrix.cpp"
using std::cin;

int main(){
    SparseMatrix<int> a(100);
    cin >> a;
    cout << a;
    SparseMatrix<int> b(100);
    SparseMatrix<int> c(100);
    b = a.Transpose();
    c = a.FastTranspose();
    cout << b;
    cout << c;
    return 0;
}

 

13 original articles published, praised 0, and 376 visitors
Private letter follow

Posted by kruahsohr on Sat, 22 Feb 2020 07:01:55 -0800