funcy  1.6.1
transpose.h
1 #pragma once
2 
3 #include <funcy/concepts.h>
4 #include <funcy/linalg/at.h>
5 #include <funcy/linalg/concepts.h>
6 #include <funcy/linalg/rows_and_cols.h>
7 #include <funcy/linalg/type_traits.h>
8 #include <funcy/util/chainer.h>
9 #include <funcy/util/macros.h>
10 
11 #include <concepts>
12 #include <type_traits>
13 
14 namespace funcy::linalg
15 {
17  namespace detail
18  {
19  template < class M >
20  struct WrappedMatrix
21  {
22  using type = M;
23  };
24 
25  template < ConstantSize M >
26  struct WrappedMatrix< M >
27  {
28  using type = typename GetTransposed< M >::type;
29  };
30 
31  template < ConstantSize Mat >
32  [[nodiscard]] Transposed_t< Mat >
33  transpose( Mat A ) requires std::same_as< Mat, Transposed_t< Mat > >
34  {
35  auto a = at( A, 0, 0 );
36  for ( int i = 0; i < rows< Mat >(); ++i )
37  for ( int j = i + 1; j < cols< Mat >(); ++j )
38  {
39  a = at( A, i, j );
40  at( A, i, j ) = at( A, j, i );
41  at( A, j, i ) = a;
42  }
43 
44  return A;
45  }
46 
48  template < ConstantSize Mat >
49  [[nodiscard]] Transposed_t< Mat >
50  transpose( const Mat& A ) requires( !std::same_as< Mat, Transposed_t< Mat > > )
51  {
52  auto B = zero< Transposed_t< Mat > >();
53  for ( int i = 0; i < rows< Mat >(); ++i )
54  for ( int j = 0; j < cols< Mat >(); ++j )
55  at( B, j, i ) = A( i, j );
56  return B;
57  }
58 
60  template < class Mat >
61  [[nodiscard]] Mat transpose( Mat A ) requires( !ConstantSize< Mat > )
62  {
63  FUNCY_ASSERT( rows( A ) == cols( A ) );
64  using Index = decltype( rows( std::declval< Mat >() ) );
65  auto a = std::decay_t< decltype( at( A, 0, 0 ) ) >( 0. );
66  for ( Index i = 0; i < rows( A ); ++i )
67  for ( Index j = i + 1; j < cols( A ); ++j )
68  {
69  a = at( A, i, j );
70  at( A, i, j ) = at( A, j, i );
71  at( A, j, i ) = a;
72  }
73 
74  return A;
75  }
76 
81  template < ConstantSize Mat >
82  [[nodiscard]] Mat& add_transposed( Mat& A )
83  {
84  using linalg::dim;
85  using Index = decltype( dim< Mat >() );
86  for ( Index i = 0; i < dim< Mat >(); ++i )
87  for ( Index j = i + 1; j < dim< Mat >(); ++j )
88  at( A, j, i ) = at( A, i, j ) = at( A, i, j ) + at( A, j, i );
89  for ( Index i = 0; i < dim< Mat >(); ++i )
90  at( A, i, i ) *= 2;
91  return A;
92  }
93 
98  template < class Mat >
99  [[nodiscard]] Mat& add_transposed( Mat& A )
100  {
101  using linalg::cols;
102  using linalg::rows;
103  FUNCY_ASSERT( rows( A ) == cols( A ) );
104  using Index = decltype( rows( std::declval< Mat >() ) );
105  for ( Index i = 0; i < rows( A ); ++i )
106  for ( Index j = i + 1; j < cols( A ); ++j )
107  at( A, j, i ) = at( A, i, j ) = at( A, i, j ) + at( A, j, i );
108  for ( Index i = 0; i < rows( A ); ++i )
109  at( A, i, i ) *= 2;
110  return A;
111  }
112  } // namespace detail
114 
117  template < class Mat >
118  class Transpose : public Chainer< Transpose< Mat > >
119  {
120  public:
121  explicit Transpose( const Mat& A )
122  {
123  AT_ = detail::transpose( A );
124  }
125 
126  void update( const Mat& A )
127  {
128  AT_ = detail::transpose( A );
129  }
130 
131  [[nodiscard]] const auto& d0() const noexcept
132  {
133  return AT_;
134  }
135 
136  [[nodiscard]] auto d1( const Mat& dA ) const
137  {
138  return detail::transpose( dA );
139  }
140 
141  private:
142  typename detail::WrappedMatrix< Mat >::type AT_;
143  };
144 
150  template < class Mat >
151  [[nodiscard]] auto transpose( const Mat& A )
152  {
153  return Transpose( A );
154  }
155 
161  template < Function F >
162  [[nodiscard]] auto transpose( const F& f )
163  {
164  return Transpose< decay_t< decltype( f() ) > >( f() )( f );
165  }
167 } // namespace funcy::linalg
auto transpose(const F &f)
Generate , where .
Definition: transpose.h:162
auto cols(const Mat &A) requires(!ConstantSize< Mat > &&static_check
Number of columns of a dynamic size matrix.
Definition: rows_and_cols.h:36
constexpr int dim()
Dimension of a fixed size matrix in .
Definition: dimension.h:19
auto rows(const Mat &A) requires(!ConstantSize< Mat > &&static_check
Number of rows of a dynamic size matrix.
Definition: rows_and_cols.h:13
Functionality from linear algebra such as (modified) principal and mixed matrix invariants.
decltype(auto) FUNCY_ALWAYS_INLINE at(M &&A, Index i, Index j) requires requires(std
Access matrix entry.
Definition: at.h:17
auto transpose(const Mat &A)
Generate .
Definition: transpose.h:151
Definition: transpose.h:118