| // This file is part of Eigen, a lightweight C++ template library | 
 | // for linear algebra. | 
 | // | 
 | // Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com> | 
 | // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> | 
 | // | 
 | // This Source Code Form is subject to the terms of the Mozilla | 
 | // Public License v. 2.0. If a copy of the MPL was not distributed | 
 | // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. | 
 |  | 
 | #ifndef EIGEN_HOUSEHOLDER_H | 
 | #define EIGEN_HOUSEHOLDER_H | 
 |  | 
 | // IWYU pragma: private | 
 | #include "./InternalHeaderCheck.h" | 
 |  | 
 | namespace Eigen { | 
 |  | 
 | namespace internal { | 
 | template <int n> | 
 | struct decrement_size { | 
 |   enum { ret = n == Dynamic ? n : n - 1 }; | 
 | }; | 
 | }  // namespace internal | 
 |  | 
 | /** 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$ | 
 |  * | 
 |  * The essential part of the vector \c v is stored in *this. | 
 |  * | 
 |  * On output: | 
 |  * \param tau the scaling factor of the Householder transformation | 
 |  * \param beta the result of H * \c *this | 
 |  * | 
 |  * \sa MatrixBase::makeHouseholder(), MatrixBase::applyHouseholderOnTheLeft(), | 
 |  *     MatrixBase::applyHouseholderOnTheRight() | 
 |  */ | 
 | template <typename Derived> | 
 | EIGEN_DEVICE_FUNC void MatrixBase<Derived>::makeHouseholderInPlace(Scalar& tau, RealScalar& beta) { | 
 |   VectorBlock<Derived, internal::decrement_size<Base::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() | 
 |  */ | 
 | template <typename Derived> | 
 | template <typename EssentialPart> | 
 | EIGEN_DEVICE_FUNC void MatrixBase<Derived>::makeHouseholder(EssentialPart& essential, Scalar& tau, | 
 |                                                             RealScalar& beta) const { | 
 |   using numext::conj; | 
 |   using numext::sqrt; | 
 |  | 
 |   EIGEN_STATIC_ASSERT_VECTOR_ONLY(EssentialPart) | 
 |   VectorBlock<const Derived, EssentialPart::SizeAtCompileTime> tail(derived(), 1, size() - 1); | 
 |  | 
 |   RealScalar tailSqNorm = size() == 1 ? RealScalar(0) : tail.squaredNorm(); | 
 |   Scalar c0 = coeff(0); | 
 |   const RealScalar tol = (std::numeric_limits<RealScalar>::min)(); | 
 |  | 
 |   if (tailSqNorm <= tol && numext::abs2(numext::imag(c0)) <= tol) { | 
 |     tau = RealScalar(0); | 
 |     beta = numext::real(c0); | 
 |     essential.setZero(); | 
 |   } else { | 
 |     beta = sqrt(numext::abs2(c0) + tailSqNorm); | 
 |     if (numext::real(c0) >= RealScalar(0)) beta = -beta; | 
 |     essential = tail / (c0 - beta); | 
 |     tau = conj((beta - c0) / beta); | 
 |   } | 
 | } | 
 |  | 
 | /** Apply the elementary reflector H given by | 
 |  * \f$ H = I - tau v v^*\f$ | 
 |  * with | 
 |  * \f$ v^T = [1 essential^T] \f$ | 
 |  * from the left to a vector or matrix. | 
 |  * | 
 |  * On input: | 
 |  * \param essential the essential part of the vector \c v | 
 |  * \param tau the scaling factor of the Householder transformation | 
 |  * \param workspace a pointer to working space with at least | 
 |  *                  this->cols() entries | 
 |  * | 
 |  * \sa MatrixBase::makeHouseholder(), MatrixBase::makeHouseholderInPlace(), | 
 |  *     MatrixBase::applyHouseholderOnTheRight() | 
 |  */ | 
 | template <typename Derived> | 
 | template <typename EssentialPart> | 
 | EIGEN_DEVICE_FUNC void MatrixBase<Derived>::applyHouseholderOnTheLeft(const EssentialPart& essential, const Scalar& tau, | 
 |                                                                       Scalar* workspace) { | 
 |   if (rows() == 1) { | 
 |     *this *= Scalar(1) - tau; | 
 |   } else if (!numext::is_exactly_zero(tau)) { | 
 |     Map<typename internal::plain_row_type<PlainObject>::type> tmp(workspace, cols()); | 
 |     Block<Derived, EssentialPart::SizeAtCompileTime, Derived::ColsAtCompileTime> bottom(derived(), 1, 0, rows() - 1, | 
 |                                                                                         cols()); | 
 |     tmp.noalias() = essential.adjoint() * bottom; | 
 |     tmp += this->row(0); | 
 |     this->row(0) -= tau * tmp; | 
 |     bottom.noalias() -= tau * essential * tmp; | 
 |   } | 
 | } | 
 |  | 
 | /** Apply the elementary reflector H given by | 
 |  * \f$ H = I - tau v v^*\f$ | 
 |  * with | 
 |  * \f$ v^T = [1 essential^T] \f$ | 
 |  * from the right to a vector or matrix. | 
 |  * | 
 |  * On input: | 
 |  * \param essential the essential part of the vector \c v | 
 |  * \param tau the scaling factor of the Householder transformation | 
 |  * \param workspace a pointer to working space with at least | 
 |  *                  this->rows() entries | 
 |  * | 
 |  * \sa MatrixBase::makeHouseholder(), MatrixBase::makeHouseholderInPlace(), | 
 |  *     MatrixBase::applyHouseholderOnTheLeft() | 
 |  */ | 
 | template <typename Derived> | 
 | template <typename EssentialPart> | 
 | EIGEN_DEVICE_FUNC void MatrixBase<Derived>::applyHouseholderOnTheRight(const EssentialPart& essential, | 
 |                                                                        const Scalar& tau, Scalar* workspace) { | 
 |   if (cols() == 1) { | 
 |     *this *= Scalar(1) - tau; | 
 |   } else if (!numext::is_exactly_zero(tau)) { | 
 |     Map<typename internal::plain_col_type<PlainObject>::type> tmp(workspace, rows()); | 
 |     Block<Derived, Derived::RowsAtCompileTime, EssentialPart::SizeAtCompileTime> right(derived(), 0, 1, rows(), | 
 |                                                                                        cols() - 1); | 
 |     tmp.noalias() = right * essential; | 
 |     tmp += this->col(0); | 
 |     this->col(0) -= tau * tmp; | 
 |     right.noalias() -= tau * tmp * essential.adjoint(); | 
 |   } | 
 | } | 
 |  | 
 | }  // end namespace Eigen | 
 |  | 
 | #endif  // EIGEN_HOUSEHOLDER_H |