Transposed.hpp 1.72 KB
Newer Older
1
2
3
4
5
6
#pragma once

#include <type_traits>

namespace AMDiS
{
Praetorius, Simon's avatar
Praetorius, Simon committed
7
  /// \brief The transposed view onto a matrix
8
9
10
  template <class Matrix>
  class TransposedMatrix
  {
11
    using RawMatrix = remove_cvref_t<Matrix>;
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

  public:
    using size_type = typename RawMatrix::size_type;
    using value_type = typename RawMatrix::value_type;

  private:
    struct ConstRowProxy
    {
      RawMatrix const* mat;
      size_type row;

      value_type const& operator[](size_type col) const
      {
        return (*mat)[col][row];
      }
    };

    struct MutableRowProxy
    {
      RawMatrix* mat;
      size_type row;

      value_type& operator[](size_type col)
      {
        return (*mat)[col][row];
      }
    };

  public:
    template <class M>
    TransposedMatrix(M&& matrix)
43
      : matrix_(FWD(matrix))
44
45
46
47
48
49
50
    {}

    ConstRowProxy operator[](size_type row) const
    {
      return ConstRowProxy{&matrix_, row};
    }

Praetorius, Simon's avatar
Praetorius, Simon committed
51
    template <class M = Matrix,
52
      std::enable_if_t<not std::is_const<M>::value, int> = 0>
Praetorius, Simon's avatar
Praetorius, Simon committed
53
    MutableRowProxy operator[](size_type row)
54
55
56
57
58
59
60
61
62
63
64
65
66
67
    {
      return MutableRowProxy{&matrix_, row};
    }

    size_type N() const
    {
      return matrix_.M();
    }

    size_type M() const
    {
      return matrix_.N();
    }

68
69
70
71
72
73
74
75
76
77
78
79
    template <class Mat>
    TransposedMatrix& operator+=(Mat const& mat)
    {
      assert(mat.N() == N());
      assert(mat.M() == M());
      for (size_type i = 0; i < N(); ++i)
        for (size_type j = 0; j < M(); ++j)
          (*this)[i][j] += mat[i][j];

      return *this;
    }

80
81
82
83
84
85
86
87
  private:
    Matrix& matrix_;
  };

  template <class Matrix>
  auto transposed(Matrix&& matrix)
  {
    using M = std::remove_reference_t<Matrix>;
88
    return TransposedMatrix<M>{FWD(matrix)};
89
90
91
  }

} // end namespace AMDiS