diff options
Diffstat (limited to 'eigen/blas/PackedTriangularMatrixVector.h')
-rw-r--r-- | eigen/blas/PackedTriangularMatrixVector.h | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/eigen/blas/PackedTriangularMatrixVector.h b/eigen/blas/PackedTriangularMatrixVector.h new file mode 100644 index 0000000..e9886d5 --- /dev/null +++ b/eigen/blas/PackedTriangularMatrixVector.h @@ -0,0 +1,79 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net> +// +// 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_PACKED_TRIANGULAR_MATRIX_VECTOR_H +#define EIGEN_PACKED_TRIANGULAR_MATRIX_VECTOR_H + +namespace internal { + +template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs, int StorageOrder> +struct packed_triangular_matrix_vector_product; + +template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs> +struct packed_triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,ColMajor> +{ + typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar; + enum { + IsLower = (Mode & Lower) ==Lower, + HasUnitDiag = (Mode & UnitDiag)==UnitDiag, + HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag + }; + static void run(Index size, const LhsScalar* lhs, const RhsScalar* rhs, ResScalar* res, ResScalar alpha) + { + internal::conj_if<ConjRhs> cj; + typedef Map<const Matrix<LhsScalar,Dynamic,1> > LhsMap; + typedef typename conj_expr_if<ConjLhs,LhsMap>::type ConjLhsType; + typedef Map<Matrix<ResScalar,Dynamic,1> > ResMap; + + for (Index i=0; i<size; ++i) + { + Index s = IsLower&&(HasUnitDiag||HasZeroDiag) ? 1 : 0; + Index r = IsLower ? size-i: i+1; + if (EIGEN_IMPLIES(HasUnitDiag||HasZeroDiag, (--r)>0)) + ResMap(res+(IsLower ? s+i : 0),r) += alpha * cj(rhs[i]) * ConjLhsType(LhsMap(lhs+s,r)); + if (HasUnitDiag) + res[i] += alpha * cj(rhs[i]); + lhs += IsLower ? size-i: i+1; + } + }; +}; + +template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs> +struct packed_triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,RowMajor> +{ + typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar; + enum { + IsLower = (Mode & Lower) ==Lower, + HasUnitDiag = (Mode & UnitDiag)==UnitDiag, + HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag + }; + static void run(Index size, const LhsScalar* lhs, const RhsScalar* rhs, ResScalar* res, ResScalar alpha) + { + internal::conj_if<ConjRhs> cj; + typedef Map<const Matrix<LhsScalar,Dynamic,1> > LhsMap; + typedef typename conj_expr_if<ConjLhs,LhsMap>::type ConjLhsType; + typedef Map<const Matrix<RhsScalar,Dynamic,1> > RhsMap; + typedef typename conj_expr_if<ConjRhs,RhsMap>::type ConjRhsType; + + for (Index i=0; i<size; ++i) + { + Index s = !IsLower&&(HasUnitDiag||HasZeroDiag) ? 1 : 0; + Index r = IsLower ? i+1 : size-i; + if (EIGEN_IMPLIES(HasUnitDiag||HasZeroDiag, (--r)>0)) + res[i] += alpha * (ConjLhsType(LhsMap(lhs+s,r)).cwiseProduct(ConjRhsType(RhsMap(rhs+(IsLower ? 0 : s+i),r)))).sum(); + if (HasUnitDiag) + res[i] += alpha * cj(rhs[i]); + lhs += IsLower ? i+1 : size-i; + } + }; +}; + +} // end namespace internal + +#endif // EIGEN_PACKED_TRIANGULAR_MATRIX_VECTOR_H |