Resizing and transposing a TMatrixFSparse - row/col indices are not set

I am trying to transpose a sparse matrix. To do that, firstly I am resizing it to a square matrix, as the following code indicates

#include "TMath.h"
#include "TMatrixF.h"
#include "TMatrixFSparse.h"

void TMatrix_Transpose(){
	TMatrixFSparse G(5, 1);
        //TMatrixFSparse G(5, 2);
	
	int   icol[3] = {0, 0, 0};
	int   irow[3] = {1, 2, 3};
	float data[3] = {1.2, 1.3, 1.4};	
	G.SetMatrixArray(3, irow, icol, data);
	
	
	
	G.Print();
	
	G.ResizeTo(5, 5);
	G.T();
	G.ResizeTo(1, 5);
        //G.ResizeTo(2, 5);
	G.Print();
}

I am compiling the code in ACLiC and the output is as expected

5x1 matrix is as follows

     |      0    |
------------------
   0 |          0 
   1 |        1.2 
   2 |        1.3 
   3 |        1.4 
   4 |          0 


1x5 matrix is as follows

     |      0    |      1    |      2    |      3    |      4    |
----------------------------------------------------------------------
   0 |          0         1.2         1.3         1.4           0 

The problem appears when I am changing the size of the matrix to

TMatrixFSparse G(5, 2);

I get the following output

5x2 matrix is as follows

     |      0    |      1    |
-------------------------------
   0 |          0           0 
   1 |        1.2           0 
   2 |        1.3           0 
   3 |        1.4           0 
   4 |          0           0 


2x5 matrix is as follows

     |      0    |      1    |      2    |      3    |      4    |
----------------------------------------------------------------------
Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

   0 |          0           0           0           0           0 
Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

   1 |          0           0           0           0           0 

So as you can see the transpose matrix is created but it’e empty.
Any idea on what might be the issue?

Thanks in advance!

I have found that if a value is set on the second column the code works fine.

#include "TMath.h"
#include "TMatrixF.h"
#include "TMatrixFSparse.h"

void TMatrix_Transpose(){
	TMatrixFSparse G(5, 2);
	
	int   icol[3] = {0, 1, 0};
	int   irow[3] = {1, 2, 3};
	float data[3] = {1.2, 1.3, 1.4};	
	G.SetMatrixArray(3, irow, icol, data);	
	G.Print();	
	G.ResizeTo(5, 5);
	G.T();
	G.ResizeTo(2, 5);
	G.Print();
}

Does this mean that you can only transpose a matrix when it isn’t a sparse one or similarly that there is at least one non-zero element set per each col or row ?

If this is the case is there a work around on that?

Check the documentation of TMatrixTSparse::ResizeTo. IIRC there’s an optional argument that determines how to deal with zeros.

Cheers,
Kim

If I understood correctly, I have to specify the number of non-zero entries, which is 3 in this example. So I changed the Resize() to

G.ResizeTo(5, 5, 3);

and then on the second resizing to

G.ResizeTo(2, 5, 3);

but I still get the same error.

Am I doing something wrong?

After a closer look I think it was a red herring.

He he he
No problem.
So no idea?

This is very important because later on, any additional calculations cannot be performed (i.e. multiplication). See for instance the following code

#include <iostream>
#include "TMath.h"
#include "TMatrixF.h"
#include "TMatrixFSparse.h"
#include "TMatrixFSym.h"

using namespace std;

void TMatrix_Transpose(){
	TMatrixFSparse G(5, 2);
	
	int   icol[3] = {0, 0, 0};
	int   irow[3] = {1, 2, 3};
	float data[3] = {1.2, 1.3, 1.4};	
	G.SetMatrixArray(3, irow, icol, data);	
	G.Print();	
	//G.Print();
	irow[0] = irow[1] = irow[2] = 0;
	data[0] = 1; data[1] = 2; data[2] = 3;
	TMatrixFSym A(2,data);
	cout << "1\n";
	TMatrixF B(G, TMatrixF::kMult, A);
	B.Print();
	cout << "2\n";
	G.ResizeTo(5, 5, 3);
	cout << "3\n";
	G.T();
	cout << "4\n";
	G.ResizeTo(2, 5, 3);
	G.Print();
	cout << "5\n";
	B *= G;
}

So this code gives exactly the same error

2x5 matrix is as follows

     |      0    |      1    |      2    |      3    |      4    |
----------------------------------------------------------------------
Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

   0 |          0           0           0           0           0 
Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

Error in <operator()(Int_t,Int_t) const>: row/col indices are not set
Info in <operator()>: fNrowIndex = 3 fRowIndex[fNrowIndex-1] = 0

   1 |          0           0           0           0           0 

5
Error in <operator=(const TMatrixTSparse &>: matrices not compatible

Any workaround on that?

The only workaround I can think of, is to fill the whole with zeros, and then assign the non-zero values using SetMatrixArray(), but I guess there is no point in that since it contradicts the meaning of the sparsity.

Maybe you should try some external library, like Eigen and/or Boost and/or some BLAS + LAPACK implementation (e.g. ATLAS).

Thanks a lot for your reply.
It seems odd not to do that in root even though there is a nice library for matrices.

In any case I need to have this running on lxplus, which means that I am not able to install it there.

I guess you should be able to download the source code of any package and build and install everything for yourself (e.g. in ${HOME}/bin, ${HOME}/lib, ${HOME}/include and so on).

It could be an option, but I selected to use root in order to avoid building a library, since root provides tools for matrices!

Is there a reason on why the sparse matrix are used like that or it could be a possible bug?

I guess, you should be able to use these libraries from inside of ROOT, especially if you use ROOT 6 (with ROOT 5 you will probably need to use your macros as precompiled only, i.e. via ACLiC).

Luckily I found that boost is installed on lxplus in /usr/include/boost

The problem is that when I try to run a simple example, I get the following error

Info in <TUnixSystem::ACLiC>: creating shared library /eos/user/a/astamato/Forums/RootForum/./boost_C.so
Error in <ACLiC>: Dictionary generation failed with a core dump!
Info in <ACLiC>: Invoking compiler to check macro's validity
Info in <ACLiC>: The compiler has not found any problem with your macro.
	Probably your macro uses something rootcint can't parse.
	Check http://root.cern.ch/viewvc/branches/v5-34-00-patches/cint/doc/limitati.txt for Cint's limitations.

My code is

#include </usr/include/boost/numeric/ublas/matrix.hpp>
#include </usr/include/boost/numeric/ublas/io.hpp>

int test_boost () {
    using namespace boost::numeric::ublas;
    matrix<double> m (3, 3);
    for (unsigned i = 0; i < m.size1 (); ++ i)
        for (unsigned j = 0; j < m.size2 (); ++ j)
            m (i, j) = 3 * i + j;
    std::cout << m << std::endl;
    return 0;
}

and I am compiling it in ACLiC in root 5.34 doing

.L boost.C++

Any idea?

Try to switch to ROOT 6.
Try to “hide” everything that CINT (in ROOT 5) cannot parse:

#if !defined(__CINT__)
#include ... whatever is needed ...
#endif /* !defined(__CINT__) */

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.