Main MRPT website > C++ reference
MRPT logo

Householder.h

Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
00005 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
00006 //
00007 // Eigen is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 3 of the License, or (at your option) any later version.
00011 //
00012 // Alternatively, you can redistribute it and/or
00013 // modify it under the terms of the GNU General Public License as
00014 // published by the Free Software Foundation; either version 2 of
00015 // the License, or (at your option) any later version.
00016 //
00017 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00018 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00019 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00020 // GNU General Public License for more details.
00021 //
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License and a copy of the GNU General Public License along with
00024 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00025 
00026 #ifndef EIGEN_HOUSEHOLDER_H
00027 #define EIGEN_HOUSEHOLDER_H
00028 
00029 namespace internal {
00030 template<int n> struct decrement_size
00031 {
00032   enum {
00033     ret = n==Dynamic ? n : n-1
00034   };
00035 };
00036 }
00037 
00038 template<typename Derived>
00039 void MatrixBase<Derived>::makeHouseholderInPlace(Scalar& tau, RealScalar& beta)
00040 {
00041   VectorBlock<Derived, internal::decrement_size<Base::SizeAtCompileTime>::ret> essentialPart(derived(), 1, size()-1);
00042   makeHouseholder(essentialPart, tau, beta);
00043 }
00044 
00045 /** Computes the elementary reflector H such that:
00046   * \f$ H *this = [ beta 0 ... 0]^T \f$
00047   * where the transformation H is:
00048   * \f$ H = I - tau v v^*\f$
00049   * and the vector v is:
00050   * \f$ v^T = [1 essential^T] \f$
00051   *
00052   * On output:
00053   * \param essential the essential part of the vector \c v
00054   * \param tau the scaling factor of the householder transformation
00055   * \param beta the result of H * \c *this
00056   *
00057   * \sa MatrixBase::makeHouseholderInPlace(), MatrixBase::applyHouseholderOnTheLeft(),
00058   *     MatrixBase::applyHouseholderOnTheRight()
00059   */
00060 template<typename Derived>
00061 template<typename EssentialPart>
00062 void MatrixBase<Derived>::makeHouseholder(
00063   EssentialPart& essential,
00064   Scalar& tau,
00065   RealScalar& beta) const
00066 {
00067   EIGEN_STATIC_ASSERT_VECTOR_ONLY(EssentialPart)
00068   VectorBlock<const Derived, EssentialPart::SizeAtCompileTime> tail(derived(), 1, size()-1);
00069   
00070   RealScalar tailSqNorm = size()==1 ? RealScalar(0) : tail.squaredNorm();
00071   Scalar c0 = coeff(0);
00072 
00073   if(tailSqNorm == RealScalar(0) && internal::imag(c0)==RealScalar(0))
00074   {
00075     tau = 0;
00076     beta = internal::real(c0);
00077   }
00078   else
00079   {
00080     beta = internal::sqrt(internal::abs2(c0) + tailSqNorm);
00081     if (internal::real(c0)>=RealScalar(0))
00082       beta = -beta;
00083     essential = tail / (c0 - beta);
00084     tau = internal::conj((beta - c0) / beta);
00085   }
00086 }
00087 
00088 template<typename Derived>
00089 template<typename EssentialPart>
00090 void MatrixBase<Derived>::applyHouseholderOnTheLeft(
00091   const EssentialPart& essential,
00092   const Scalar& tau,
00093   Scalar* workspace)
00094 {
00095   if(rows() == 1)
00096   {
00097     *this *= Scalar(1)-tau;
00098   }
00099   else
00100   {
00101     Map<typename internal::plain_row_type<PlainObject>::type> tmp(workspace,cols());
00102     Block<Derived, EssentialPart::SizeAtCompileTime, Derived::ColsAtCompileTime> bottom(derived(), 1, 0, rows()-1, cols());
00103     tmp.noalias() = essential.adjoint() * bottom;
00104     tmp += this->row(0);
00105     this->row(0) -= tau * tmp;
00106     bottom.noalias() -= tau * essential * tmp;
00107   }
00108 }
00109 
00110 template<typename Derived>
00111 template<typename EssentialPart>
00112 void MatrixBase<Derived>::applyHouseholderOnTheRight(
00113   const EssentialPart& essential,
00114   const Scalar& tau,
00115   Scalar* workspace)
00116 {
00117   if(cols() == 1)
00118   {
00119     *this *= Scalar(1)-tau;
00120   }
00121   else
00122   {
00123     Map<typename internal::plain_col_type<PlainObject>::type> tmp(workspace,rows());
00124     Block<Derived, Derived::RowsAtCompileTime, EssentialPart::SizeAtCompileTime> right(derived(), 0, 1, rows(), cols()-1);
00125     tmp.noalias() = right * essential.conjugate();
00126     tmp += this->col(0);
00127     this->col(0) -= tau * tmp;
00128     right.noalias() -= tau * tmp * essential.transpose();
00129   }
00130 }
00131 
00132 #endif // EIGEN_HOUSEHOLDER_H



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN: at Sat Mar 26 06:16:28 UTC 2011