2009-08-03 16:06:57 +02:00
|
|
|
// This file is part of Eigen, a lightweight C++ template library
|
|
|
|
|
// for linear algebra.
|
|
|
|
|
//
|
|
|
|
|
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
2009-08-22 01:13:21 -04:00
|
|
|
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr>
|
2009-08-03 16:06:57 +02:00
|
|
|
//
|
|
|
|
|
// Eigen is free software; you can redistribute it and/or
|
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
|
// version 3 of the License, or (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// Alternatively, you can redistribute it and/or
|
|
|
|
|
// modify it under the terms of the GNU General Public License as
|
|
|
|
|
// published by the Free Software Foundation; either version 2 of
|
|
|
|
|
// the License, or (at your option) any later version.
|
|
|
|
|
//
|
|
|
|
|
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
|
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
// License and a copy of the GNU General Public License along with
|
|
|
|
|
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
#ifndef EIGEN_HOUSEHOLDER_H
|
|
|
|
|
#define EIGEN_HOUSEHOLDER_H
|
|
|
|
|
|
|
|
|
|
template<int n> struct ei_decrement_size
|
|
|
|
|
{
|
|
|
|
|
enum {
|
|
|
|
|
ret = (n==1 || n==Dynamic) ? n : n-1
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
2009-08-09 16:58:13 +02:00
|
|
|
template<typename EssentialPart>
|
|
|
|
|
void makeTrivialHouseholder(
|
|
|
|
|
EssentialPart *essential,
|
|
|
|
|
typename EssentialPart::RealScalar *beta)
|
|
|
|
|
{
|
|
|
|
|
*beta = typename EssentialPart::RealScalar(0);
|
|
|
|
|
essential->setZero();
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-16 19:22:15 +02:00
|
|
|
template<typename Derived>
|
2009-08-17 17:04:32 +02:00
|
|
|
void MatrixBase<Derived>::makeHouseholderInPlace(Scalar *tau, RealScalar *beta)
|
2009-08-16 19:22:15 +02:00
|
|
|
{
|
|
|
|
|
VectorBlock<Derived, ei_decrement_size<SizeAtCompileTime>::ret> essentialPart(derived(), 1, size()-1);
|
|
|
|
|
makeHouseholder(&essentialPart, tau, beta);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Computes the elementary reflector H such that:
|
|
|
|
|
* \f$ H *this = [ beta 0 ... 0]^T \f$
|
|
|
|
|
* where the transformation H is:
|
|
|
|
|
* \f$ H = I - tau v v^*\f$
|
|
|
|
|
* and the vector v is:
|
|
|
|
|
* \f$ v^T = [1 essential^T] \f$
|
|
|
|
|
*
|
|
|
|
|
* On output:
|
|
|
|
|
* \param essential the essential part of the vector \c v
|
|
|
|
|
* \param tau the scaling factor of the householder transformation
|
|
|
|
|
* \param beta the result of H * \c *this
|
|
|
|
|
*
|
|
|
|
|
* \sa MatrixBase::makeHouseholderInPlace(), MatrixBase::applyHouseholderOnTheLeft(),
|
|
|
|
|
* MatrixBase::applyHouseholderOnTheRight()
|
|
|
|
|
*/
|
2009-08-03 16:06:57 +02:00
|
|
|
template<typename Derived>
|
|
|
|
|
template<typename EssentialPart>
|
|
|
|
|
void MatrixBase<Derived>::makeHouseholder(
|
|
|
|
|
EssentialPart *essential,
|
2009-08-17 17:04:32 +02:00
|
|
|
Scalar *tau,
|
|
|
|
|
RealScalar *beta) const
|
2009-08-03 16:06:57 +02:00
|
|
|
{
|
|
|
|
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(EssentialPart)
|
2009-08-17 17:04:32 +02:00
|
|
|
VectorBlock<Derived, EssentialPart::SizeAtCompileTime> tail(derived(), 1, size()-1);
|
|
|
|
|
|
2009-08-24 00:02:22 -04:00
|
|
|
RealScalar tailSqNorm = size()==1 ? 0 : tail.squaredNorm();
|
2009-08-17 17:04:32 +02:00
|
|
|
Scalar c0 = coeff(0);
|
|
|
|
|
|
2009-08-24 00:23:35 -04:00
|
|
|
if(tailSqNorm == RealScalar(0) && ei_imag(c0)==RealScalar(0))
|
2009-08-03 16:06:57 +02:00
|
|
|
{
|
2009-08-17 17:04:32 +02:00
|
|
|
*tau = 0;
|
|
|
|
|
*beta = ei_real(c0);
|
2009-08-03 16:06:57 +02:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2009-08-17 17:04:32 +02:00
|
|
|
*beta = ei_sqrt(ei_abs2(c0) + tailSqNorm);
|
|
|
|
|
if (ei_real(c0)>=0.)
|
|
|
|
|
*beta = -*beta;
|
|
|
|
|
*essential = tail / (c0 - *beta);
|
|
|
|
|
*tau = ei_conj((*beta - c0) / *beta);
|
2009-08-03 16:06:57 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename Derived>
|
|
|
|
|
template<typename EssentialPart>
|
|
|
|
|
void MatrixBase<Derived>::applyHouseholderOnTheLeft(
|
|
|
|
|
const EssentialPart& essential,
|
2009-08-17 17:04:32 +02:00
|
|
|
const Scalar& tau,
|
2009-08-16 19:22:15 +02:00
|
|
|
Scalar* workspace)
|
2009-08-03 16:06:57 +02:00
|
|
|
{
|
2009-08-16 19:22:15 +02:00
|
|
|
Map<Matrix<Scalar, 1, ColsAtCompileTime, PlainMatrixType::Options, 1, MaxColsAtCompileTime> > tmp(workspace,cols());
|
2009-08-04 00:27:58 +02:00
|
|
|
Block<Derived, EssentialPart::SizeAtCompileTime, Derived::ColsAtCompileTime> bottom(derived(), 1, 0, rows()-1, cols());
|
2009-08-16 19:22:15 +02:00
|
|
|
tmp.noalias() = essential.adjoint() * bottom;
|
2009-08-15 13:12:50 +02:00
|
|
|
tmp += row(0);
|
2009-08-16 19:22:15 +02:00
|
|
|
row(0) -= tau * tmp;
|
|
|
|
|
bottom.noalias() -= tau * essential * tmp;
|
2009-08-03 16:06:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename Derived>
|
|
|
|
|
template<typename EssentialPart>
|
|
|
|
|
void MatrixBase<Derived>::applyHouseholderOnTheRight(
|
|
|
|
|
const EssentialPart& essential,
|
2009-08-17 17:04:32 +02:00
|
|
|
const Scalar& tau,
|
2009-08-16 19:22:15 +02:00
|
|
|
Scalar* workspace)
|
2009-08-03 16:06:57 +02:00
|
|
|
{
|
2009-08-16 19:22:15 +02:00
|
|
|
Map<Matrix<Scalar, RowsAtCompileTime, 1, PlainMatrixType::Options, MaxRowsAtCompileTime, 1> > tmp(workspace,rows());
|
2009-08-04 00:27:58 +02:00
|
|
|
Block<Derived, Derived::RowsAtCompileTime, EssentialPart::SizeAtCompileTime> right(derived(), 0, 1, rows(), cols()-1);
|
2009-08-16 19:22:15 +02:00
|
|
|
tmp.noalias() = right * essential.conjugate();
|
2009-08-15 13:12:50 +02:00
|
|
|
tmp += col(0);
|
2009-08-16 19:22:15 +02:00
|
|
|
col(0) -= tau * tmp;
|
|
|
|
|
right.noalias() -= tau * tmp * essential.transpose();
|
2009-08-03 16:06:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif // EIGEN_HOUSEHOLDER_H
|