ITK 6.0.0
Insight Toolkit
 
Loading...
Searching...
No Matches
itkMatrix.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18#ifndef itkMatrix_h
19#define itkMatrix_h
20
21#include "itkPoint.h"
22#include "itkCovariantVector.h"
23
24#include <vxl_version.h>
25#include "vnl/vnl_matrix_fixed.hxx" // Get the templates
26#include "vnl/vnl_transpose.h"
27#include "itkMathSVD.h"
28#include "vnl/vnl_matrix.h"
29
30// GetInverse is Eigen-backed via itk::Math::SVD, but ITK 5.4 exposed
31// vnl_matrix_inverse (and through it vnl_svd / vnl_diag_matrix) transitively to
32// every itkMatrix.h consumer. Retain that surface for release-5.4 source
33// compatibility in default builds; ITK proper includes what it uses, so
34// ITK_LEGACY_REMOVE drops the leak. The transitional guard keeps the
35// vnl_matrix_inverse deprecation warning off itkMatrix consumers.
36#if !defined(ITK_LEGACY_REMOVE) && !defined(ITK_FUTURE_LEGACY_REMOVE)
37# define ITK_VNL_SVD_TRANSITIONAL_INCLUDE
38# include "vnl/algo/vnl_matrix_inverse.h"
39# undef ITK_VNL_SVD_TRANSITIONAL_INCLUDE
40#endif
41#include "itkMathDeterminant.h"
42// GetInverse's singular check is Eigen-backed via itk::Math::Determinant, but
43// ITK 5.4 exposed vnl_determinant transitively through this header; keep it
44// reachable during the deprecation window so downstream code still compiles.
45#if !defined(ITK_LEGACY_REMOVE) && !defined(ITK_FUTURE_LEGACY_REMOVE)
46# include "vnl/algo/vnl_determinant.h"
47#endif
48#include "itkMath.h"
49#include <type_traits> // For is_same.
50
51namespace itk
52{
68
69template <typename T, unsigned int VRows = 3, unsigned int VColumns = 3>
70class ITK_TEMPLATE_EXPORT Matrix
71{
72public:
74 using Self = Matrix;
75
77 using ValueType = T;
78 using ComponentType = T;
79
81 using pointer = ValueType *;
82
84 using const_pointer = const ValueType *;
85
88
90 using const_reference = const ValueType &;
91
94
96 using const_iterator = const ValueType *;
97
99 static constexpr unsigned int RowDimensions = VRows;
100 static constexpr unsigned int ColumnDimensions = VColumns;
101
103 using InternalMatrixType = vnl_matrix_fixed<T, VRows, VColumns>;
104
109
112 operator*(const Vector<T, VColumns> & vect) const;
113
116 operator*(const Point<T, VColumns> & pnt) const;
117
121
123 vnl_vector_fixed<T, VRows>
124 operator*(const vnl_vector_fixed<T, VColumns> & inVNLvect) const;
125
127 Self
129
130 template <unsigned int OuterDim>
132 operator*(const vnl_matrix_fixed<T, VRows, OuterDim> & matrix) const
133 {
134 const Matrix<T, VRows, OuterDim> result(m_Matrix * matrix);
135 return result;
136 }
137
139 Self
140 operator+(const Self & matrix) const;
141
142 const Self &
143 operator+=(const Self & matrix);
144
146 Self
147 operator-(const Self & matrix) const;
148
149 const Self &
150 operator-=(const Self & matrix);
151
153 vnl_matrix<T>
154 operator*(const vnl_matrix<T> & matrix) const;
155
157 void
159
161 void
162 operator*=(const vnl_matrix<T> & matrix);
163
165 vnl_vector<T>
166 operator*(const vnl_vector<T> & vc) const;
167
169 void
170 operator*=(const T & value)
171 {
172 m_Matrix *= value;
173 }
174
176 Self
177 operator*(const T & value) const
178 {
179 Self result(*this);
180
181 result *= value;
182 return result;
183 }
184
186 void
187 operator/=(const T & value)
188 {
189 m_Matrix /= value;
190 }
191
193 Self
194 operator/(const T & value) const
195 {
196 Self result(*this);
197
198 result /= value;
199 return result;
200 }
201
203 inline T &
204 operator()(unsigned int row, unsigned int col)
205 {
206 return m_Matrix(row, col);
207 }
208
210 inline const T &
211 operator()(unsigned int row, unsigned int col) const
212 {
213 return m_Matrix(row, col);
214 }
215
217 inline T *
218 operator[](unsigned int i)
219 {
220 return m_Matrix[i];
221 }
222
224 inline const T *
225 operator[](unsigned int i) const
226 {
227 return m_Matrix[i];
228 }
229
231 inline InternalMatrixType &
233 {
234 return m_Matrix;
235 }
236
238 [[nodiscard]] inline const InternalMatrixType &
240 {
241 return m_Matrix;
242 }
243
245 inline void
247 {
248 m_Matrix.set_identity();
249 }
250
252 static Self
254 {
255 InternalMatrixType internalMatrix;
256 internalMatrix.set_identity();
257 return Self{ internalMatrix };
258 }
259
261 inline void
262 Fill(const T & value)
263 {
264 m_Matrix.fill(value);
265 }
266
268 inline Self &
269 operator=(const vnl_matrix<T> & matrix)
270 {
271 m_Matrix = matrix;
272 return *this;
273 }
274
277 inline explicit Matrix(const vnl_matrix<T> & matrix)
278 : m_Matrix(matrix)
279 {}
280
285 template <typename TElement>
286 explicit Matrix(const TElement (&elements)[VRows][VColumns])
287 : m_Matrix(&elements[0][0])
288 {
289 static_assert(std::is_same_v<TElement, T>,
290 "The type of an element should correspond with this itk::Matrix instantiation.");
291 }
292
294 inline bool
295 operator==(const Self & matrix) const
296 {
297 bool equal = true;
298
299 for (unsigned int r = 0; r < VRows; ++r)
300 {
301 for (unsigned int c = 0; c < VColumns; ++c)
302 {
303 if (Math::NotExactlyEquals(m_Matrix(r, c), matrix.m_Matrix(r, c)))
304 {
305 equal = false;
306 break;
307 }
308 }
309 }
310 return equal;
311 }
312
314
315
316 inline Self &
318 {
319 this->m_Matrix = matrix;
320 return *this;
321 }
322
324 inline Matrix(const InternalMatrixType & matrix)
325 : m_Matrix(matrix)
326 {}
327
329 [[nodiscard]] inline vnl_matrix_fixed<T, VColumns, VRows>
331 {
332 if (Math::Determinant(m_Matrix) == T{})
333 {
334 itkGenericExceptionMacro("Singular matrix. Determinant is 0.");
335 }
336 return vnl_matrix_fixed<T, VColumns, VRows>{ Math::SVD(m_Matrix.as_ref()).PseudoInverse() };
337 }
338
340 [[nodiscard]] inline vnl_matrix_fixed<T, VColumns, VRows>
342 {
343 return vnl_matrix_fixed<T, VColumns, VRows>{ m_Matrix.transpose().as_matrix() };
344 }
345
351 Matrix() = default;
352
354 [[nodiscard]] constexpr unsigned int
355 size() const
356 {
357 return m_Matrix.size();
358 }
359
361 [[nodiscard]] iterator
363 {
364 return m_Matrix.begin();
365 }
366
368 [[nodiscard]] iterator
370 {
371 return m_Matrix.end();
372 }
373
375 [[nodiscard]] const_iterator
376 begin() const
377 {
378 return m_Matrix.begin();
379 }
380
382 [[nodiscard]] const_iterator
383 end() const
384 {
385 return m_Matrix.end();
386 }
387
389 [[nodiscard]] const_iterator
390 cbegin() const
391 {
392 return m_Matrix.begin();
393 }
394
396 [[nodiscard]] const_iterator
397 cend() const
398 {
399 return m_Matrix.end();
400 }
401
402 void
403 swap(Self & other) noexcept
404 {
405 // allow for augment dependent look up
406 using std::swap;
407 swap(this->m_Matrix, other.m_Matrix);
408 }
409
410 inline void
411 PrintSelf(std::ostream & os, Indent indent) const
412 {
413 os << indent << "Matrix (" << VRows << "x" << VColumns << ")\n";
414 for (unsigned int r = 0; r < VRows; ++r)
415 {
416 os << indent << " ";
417 for (unsigned int c = 0; c < VColumns; ++c)
418 {
419 os << m_Matrix(r, c) << " ";
420 }
421 os << "\n";
422 }
423 }
424
425private:
427};
428
429template <typename T, unsigned int VRows, unsigned int VColumns>
430std::ostream &
431operator<<(std::ostream & os, const Matrix<T, VRows, VColumns> & v)
432{
433 os << v.GetVnlMatrix();
434 return os;
435}
436
437
438template <typename T, unsigned int VRows, unsigned int VColumns>
439inline void
441{
442 a.swap(b);
443}
444
445} // end namespace itk
446
447#ifndef ITK_MANUAL_INSTANTIATION
448# include "itkMatrix.hxx"
449#endif
450
451#endif
A templated class holding a n-Dimensional covariant vector.
Control indentation during Print() invocation.
Definition itkIndent.h:51
A templated class holding a M x N size Matrix.
Definition itkMatrix.h:71
constexpr unsigned int size() const
Definition itkMatrix.h:355
const_iterator cbegin() const
Definition itkMatrix.h:390
iterator end()
Definition itkMatrix.h:369
T & operator()(unsigned int row, unsigned int col)
Definition itkMatrix.h:204
Self operator/(const T &value) const
Definition itkMatrix.h:194
void operator/=(const T &value)
Definition itkMatrix.h:187
T * operator[](unsigned int i)
Definition itkMatrix.h:218
void Fill(const T &value)
Definition itkMatrix.h:262
Self operator-(const Self &matrix) const
Self & operator=(const InternalMatrixType &matrix)
Definition itkMatrix.h:317
Matrix< VComponent, VColumns, VColumns > CompatibleSquareMatrixType
Definition itkMatrix.h:108
const_iterator end() const
Definition itkMatrix.h:383
Self & operator=(const vnl_matrix< T > &matrix)
Definition itkMatrix.h:269
bool operator==(const Self &matrix) const
Definition itkMatrix.h:295
static constexpr unsigned int ColumnDimensions
Definition itkMatrix.h:100
void SetIdentity()
Definition itkMatrix.h:246
vnl_vector< T > operator*(const vnl_vector< T > &vc) const
const T & operator()(unsigned int row, unsigned int col) const
Definition itkMatrix.h:211
InternalMatrixType & GetVnlMatrix()
Definition itkMatrix.h:232
const_iterator begin() const
Definition itkMatrix.h:376
Matrix< T, VRows, OuterDim > operator*(const vnl_matrix_fixed< T, VRows, OuterDim > &matrix) const
Definition itkMatrix.h:132
static Self GetIdentity()
Definition itkMatrix.h:253
ITK_UNEQUAL_OPERATOR_MEMBER_FUNCTION(Self)
CovariantVector< T, VRows > operator*(const CovariantVector< T, VColumns > &covect) const
const Self & operator+=(const Self &matrix)
vnl_vector_fixed< T, VRows > operator*(const vnl_vector_fixed< T, VColumns > &inVNLvect) const
void operator*=(const vnl_matrix< T > &matrix)
const Self & operator-=(const Self &matrix)
vnl_matrix< T > operator*(const vnl_matrix< T > &matrix) const
Matrix(const InternalMatrixType &matrix)
Definition itkMatrix.h:324
static constexpr unsigned int RowDimensions
Definition itkMatrix.h:99
void PrintSelf(std::ostream &os, Indent indent) const
Definition itkMatrix.h:411
Matrix(const vnl_matrix< T > &matrix)
Definition itkMatrix.h:277
const_iterator cend() const
Definition itkMatrix.h:397
Self operator*(const T &value) const
Definition itkMatrix.h:177
Self operator+(const Self &matrix) const
vnl_matrix_fixed< T, VColumns, VRows > GetTranspose() const
Definition itkMatrix.h:341
void operator*=(const CompatibleSquareMatrixType &matrix)
Matrix()=default
void swap(Self &other) noexcept
Definition itkMatrix.h:403
vnl_matrix_fixed< T, VColumns, VRows > GetInverse() const
Definition itkMatrix.h:330
vnl_matrix_fixed< VComponent, VRows, VColumns > InternalMatrixType
Definition itkMatrix.h:103
iterator begin()
Definition itkMatrix.h:362
const InternalMatrixType & GetVnlMatrix() const
Definition itkMatrix.h:239
const T * operator[](unsigned int i) const
Definition itkMatrix.h:225
void operator*=(const T &value)
Definition itkMatrix.h:170
Vector< T, VRows > operator*(const Vector< T, VColumns > &vect) const
Self operator*(const CompatibleSquareMatrixType &matrix) const
Matrix(const TElement(&elements)[VRows][VColumns])
Definition itkMatrix.h:286
Point< T, VRows > operator*(const Point< T, VColumns > &pnt) const
A templated class holding a geometric point in n-Dimensional space.
Definition itkPoint.h:54
A templated class holding a n-Dimensional vector.
Definition itkVector.h:63
TReal Determinant(const vnl_matrix_fixed< TReal, VDim, VDim > &A)
Determinant of a square matrix, backed by Eigen.
FixedSquareSVDResult< TReal, VDim > SVD(const vnl_matrix_fixed< TReal, VDim, VDim > &A, bool canonicalizeSigns=true)
Singular value decomposition A = U diag(W) V^T, backed by Eigen.
Definition itkMathSVD.h:574
constexpr bool NotExactlyEquals(const TInput1 &x1, const TInput2 &x2)
Definition itkMath.h:754
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes....
void swap(Array< T > &a, Array< T > &b) noexcept
Definition itkArray.h:244
ITKCommon_EXPORT std::ostream & operator<<(std::ostream &out, AnatomicalOrientation::CoordinateEnum value)