// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2009 Gael Guennebaud // // 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_SELFADJOINTRANK2UPTADE_H #define EIGEN_SELFADJOINTRANK2UPTADE_H namespace Eigen { namespace internal { /* Optimized selfadjoint matrix += alpha * uv' + conj(alpha)*vu' * It corresponds to the Level2 syr2 BLAS routine */ template struct selfadjoint_rank2_update_selector; template struct 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) += (conj(alpha) * conj(u.coeff(i))) * v.tail(size-i) + (alpha * conj(v.coeff(i))) * u.tail(size-i); } } }; template struct 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) += (conj(alpha) * conj(u.coeff(i))) * v.head(i+1) + (alpha * conj(v.coeff(i))) * u.head(i+1); } }; template struct conj_expr_if : conditional::Scalar>,T> > {}; } // end namespace internal template template SelfAdjointView& SelfAdjointView ::rankUpdate(const MatrixBase& u, const MatrixBase& v, Scalar alpha) { typedef internal::blas_traits UBlasTraits; typedef typename UBlasTraits::DirectLinearAccessType ActualUType; typedef typename internal::remove_all::type _ActualUType; typename internal::add_const_on_value_type::type actualU = UBlasTraits::extract(u.derived()); typedef internal::blas_traits VBlasTraits; typedef typename VBlasTraits::DirectLinearAccessType ActualVType; typedef typename internal::remove_all::type _ActualVType; typename internal::add_const_on_value_type::type actualV = VBlasTraits::extract(v.derived()); // If MatrixType is row major, then we use the routine for lower triangular in the upper triangular case and // vice versa, and take the complex conjugate of all coefficients and vector entries. enum { IsRowMajor = (internal::traits::Flags&RowMajorBit) ? 1 : 0 }; Scalar actualAlpha = alpha * UBlasTraits::extractScalarFactor(u.derived()) * internal::conj(VBlasTraits::extractScalarFactor(v.derived())); if (IsRowMajor) actualAlpha = internal::conj(actualAlpha); internal::selfadjoint_rank2_update_selector::type>::type, typename internal::remove_all::type>::type, (IsRowMajor ? int(UpLo==Upper ? Lower : Upper) : UpLo)> ::run(_expression().const_cast_derived().data(),_expression().outerStride(),actualU,actualV,actualAlpha); return *this; } } // end namespace Eigen #endif // EIGEN_SELFADJOINTRANK2UPTADE_H