From Jason Turner

[linalg.scaled]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmps3nabvg3/{from.md → to.md} +150 -0
tmp/tmps3nabvg3/{from.md → to.md} RENAMED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### Scaled in-place transformation <a id="linalg.scaled">[[linalg.scaled]]</a>
2
+
3
+ #### Introduction <a id="linalg.scaled.intro">[[linalg.scaled.intro]]</a>
4
+
5
+ The `scaled` function takes a value `alpha` and an `mdspan` `x`, and
6
+ returns a new read-only `mdspan` that represents the elementwise product
7
+ of `alpha` with each element of `x`.
8
+
9
+ [*Example 1*:
10
+
11
+ ``` cpp
12
+ using Vec = mdspan<double, dextents<size_t, 1>>;
13
+
14
+ // z = alpha * x + y
15
+ void z_equals_alpha_times_x_plus_y(double alpha, Vec x, Vec y, Vec z) {
16
+ add(scaled(alpha, x), y, z);
17
+ }
18
+
19
+ // z = alpha * x + beta * y
20
+ void z_equals_alpha_times_x_plus_beta_times_y(double alpha, Vec x, double beta, Vec y, Vec z) {
21
+ add(scaled(alpha, x), scaled(beta, y), z);
22
+ }
23
+ ```
24
+
25
+ — *end example*]
26
+
27
+ #### Class template `scaled_accessor` <a id="linalg.scaled.scaledaccessor">[[linalg.scaled.scaledaccessor]]</a>
28
+
29
+ The class template `scaled_accessor` is an `mdspan` accessor policy
30
+ which upon access produces scaled elements. It is part of the
31
+ implementation of `scaled` [[linalg.scaled.scaled]].
32
+
33
+ ``` cpp
34
+ namespace std::linalg {
35
+ template<class ScalingFactor, class NestedAccessor>
36
+ class scaled_accessor {
37
+ public:
38
+ using element_type =
39
+ const decltype(declval<ScalingFactor>() * declval<NestedAccessor::element_type>());
40
+ using reference = remove_const_t<element_type>;
41
+ using data_handle_type = NestedAccessor::data_handle_type;
42
+ using offset_policy = scaled_accessor<ScalingFactor, NestedAccessor::offset_policy>;
43
+
44
+ constexpr scaled_accessor() = default;
45
+ template<class OtherNestedAccessor>
46
+ explicit(!is_convertible_v<OtherNestedAccessor, NestedAccessor>)
47
+ constexpr scaled_accessor(const scaled_accessor<ScalingFactor,
48
+ OtherNestedAccessor>& other);
49
+ constexpr scaled_accessor(const ScalingFactor& s, const NestedAccessor& a);
50
+
51
+ constexpr reference access(data_handle_type p, size_t i) const;
52
+ constexpr offset_policy::data_handle_type offset(data_handle_type p, size_t i) const;
53
+
54
+ constexpr const ScalingFactor& scaling_factor() const noexcept { return scaling-factor; }
55
+ constexpr const NestedAccessor& nested_accessor() const noexcept { return nested-accessor; }
56
+
57
+ private:
58
+ ScalingFactor scaling-factor{}; // exposition only
59
+ NestedAccessor nested-accessor{}; // exposition only
60
+ };
61
+ }
62
+ ```
63
+
64
+ *Mandates:*
65
+
66
+ - `element_type` is valid and denotes a type,
67
+ - `is_copy_constructible_v<reference>` is `true`,
68
+ - `is_reference_v<element_type>` is `false`,
69
+ - `ScalingFactor` models `semiregular`, and
70
+ - `NestedAccessor` meets the accessor policy requirements
71
+ [[mdspan.accessor.reqmts]].
72
+
73
+ ``` cpp
74
+ template<class OtherNestedAccessor>
75
+ explicit(!is_convertible_v<OtherNestedAccessor, NestedAccessor>)
76
+ constexpr scaled_accessor(const scaled_accessor<ScalingFactor, OtherNestedAccessor>& other);
77
+ ```
78
+
79
+ *Constraints:*
80
+ `is_constructible_v<NestedAccessor, const OtherNestedAccessor&>` is
81
+ `true`.
82
+
83
+ *Effects:*
84
+
85
+ - Direct-non-list-initializes *scaling-factor* with
86
+ `other.scaling_factor()`, and
87
+ - direct-non-list-initializes *nested-accessor* with
88
+ `other.nested_accessor()`.
89
+
90
+ ``` cpp
91
+ constexpr scaled_accessor(const ScalingFactor& s, const NestedAccessor& a);
92
+ ```
93
+
94
+ *Effects:*
95
+
96
+ - Direct-non-list-initializes *scaling-factor* with `s`, and
97
+ - direct-non-list-initializes *nested-accessor* with `a`.
98
+
99
+ ``` cpp
100
+ constexpr reference access(data_handle_type p, size_t i) const;
101
+ ```
102
+
103
+ *Returns:*
104
+
105
+ ``` cpp
106
+ scaling_factor() * NestedAccessor::element_type(nested-accessor.access(p, i))
107
+ ```
108
+
109
+ ``` cpp
110
+ constexpr offset_policy::data_handle_type offset(data_handle_type p, size_t i) const;
111
+ ```
112
+
113
+ *Returns:* *`nested-accessor`*`.offset(p, i)`
114
+
115
+ #### Function template `scaled` <a id="linalg.scaled.scaled">[[linalg.scaled.scaled]]</a>
116
+
117
+ The `scaled` function template takes a scaling factor `alpha` and an
118
+ `mdspan` `x`, and returns a new read-only `mdspan` with the same domain
119
+ as `x`, that represents the elementwise product of `alpha` with each
120
+ element of `x`.
121
+
122
+ ``` cpp
123
+ template<class ScalingFactor,
124
+ class ElementType, class Extents, class Layout, class Accessor>
125
+ constexpr auto scaled(ScalingFactor alpha, mdspan<ElementType, Extents, Layout, Accessor> x);
126
+ ```
127
+
128
+ Let `SA` be `scaled_accessor<ScalingFactor, Accessor>`.
129
+
130
+ *Returns:*
131
+
132
+ ``` cpp
133
+ mdspan<typename SA::element_type, Extents, Layout, SA>(x.data_handle(), x.mapping(),
134
+ SA(alpha, x.accessor()))
135
+ ```
136
+
137
+ [*Example 1*:
138
+
139
+ ``` cpp
140
+ void test_scaled(mdspan<double, extents<int, 10>> x)
141
+ {
142
+ auto x_scaled = scaled(5.0, x);
143
+ for (int i = 0; i < x.extent(0); ++i) {
144
+ assert(x_scaled[i] == 5.0 * x[i]);
145
+ }
146
+ }
147
+ ```
148
+
149
+ — *end example*]
150
+