MVE - Multi-View Environment mve-devel
Loading...
Searching...
No Matches
matrix.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2015, Simon Fuhrmann
3 * TU Darmstadt - Graphics, Capture and Massively Parallel Computing
4 * All rights reserved.
5 *
6 * This software may be modified and distributed under the terms
7 * of the BSD 3-Clause license. See the LICENSE.txt file for details.
8 */
9
10#ifndef MATH_MATRIX_HEADER
11#define MATH_MATRIX_HEADER
12
13#include <algorithm>
14#include <functional>
15#include <utility>
16#include <numeric>
17#include <ostream>
18
19#include "math/defines.h"
20#include "math/algo.h"
21#include "math/vector.h"
22
24
25/*
26 * Vector type definitions for convenience.
27 */
28template <typename T, int N, int M> class Matrix;
41
52template <typename T, int N, int M>
53class Matrix
54{
55public:
56 typedef T ValueType;
57
58 static int constexpr rows = N;
59 static int constexpr cols = M;
60
61 /* ------------------------ Constructors ---------------------- */
62
64 Matrix (void);
66 explicit Matrix (T const* values);
68 explicit Matrix (T const& value);
69
71 Matrix (Matrix<T,N,M> const& other);
73 template <typename O>
74 Matrix (Matrix<O,N,M> const& other);
75
76 /* ------------------------- Management ----------------------- */
77
79 Matrix<T,N,M>& fill (T const& value);
80
82 bool is_square (void) const;
83
85 Vector<T,M> row (int index) const;
87 Vector<T,N> col (int index) const;
88
90 T minimum (void) const;
92 T maximum (void) const;
93
95 template <int O>
96 Matrix<T,N,M+O> hstack (Matrix<T,N,O> const& other) const;
97
99 template <int O>
101
103 Matrix<T,N,M+1> hstack (Vector<T,N> const& other) const;
104
106 Matrix<T,N+1,M> vstack (Vector<T,M> const& other) const;
107
109 Matrix<T,N-1,M> delete_row (int index) const;
110
112 Matrix<T,N,M-1> delete_col (int index) const;
113
114 /* ---------------------- Unary operators --------------------- */
115
119 Matrix<T,N,M> negated (void) const;
120
125
126 /* --------------------- Binary operators --------------------- */
127
129 template <int U>
130 Matrix<T,N,U> mult (Matrix<T,M,U> const& rhs) const;
131
133 Vector<T,N> mult (Vector<T,M> const& rhs) const;
134
136 Vector<T,N-1> mult (Vector<T,M-1> const& rhs, T const& v) const;
137
139 bool is_similar (Matrix<T,N,M> const& other, T const& epsilon) const;
140
141 /* --------------------- Value iterators ---------------------- */
142
143 T* begin (void);
144 T const* begin (void) const;
145 T* end (void);
146 T const* end (void) const;
147
148 /* --------------------- Object operators --------------------- */
149
151 T* operator* (void);
153 T const* operator* (void) const;
154
156 T& operator() (int row, int col);
158 T const& operator() (int row, int col) const;
159
161 T& operator[] (unsigned int i);
163 T const& operator[] (unsigned int i) const;
164
166 bool operator== (Matrix<T,N,M> const& rhs) const;
168 bool operator!= (Matrix<T,N,M> const& rhs) const;
169
171 Matrix<T,N,M>& operator= (Matrix<T,N,M> const& rhs);
173 template <typename O>
174 Matrix<T,N,M>& operator= (Matrix<O,N,M> const& rhs);
175
177 Matrix<T,N,M> operator- (void) const;
178
180 Matrix<T,N,M>& operator-= (Matrix<T,N,M> const& rhs);
182 Matrix<T,N,M> operator- (Matrix<T,N,M> const& rhs) const;
184 Matrix<T,N,M>& operator+= (Matrix<T,N,M> const& rhs);
186 Matrix<T,N,M> operator+ (Matrix<T,N,M> const& rhs) const;
187
189 template <int U>
190 Matrix<T,N,U> operator* (Matrix<T,M,U> const& rhs) const;
192 Vector<T,N> operator* (Vector<T,M> const& rhs) const;
193
195 Matrix<T,N,M>& operator-= (T const& rhs);
197 Matrix<T,N,M> operator- (T const& rhs) const;
199 Matrix<T,N,M>& operator+= (T const& rhs);
201 Matrix<T,N,M> operator+ (T const& rhs) const;
203 Matrix<T,N,M>& operator*= (T const& rhs);
205 Matrix<T,N,M> operator* (T const& rhs) const;
207 Matrix<T,N,M>& operator/= (T const& rhs);
209 Matrix<T,N,M> operator/ (T const& rhs) const;
210
211protected:
212 T m[N * M];
213};
214
216
217/* ------------------------ Implementation ------------------------ */
218
219#include <algorithm>
220
222
223template <typename T, int N, int M>
224int constexpr Matrix<T,N,M>::rows;
225
226template <typename T, int N, int M>
227int constexpr Matrix<T,N,M>::cols;
228
229template <typename T, int N, int M>
230inline
232{
233}
234
235template <typename T, int N, int M>
236inline
237Matrix<T,N,M>::Matrix (T const* values)
238{
239 std::copy(values, values + N * M, m);
240}
241
242template <typename T, int N, int M>
243inline
244Matrix<T,N,M>::Matrix (T const& value)
245{
246 fill(value);
247}
248
249template <typename T, int N, int M>
250inline
252{
253 std::copy(*other, *other + M * N, m);
254}
255
256template <typename T, int N, int M>
257template <typename O>
258inline
260{
261 std::copy(*other, *other + M * N, m);
262}
263
264/* ------------------------- Matrix helpers ----------------------- */
265
266template <typename T, int N, int M>
267inline bool
269{
270 return false;
271}
272
273template <typename T, int N>
274inline bool
276{
277 return true;
278}
279
280template <typename T, int N>
281inline Matrix<T,N,N>&
283{
284 for (int i = 0; i < matrix.rows; ++i)
285 for (int j = i + 1; j < matrix.cols; ++j)
286 std::swap(matrix(i, j), matrix(j, i));
287 return matrix;
288}
289
290/* ---------------------------- Management ------------------------ */
291
292template <typename T, int N, int M>
293inline Matrix<T,N,M>&
294Matrix<T,N,M>::fill (T const& value)
295{
296 std::fill(m, m + N * M, value);
297 return *this;
298}
299
300template <typename T, int N, int M>
301inline bool
303{
304 return matrix_is_square(*this);
305}
306
307template <typename T, int N, int M>
308inline T
310{
311 return *std::min_element(m, m + N * M);
312}
313
314template <typename T, int N, int M>
315inline T
317{
318 return *std::max_element(m, m + N * M);
319}
320
321template <typename T, int N, int M>
322inline Vector<T,M>
323Matrix<T,N,M>::row (int index) const
324{
325 return Vector<T,M>(m + index * M);
326}
327
328template <typename T, int N, int M>
329inline Vector<T,N>
330Matrix<T,N,M>::col (int index) const
331{
332 typedef algo::InterleavedIter<T,M> RowIter;
333 Vector<T,N> ret;
334 std::copy_n(RowIter(m + index), N, *ret);
335 return ret;
336}
337
338template <typename T, int N, int M>
339template <int O>
340inline Matrix<T,N,M+O>
342{
344 T const* in1 = m;
345 T const* in2 = *other;
346 for (T* out = *ret; in1 < m + M*N; in1 += M, in2 += O, out += O+M)
347 {
348 std::copy(in1, in1 + M, out);
349 std::copy(in2, in2 + O, out + M);
350 }
351 return ret;
352}
353
354template <typename T, int N, int M>
355template <int O>
356inline Matrix<T,N+O,M>
358{
359 Matrix<T,N+O,M> ret;
360 std::copy(m, m + M*N, *ret);
361 std::copy(*other, *other + O*M, *ret + M*N);
362 return ret;
363}
364
365template <typename T, int N, int M>
366inline Matrix<T,N,M+1>
368{
369 Matrix<T,N,M+1> ret;
370 T const* in1 = m;
371 T const* in2 = *other;
372 for (T* out = *ret; in1 < m + M*N; in1 += M, in2 += 1, out += M+1)
373 {
374 std::copy(in1, in1 + M, out);
375 std::copy(in2, in2 + 1, out + M);
376 }
377 return ret;
378}
379
380template <typename T, int N, int M>
381inline Matrix<T,N+1,M>
383{
384 Matrix<T,N+1,M> ret;
385 std::copy(m, m + M*N, *ret);
386 std::copy(*other, *other + M, *ret + M*N);
387 return ret;
388}
389
390template <typename T, int N, int M>
391inline Matrix<T,N-1,M>
393{
394 Matrix<T,N-1,M> ret;
395 T const* in_ptr = this->begin();
396 T* out_ptr = ret.begin();
397 for (int i = 0; i < N; ++i, in_ptr += M)
398 if (i != index)
399 {
400 std::copy(in_ptr, in_ptr + M, out_ptr);
401 out_ptr += M;
402 }
403 return ret;
404}
405
406template <typename T, int N, int M>
407inline Matrix<T,N,M-1>
409{
410 Matrix<T,N,M-1> ret;
411 T const* in_ptr = this->begin();
412 T* out_ptr = ret.begin();
413 for (int i = 0; i < M*N; ++i, ++in_ptr)
414 if (i % M != index)
415 {
416 *out_ptr = *in_ptr;
417 out_ptr += 1;
418 }
419 return ret;
420}
421
422/* ------------------------- Unary operators ---------------------- */
423
424template <typename T, int N, int M>
425inline Matrix<T,N,M>&
427{
428 std::for_each(m, m + N*M, &algo::foreach_negate_value<T>);
429 return *this;
430}
431
432template <typename T, int N, int M>
433inline Matrix<T,N,M>
435{
436 return Matrix<T,N,M>(*this).negate();
437}
438
439template <typename T, int N, int M>
440inline Matrix<T,M,N>&
442{
443 return matrix_inplace_transpose(*this);
444}
445
446template <typename T, int N, int M>
447inline Matrix<T,M,N>
449{
450 Matrix<T,M,N> ret;
451 for (int i = 0; i < N; ++i)
452 for (int j = 0; j < M; ++j)
453 ret(j,i) = (*this)(i,j);
454 return ret;
455}
456
457/* ------------------------ Binary operators ---------------------- */
458
459template <typename T, int N, int M>
460template <int U>
461inline Matrix<T,N,U>
463{
464 typedef algo::InterleavedIter<T,U> RowIter;
465 Matrix<T,N,U> ret;
466 for (int i = 0; i < ret.rows; ++i)
467 for (int j = 0; j < ret.cols; ++j)
468 ret(i,j) = std::inner_product(m + M * i,
469 m + M * i + M, RowIter(*rhs + j), T(0));
470 return ret;
471}
472
473template <typename T, int N, int M>
474inline Vector<T,N>
476{
477 Vector<T,N> ret;
478 for (int i = 0; i < N; ++i)
479 ret[i] = std::inner_product(m + M * i, m + M * i + M, *rhs, T(0));
480 return ret;
481}
482
483template <typename T, int N, int M>
484inline Vector<T,N-1>
485Matrix<T,N,M>::mult (Vector<T,M-1> const& rhs, T const& v) const
486{
487 Vector<T,N-1> ret;
488 for (int i = 0; i < N-1; ++i)
489 ret[i] = std::inner_product(m + M * i, m + M * i + M - 1, *rhs, T(0))
490 + v * m[M * i + M - 1];
491 return ret;
492}
493
494template <typename T, int N, int M>
495inline bool
496Matrix<T,N,M>::is_similar (Matrix<T,N,M> const& other, T const& eps) const
497{
498 return std::equal(m, m + N * M, *other,
500}
501
502/* ------------------------ Value iterators ----------------------- */
503
504template <typename T, int N, int M>
505inline T*
507{
508 return m;
509}
510
511template <typename T, int N, int M>
512inline T const*
514{
515 return m;
516}
517
518template <typename T, int N, int M>
519inline T*
521{
522 return m + N * M;
523}
524
525template <typename T, int N, int M>
526inline T const*
528{
529 return m + N * M;
530}
531
532/* ------------------------ Object operators ---------------------- */
533
534template <typename T, int N, int M>
535inline T*
537{
538 return m;
539}
540
541template <typename T, int N, int M>
542inline T const*
544{
545 return m;
546}
547
548template <typename T, int N, int M>
549inline T&
551{
552 return m[row * M + col];
553}
554
555template <typename T, int N, int M>
556inline T const&
557Matrix<T,N,M>::operator() (int row, int col) const
558{
559 return m[row * M + col];
560}
561template <typename T, int N, int M>
562inline T&
564{
565 return m[i];
566}
567
568template <typename T, int N, int M>
569inline T const&
570Matrix<T,N,M>::operator[] (unsigned int i) const
571{
572 return m[i];
573}
574
575template <typename T, int N, int M>
576inline bool
578{
579 return std::equal(m, m + N * M, *rhs);
580}
581
582template <typename T, int N, int M>
583inline bool
585{
586 return !std::equal(m, m + N * M, *rhs);
587}
588
589template <typename T, int N, int M>
590inline Matrix<T,N,M>&
592{
593 std::copy(*rhs, *rhs + N * M, m);
594 return *this;
595}
596
597template <typename T, int N, int M>
598template <typename O>
599inline Matrix<T,N,M>&
601{
602 std::copy(*rhs, *rhs + N * M, m);
603 return *this;
604}
605
606template <typename T, int N, int M>
607inline Matrix<T,N,M>
609{
610 return negated();
611}
612
613template <typename T, int N, int M>
614inline Matrix<T,N,M>&
616{
617 std::transform(m, m + N * M, *rhs, m, std::minus<T>());
618 return *this;
619}
620
621template <typename T, int N, int M>
622inline Matrix<T,N,M>
624{
625 return Matrix<T,N,M>(*this) -= rhs;
626}
627
628template <typename T, int N, int M>
629template <int U>
630inline Matrix<T,N,U>
632{
633 return mult(rhs);
634}
635
636template <typename T, int N, int M>
637inline Vector<T,N>
639{
640 return mult(rhs);
641}
642
643template <typename T, int N, int M>
644inline Matrix<T,N,M>&
646{
647 std::transform(m, m + N * M, *rhs, m, std::plus<T>());
648 return *this;
649}
650
651template <typename T, int N, int M>
652inline Matrix<T,N,M>
654{
655 return Matrix<T,N,M>(*this) += rhs;
656}
657
658template <typename T, int N, int M>
659inline Matrix<T,N,M>&
661{
662 std::for_each(m, m + N * M, algo::foreach_substraction_with_const<T>(rhs));
663 return *this;
664}
665
666template <typename T, int N, int M>
667inline Matrix<T,N,M>
668Matrix<T,N,M>::operator- (T const& rhs) const
669{
670 return Matrix<T,N,M>(*this) -= rhs;
671}
672
673template <typename T, int N, int M>
674inline Matrix<T,N,M>&
676{
677 std::for_each(m, m + N * M, algo::foreach_addition_with_const<T>(rhs));
678 return *this;
679}
680
681template <typename T, int N, int M>
682inline Matrix<T,N,M>
683Matrix<T,N,M>::operator+ (T const& rhs) const
684{
685 return Matrix<T,N,M>(*this) += rhs;
686}
687
688template <typename T, int N, int M>
689inline Matrix<T,N,M>&
691{
692 std::for_each(m, m + N * M, algo::foreach_multiply_with_const<T>(rhs));
693 return *this;
694}
695
696template <typename T, int N, int M>
697inline Matrix<T,N,M>
698Matrix<T,N,M>::operator* (T const& rhs) const
699{
700 return Matrix<T,N,M>(*this) *= rhs;
701}
702
703template <typename T, int N, int M>
704inline Matrix<T,N,M>&
706{
707 std::for_each(m, m + N * M, algo::foreach_divide_by_const<T>(rhs));
708 return *this;
709}
710
711template <typename T, int N, int M>
712inline Matrix<T,N,M>
713Matrix<T,N,M>::operator/ (T const& rhs) const
714{
715 return Matrix<T,N,M>(*this) /= rhs;
716}
717
719
720/* --------------------- Ouput stream adapter --------------------- */
721
722#include <ostream>
723
725
727template <typename T, int N, int M>
728inline std::ostream&
729operator<< (std::ostream& os, Matrix<T,N,M> const& m)
730{
731 for (int i = 0; i < m.rows; ++i)
732 for (int j = 0; j < m.cols; ++j)
733 os << m(i,j) << (j == m.cols - 1 ? "\n" : " ");
734 return os;
735}
736
738
739#endif /* MATH_MATRIX_HEADER */
Matrix class for arbitrary dimensions and types.
Definition matrix.h:54
Matrix< T, N, M > negated(void) const
Returns a component-wise negation on copy of self.
Definition matrix.h:434
Matrix(void)
Default ctor that leaves values uninitialized.
Definition matrix.h:231
T minimum(void) const
Returns the smallest element in the matrix.
Definition matrix.h:309
Matrix< T, N, U > mult(Matrix< T, M, U > const &rhs) const
Matrix with matrix multiplication.
Definition matrix.h:462
static int constexpr rows
Definition matrix.h:58
Vector< T, N > mult(Vector< T, M > const &rhs) const
Matrix with vector multiplication.
Definition matrix.h:475
T * end(void)
Definition matrix.h:520
Matrix< T, N+1, M > vstack(Vector< T, M > const &other) const
Stacks this matrix (top) and another vector (bottom) vertically.
Definition matrix.h:382
Matrix(Matrix< T, N, M > const &other)
Copy ctor from matrix of same type.
Definition matrix.h:251
T const * begin(void) const
Definition matrix.h:513
Matrix(T const &value)
Ctor that initializes ALL elements.
Definition matrix.h:244
Vector< T, M > row(int index) const
Returns a row of the matrix as vector.
Definition matrix.h:323
bool is_similar(Matrix< T, N, M > const &other, T const &epsilon) const
Component-wise similarity using epsilon checks.
Definition matrix.h:496
Matrix< T, N-1, M > delete_row(int index) const
Returns a new matrix with the specified row deleted.
Definition matrix.h:392
bool is_square(void) const
Tests if the matrix is square.
Definition matrix.h:302
Vector< T, N > col(int index) const
Returns a column of the matrix as vector.
Definition matrix.h:330
Vector< T, N-1 > mult(Vector< T, M-1 > const &rhs, T const &v) const
Matrix with smaller vector multiplication.
Definition matrix.h:485
Matrix< T, N, M > & negate(void)
Component-wise negation on self, returns self.
Definition matrix.h:426
Matrix< T, N, M-1 > delete_col(int index) const
Returns a new matrix with the specified column deleted.
Definition matrix.h:408
Matrix(T const *values)
Ctor taking a pointer to initialize values.
Definition matrix.h:237
T const * end(void) const
Definition matrix.h:527
Matrix< T, N, M+O > hstack(Matrix< T, N, O > const &other) const
Stacks this (left) and another matrix (right) horizontally.
Definition matrix.h:341
Matrix< T, M, N > transposed(void) const
Returns a transposed copy of self by treating rows as columns.
Definition matrix.h:448
Matrix(Matrix< O, N, M > const &other)
Copy ctor from matrix of different type.
Definition matrix.h:259
Matrix< T, N+O, M > vstack(Matrix< T, O, M > const &other) const
Stacks this (top) and another matrix (bottom) vertically.
Definition matrix.h:357
static int constexpr cols
Definition matrix.h:59
T * begin(void)
Definition matrix.h:506
Matrix< T, N, M > & fill(T const &value)
Fills all vector elements with the given value.
Definition matrix.h:294
Matrix< T, M, N > & transpose(void)
Transpose the current matrix.
Definition matrix.h:441
T maximum(void) const
Returns the largest element in the matrix.
Definition matrix.h:316
Matrix< T, N, M+1 > hstack(Vector< T, N > const &other) const
Stacks this matrix (left) and another vector (right) horizontally.
Definition matrix.h:367
Vector class for arbitrary dimensions and types.
Definition vector.h:87
#define MATH_NAMESPACE_BEGIN
Definition defines.h:15
#define MATH_NAMESPACE_END
Definition defines.h:16
Matrix< T, N, N > & matrix_inplace_transpose(Matrix< T, N, N > &matrix)
Definition matrix.h:282
bool matrix_is_square(Matrix< T, N, M > const &)
Definition matrix.h:268
void swap(mve::Image< T > &a, mve::Image< T > &b)
Specialization of std::swap for efficient image swapping.
Definition image.h:478
Iterator that advances 'S' elements of type T.
Definition algo.h:146
for-each functor: adds a constant value to operand.
Definition algo.h:241
for-each functor: divides operand by constant divisor.
Definition algo.h:232
for-each functor: multiplies operand with constant factor.
Definition algo.h:223
for-each functor: substracts a constant value to operand.
Definition algo.h:250
Epsilon comparator predicate.
Definition algo.h:136