28 Numerics library [numerics]

28.9 Basic linear algebra algorithms [linalg]

28.9.8 Scaled in-place transformation [linalg.scaled]

28.9.8.1 Introduction [linalg.scaled.intro]

The scaled function takes a value alpha and an mdspan x, and returns a new read-only mdspan that represents the elementwise product of alpha with each element of x.
[Example 1: using Vec = mdspan<double, dextents<size_t, 1>>; // z = alpha * x + y void z_equals_alpha_times_x_plus_y(double alpha, Vec x, Vec y, Vec z) { add(scaled(alpha, x), y, z); } // z = alpha * x + beta * y void z_equals_alpha_times_x_plus_beta_times_y(double alpha, Vec x, double beta, Vec y, Vec z) { add(scaled(alpha, x), scaled(beta, y), z); } — end example]

28.9.8.2 Class template scaled_accessor [linalg.scaled.scaledaccessor]

The class template scaled_accessor is an mdspan accessor policy which upon access produces scaled elements.
It is part of the implementation of scaled ([linalg.scaled.scaled]).
namespace std::linalg { template<class ScalingFactor, class NestedAccessor> class scaled_accessor { public: using element_type = add_const_t<decltype(declval<ScalingFactor>() * declval<NestedAccessor::element_type>())>; using reference = remove_const_t<element_type>; using data_handle_type = NestedAccessor::data_handle_type; using offset_policy = scaled_accessor<ScalingFactor, NestedAccessor::offset_policy>; constexpr scaled_accessor() = default; template<class OtherNestedAccessor> explicit(!is_convertible_v<OtherNestedAccessor, NestedAccessor>) constexpr scaled_accessor(const scaled_accessor<ScalingFactor, OtherNestedAccessor>& other); constexpr scaled_accessor(const ScalingFactor& s, const NestedAccessor& a); constexpr reference access(data_handle_type p, size_t i) const; constexpr offset_policy::data_handle_type offset(data_handle_type p, size_t i) const; constexpr const ScalingFactor& scaling_factor() const noexcept { return scaling-factor; } constexpr const NestedAccessor& nested_accessor() const noexcept { return nested-accessor; } private: ScalingFactor scaling-factor{}; // exposition only NestedAccessor nested-accessor{}; // exposition only }; }
Mandates:
template<class OtherNestedAccessor> explicit(!is_convertible_v<OtherNestedAccessor, NestedAccessor>) constexpr scaled_accessor(const scaled_accessor<ScalingFactor, OtherNestedAccessor>& other);
Constraints: is_constructible_v<NestedAccessor, const OtherNestedAccessor&> is true.
Effects:
  • Direct-non-list-initializes scaling-factor with other.scaling_factor(), and
  • direct-non-list-initializes nested-accessor with other.nested_accessor().
constexpr scaled_accessor(const ScalingFactor& s, const NestedAccessor& a);
Effects:
  • Direct-non-list-initializes scaling-factor with s, and
  • direct-non-list-initializes nested-accessor with a.
constexpr reference access(data_handle_type p, size_t i) const;
Returns: scaling_factor() * NestedAccessor::element_type(nested-accessor.access(p, i))
constexpr offset_policy::data_handle_type offset(data_handle_type p, size_t i) const;
Returns: nested-accessor.offset(p, i)

28.9.8.3 Function template scaled [linalg.scaled.scaled]

The scaled function template takes a scaling factor alpha and an mdspan x, and returns a new read-only mdspan with the same domain as x, that represents the elementwise product of alpha with each element of x.
template<class ScalingFactor, class ElementType, class Extents, class Layout, class Accessor> constexpr auto scaled(ScalingFactor alpha, mdspan<ElementType, Extents, Layout, Accessor> x);
Let SA be scaled_accessor<ScalingFactor, Accessor>.
Returns: mdspan<typename SA::element_type, Extents, Layout, SA>(x.data_handle(), x.mapping(), SA(alpha, x.accessor()))
[Example 1: void test_scaled(mdspan<double, extents<int, 10>> x) { auto x_scaled = scaled(5.0, x); for(int i = 0; i < x.extent(0); ++i) { assert(x_scaled[i] == 5.0 * x[i]); } } — end example]