Re: [eigen] How to get triangular lower part of a matrix with dev branche ?

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]


2010/5/20  <vincent.lejeune@xxxxxxxxxx>:
>
> I have another issue with triangularview :
>
>
>
> when compiling the following code :
>
>
>
>  template<typename Derived>
>
>  void applyBlockHouseholderOnTheRight(Derived& A,const Derived& V,
>
>      const Matrix<typename Derived::Scalar,Derived::RowsAtCompileTime,1>&
>
> coeffs)
>
>  {
>
>    typedef Matrix<typename
>
> Derived::Scalar,Derived::RowsAtCompileTime,Derived::RowsAtCompileTime>
>
> TriangularDerivedBlock;
>
>    const TriangularDerivedBlock&
>
> T=BlockHouseholderTriangularFactor(V,coeffs);
>
>    A -= A* V.triangularView<UnitLower>() * T.transpose() *
>
> V.triangularView<UnitLower>().transpose() ;
>
>  }
>
>
>
> int main()
>
> {
>
>  MAT A=MAT::Random();
>
>  MAT Abis(A);
>
>  MAT mat=MAT::Random();
>
>  VECT vect=VECT::Random();
>
>  applyBlockHouseholderOnTheRight(A,mat,vect);
>
>
>
>  return 0;
>
> }
>
>
>
> I get this (rather long) error message, telling me that gcc is trying to
>
> consider  V.triangularView<UnitLower>() as (V.triangularView) <
>
> (UnitLower>(...something...))  :


This is again a general c++ issue, not at all eigen specific: since
the type of V depends on template params, when you call a templated
method on it, you must write "template" like this:

    V.template triangularView<UnitLower>()

Benoit

>
>
>
> /home/vlj/Sources/cudalinalg/eigen-fork/src/QR.h: In function ‘void
>
> GPU::applyBlockHouseholderOnTheRight(Derived&, const Derived&, const
>
> Eigen::Matrix<typename _MatrixType::Scalar, _MatrixType::RowsAtCompileTime,
>
> 1, ((Eigen::._89)0u | (((_MatrixType::RowsAtCompileTime == 1) && (1 != 1))
>
> ? (Eigen::._89)1u : (((1 == 1) && (_MatrixType::RowsAtCompileTime != 1)) ?
>
> (Eigen::._89)0u : (Eigen::._89)0u))), _MatrixType::RowsAtCompileTime,
>
> 1>&)’:
>
> /home/vlj/Sources/cudalinalg/eigen-fork/src/QR.h:45: error: expected
>
> primary-expression before ‘)’ token
>
> /home/vlj/Sources/cudalinalg/eigen-fork/src/QR.h:45: error: expected
>
> primary-expression before ‘)’ token
>
> /home/vlj/Sources/cudalinalg/eigen-fork/src/QR.h: In function ‘void
>
> GPU::applyBlockHouseholderOnTheRight(Derived&, const Derived&, const
>
> Eigen::Matrix<typename _MatrixType::Scalar, _MatrixType::RowsAtCompileTime,
>
> 1, ((Eigen::._89)0u | (((_MatrixType::RowsAtCompileTime == 1) && (1 != 1))
>
> ? (Eigen::._89)1u : (((1 == 1) && (_MatrixType::RowsAtCompileTime != 1)) ?
>
> (Eigen::._89)0u : (Eigen::._89)0u))), _MatrixType::RowsAtCompileTime, 1>&)
>
> [with Derived = MAT]’:
>
> /home/vlj/Sources/cudalinalg/eigen-fork/tests/blockhouseholder.cpp:44:
>
> instantiated from here
>
> /home/vlj/Sources/cudalinalg/eigen-fork/src/QR.h:45: error: no match for
>
> ‘operator*’ in ‘A * V->Eigen::MatrixBase::triangularView [with unsigned int
>
> Mode = Mode, Derived = Eigen::Matrix<double, 4, 4, 0, 4, 4>]’
>
> /home/vlj/Sources/cudalinalg/eigen-fork/eigen-ref/Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:64:
>
> note: candidates are: const
>
> Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple_op<typename
>
> Eigen::ei_traits<Derived>::Scalar>, Derived>
>
> Eigen::MatrixBase<Derived>::operator*(const typename
>
> Eigen::ei_traits<Derived>::Scalar&) const [with Derived =
>
> Eigen::Matrix<double, 4, 4, 0, 4, 4>]
>
> /home/vlj/Sources/cudalinalg/eigen-fork/eigen-ref/Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:84:
>
> note:                 const
>
> Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple2_op<typename
>
> Eigen::ei_traits<Derived>::Scalar, std::complex<typename
>
> Eigen::ei_traits<Derived>::Scalar> >, Derived>
>
> Eigen::MatrixBase<Derived>::operator*(const std::complex<typename
>
> Eigen::ei_traits<Derived>::Scalar>&) const [with Derived =
>
> Eigen::Matrix<double, 4, 4, 0, 4, 4>]
>
> /home/vlj/Sources/cudalinalg/eigen-fork/eigen-ref/Eigen/src/Geometry/Scaling.h:119:
>
> note:                 const
>
> Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple_op<typename
>
> Eigen::ei_traits<Derived>::Scalar>, Derived>
>
> Eigen::MatrixBase<Derived>::operator*(const Eigen::UniformScaling<typename
>
> Eigen::ei_traits<Derived>::Scalar>&) const [with Derived =
>
> Eigen::Matrix<double, 4, 4, 0, 4, 4>]
>
> /usr/include/c++/4.4/complex:397: note:                 std::complex<_Tp>
>
> std::operator*(const _Tp&, const std::complex<_Tp>&) [with _Tp =
>
> Eigen::Matrix<double, 4, 4, 0, 4, 4>]
>
> /home/vlj/Sources/cudalinalg/eigen-fork/eigen-ref/Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:95:
>
> note:                 const
>
> Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple2_op<double,
>
> std::complex<double> >, Eigen::Matrix<double, 4, 4, 0, 4, 4> >
>
> Eigen::operator*(const std::complex<double>&, const
>
> Eigen::MatrixBase<Eigen::Matrix<double, 4, 4, 0, 4, 4> >&)
>
> /home/vlj/Sources/cudalinalg/eigen-fork/eigen-ref/Eigen/src/Core/../plugins/CommonCwiseUnaryOps.h:91:
>
> note:                 const
>
> Eigen::CwiseUnaryOp<Eigen::ei_scalar_multiple_op<double>,
>
> Eigen::Matrix<double, 4, 4, 0, 4, 4> > Eigen::operator*(const double&,
>
> const Eigen::MatrixBase<Eigen::Matrix<double, 4, 4, 0, 4, 4> >&)
>
>
>
>
>
> I'm a bit stuck in front of this compilation error...
>
>
>
>
>
> On Thu, 20 May 2010 08:08:51 -0400, Benoit Jacob
>
> <jacob.benoit.1@xxxxxxxxx>
>
> wrote:
>
>> Fun coincidence: the problem you were hitting was exaclty issue A2 in
>
>> the link that Hauke just sent to this list (see thread "very
>
>> interesting...").
>
>>
>
>> You can't bind a ref-to-non-const to a temporary.
>
>>
>
>> The solution in your case is to make that temporary a named variable.
>
>> Not any more inefficient than what you were trying to do.
>
>>
>
>> See attached file.
>
>>
>
>> Benoit
>
>>
>
>> 2010/5/20  <vincent.lejeune@xxxxxxxxxx>:
>
>>>
>
>>> Of course :
>
>>>
>
>>>
>
>>>
>
>>> #include <QR.h>
>
>>>
>
>>> using namespace Eigen;
>
>>>
>
>>>
>
>>>
>
>>> typedef  Matrix<double,4,4> MAT;
>
>>>
>
>>> typedef  Matrix<double,4,1> VECT;
>
>>>
>
>>>
>
>>>
>
>>>  template<typename MatrixType>
>
>>>
>
>>>  MatrixType triangfactor(MatrixType& V,
>
>>>
>
>>>      Matrix<typename
>
>>> MatrixType::Scalar,MatrixType::RowsAtCompileTime,1>&
>
>>>
>
>>> coeffs)
>
>>>
>
>>>  {
>
>>>
>
>>>    typedef typename MatrixType::Scalar Scalar;
>
>>>
>
>>>    const int k=coeffs.size();
>
>>>
>
>>>
>
>>>
>
>>>    ei_assert(V.cols()==k && V.rows()>=k && "Vector storing Matrix must
>
>>>
>
>>> have same columns than coeffs size and more rows than columns");
>
>>>
>
>>>
>
>>>
>
>>>
>
>>>
>
>>>    MatrixType ret=MatrixType::Zero(k,k);
>
>>>
>
>>>    const int j=k;
>
>>>
>
>>>
>
>>>
>
>>>    for(int i=0;i<k;i++)
>
>>>
>
>>>    {
>
>>>
>
>>>      Scalar Vii=V(i,i);
>
>>>
>
>>>      V(i,i)=1;
>
>>>
>
>>>      ret.block(0,i,i,1) = - coeffs(i,0) *
>
> V.block(i,0,j-i,i).transpose()
>
>>>
>
>>> * V.block(i,i,j-i,1);
>
>>>
>
>>>      V(i,i)=Vii;
>
>>>
>
>>>      ret.block(0,i,i,1)=ret.block(0,0,i,i)*ret.block(0,i,i,1);
>
>>>
>
>>>      ret(i,i)=coeffs(i,0);
>
>>>
>
>>>    }
>
>>>
>
>>>    return ret;
>
>>>
>
>>>  }
>
>>>
>
>>>
>
>>>
>
>>> int main()
>
>>>
>
>>> {
>
>>>
>
>>>  MAT mat=MAT::Random();
>
>>>
>
>>>  VECT vect=VECT::Random();
>
>>>
>
>>>  MAT tst=triangfactor(MAT(mat.triangularView<Lower>()),vect);
>
>>>
>
>>>  cout<<tst<<endl<<endl;
>
>>>
>
>>>
>
>>>
>
>>>  return 0;
>
>>>
>
>>> }
>
>>>
>
>>>
>
>>>
>
>>>
>
>>>
>
>>>
>
>>>
>
>>>
>
>>>
>
>>>
>
>>>
>
>>> On Thu, 20 May 2010 07:16:26 -0400, Benoit Jacob
>
>>>
>
>>> <jacob.benoit.1@xxxxxxxxx>
>
>>>
>
>>> wrote:
>
>>>
>
>>>> 2010/5/20  <vincent.lejeune@xxxxxxxxxx>:
>
>>>
>
>>>>>
>
>>>
>
>>>>> Hi,
>
>>>
>
>>>>>
>
>>>
>
>>>>>
>
>>>
>
>>>>>
>
>>>
>
>>>>> I'm trying to get the lower triangular part of a (non-square) matrix,
>
>>>
>
>>> but
>
>>>
>
>>>>>
>
>>>
>
>>>>> it seems that the part() function is deprecated in Eigen 2.91.
>
>>>
>
>>>>>
>
>>>
>
>>>>> Using mat.triangularView<Lower>(), I meet the following compile error
>
> :
>
>>>
>
>>>>
>
>>>
>
>>>> Sounds like  a bug. Can you send us a test program reproducing it?
>
>>>
>
>>>>
>
>>>
>
>>>> Benoit
>
>>>
>
>>>>
>
>>>
>
>>>>
>
>>>
>
>>>>>
>
>>>
>
>>>>>
>
>>>
>
>>>>>
>
>>>
>
>>>>> error: invalid initialization of non-const reference of type
>
>>>
>
>>>>>
>
>>>
>
>>>>> ‘Eigen::TriangularView<Eigen::Matrix<double, 4, 4, 0, 4, 4>, 1u>&’
>
>>>>> from
>
>>>
>
>>>>> a
>
>>>
>
>>>>>
>
>>>
>
>>>>> temporary of type ‘Eigen::TriangularView<Eigen::Matrix<double, 4, 4,
>
>>>>> 0,
>
>>>
>
>>>>> 4,
>
>>>
>
>>>>>
>
>>>
>
>>>>> 4>, 1u>’
>
>>>
>
>>>>>
>
>>>
>
>>>>>
>
>>>
>
>>>>>
>
>>>
>
>>>>> That I do not really understand...
>
>>>
>
>>>>>
>
>>>
>
>>>>>
>
>>>
>
>>>>>
>
>>>
>
>>>>> Thx
>
>>>
>
>>>>>
>
>>>
>
>>>>>
>
>>>
>
>>>>>
>
>>>
>
>>>
>
>>>
>
>
>



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/