28 Numerics library [numerics]

28.9 Basic linear algebra algorithms [linalg]

28.9.9 Conjugated in-place transformation [linalg.conj]

28.9.9.1 Introduction [linalg.conj.intro]

The conjugated function takes an mdspan x, and returns a new read-only mdspan y with the same domain as x, whose elements are the complex conjugates of the corresponding elements of x.

28.9.9.2 Class template conjugated_accessor [linalg.conj.conjugatedaccessor]

The class template conjugated_accessor is an mdspan accessor policy which upon access produces conjugate elements.
It is part of the implementation of conjugated ([linalg.conj.conjugated]).
namespace std::linalg { template<class NestedAccessor> class conjugated_accessor { public: using element_type = add_const_t<decltype(conj-if-needed(declval<NestedAccessor::element_type>()))>; using reference = remove_const_t<element_type>; using data_handle_type = typename NestedAccessor::data_handle_type; using offset_policy = conjugated_accessor<NestedAccessor::offset_policy>; constexpr conjugated_accessor() = default; template<class OtherNestedAccessor> explicit(!is_convertible_v<OtherNestedAccessor, NestedAccessor>>) constexpr conjugated_accessor(const conjugated_accessor<OtherNestedAccessor>& other); constexpr reference access(data_handle_type p, size_t i) const; constexpr typename offset_policy::data_handle_type offset(data_handle_type p, size_t i) const; constexpr const Accessor& nested_accessor() const noexcept { return nested-accessor_; } private: NestedAccessor nested-accessor_{}; // exposition only }; }
Mandates:
  • element_type is valid and denotes a type,
  • is_copy_constructible_v<reference> is true,
  • is_reference_v<element_type> is false, and
  • NestedAccessor meets the accessor policy requirements ([mdspan.accessor.reqmts]).
constexpr conjugated_accessor(const NestedAccessor& acc);
Effects: Direct-non-list-initializes nested-accessor_ with acc.
template<class OtherNestedAccessor> explicit(!is_convertible_v<OtherNestedAccessor, NestedAccessor>>) constexpr conjugated_accessor(const conjugated_accessor<OtherNestedAccessor>& other);
Constraints: is_constructible_v<NestedAccessor, const OtherNestedAccessor&> is true.
Effects: Direct-non-list-initializes nested-accessor_ with other.nested_accessor().
constexpr reference access(data_handle_type p, size_t i) const;
Returns: conj-if-needed(NestedAccessor​::​element_type(nested-accessor_.access(p, i)))
constexpr typename offset_policy::data_handle_type offset(data_handle_type p, size_t i) const;
Returns: nested-accessor_.offset(p, i)

28.9.9.3 Function template conjugated [linalg.conj.conjugated]

template<class ElementType, class Extents, class Layout, class Accessor> constexpr auto conjugated(mdspan<ElementType, Extents, Layout, Accessor> a);
Let A be remove_cvref_t<decltype(a.accessor().nested_accessor())> if Accessor is a specialization of conjugated_accessor, and otherwise conjugated_accessor<Accessor>.
Returns:
  • If Accessor is a specialization of conjugated_accessor, mdspan<typename A::element_type, Extents, Layout, A>(a.data_handle(), a.mapping(), a.accessor().nested_accessor())
  • otherwise, mdspan<typename A::element_type, Extents, Layout, A>(a.data_handle(), a.mapping(), conjugated_accessor(a.accessor()))
[Example 1: void test_conjugated_complex(mdspan<complex<double>, extents<int, 10>> a) { auto a_conj = conjugated(a); for (int i = 0; i < a.extent(0); ++i) { assert(a_conj[i] == conj(a[i]); } auto a_conj_conj = conjugated(a_conj); for (int i = 0; i < a.extent(0); ++i) { assert(a_conj_conj[i] == a[i]); } } void test_conjugated_real(mdspan<double, extents<int, 10>> a) { auto a_conj = conjugated(a); for (int i = 0; i < a.extent(0); ++i) { assert(a_conj[i] == a[i]); } auto a_conj_conj = conjugated(a_conj); for (int i = 0; i < a.extent(0); ++i) { assert(a_conj_conj[i] == a[i]); } } — end example]