CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 21
  1. #1
    Join Date
    Apr 2016
    Posts
    8

    Sparse Matrix Operations

    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

    My code:
    Code:
    /* 
    *   Read sparse matrix in MatrixMarket(*.mtx) format
    *   Stored method:  coordinate format
    */
    #define extfis ".txt"
    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    extern "C"
    {
    #include "mmio.h"
    #include "mmio.c"
    }
    
    class SparseMatrix {
       int ret_code;
        MM_typecode matcode;
        FILE *f;
        int M, N, nz;   
        int i, *I, *J;
        double *val;
        const char* mtx_file;
        string matrice;
        string numefin;
        public:
            void Read (const char*);
            void Show(string);
       };
    
       
          
    void SparseMatrix::Read(const char* mtx) {
       mtx_file = mtx;
       if ((f = fopen(mtx_file, "r")) == NULL) 
                exit(1);
       
                   
       if (mm_read_banner(f, &matcode) != 0)
        {
            printf("Could not process Matrix Market banner.\n");
            exit(1);
        }
        
    
        if (mm_is_complex(matcode) && mm_is_matrix(matcode) && 
                mm_is_sparse(matcode) )
        {
            printf("Sorry, this application does not support ");
            printf("Market Market type: [%s]\n", mm_typecode_to_str(matcode));
            exit(1);
        }
    
        /* dimension*/
    
        if ((ret_code = mm_read_mtx_crd_size(f, &M, &N, &nz)) !=0)
            exit(1);
    
    
        /* storage */
    
        I = (int *) malloc(nz * sizeof(int));
        J = (int *) malloc(nz * sizeof(int));
        val = (double *) malloc(nz * sizeof(double));
    
    
        
        for (i=0; i<nz; i++)
        {
            fscanf(f, "%d %d %lg\n", &I[i], &J[i], &val[i]);
            I[i]--;  
            J[i]--;
        }
    
        if (f !=stdin)
            {
             fclose(f);
          }
    
       }
    
    void SparseMatrix::Show(string txt) {
       
        /* print matrix */
        /* write matrix in text file */
        matrice = txt;
        const char * c = matrice.c_str();
       
        mm_write_banner(stdout, matcode);
        mm_write_mtx_crd_size(stdout, M, N, nz);
        ofstream output;
        output.open(c);
        cout << "Matrix " << matrice << ":" << endl; 
        for (i=0; i<nz; i++) {
            fprintf(stdout, "%d %d %20.19g\n", I[i]+1, J[i]+1, val[i]);
            output << I[i]+1 << " " << J[i]+1 << " " << val[i] << endl;
       }
       output.close();   
       //extract matrix name,without extension(.txt)
       string nume_matrice = matrice.substr (0,1);
       cout << "Matrix " << matrice << " is save in file" << nume_matrice << ".txt" << endl;
    }
    
          
    int main()
    {
        SparseMatrix matrixA;
        SparseMatrix matrixB;
        
       matrixA.Read("A.mtx");
        matrixA.Show("A.txt");     
        
        matrixB.Read("B.mtx");
        matrixB.Show("B.txt");
        
        return 0;
    }
    So, please help me with addition(A+B) implementation.
    All the best !

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Sparse Matrix Operations

    Quote Originally Posted by euclid2016 View Post
    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?
    Victor Nijegorodov

  3. #3
    Join Date
    Apr 2016
    Posts
    8

    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 !!!

  4. #4
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    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.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  5. #5
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Sparse Matrix Operations

    Quote Originally Posted by euclid2016 View Post
    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!
    Victor Nijegorodov

  6. #6
    Join Date
    Apr 2016
    Posts
    8

    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];

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    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.
    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)

  8. #8
    Join Date
    Apr 2016
    Posts
    8

    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)

  9. #9
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    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);
    }
    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)

  10. #10
    Join Date
    Apr 2016
    Posts
    8

    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

  11. #11
    Join Date
    Aug 2000
    Location
    West Virginia
    Posts
    7,721

    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;
    }

  12. #12
    Join Date
    Aug 2006
    Posts
    231

    Re: Sparse Matrix Operations

    By the way, the member variable nrElemente is redundant. Just get the size from the vector.

  13. #13
    Join Date
    Apr 2016
    Posts
    8

    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];

  14. #14
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    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.
    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)

  15. #15
    Join Date
    Apr 2016
    Posts
    8

    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.

Page 1 of 2 12 LastLast

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
  •  





Click Here to Expand Forum to Full Width

Featured