Product of two symmetric SMatrix objects

Hello,

I am trying to use (root 6.10.07) symmetric SMatrix in my code, one of the operations being a product of 2 symmetric matrices. I expect the result to be also symmetric matrix, e.g.

using CovSMatrixD = ROOT::Math::SMatrix<double,3, 3, ROOT::Math::MatRepSym<double, 3>>;
CovSMatrixD m0,m1, mprod;
mprod = m0*m1;

mprod to be of the type CovSMatrixD, but such a code fails to compile with error quoted below. In opposite,
auto mproda = m0*m1; works w/o problem, but the mproda appears to be of the type ROOT::Math::Expr<MatrixMulOp<SMatrix<double, 3, 3, MatRepSym<double, 3> >, SMatrix<double, 3, 3, MatRepSym<double, 3> >, double, 3>, double, 3, 3, MatRepStd<double, 3, 3> >
which explains why the compilation fails.

From the SMatrix code I see that the
template <class R2> SMatrix<T,D1,D2,R>& operator*=(const SMatrix<T,D1,D2,R2>& rhs);
should do what I need, but why it is not used? Is this a bug?

In fact, the lines like

CovSMatrixD m0,m1; 
m1 *= m0;

also lead to compilation error.

Attached macro mtst.C (921 Bytes) shows the problem:

root [0] .x mtst.C+
Info in <TUnixSystem::ACLiC>: creating shared library /home/shahoian/Downloads/./mtst_C.so
In file included from input_line_11:9:
In file included from ././mtst.C:4:
In file included from /home/shahoian/alice/sw/ubuntu1604_x86-64/ROOT/v6-10-06+git_c54db1c10b-1/include/Math/SMatrix.h:734:
In file included from /home/shahoian/alice/sw/ubuntu1604_x86-64/ROOT/v6-10-06+git_c54db1c10b-1/include/Math/SMatrix.icc:53:
/home/shahoian/alice/sw/ubuntu1604_x86-64/ROOT/v6-10-06+git_c54db1c10b-1/include/Math/HelperOps.h:136:10: error: no matching conversion for functional-style cast from 'ERROR_Cannot_assign_general_to_symmetric_matrix *' to
      'ROOT::Math::CompileTimeChecker<(0 == 1) != 0>'
         STATIC_CHECK(0==1, Cannot_assign_general_to_symmetric_matrix);
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/shahoian/alice/sw/ubuntu1604_x86-64/ROOT/v6-10-06+git_c54db1c10b-1/include/Math/StaticCheck.h:59:12: note: expanded from macro 'STATIC_CHECK'
   (void) (ROOT::Math::CompileTimeChecker<(expr) != 0> (&e)); }
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/shahoian/alice/sw/ubuntu1604_x86-64/ROOT/v6-10-06+git_c54db1c10b-1/include/Math/SMatrix.icc:164:28: note: in instantiation of member function 'ROOT::Math::Assign<double, 3, 3, ROOT::Math::MatrixMulOp<ROOT::Math::SMatrix<double, 3, 3,
      ROOT::Math::MatRepSym<double, 3> >, ROOT::Math::SMatrix<double, 3, 3, ROOT::Math::MatRepSym<double, 3> >, double, 3>,
      ROOT::Math::MatRepSym<double, 3>, ROOT::Math::MatRepStd<double, 3, 3> >::Evaluate' requested here
   Assign<T,D1,D2,A,R,R2>::Evaluate(*this, rhs);
                           ^
/home/shahoian/alice/sw/ubuntu1604_x86-64/ROOT/v6-10-06+git_c54db1c10b-1/include/Math/SMatrix.icc:108:4: note: in instantiation of function template specialization 'ROOT::Math::SMatrix<double, 3, 3, ROOT::Math::MatRepSym<double, 3>
      >::operator=<ROOT::Math::MatrixMulOp<ROOT::Math::SMatrix<double, 3, 3, ROOT::Math::MatRepSym<double, 3> >, ROOT::Math::SMatrix<double, 3, 3,
      ROOT::Math::MatRepSym<double, 3> >, double, 3>, ROOT::Math::MatRepStd<double, 3, 3> >' requested here
   operator=(rhs);
   ^
././mtst.C:34:22: note: in instantiation of function template specialization 'ROOT::Math::SMatrix<double, 3, 3, ROOT::Math::MatRepSym<double, 3>
      >::SMatrix<ROOT::Math::MatrixMulOp<ROOT::Math::SMatrix<double, 3, 3, ROOT::Math::MatRepSym<double, 3> >, ROOT::Math::SMatrix<double, 3, 3,
      ROOT::Math::MatRepSym<double, 3> >, double, 3>, ROOT::Math::MatRepStd<double, 3, 3> >' requested here
  CovSMatrixD mmi1 = m0*m0inv;
                     ^
/home/shahoian/alice/sw/ubuntu1604_x86-64/ROOT/v6-10-06+git_c54db1c10b-1/include/Math/StaticCheck.h:51:24: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'ERROR_Cannot_assign_general_to_symmetric_matrix *' to
      'const ROOT::Math::CompileTimeChecker<false>' for 1st argument
     template<> struct CompileTimeChecker<false> {};
                       ^
/home/shahoian/alice/sw/ubuntu1604_x86-64/ROOT/v6-10-06+git_c54db1c10b-1/include/Math/StaticCheck.h:51:24: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'ERROR_Cannot_assign_general_to_symmetric_matrix *' to
      'ROOT::Math::CompileTimeChecker<false>' for 1st argument
     template<> struct CompileTimeChecker<false> {};
                       ^
/home/shahoian/alice/sw/ubuntu1604_x86-64/ROOT/v6-10-06+git_c54db1c10b-1/include/Math/StaticCheck.h:51:24: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
Error in <ACLiC>: Dictionary generation failed!

Hi,
I’m not the author of the code but the product of two symmetric matrices is not necessarily symmetric, so at compile-time, when the types of the objects have to be decided, I guess one has to go with a more relaxed assumption.
@moneta can probably confirm (or correct me).

Hi @eguiraud

Thanks a lot, indeed, I have completely missed that the final matrix might be indeed asymmetric. So, my question was wrong…

Cheers
Ruben

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