* Fix #97 : Householder operations on 1x1 matrices

* Fix VectorBlock on 1x1 "vectors"
* remove useless makeTrivialHouseholder function
This commit is contained in:
Benoit Jacob 2010-03-08 12:37:04 -05:00
parent 4293a4d1af
commit 89343a38af
2 changed files with 45 additions and 27 deletions

View File

@ -59,20 +59,33 @@ template<typename VectorType, int Size>
struct ei_traits<VectorBlock<VectorType, Size> > struct ei_traits<VectorBlock<VectorType, Size> >
: public ei_traits<Block<VectorType, : public ei_traits<Block<VectorType,
ei_traits<VectorType>::RowsAtCompileTime==1 ? 1 : Size, ei_traits<VectorType>::RowsAtCompileTime==1 ? 1 : Size,
ei_traits<VectorType>::ColsAtCompileTime==1 ? 1 : Size> > ei_traits<VectorType>::ColsAtCompileTime==1
// handle the 1x1 case. Taking a dynamic-sized vectorblock in a 1x1 xpr.
// example: when doing HouseholderQR<Matrix<float,1,1> >.
&& ei_traits<VectorType>::RowsAtCompileTime!=1
? 1 : Size> >
{ {
}; };
template<typename VectorType, int Size> class VectorBlock template<typename VectorType, int Size> class VectorBlock
: public Block<VectorType, : public Block<VectorType,
ei_traits<VectorType>::RowsAtCompileTime==1 ? 1 : Size, ei_traits<VectorType>::RowsAtCompileTime==1 ? 1 : Size,
ei_traits<VectorType>::ColsAtCompileTime==1 ? 1 : Size> ei_traits<VectorType>::ColsAtCompileTime==1
// handle the 1x1 case. Taking a dynamic-sized vectorblock in a 1x1 xpr.
// example: when doing HouseholderQR<Matrix<float,1,1> >.
&& ei_traits<VectorType>::RowsAtCompileTime!=1
? 1 : Size>
{ {
typedef Block<VectorType, typedef Block<VectorType,
ei_traits<VectorType>::RowsAtCompileTime==1 ? 1 : Size, ei_traits<VectorType>::RowsAtCompileTime==1 ? 1 : Size,
ei_traits<VectorType>::ColsAtCompileTime==1 ? 1 : Size> Base; ei_traits<VectorType>::ColsAtCompileTime==1
// handle the 1x1 case. Taking a dynamic-sized vectorblock in a 1x1 xpr.
// example: when doing HouseholderQR<Matrix<float,1,1> >.
&& ei_traits<VectorType>::RowsAtCompileTime!=1
? 1 : Size
> Base;
enum { enum {
IsColVector = ei_traits<VectorType>::ColsAtCompileTime==1 IsColVector = ei_traits<VectorType>::ColsAtCompileTime==1 && ei_traits<VectorType>::RowsAtCompileTime!=1
}; };
public: public:
EIGEN_DENSE_PUBLIC_INTERFACE(VectorBlock) EIGEN_DENSE_PUBLIC_INTERFACE(VectorBlock)

View File

@ -29,19 +29,10 @@
template<int n> struct ei_decrement_size template<int n> struct ei_decrement_size
{ {
enum { enum {
ret = (n==1 || n==Dynamic) ? n : n-1 ret = n==Dynamic ? n : n-1
}; };
}; };
template<typename EssentialPart>
void makeTrivialHouseholder(
EssentialPart &essential,
typename EssentialPart::RealScalar &beta)
{
beta = typename EssentialPart::RealScalar(0);
essential.setZero();
}
template<typename Derived> template<typename Derived>
void MatrixBase<Derived>::makeHouseholderInPlace(Scalar& tau, RealScalar& beta) void MatrixBase<Derived>::makeHouseholderInPlace(Scalar& tau, RealScalar& beta)
{ {
@ -98,6 +89,12 @@ void MatrixBase<Derived>::applyHouseholderOnTheLeft(
const EssentialPart& essential, const EssentialPart& essential,
const Scalar& tau, const Scalar& tau,
Scalar* workspace) Scalar* workspace)
{
if(rows() == 1)
{
*this *= Scalar(1)-tau;
}
else
{ {
Map<Matrix<Scalar, 1, Base::ColsAtCompileTime, PlainObject::Options, 1, Base::MaxColsAtCompileTime> > tmp(workspace,cols()); Map<Matrix<Scalar, 1, Base::ColsAtCompileTime, PlainObject::Options, 1, Base::MaxColsAtCompileTime> > tmp(workspace,cols());
Block<Derived, EssentialPart::SizeAtCompileTime, Derived::ColsAtCompileTime> bottom(derived(), 1, 0, rows()-1, cols()); Block<Derived, EssentialPart::SizeAtCompileTime, Derived::ColsAtCompileTime> bottom(derived(), 1, 0, rows()-1, cols());
@ -106,6 +103,7 @@ void MatrixBase<Derived>::applyHouseholderOnTheLeft(
this->row(0) -= tau * tmp; this->row(0) -= tau * tmp;
bottom.noalias() -= tau * essential * tmp; bottom.noalias() -= tau * essential * tmp;
} }
}
template<typename Derived> template<typename Derived>
template<typename EssentialPart> template<typename EssentialPart>
@ -113,6 +111,12 @@ void MatrixBase<Derived>::applyHouseholderOnTheRight(
const EssentialPart& essential, const EssentialPart& essential,
const Scalar& tau, const Scalar& tau,
Scalar* workspace) Scalar* workspace)
{
if(cols() == 1)
{
*this *= Scalar(1)-tau;
}
else
{ {
Map<Matrix<Scalar, Base::RowsAtCompileTime, 1, PlainObject::Options, Base::MaxRowsAtCompileTime, 1> > tmp(workspace,rows()); Map<Matrix<Scalar, Base::RowsAtCompileTime, 1, PlainObject::Options, Base::MaxRowsAtCompileTime, 1> > tmp(workspace,rows());
Block<Derived, Derived::RowsAtCompileTime, EssentialPart::SizeAtCompileTime> right(derived(), 0, 1, rows(), cols()-1); Block<Derived, Derived::RowsAtCompileTime, EssentialPart::SizeAtCompileTime> right(derived(), 0, 1, rows(), cols()-1);
@ -121,5 +125,6 @@ void MatrixBase<Derived>::applyHouseholderOnTheRight(
this->col(0) -= tau * tmp; this->col(0) -= tau * tmp;
right.noalias() -= tau * tmp * essential.transpose(); right.noalias() -= tau * tmp * essential.transpose();
} }
}
#endif // EIGEN_HOUSEHOLDER_H #endif // EIGEN_HOUSEHOLDER_H