5#ifndef DUNE_COMMON_TRANSPOSE_HH 
    6#define DUNE_COMMON_TRANSPOSE_HH 
   12#include <dune/common/std/type_traits.hh> 
   15#include <dune/common/referencehelper.hh> 
   17#include <dune/common/matrixconcepts.hh> 
   25  template<class M, bool = IsStaticSizeMatrix<M>::value>
 
   26  struct TransposedDenseMatrixTraits
 
   32  struct TransposedDenseMatrixTraits<M, false>
 
   38  using TransposedDenseMatrixTraits_t = 
typename TransposedDenseMatrixTraits<M>::type;
 
   44  template<class WM, bool staticSize = IsStaticSizeMatrix<WM>::value>
 
   45  class TransposedMatrixWrapperMixin {};
 
   48  class TransposedMatrixWrapperMixin<WM, true>
 
   53    constexpr static int rows = WM::cols;
 
   55    constexpr static int cols = WM::rows;
 
   61  class TransposedMatrixWrapper;
 
   67struct FieldTraits< Impl::TransposedMatrixWrapper<M> >
 
   69  using field_type = 
typename FieldTraits<ResolveRef_t<M>>::field_type;
 
   70  using real_type = 
typename FieldTraits<ResolveRef_t<M>>::real_type;
 
   78  struct IsDenseMatrix< TransposedMatrixWrapper<M> > :
 
   79    public IsDenseMatrix<ResolveRef_t<M>> {};
 
   87  template<
class Matrix>
 
   88  class TransposedMatrixWrapper :
 
   89    public TransposedMatrixWrapperMixin<ResolveRef_t<Matrix>>
 
   91    constexpr static bool hasStaticSize = IsStaticSizeMatrix<ResolveRef_t<Matrix>>::value;
 
   93    using WrappedMatrix = ResolveRef_t<Matrix>;
 
   95    const WrappedMatrix& wrappedMatrix()
 const {
 
  100    using value_type = 
typename WrappedMatrix::value_type;
 
  101    using field_type = 
typename FieldTraits<WrappedMatrix>::field_type;
 
  102    using size_type = 
typename WrappedMatrix::size_type;
 
  104    TransposedMatrixWrapper(Matrix&& matrix) : matrix_(
std::move(matrix)) {}
 
  105    TransposedMatrixWrapper(
const Matrix& matrix) : matrix_(matrix) {}
 
  112      const WrappedMatrix& wrappedMatrix_;
 
  115      decltype(
auto) 
operator[] (size_type j) 
const 
  118        return wrappedMatrix_[j][i_];
 
  130    auto operator[] (size_type i) 
const requires(Impl::IsDenseMatrix_v<WrappedMatrix>)
 
  133      return AccessProxy{wrappedMatrix(),i};
 
  136    template<
class MatrixA,
 
  138        ((not Impl::IsFieldMatrix<MatrixA>::value) or (not hasStaticSize))
 
  139        and Impl::IsDenseMatrix_v<MatrixA>, 
int> = 0>
 
  140    friend auto operator* (
const MatrixA& matrixA, 
const TransposedMatrixWrapper& matrixB)
 
  142      using FieldA = 
typename FieldTraits<MatrixA>::field_type;
 
  143      using FieldB = 
typename FieldTraits<TransposedMatrixWrapper>::field_type;
 
  144      using Field = 
typename PromotionTraits<FieldA, FieldB>::PromotedType;
 
  149      if constexpr(IsStaticSizeMatrix_v<MatrixA> and IsStaticSizeMatrix_v<WrappedMatrix>)
 
  151        FieldMatrix<Field, MatrixA::rows, WrappedMatrix::rows> result;
 
  152        for (std::size_t j=0; j<MatrixA::rows; ++j)
 
  153          matrixB.wrappedMatrix().mv(matrixA[j], result[j]);
 
  158        DynamicMatrix<Field> result(matrixA.N(), matrixB.wrappedMatrix().N());
 
  159        for (std::size_t j=0; j<matrixA.N(); ++j)
 
  160          matrixB.wrappedMatrix().mv(matrixA[j], result[j]);
 
  167    constexpr size_type N ()
 const 
  169      return wrappedMatrix().M();
 
  174    constexpr size_type M ()
 const 
  176      return wrappedMatrix().N();
 
  179    template<
class X, 
class Y>
 
  180    void mv (
const X& x, Y& y)
 const 
  182      wrappedMatrix().mtv(x,y);
 
  185    template<
class X, 
class Y>
 
  186    void mtv (
const X& x, Y& y)
 const 
  188      wrappedMatrix().mv(x,y);
 
  196    TransposedDenseMatrixTraits_t<WrappedMatrix> asDense()
 const 
  198      TransposedDenseMatrixTraits_t<WrappedMatrix> MT;
 
  199      if constexpr(not IsStaticSizeMatrix<WrappedMatrix>::value)
 
  201        MT.resize(wrappedMatrix().M(), wrappedMatrix().N(), 0);
 
  215  using MemberFunctionTransposedConcept = std::void_t<decltype(std::declval<M>().transposed())>;
 
  232template<
class Matrix,
 
  233  std::enable_if_t<Impl::HasMemberFunctionTransposed<Matrix>::value, 
int> = 0>
 
  235  return matrix.transposed();
 
  261template<
class Matrix,
 
  262  std::enable_if_t<not Impl::HasMemberFunctionTransposed<std::decay_t<Matrix>>::value, 
int> = 0>
 
  264  return Impl::TransposedMatrixWrapper(std::forward<Matrix>(matrix));
 
  295template<
class Matrix>
 
  296auto transpose(
const std::reference_wrapper<Matrix>& matrix) {
 
  297  return Impl::TransposedMatrixWrapper(matrix);
 
  311template<
class Matrix>
 
Macro for wrapping boundary checks.
 
Construct a matrix with a dynamic size.
Definition: dynmatrix.hh:61
 
A dense n x m matrix.
Definition: fmatrix.hh:117
 
A generic dynamic dense matrix.
Definition: matrix.hh:561
 
This file implements a dense matrix with dynamic numbers of rows and columns.
 
Implements a matrix constructed from a given type representing a field and compile-time given number ...
 
#define DUNE_ASSERT_BOUNDS(cond)
If DUNE_CHECK_BOUNDS is defined: check if condition cond holds; otherwise, do nothing.
Definition: boundschecking.hh:30
 
constexpr T & resolveRef(T &gf) noexcept
Helper function to resolve std::reference_wrapper.
Definition: referencehelper.hh:47
 
typename detected_or< nonesuch, Op, Args... >::value_t is_detected
Detects whether Op<Args...> is valid.
Definition: type_traits.hh:145
 
auto sparseRange(Range &&range)
Allow structured-binding for-loops for sparse iterators.
Definition: rangeutilities.hh:716
 
Dune namespace.
Definition: alignedallocator.hh:13
 
auto transpose(const Matrix &matrix)
Return the transposed of the given matrix.
Definition: transpose.hh:234
 
auto transposedView(const Matrix &matrix)
Create a view modelling the transposed matrix.
Definition: transpose.hh:312