From d10c710b15676935ccc93faf59fe0f37e0f1b7cd Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Mon, 3 Aug 2009 16:06:57 +0200 Subject: add new Householder module --- Eigen/src/Core/MatrixBase.h | 14 ++++++ Eigen/src/Householder/CMakeLists.txt | 6 +++ Eigen/src/Householder/Householder.h | 88 ++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 Eigen/src/Householder/CMakeLists.txt create mode 100644 Eigen/src/Householder/Householder.h (limited to 'Eigen/src') diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index b881c09c3..eb29c0ebe 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -40,6 +40,7 @@ template struct AnyMatrixBase Derived& derived() { return *static_cast(this); } const Derived& derived() const { return *static_cast(this); } }; + /** Common base class for all classes T such that there are overloaded operator* allowing to * multiply a MatrixBase by a T on both sides. * @@ -749,6 +750,19 @@ template class MatrixBase template Derived& lazyAssign(const SparseProduct& product); +////////// Householder module /////////// + + template + void makeHouseholder(EssentialPart *essential, + RealScalar *beta) const; + template + void applyHouseholderOnTheLeft(const EssentialPart& essential, + const RealScalar& beta); + template + void applyHouseholderOnTheRight(const EssentialPart& essential, + const RealScalar& beta); + + #ifdef EIGEN_MATRIXBASE_PLUGIN #include EIGEN_MATRIXBASE_PLUGIN #endif diff --git a/Eigen/src/Householder/CMakeLists.txt b/Eigen/src/Householder/CMakeLists.txt new file mode 100644 index 000000000..ce4937db0 --- /dev/null +++ b/Eigen/src/Householder/CMakeLists.txt @@ -0,0 +1,6 @@ +FILE(GLOB Eigen_Householder_SRCS "*.h") + +INSTALL(FILES + ${Eigen_Householder_SRCS} + DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Householder COMPONENT Devel + ) diff --git a/Eigen/src/Householder/Householder.h b/Eigen/src/Householder/Householder.h new file mode 100644 index 000000000..b5571f40d --- /dev/null +++ b/Eigen/src/Householder/Householder.h @@ -0,0 +1,88 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 Benoit Jacob +// +// 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 . + +#ifndef EIGEN_HOUSEHOLDER_H +#define EIGEN_HOUSEHOLDER_H + +template struct ei_decrement_size +{ + enum { + ret = (n==1 || n==Dynamic) ? n : n-1 + }; +}; + +template +template +void MatrixBase::makeHouseholder( + EssentialPart *essential, + RealScalar *beta) const +{ + EIGEN_STATIC_ASSERT_VECTOR_ONLY(EssentialPart) + RealScalar _squaredNorm = squaredNorm(); + Scalar c0; + if(ei_abs2(coeff(0)) <= ei_abs2(precision()) * _squaredNorm) + { + c0 = ei_sqrt(_squaredNorm); + } + else + { + Scalar sign = coeff(0) / ei_abs(coeff(0)); + c0 = coeff(0) + sign * ei_sqrt(_squaredNorm); + } + *essential = end(size()-1) / c0; // FIXME take advantage of fixed size + const RealScalar c0abs2 = ei_abs2(c0); + *beta = RealScalar(2) * c0abs2 / (c0abs2 + _squaredNorm - ei_abs2(coeff(0))); +} + +template +template +void MatrixBase::applyHouseholderOnTheLeft( + const EssentialPart& essential, + const RealScalar& beta) +{ + Matrix tmp(cols()); + tmp = row(0) + essential.adjoint() * block(1,0,rows()-1,cols()); + // FIXME take advantage of fixed size + // FIXME play with lazy() + // FIXME maybe not a good idea to use matrix product + row(0) -= beta * tmp; + block(1,0,rows()-1,cols()) -= beta * essential * tmp; +} + +template +template +void MatrixBase::applyHouseholderOnTheRight( + const EssentialPart& essential, + const RealScalar& beta) +{ + Matrix tmp(rows()); + tmp = col(0) + block(0,1,rows(),cols()-1) * essential.conjugate(); + // FIXME take advantage of fixed size + // FIXME play with lazy() + // FIXME maybe not a good idea to use matrix product + col(0) -= beta * tmp; + block(0,1,rows(),cols()-1) -= beta * tmp * essential.transpose(); +} + +#endif // EIGEN_HOUSEHOLDER_H -- cgit v1.2.3