From Jason Turner

[linalg.conj]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpi69ibfsx/{from.md → to.md} +141 -0
tmp/tmpi69ibfsx/{from.md → to.md} RENAMED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Conjugated in-place transformation <a id="linalg.conj">[[linalg.conj]]</a>
2
+
3
+ #### Introduction <a id="linalg.conj.intro">[[linalg.conj.intro]]</a>
4
+
5
+ The `conjugated` function takes an `mdspan` `x`, and returns a new
6
+ read-only `mdspan` `y` with the same domain as `x`, whose elements are
7
+ the complex conjugates of the corresponding elements of `x`.
8
+
9
+ #### Class template `conjugated_accessor` <a id="linalg.conj.conjugatedaccessor">[[linalg.conj.conjugatedaccessor]]</a>
10
+
11
+ The class template `conjugated_accessor` is an `mdspan` accessor policy
12
+ which upon access produces conjugate elements. It is part of the
13
+ implementation of `conjugated` [[linalg.conj.conjugated]].
14
+
15
+ ``` cpp
16
+ namespace std::linalg {
17
+ template<class NestedAccessor>
18
+ class conjugated_accessor {
19
+ public:
20
+ using element_type =
21
+ const decltype(conj-if-needed(declval<NestedAccessor::element_type>()));
22
+ using reference = remove_const_t<element_type>;
23
+ using data_handle_type = NestedAccessor::data_handle_type;
24
+ using offset_policy = conjugated_accessor<NestedAccessor::offset_policy>;
25
+
26
+ constexpr conjugated_accessor() = default;
27
+ constexpr conjugated_accessor(const NestedAccessor& acc);
28
+ template<class OtherNestedAccessor>
29
+ explicit(!is_convertible_v<OtherNestedAccessor, NestedAccessor>)
30
+ constexpr conjugated_accessor(const conjugated_accessor<OtherNestedAccessor>& other);
31
+
32
+ constexpr reference access(data_handle_type p, size_t i) const;
33
+
34
+ constexpr typename offset_policy::data_handle_type
35
+ offset(data_handle_type p, size_t i) const;
36
+
37
+ constexpr const NestedAccessor& nested_accessor() const noexcept { return nested-accessor_; }
38
+
39
+ private:
40
+ NestedAccessor nested-accessor_{}; // exposition only
41
+ };
42
+ }
43
+ ```
44
+
45
+ *Mandates:*
46
+
47
+ - `element_type` is valid and denotes a type,
48
+ - `is_copy_constructible_v<reference>` is `true`,
49
+ - `is_reference_v<element_type>` is `false`, and
50
+ - `NestedAccessor` meets the accessor policy requirements
51
+ [[mdspan.accessor.reqmts]].
52
+
53
+ ``` cpp
54
+ constexpr conjugated_accessor(const NestedAccessor& acc);
55
+ ```
56
+
57
+ *Effects:* Direct-non-list-initializes *nested-accessor\_* with `acc`.
58
+
59
+ ``` cpp
60
+ template<class OtherNestedAccessor>
61
+ explicit(!is_convertible_v<OtherNestedAccessor, NestedAccessor>)
62
+ constexpr conjugated_accessor(const conjugated_accessor<OtherNestedAccessor>& other);
63
+ ```
64
+
65
+ *Constraints:*
66
+ `is_constructible_v<NestedAccessor, const OtherNestedAccessor&>` is
67
+ `true`.
68
+
69
+ *Effects:* Direct-non-list-initializes *nested-accessor\_* with
70
+ `other.nested_accessor()`.
71
+
72
+ ``` cpp
73
+ constexpr reference access(data_handle_type p, size_t i) const;
74
+ ```
75
+
76
+ *Returns:*
77
+ *`conj-if-needed`*`(NestedAccessor::element_type(`*`nested-accessor_`*`.access(p, i)))`
78
+
79
+ ``` cpp
80
+ constexpr typename offset_policy::data_handle_type offset(data_handle_type p, size_t i) const;
81
+ ```
82
+
83
+ *Returns:* *`nested-accessor_`*`.offset(p, i)`
84
+
85
+ #### Function template `conjugated` <a id="linalg.conj.conjugated">[[linalg.conj.conjugated]]</a>
86
+
87
+ ``` cpp
88
+ template<class ElementType, class Extents, class Layout, class Accessor>
89
+ constexpr auto conjugated(mdspan<ElementType, Extents, Layout, Accessor> a);
90
+ ```
91
+
92
+ Let `A` be
93
+
94
+ - `remove_cvref_t<decltype(a.accessor().nested_accessor())>` if
95
+ `Accessor` is a specialization of `conjugated_accessor`;
96
+ - otherwise, `Accessor` if `remove_cvref_t<ElementType>` is an
97
+ arithmetic type;
98
+ - otherwise, `conjugated_accessor<Accessor>` if the expression `conj(E)`
99
+ is valid for any subexpression `E` whose type is
100
+ `remove_cvref_t<ElementType>` with overload resolution performed in a
101
+ context that includes the declaration
102
+ `template<class U> U conj(const U&) = delete;`;
103
+ - otherwise, `Accessor`.
104
+
105
+ *Returns:* Let `MD` be
106
+ `mdspan<typename A::element_type, Extents, Layout, A>`.
107
+
108
+ - `MD(a.data_handle(), a.mapping(), a.accessor().nested_accessor())` if
109
+ `Accessor` is a specialization of `conjugated_accessor`;
110
+ - otherwise, `a`, if `is_same_v<A, Accessor>` is `true`;
111
+ - otherwise,
112
+ `MD(a.data_handle(), a.mapping(), conjugated_accessor(a.accessor()))`.
113
+
114
+ [*Example 1*:
115
+
116
+ ``` cpp
117
+ void test_conjugated_complex(mdspan<complex<double>, extents<int, 10>> a) {
118
+ auto a_conj = conjugated(a);
119
+ for (int i = 0; i < a.extent(0); ++i) {
120
+ assert(a_conj[i] == conj(a[i]);
121
+ }
122
+ auto a_conj_conj = conjugated(a_conj);
123
+ for (int i = 0; i < a.extent(0); ++i) {
124
+ assert(a_conj_conj[i] == a[i]);
125
+ }
126
+ }
127
+
128
+ void test_conjugated_real(mdspan<double, extents<int, 10>> a) {
129
+ auto a_conj = conjugated(a);
130
+ for (int i = 0; i < a.extent(0); ++i) {
131
+ assert(a_conj[i] == a[i]);
132
+ }
133
+ auto a_conj_conj = conjugated(a_conj);
134
+ for (int i = 0; i < a.extent(0); ++i) {
135
+ assert(a_conj_conj[i] == a[i]);
136
+ }
137
+ }
138
+ ```
139
+
140
+ — *end example*]
141
+