forked from Duet3D/RepRapFirmware
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMatrix.h
More file actions
132 lines (115 loc) · 2.95 KB
/
Matrix.h
File metadata and controls
132 lines (115 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
* Matrix.h
*
* Created on: 31 Mar 2015
* Author: David
*/
#ifndef MATRIX_H_
#define MATRIX_H_
#include <cstddef> // for size_t
// Base class for matrices, allows us to write functions that work with any size matrix
template<class T> class MathMatrix
{
public:
virtual size_t rows() const = 0;
virtual size_t cols() const = 0;
virtual T& operator() (size_t r, size_t c) = 0;
virtual const T& operator() (size_t r, size_t c) const = 0;
virtual ~MathMatrix() { } // to keep Eclipse code analysis happy
};
// Fixed size matrix class
template<class T, size_t ROWS, size_t COLS> class FixedMatrix : public MathMatrix<T>
{
public:
size_t rows() const override { return ROWS; }
size_t cols() const override { return COLS; }
// Indexing operator, non-const version
T& operator() (size_t r, size_t c) override
//pre(r < ROWS; c < COLS)
{
return data[r * COLS + c];
}
// Indexing operator, const version
const T& operator() (size_t r, size_t c) const override
//pre(r < ROWS; c < COLS)
{
return data[r * COLS + c];
}
void SwapRows(size_t i, size_t j, size_t numCols = COLS)
//pre(i < ROWS; j < ROWS)
;
void GaussJordan(T *solution, size_t numRows)
//pre(numRows <= ROWS; numRows + 1 <= COLS)
;
// Return a pointer to a specified row, non-const version
T* GetRow(size_t r)
//pre(r < ROWS)
{
return data + (r * COLS);
}
// Return a pointer to a specified row, const version
const T* GetRow(size_t r) const
//pre(r < ROWS)
{
return data + (r * COLS);
}
private:
T data[ROWS * COLS];
};
// Swap 2 rows of a matrix
template<class T, size_t ROWS, size_t COLS> inline void FixedMatrix<T, ROWS, COLS>::SwapRows(size_t i, size_t j, size_t numCols)
{
if (i != j)
{
for (size_t k = i; k < numCols; ++k)
{
T temp = (*this)(i, k);
(*this)(i, k) = (*this)(j, k);
(*this)(j, k) = temp;
}
}
}
// Perform Gauss-Jordan elimination on a N x (N+1) matrix.
// Returns a pointer to the solution vector.
template<class T, size_t ROWS, size_t COLS> void FixedMatrix<T, ROWS, COLS>::GaussJordan(T *solution, size_t numRows)
{
for (size_t i = 0; i < numRows; ++i)
{
// Swap the rows around for stable Gauss-Jordan elimination
float vmax = fabs((*this)(i, i));
for (size_t j = i + 1; j < numRows; ++j)
{
const float rmax = fabs((*this)(j, i));
if (rmax > vmax)
{
SwapRows(i, j);
vmax = rmax;
}
}
// Use row i to eliminate the ith element from previous and subsequent rows
float v = (*this)(i, i);
for (size_t j = 0; j < i; ++j)
{
float factor = (*this)(j, i)/v;
(*this)(j, i) = 0.0;
for (size_t k = i + 1; k <= numRows; ++k)
{
(*this)(j, k) -= (*this)(i, k) * factor;
}
}
for (size_t j = i + 1; j < numRows; ++j)
{
float factor = (*this)(j, i)/v;
(*this)(j, i) = 0.0;
for (size_t k = i + 1; k <= numRows; ++k)
{
(*this)(j, k) -= (*this)(i, k) * factor;
}
}
}
for (size_t i = 0; i < numRows; ++i)
{
solution[i] = (*this)(i, numRows) / (*this)(i, i);
}
}
#endif /* MATRIX_H_ */