Loading...
Searching...
No Matches
vector.hpp
Go to the documentation of this file.
1#pragma once
2
3namespace terra::linalg {
4
5/// @brief Concept for types that behave like vectors.
6/// Requires exposing ScalarType and implementations for linear algebra operations.
7template < typename T >
8concept VectorLike = requires(
9 const T& self_const,
10 T& self,
11 const std::vector< typename T::ScalarType >& c,
12 const T& x,
13 T& x_non_const,
14 const std::vector< T >& xx,
15 const typename T::ScalarType c0 ) {
16 // Requires exposing the scalar type.
17 typename T::ScalarType;
18
19 // Required lincomb overload
20 { self.lincomb_impl( c, xx, c0 ) } -> std::same_as< void >;
21
22 // Required dot product
23 { self_const.dot_impl( x ) } -> std::same_as< typename T::ScalarType >;
24
25 // Required entries inversion
26 { self.invert_entries_impl() } -> std::same_as< void >;
27
28 // Required scale with vector
29 { self.scale_with_vector_impl( x ) } -> std::same_as< void >;
30
31 // Required randomization
32 { self.randomize_impl() } -> std::same_as< void >;
33
34 // Required max magnitude
35 { self_const.max_abs_entry_impl() } -> std::same_as< typename T::ScalarType >;
36
37 // Required nan/inf check
38 { self_const.has_nan_or_inf_impl() } -> std::same_as< bool >;
39
40 // Required swap operation
41 { self.swap_impl( x_non_const ) } -> std::same_as< void >;
42};
43
44/// @brief Concept for types that behave like block 2-vectors.
45/// Extends VectorLike and requires block types and accessors.
46template < typename T >
47concept Block2VectorLike = VectorLike< T > && requires( const T& self_const, T& self ) {
48 typename T::Block1Type;
49 typename T::Block2Type;
50
53
54 { self_const.block_1() } -> std::same_as< const typename T::Block1Type& >;
55 { self_const.block_2() } -> std::same_as< const typename T::Block2Type& >;
56
57 { self.block_1() } -> std::same_as< typename T::Block1Type& >;
58 { self.block_2() } -> std::same_as< typename T::Block2Type& >;
59};
60
61/// @brief Alias for the scalar type of a vector.
62template < VectorLike Vector >
63using ScalarOf = typename Vector::ScalarType;
64
65/// @brief Compute a linear combination of vectors.
66/// Implements: \f$ y = \sum_{i} c_i x_i + c_0 \f$
67/// @param y Output vector.
68/// @param c Coefficients \f$ c_i \f$.
69/// @param x Input vectors \f$ x_i \f$.
70/// @param c0 Scalar to add \f$ c_0 \f$.
71template < VectorLike Vector >
73 Vector& y,
74 const std::vector< ScalarOf< Vector > >& c,
75 const std::vector< Vector >& x,
76 const ScalarOf< Vector >& c0 )
77{
78 y.lincomb_impl( c, x, c0 );
79}
80
81/// @brief Compute a linear combination of vectors with zero scalar.
82/// Implements: \f$ y = \sum_{i} c_i x_i \f$
83/// @param y Output vector.
84/// @param c Coefficients \f$ c_i \f$.
85/// @param x Input vectors \f$ x_i \f$.
86template < VectorLike Vector >
87void lincomb( Vector& y, const std::vector< ScalarOf< Vector > >& c, const std::vector< Vector >& x )
88{
89 lincomb( y, c, x, static_cast< ScalarOf< Vector > >( 0 ) );
90}
91
92/// @brief Assign a scalar value to a vector.
93/// Implements: \f$ y \gets c_0 \f$
94/// @param y Output vector.
95/// @param c0 Scalar value \f$ c_0 \f$.
96template < VectorLike Vector >
97void assign( Vector& y, const ScalarOf< Vector >& c0 )
98{
99 lincomb( y, {}, {}, c0 );
100}
101
102/// @brief Assign one vector to another.
103/// Implements: \f$ y \gets x \f$
104/// @param y Output vector.
105/// @param x Input vector.
106template < VectorLike Vector >
107void assign( Vector& y, const Vector& x )
108{
109 lincomb( y, { static_cast< ScalarOf< Vector > >( 1 ) }, { x } );
110}
111
112/// @brief Compute the dot product of two vectors.
113/// Implements: \f$ y \cdot x = \sum_{i} y_i x_i \f$
114/// @param y First vector.
115/// @param x Second vector.
116/// @return Dot product value.
117template < VectorLike Vector >
118ScalarOf< Vector > dot( const Vector& y, const Vector& x )
119{
120 return y.dot_impl( x );
121}
122
123/// @brief Invert the entries of a vector.
124/// For each entry \f$ y_i \f$, computes \f$ y_i = 1 / y_i \f$.
125/// @param y Vector to invert.
126template < VectorLike Vector >
127void invert_entries( Vector& y )
128{
129 y.invert_entries_impl();
130}
131
132/// @brief Scale a vector in place with another vector.
133/// For each entry \f$ y_i \f$, computes \f$ y_i = y_i \cdot x_i \f$.
134/// @param y Vector to scale.
135/// @param x Scaling vector.
136template < VectorLike Vector >
137void scale_in_place( Vector& y, const Vector& x )
138{
139 y.scale_with_vector_impl( x );
140}
141
142/// @brief Randomize the entries of a vector.
143/// Sets each entry of \f$ y \f$ to a random value.
144/// @param y Vector to randomize.
145template < VectorLike Vector >
146void randomize( Vector& y )
147{
148 y.randomize_impl();
149}
150
151/// @brief Compute the infinity norm (max absolute entry) of a vector.
152/// Implements: \f$ \|y\|_\infty = \max_i |y_i| \f$
153/// @param y Input vector.
154/// @return Infinity norm value.
155template < VectorLike Vector >
156ScalarOf< Vector > norm_inf( const Vector& y )
157{
158 return y.max_abs_entry_impl();
159}
160
161/// @brief Compute the 2-norm (Euclidean norm) of a vector.
162/// Implements: \f$ \|y\|_2 = \sqrt{ \sum_i y_i^2 } \f$
163/// @param y Input vector.
164/// @return 2-norm value.
165template < VectorLike Vector >
166ScalarOf< Vector > norm_2( const Vector& y )
167{
168 const auto dot_prod = dot( y, y );
169 return std::sqrt( dot_prod );
170}
171
172/// @brief Compute the scaled 2-norm of a vector.
173/// Implements: \f$ \|y\|_2^{\text{scaled}} = \sqrt{ (\sum_i y_i^2) \cdot s } \f$
174/// @param y Input vector.
175/// @param scaling_factor_under_the_root Scaling factor \f$ s \f$ under the square root.
176/// @return Scaled 2-norm value.
177template < VectorLike Vector >
178ScalarOf< Vector > norm_2_scaled( const Vector& y, const ScalarOf< Vector >& scaling_factor_under_the_root )
179{
180 const auto dot_prod = dot( y, y );
181 return std::sqrt( dot_prod * scaling_factor_under_the_root );
182}
183
184/// @brief Check if a vector contains NaN or inf entries.
185/// Returns true if any entry of \f$ y \f$ is NaN or inf.
186/// @param y Input vector.
187/// @return True if NaN or inf is present, false otherwise.
188template < VectorLike Vector >
189bool has_nan_or_inf( const Vector& y )
190{
191 return y.has_nan_or_inf_impl();
192}
193
194/// @brief Swap the contents of two vectors.
195/// Exchanges the entries of \f$ x \f$ and \f$ y \f$.
196/// @param x First vector.
197/// @param y Second vector.
198template < VectorLike Vector >
199void swap( Vector& x, Vector& y )
200{
201 y.swap_impl( x );
202}
203
204namespace detail {
205
206/// @brief Dummy vector class for concept checks and testing.
207/// Implements required vector operations as no-ops.
208template < typename ScalarT >
210{
211 public:
212 /// @brief Scalar type used by the vector.
213 using ScalarType = ScalarT;
214
215 /// @brief Dummy implementation of linear combination.
216 void lincomb_impl( const std::vector< ScalarType >& c, const std::vector< DummyVector >& x, const ScalarType c0 )
217 {
218 (void) c;
219 (void) x;
220 (void) c0;
221 }
222
223 /// @brief Dummy implementation of dot product.
225 {
226 (void) x;
227 return 0;
228 }
229
230 /// @brief Dummy implementation of invert entries.
232
233 /// @brief Dummy implementation of scale with vector.
234 void scale_with_vector_impl( const DummyVector& x ) { (void) x; }
235
236 /// @brief Dummy implementation of randomize.
238
239 /// @brief Dummy implementation of max absolute entry.
240 ScalarType max_abs_entry_impl() const { return 0; }
241
242 /// @brief Dummy implementation of NaN check.
243 bool has_nan_or_inf_impl() const { return false; }
244
245 /// @brief Dummy implementation of swap.
246 void swap_impl( DummyVector< ScalarType >& other ) { (void) other; }
247};
248
249/// @brief Dummy block 2-vector class for concept checks and testing.
250/// Contains two DummyVector blocks.
251template < typename ScalarT >
253{
254 public:
255 /// @brief Scalar type used by the block vector.
256 using ScalarType = ScalarT;
257
258 /// @brief Type of the first block.
260 /// @brief Type of the second block.
262
263 /// @brief Dummy implementation of linear combination.
265 const std::vector< ScalarType >& c,
266 const std::vector< DummyBlock2Vector >& x,
267 const ScalarType c0 )
268 {
269 (void) c;
270 (void) x;
271 (void) c0;
272 }
273
274 /// @brief Dummy implementation of dot product.
276 {
277 (void) x;
278 return 0;
279 }
280
281 /// @brief Dummy implementation of invert entries.
283
284 /// @brief Dummy implementation of scale with vector.
285 void scale_with_vector_impl( const DummyBlock2Vector& x ) { (void) x; }
286
287 /// @brief Dummy implementation of randomize.
289
290 /// @brief Dummy implementation of max absolute entry.
291 ScalarType max_abs_entry_impl() const { return 0; }
292
293 /// @brief Dummy implementation of NaN check.
294 bool has_nan_or_inf_impl() const { return false; }
295
296 /// @brief Dummy implementation of swap.
297 void swap_impl( DummyBlock2Vector& other ) { (void) other; }
298
299 /// @brief Get const reference to block 1.
300 const DummyVector< ScalarType >& block_1() const { return block_1_; }
301 /// @brief Get const reference to block 2.
302 const DummyVector< ScalarType >& block_2() const { return block_2_; }
303
304 /// @brief Get mutable reference to block 1.
305 DummyVector< ScalarType >& block_1() { return block_1_; }
306 /// @brief Get mutable reference to block 2.
307 DummyVector< ScalarType >& block_2() { return block_2_; }
308
309 private:
312};
313
314/// @brief Static assertion to check VectorLike concept for DummyVector.
315static_assert( VectorLike< DummyVector< double > > );
316/// @brief Static assertion to check Block2VectorLike concept for DummyBlock2Vector.
318
319} // namespace detail
320
321} // namespace terra::linalg
Dummy block 2-vector class for concept checks and testing. Contains two DummyVector blocks.
Definition vector.hpp:253
bool has_nan_or_inf_impl() const
Dummy implementation of NaN check.
Definition vector.hpp:294
ScalarType dot_impl(const DummyBlock2Vector &x) const
Dummy implementation of dot product.
Definition vector.hpp:275
void randomize_impl()
Dummy implementation of randomize.
Definition vector.hpp:288
ScalarT ScalarType
Scalar type used by the block vector.
Definition vector.hpp:256
void invert_entries_impl()
Dummy implementation of invert entries.
Definition vector.hpp:282
DummyVector< ScalarType > & block_1()
Get mutable reference to block 1.
Definition vector.hpp:305
void lincomb_impl(const std::vector< ScalarType > &c, const std::vector< DummyBlock2Vector > &x, const ScalarType c0)
Dummy implementation of linear combination.
Definition vector.hpp:264
const DummyVector< ScalarType > & block_1() const
Get const reference to block 1.
Definition vector.hpp:300
DummyVector< ScalarType > & block_2()
Get mutable reference to block 2.
Definition vector.hpp:307
ScalarType max_abs_entry_impl() const
Dummy implementation of max absolute entry.
Definition vector.hpp:291
void swap_impl(DummyBlock2Vector &other)
Dummy implementation of swap.
Definition vector.hpp:297
void scale_with_vector_impl(const DummyBlock2Vector &x)
Dummy implementation of scale with vector.
Definition vector.hpp:285
const DummyVector< ScalarType > & block_2() const
Get const reference to block 2.
Definition vector.hpp:302
Dummy vector class for concept checks and testing. Implements required vector operations as no-ops.
Definition vector.hpp:210
bool has_nan_or_inf_impl() const
Dummy implementation of NaN check.
Definition vector.hpp:243
void lincomb_impl(const std::vector< ScalarType > &c, const std::vector< DummyVector > &x, const ScalarType c0)
Dummy implementation of linear combination.
Definition vector.hpp:216
ScalarType max_abs_entry_impl() const
Dummy implementation of max absolute entry.
Definition vector.hpp:240
ScalarT ScalarType
Scalar type used by the vector.
Definition vector.hpp:213
void swap_impl(DummyVector< ScalarType > &other)
Dummy implementation of swap.
Definition vector.hpp:246
void scale_with_vector_impl(const DummyVector &x)
Dummy implementation of scale with vector.
Definition vector.hpp:234
void invert_entries_impl()
Dummy implementation of invert entries.
Definition vector.hpp:231
ScalarType dot_impl(const DummyVector &x) const
Dummy implementation of dot product.
Definition vector.hpp:224
void randomize_impl()
Dummy implementation of randomize.
Definition vector.hpp:237
Concept for types that behave like block 2-vectors. Extends VectorLike and requires block types and a...
Definition vector.hpp:47
Concept for types that behave like vectors. Requires exposing ScalarType and implementations for line...
Definition vector.hpp:8
Contains linear algebra utilities and functions for the Terra project.
Definition diagonally_scaled_operator.hpp:8
void invert_entries(Vector &y)
Invert the entries of a vector. For each entry , computes .
Definition vector.hpp:127
void lincomb(Vector &y, const std::vector< ScalarOf< Vector > > &c, const std::vector< Vector > &x, const ScalarOf< Vector > &c0)
Compute a linear combination of vectors. Implements: .
Definition vector.hpp:72
ScalarOf< Vector > norm_2(const Vector &y)
Compute the 2-norm (Euclidean norm) of a vector. Implements: .
Definition vector.hpp:166
void randomize(Vector &y)
Randomize the entries of a vector. Sets each entry of to a random value.
Definition vector.hpp:146
ScalarOf< Vector > dot(const Vector &y, const Vector &x)
Compute the dot product of two vectors. Implements: .
Definition vector.hpp:118
ScalarOf< Vector > norm_2_scaled(const Vector &y, const ScalarOf< Vector > &scaling_factor_under_the_root)
Compute the scaled 2-norm of a vector. Implements: .
Definition vector.hpp:178
ScalarOf< Vector > norm_inf(const Vector &y)
Compute the infinity norm (max absolute entry) of a vector. Implements: .
Definition vector.hpp:156
void scale_in_place(Vector &y, const Vector &x)
Scale a vector in place with another vector. For each entry , computes .
Definition vector.hpp:137
bool has_nan_or_inf(const Vector &y)
Check if a vector contains NaN or inf entries. Returns true if any entry of is NaN or inf.
Definition vector.hpp:189
void assign(Vector &y, const ScalarOf< Vector > &c0)
Assign a scalar value to a vector. Implements: .
Definition vector.hpp:97
void swap(Vector &x, Vector &y)
Swap the contents of two vectors. Exchanges the entries of and .
Definition vector.hpp:199
typename Vector::ScalarType ScalarOf
Alias for the scalar type of a vector.
Definition vector.hpp:63