// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2009 Gael Guennebaud // // 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_SELFADJOINTRANK2UPTADE_H #define EIGEN_SELFADJOINTRANK2UPTADE_H /* Optimized selfadjoint matrix += alpha * uv' + vu' * It corresponds to the Level2 syr2 BLAS routine */ template struct ei_selfadjoint_rank2_update_selector; template struct ei_selfadjoint_rank2_update_selector { static void run(Scalar* mat, Index stride, const UType& u, const VType& v, Scalar alpha) { const Index size = u.size(); for (Index i=0; i >(mat+stride*i+i, size-i) += (alpha * ei_conj(u.coeff(i))) * v.tail(size-i) + (alpha * ei_conj(v.coeff(i))) * u.tail(size-i); } } }; template struct ei_selfadjoint_rank2_update_selector { static void run(Scalar* mat, Index stride, const UType& u, const VType& v, Scalar alpha) { const Index size = u.size(); for (Index i=0; i >(mat+stride*i, i+1) += (alpha * ei_conj(u.coeff(i))) * v.head(i+1) + (alpha * ei_conj(v.coeff(i))) * u.head(i+1); } }; template struct ei_conj_expr_if : ei_meta_if::Scalar>,T> > {}; template template SelfAdjointView& SelfAdjointView ::rankUpdate(const MatrixBase& u, const MatrixBase& v, Scalar alpha) { typedef ei_blas_traits UBlasTraits; typedef typename UBlasTraits::DirectLinearAccessType ActualUType; typedef typename ei_cleantype::type _ActualUType; const ActualUType actualU = UBlasTraits::extract(u.derived()); typedef ei_blas_traits VBlasTraits; typedef typename VBlasTraits::DirectLinearAccessType ActualVType; typedef typename ei_cleantype::type _ActualVType; const ActualVType actualV = VBlasTraits::extract(v.derived()); Scalar actualAlpha = alpha * UBlasTraits::extractScalarFactor(u.derived()) * VBlasTraits::extractScalarFactor(v.derived()); enum { IsRowMajor = (ei_traits::Flags&RowMajorBit) ? 1 : 0 }; ei_selfadjoint_rank2_update_selector::ret>::type, typename ei_cleantype::ret>::type, (IsRowMajor ? int(UpLo==Upper ? Lower : Upper) : UpLo)> ::run(const_cast(_expression().data()),_expression().outerStride(),actualU,actualV,actualAlpha); return *this; } #endif // EIGEN_SELFADJOINTRANK2UPTADE_H