Line data Source code
1 : #ifndef CE10BDD8_6874_4771_89BA_D153438C3E01
2 : #define CE10BDD8_6874_4771_89BA_D153438C3E01
3 :
4 : #include "base/first_include.h" // IWYU pragma: keep
5 : #include "math/linalg/matrix.h" // IWYU pragma: keep
6 : #include <initializer_list>
7 :
8 : namespace tracking
9 : {
10 : namespace math
11 : {
12 :
13 : template <typename ValueType_, sint32 Rows_, sint32 Cols_, bool IsRowMajor_>
14 : class MatrixColumnView;
15 :
16 : // TODO(matthias): add interface contract
17 :
18 : /// \brief A column vector class template, specializing Matrix for single-column matrixes.
19 : ///
20 : /// The Vector class provides a convenient interface for column vectors, inheriting all
21 : /// matrix operations from Matrix while adding vector-specific operations like dot product,
22 : /// norm calculations, and normalization.
23 : ///
24 : /// \tparam ValueType_ The atomic data type of internal elements
25 : /// \tparam Size_ The number of elements in the vector (must be > 0)
26 : ///
27 : /// \note This class is a specialization of Matrix<ValueType_, Size_, 1, true> where
28 : /// the third template parameter (Cols) is fixed to 1 and IsRowMajor is fixed to true.
29 : /// All matrix operations are inherited from the base Matrix class.
30 : ///
31 : /// \see Matrix for the base class functionality
32 : template <typename ValueType_, sint32 Size_>
33 909 : class Vector: public Matrix<ValueType_, Size_, 1, true>
34 : {
35 : public:
36 : using BaseMatrix = Matrix<ValueType_, Size_, 1, true>; ///< type of the parent class
37 :
38 : // unhide ctor of base class to allow implicit call in derived default ctors
39 1735 : using BaseMatrix::BaseMatrix;
40 :
41 : //////////////////////////////////////////////////
42 : // additional constructors --->
43 : /// \brief Construct a vector from a compatible matrix
44 : /// \param[in] other A matrix with dimensions Size_ x 1
45 : explicit Vector(const BaseMatrix& other)
46 : : BaseMatrix{other}
47 : {
48 : }
49 :
50 : /// \brief Construct a vector from a compatible matrix with different memory layout
51 : /// \param[in] other A matrix with dimensions Size_ x 1
52 : explicit Vector(const Matrix<ValueType_, Size_, 1, false>& other)
53 : : BaseMatrix{reinterpret_cast<const Vector&>(other)}
54 : {
55 : // This constructor allows constructing a Vector from a matrix with the same dimensions but different memory layout
56 : // (column-major). The reinterpret_cast is safe here because the memory layout of a Size_ x 1 matrix is the same regardless of
57 : // row-major or column-major storage, as there is only one column.
58 : }
59 :
60 : /// \brief Move construct a vector from a compatible matrix
61 : /// \param[in] other A matrix with dimensions Size_ x 1 (moved from)
62 107 : explicit Vector(BaseMatrix&& other) noexcept
63 59 : : BaseMatrix{std::move(other)}
64 : {
65 : }
66 :
67 : /// \brief Move construct a vector from a compatible matrix with different memory layout
68 : /// \param[in] other A matrix with dimensions Size_ x 1 (moved from)
69 40 : explicit Vector(Matrix<ValueType_, Size_, 1, false>&& other) noexcept
70 40 : : BaseMatrix{std::move(reinterpret_cast<const Vector&&>(other))}
71 : {
72 : // This constructor allows constructing a Vector from a matrix with the same dimensions but different memory layout
73 : // (column-major). The reinterpret_cast is safe here because the memory layout of a Size_ x 1 matrix is the same regardless of
74 : // row-major or column-major storage, as there is only one column.
75 : }
76 :
77 : /// \brief Construct a zero vector
78 : /// \return A vector filled with zeros
79 : [[nodiscard]] static auto Zeros() -> Vector;
80 :
81 : /// \brief Construct a vector filled with ones
82 : /// \return A vector filled with ones
83 : [[nodiscard]] static auto Ones() -> Vector;
84 :
85 : /// \brief Create a unit vector with 1 at the specified position
86 : /// \tparam Row_ The index position (0-based) where the 1 should be placed
87 : /// \return A unit vector with 1 at position Row_ and 0 elsewhere
88 : template <sint32 Row_>
89 : [[nodiscard]] static auto UnitVector() -> Vector;
90 :
91 : /// \brief Creates a Vector from an initializer list
92 : ///
93 : /// This function constructs a Vector from a flat initializer list.
94 : /// The list size must exactly match the vector size.
95 : ///
96 : /// \param[in] list Initializer list containing the vector values
97 : /// \return Vector instance initialized with the provided values
98 : /// \note The list size must equal Size_, otherwise assertion fails
99 : [[nodiscard]] static auto FromList(const std::initializer_list<ValueType_>& list) -> Vector;
100 : // <---
101 :
102 : //////////////////////////////////////////////////
103 : // access operators --->
104 : /// \brief Element read-only access to a scalar vector value
105 : /// \param[in] idx Row index of the element
106 : /// \return The scalar vector value wrapped in tl::expected for error handling
107 : /// \note Performs bounds checking
108 : [[nodiscard]] auto operator[](sint32 idx) const -> tl::expected<ValueType_, Errors>;
109 :
110 : /// \brief Element access to a scalar vector value
111 : /// \param[in] idx Row index of the element
112 : /// \return Reference to the scalar vector value wrapped in tl::expected for error handling
113 : /// \note Performs bounds checking
114 : [[nodiscard]] auto operator[](sint32 idx) -> tl::expected<std::reference_wrapper<ValueType_>, Errors>;
115 : // <---
116 :
117 : //////////////////////////////////////////////////
118 : // arithmentic operators --->
119 : /// \brief Compute the dot product with another vector
120 : /// \param[in] other The other vector (must have the same size)
121 : /// \return The dot product value
122 : /// \note Mathematically: \f$ \mathbf{v} \cdot \mathbf{w} = \sum_{i=0}^{n-1} v_i w_i \f$
123 : [[nodiscard]] auto operator*(const Vector& other) const -> ValueType_;
124 : // <---
125 :
126 : //////////////////////////////////////////////////
127 : // other operations --->
128 : /// \brief Compute the squared Euclidean norm (L2 norm squared) of the vector
129 : /// \return The squared L2 norm value
130 : /// \note Mathematically: \f$ \|\mathbf{v}\|_2^2 = \sum_{i=0}^{n-1} v_i^2 \f$
131 : [[nodiscard]] auto normSq() const -> ValueType_;
132 :
133 : /// \brief Compute the Euclidean norm (L2 norm) of the vector
134 : /// \return The L2 norm value
135 : /// \note Only available for floating-point ValueType_
136 : /// \note Mathematically: \f$ \|\mathbf{v}\|_2 = \sqrt{\sum_{i=0}^{n-1} v_i^2} \f$
137 : template <typename U = ValueType_, std::enable_if_t<std::is_floating_point<U>::value, int> = 0>
138 : [[nodiscard]] auto norm() const -> ValueType_;
139 :
140 : /// \brief Normalize this vector in-place to unit length
141 : /// \note Only available for floating-point ValueType_
142 : /// \note Modifies this vector in-place
143 : /// \warning Undefined behavior if the vector norm is zero
144 : /// \note Mathematically: \f$ \mathbf{v} \leftarrow \frac{\mathbf{v}}{\|\mathbf{v}\|_2} \f$
145 : template <typename U = ValueType_, std::enable_if_t<std::is_floating_point<U>::value, int> = 0>
146 : void normalize();
147 :
148 : /// \brief Create a new normalized vector of unit length
149 : /// \return A new vector normalized to unit length
150 : /// \note Only available for floating-point ValueType_
151 : /// \note Returns a new normalized vector, leaving this vector unchanged
152 : /// \warning Undefined behavior if the vector norm is zero
153 : /// \note Mathematically: \f$ \mathbf{w} = \frac{\mathbf{v}}{\|\mathbf{v}\|_2} \f$
154 : template <typename U = ValueType_, std::enable_if_t<std::is_floating_point<U>::value, int> = 0>
155 : [[nodiscard]] auto normalize() const -> Vector;
156 : // <---
157 :
158 : //////////////////////////////////////////////////
159 : // unsafe access operators --->
160 : /// \brief Element read-only access to a scalar vector value (unchecked)
161 : /// \param[in] idx Row index of the element (must be valid)
162 : /// \return The scalar vector value
163 : /// \note No bounds checking performed - use with caution
164 15499 : [[nodiscard]] auto at_unsafe(sint32 idx) const -> ValueType_ { return BaseMatrix::at_unsafe(idx, 0); }
165 :
166 : /// \brief Element access to a scalar vector value (unchecked)
167 : /// \param[in] idx Row index of the element (must be valid)
168 : /// \return Reference to the scalar vector value
169 : /// \note No bounds checking performed - use with caution
170 14981 : [[nodiscard]] auto at_unsafe(sint32 idx) -> ValueType_& { return BaseMatrix::at_unsafe(idx, 0); }
171 : // <---
172 :
173 : protected:
174 : using BaseMatrix::Ones;
175 : using BaseMatrix::Zeros;
176 : using BaseMatrix::operator();
177 : using BaseMatrix::at_unsafe;
178 : };
179 :
180 : } // namespace math
181 : } // namespace tracking
182 :
183 : #endif // CE10BDD8_6874_4771_89BA_D153438C3E01
|