diff --git a/dune/matrix-vector/axpy.hh b/dune/matrix-vector/axpy.hh index 3a5e13038de1a1d0d41f5f29e497f890a8b746d0..3d189a7a22465a7e41781d1c86290a7f6760c2ab 100644 --- a/dune/matrix-vector/axpy.hh +++ b/dune/matrix-vector/axpy.hh @@ -14,6 +14,90 @@ namespace Dune { namespace MatrixVector { + + /// forward declarations of internal helper classes for product operations + template <class A, class B, class C, bool AisScalar, bool BisScalar, + bool CisScalar> + struct ProductHelper; + + template <class A, class Scalar, class B, class C, bool AisScalar, + bool BisScalar, bool CisScalar> + struct ScaledProductHelper; + + + /** \brief Add a product to some matrix or vector + * + * This function computes a+=b*c. + * + * This function should tolerate all meaningful + * combinations of scalars, vectors, and matrices. + * + * a,b,c could be matrices with appropriate + * dimensions. But b can also always be a scalar + * represented by a 1-dim vector or a 1 by 1 matrix. + */ + template <class A, class B, class C> + void addProduct(A& a, const B& b, const C& c) { + ProductHelper<A, B, C, ScalarTraits<A>::isScalar, ScalarTraits<B>::isScalar, + ScalarTraits<C>::isScalar>::addProduct(a, b, c); + } + + /** \brief Subtract a product from some matrix or vector + * + * This function computes a-=b*c. + * + * This function should tolerate all meaningful + * combinations of scalars, vectors, and matrices. + * + * a,b,c could be matrices with appropriate + * dimensions. But b can also always be a scalar + * represented by a 1-dim vector or a 1 by 1 matrix. + */ + template <class A, class B, class C> + void subtractProduct(A& a, const B& b, const C& c) { + ScaledProductHelper<A, int, B, C, ScalarTraits<A>::isScalar, + ScalarTraits<B>::isScalar, + ScalarTraits<C>::isScalar>::addProduct(a, -1, b, c); + } + + /** \brief Add a scaled product to some matrix or vector + * + * This function computes a+=b*c*d. + * + * This function should tolerate all meaningful + * combinations of scalars, vectors, and matrices. + * + * a,c,d could be matrices with appropriate dimensions. But b must + * (currently) and c can also always be a scalar represented by a + * 1-dim vector or a 1 by 1 matrix. + */ + template <class A, class B, class C, class D> + typename std::enable_if<ScalarTraits<B>::isScalar, void>::type addProduct( + A& a, const B& b, const C& c, const D& d) { + ScaledProductHelper<A, B, C, D, ScalarTraits<A>::isScalar, + ScalarTraits<C>::isScalar, + ScalarTraits<D>::isScalar>::addProduct(a, b, c, d); + } + + /** \brief Subtract a scaled product from some matrix or vector + * + * This function computes a-=b*c*d. + * + * This function should tolerate all meaningful + * combinations of scalars, vectors, and matrices. + * + * a,c,d could be matrices with appropriate dimensions. But b must + * (currently) and c can also always be a scalar represented by a + * 1-dim vector or a 1 by 1 matrix. + */ + template <class A, class B, class C, class D> + typename std::enable_if<ScalarTraits<B>::isScalar, void>::type + subtractProduct(A& a, const B& b, const C& c, const D& d) { + ScaledProductHelper<A, B, C, D, ScalarTraits<A>::isScalar, + ScalarTraits<C>::isScalar, + ScalarTraits<D>::isScalar>::addProduct(a, -b, c, d); + } + /** \brief Internal helper class for product operations * */ @@ -368,78 +452,6 @@ namespace MatrixVector { } }; - /** \brief Add a product to some matrix or vector - * - * This function computes a+=b*c. - * - * This function should tolerate all meaningful - * combinations of scalars, vectors, and matrices. - * - * a,b,c could be matrices with appropriate - * dimensions. But b can also always be a scalar - * represented by a 1-dim vector or a 1 by 1 matrix. - */ - template <class A, class B, class C> - void addProduct(A& a, const B& b, const C& c) { - ProductHelper<A, B, C, ScalarTraits<A>::isScalar, ScalarTraits<B>::isScalar, - ScalarTraits<C>::isScalar>::addProduct(a, b, c); - } - - /** \brief Subtract a product from some matrix or vector - * - * This function computes a-=b*c. - * - * This function should tolerate all meaningful - * combinations of scalars, vectors, and matrices. - * - * a,b,c could be matrices with appropriate - * dimensions. But b can also always be a scalar - * represented by a 1-dim vector or a 1 by 1 matrix. - */ - template <class A, class B, class C> - void subtractProduct(A& a, const B& b, const C& c) { - ScaledProductHelper<A, int, B, C, ScalarTraits<A>::isScalar, - ScalarTraits<B>::isScalar, - ScalarTraits<C>::isScalar>::addProduct(a, -1, b, c); - } - - /** \brief Add a scaled product to some matrix or vector - * - * This function computes a+=b*c*d. - * - * This function should tolerate all meaningful - * combinations of scalars, vectors, and matrices. - * - * a,c,d could be matrices with appropriate dimensions. But b must - * (currently) and c can also always be a scalar represented by a - * 1-dim vector or a 1 by 1 matrix. - */ - template <class A, class B, class C, class D> - typename std::enable_if<ScalarTraits<B>::isScalar, void>::type addProduct( - A& a, const B& b, const C& c, const D& d) { - ScaledProductHelper<A, B, C, D, ScalarTraits<A>::isScalar, - ScalarTraits<C>::isScalar, - ScalarTraits<D>::isScalar>::addProduct(a, b, c, d); - } - - /** \brief Subtract a scaled product from some matrix or vector - * - * This function computes a-=b*c*d. - * - * This function should tolerate all meaningful - * combinations of scalars, vectors, and matrices. - * - * a,c,d could be matrices with appropriate dimensions. But b must - * (currently) and c can also always be a scalar represented by a - * 1-dim vector or a 1 by 1 matrix. - */ - template <class A, class B, class C, class D> - typename std::enable_if<ScalarTraits<B>::isScalar, void>::type - subtractProduct(A& a, const B& b, const C& c, const D& d) { - ScaledProductHelper<A, B, C, D, ScalarTraits<A>::isScalar, - ScalarTraits<C>::isScalar, - ScalarTraits<D>::isScalar>::addProduct(a, -b, c, d); - } } } #endif