Re: [eigen] How to get triangular lower part of a matrix with dev branche ? |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/eigen Archives
]
- To: eigen@xxxxxxxxxxxxxxxxxxx
- Subject: Re: [eigen] How to get triangular lower part of a matrix with dev branche ?
- From: Benoit Jacob <jacob.benoit.1@xxxxxxxxx>
- Date: Thu, 20 May 2010 09:51:44 -0400
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:received:in-reply-to :references:date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=qip+R/AeVTnbjbe2bRHT+t93TI3xN3SXfaf2fo96YWQ=; b=ClqHQmhN8+hviEUHGypJ+0/pnDiZkMlXU5p7ZRKXyCXk1FCbzaVkPuwy4oIjsNhkZq xtAjdTmGD0PWc3oW1qI5McMYNOZ6X8hLfaY2lFm8GNXKK0StenQdsV8OOHJWXywrIUNW e/bFoDvHZfrZ7E5zuJiI9Vzq4FeINlTkCJBgs=
- Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=UYvtDZ4DTvA5cWlT+5aZjkjEf7xS2JYNxVL32mZFwhcOXJSNMT2KXrPjunmT9d36rZ cPE1ZRWQXhJMEn4TW2Zslaq/bOTWZy8W6zkxF3EeNHQ8jAWuRwqXEDoXlbX6cdkUSvKF tI4yVZqoLbsZdYWq1vQGi3WCDfLke3JmD+fd0=
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
>
>>>
>
>>>>>
>
>>>
>
>>>>>
>
>>>
>
>>>>>
>
>>>
>
>>>
>
>>>
>
>
>