1
// This file is part of Eigen, a lightweight C++ template library
4
// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
5
// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
7
// Eigen is free software; you can redistribute it and/or
8
// modify it under the terms of the GNU Lesser General Public
9
// License as published by the Free Software Foundation; either
10
// version 3 of the License, or (at your option) any later version.
12
// Alternatively, you can redistribute it and/or
13
// modify it under the terms of the GNU General Public License as
14
// published by the Free Software Foundation; either version 2 of
15
// the License, or (at your option) any later version.
17
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
20
// GNU General Public License for more details.
22
// You should have received a copy of the GNU Lesser General Public
23
// License and a copy of the GNU General Public License along with
24
// Eigen. If not, see <http://www.gnu.org/licenses/>.
26
#ifndef EIGEN_HOUSEHOLDER_H
27
#define EIGEN_HOUSEHOLDER_H
30
template<int n> struct decrement_size
33
ret = n==Dynamic ? n : n-1
38
template<typename Derived>
39
void MatrixBase<Derived>::makeHouseholderInPlace(Scalar& tau, RealScalar& beta)
41
VectorBlock<Derived, internal::decrement_size<Base::SizeAtCompileTime>::ret> essentialPart(derived(), 1, size()-1);
42
makeHouseholder(essentialPart, tau, beta);
45
/** Computes the elementary reflector H such that:
46
* \f$ H *this = [ beta 0 ... 0]^T \f$
47
* where the transformation H is:
48
* \f$ H = I - tau v v^*\f$
49
* and the vector v is:
50
* \f$ v^T = [1 essential^T] \f$
53
* \param essential the essential part of the vector \c v
54
* \param tau the scaling factor of the householder transformation
55
* \param beta the result of H * \c *this
57
* \sa MatrixBase::makeHouseholderInPlace(), MatrixBase::applyHouseholderOnTheLeft(),
58
* MatrixBase::applyHouseholderOnTheRight()
60
template<typename Derived>
61
template<typename EssentialPart>
62
void MatrixBase<Derived>::makeHouseholder(
63
EssentialPart& essential,
65
RealScalar& beta) const
67
EIGEN_STATIC_ASSERT_VECTOR_ONLY(EssentialPart)
68
VectorBlock<const Derived, EssentialPart::SizeAtCompileTime> tail(derived(), 1, size()-1);
70
RealScalar tailSqNorm = size()==1 ? RealScalar(0) : tail.squaredNorm();
73
if(tailSqNorm == RealScalar(0) && internal::imag(c0)==RealScalar(0))
76
beta = internal::real(c0);
81
beta = internal::sqrt(internal::abs2(c0) + tailSqNorm);
82
if (internal::real(c0)>=RealScalar(0))
84
essential = tail / (c0 - beta);
85
tau = internal::conj((beta - c0) / beta);
89
template<typename Derived>
90
template<typename EssentialPart>
91
void MatrixBase<Derived>::applyHouseholderOnTheLeft(
92
const EssentialPart& essential,
98
*this *= Scalar(1)-tau;
102
Map<typename internal::plain_row_type<PlainObject>::type> tmp(workspace,cols());
103
Block<Derived, EssentialPart::SizeAtCompileTime, Derived::ColsAtCompileTime> bottom(derived(), 1, 0, rows()-1, cols());
104
tmp.noalias() = essential.adjoint() * bottom;
106
this->row(0) -= tau * tmp;
107
bottom.noalias() -= tau * essential * tmp;
111
template<typename Derived>
112
template<typename EssentialPart>
113
void MatrixBase<Derived>::applyHouseholderOnTheRight(
114
const EssentialPart& essential,
120
*this *= Scalar(1)-tau;
124
Map<typename internal::plain_col_type<PlainObject>::type> tmp(workspace,rows());
125
Block<Derived, Derived::RowsAtCompileTime, EssentialPart::SizeAtCompileTime> right(derived(), 0, 1, rows(), cols()-1);
126
tmp.noalias() = right * essential.conjugate();
128
this->col(0) -= tau * tmp;
129
right.noalias() -= tau * tmp * essential.transpose();
133
#endif // EIGEN_HOUSEHOLDER_H