What happened to TMatrixTRow?

execution of the script

{
   double am[] = {0.0,1.0,2.0,3.0};
   TMatrixD m; m.Use(2,2,am);
   auto colval = 4.;
   auto rowval = 5.;
   TMatrixDColumn(m,1) = colval;
   TMatrixDRow(m,1) = rowval;
   m.Print();
}

results in

**row.C:8:21:** **error:** **no viable overloaded '='**

TMatrixDRow(m,1) = rowval;
**~~~~~~~~~~~~~~~~ ^ ~~**

This is because since 6.10 the operator= has been removed from TMatrixTRow but
not from TMatrixTColumn (for backward compatibility :grinning:) .

The implementation is now through a std::initializer_list, so one must use in order to
replicate the old behavior:

TMatrixDRow(m,1) = {rowval,rowval};

(and yes can also do

TMatrixDRow(m,1) = {rowval,rowval,rowval};

because the size is not checked)

This hack raises many issues/questions:

  1. What is the purpose of TMatrixTRow now, because the operator= does
    not change the whole row. It has now the flavor of
    TMatrixT::&operator()(Int_t rown,Int_t coln);
  2. This change broke m[irow][icol], it will give a compilation error, m(irow,icol) still works.
  3. This implementation is now in contradiction with operator+= and operator*=
    because there only one value is given which operates on the whole row.
  4. Last and probably shows the lack of C++ knowledge by this practitioner, how will I fill this initializer_list with a vector because the size of the matrix will fluctuate in my code.

-Eddy

_ROOT Version: 6.22
Platform: Not Provided
Compiler: Not Provided


Hi Eddy! I’m sure @moneta will take care of this.

Cheers, Bertrand.

Hi Eddy,
If I remember well the reason for removing it was that the operator= was dangerous, because, was allowing to do something like:

TMatrixD m(2,2); 
m[0,1] = 2

And this changes the all row instead of a single element, as a native user my expect. This in my opinion is very confusing.
The changed happen in this commit.
The removel was done for both TMatrixTRow and TMatrixTColumn.
Concerning your points:

  1. If you want to change a whole matrix row there is now TMatrixTRow::Assign. Do
TMatrixDRow(m,1).Assign(rowval); 
  1. m[irow][icol] should still work
  2. Yes , this is true, but I think it is not a contradiction, but some missing consistency, but it is in my opinion acceptable if we document it
  3. ?? (not clear your point to me). For the other point about initializing with a different size, you are right, we should check that the size of the iniitializer list matches the matrix row size.

Best

Lorenzo

Hi Lorenzo,
Still getting some skiing done despite the Covid pandemic :grinning: ?

Currently there are two documented ways to access the elements of matrix m at row i and column j:
m(i,j) = 2; and
m[i][j] = 2

There is a nice discussion of the implementation of operator() versus operator[] here where the last one is referred to as array-of-array solution.

Now apparently somebody became adventurous and confused by the fact that m[1,2]=2
sets the complete row 2 to the value instead of just the element at row=1,
column=2 . Let’s confuse this person a bit more :stuck_out_tongue_winking_eye:

m[1][1,2]=2 or m((2,1),2)=2

all the same and just the comma-operator doing its job,
m[1,2]=2 is the same as m[2]=2.

Maybe confusion sets easier in with the operator[] than with operator() because of its implementation (currently the operator[] only allows one argument).

The better way to ends this confusion is introducing statements like:

inline Element &operator[](Int_t rown) = delete;
inline Element operator[](Int_t rown) const = delete;

Thereby keeping the TMatrixTRow interface like all the other Matrix classes.

-Eddy

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