Statistics
| Branch: | Revision:

adafruit_bno055 / utility / matrix.h @ b79e511b

History | View | Annotate | Download (4.863 KB)

1 4bc1c0c1 Kevin Townsend
/*
2
    Inertial Measurement Unit Maths Library
3
    Copyright (C) 2013-2014  Samuel Cowen
4 d964148c Tony DiCola
    www.camelsoftware.com
5 4bc1c0c1 Kevin Townsend

6
    This program is free software: you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation, either version 3 of the License, or
9
    (at your option) any later version.
10

11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15

16
    You should have received a copy of the GNU General Public License
17
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
#ifndef IMUMATH_MATRIX_HPP
21
#define IMUMATH_MATRIX_HPP
22
23
#include <stdlib.h>
24
#include <string.h>
25
#include <stdint.h>
26
#include <math.h>
27
28 c2a8045b Gé Vissers
#include "vector.h"
29
30 4bc1c0c1 Kevin Townsend
namespace imu
31
{
32
33
34
template <uint8_t N> class Matrix
35
{
36
public:
37 d964148c Tony DiCola
    Matrix()
38
    {
39 b79e511b Gé Vissers
        memset(_cell_data, 0, N*N*sizeof(double));
40 d964148c Tony DiCola
    }
41 4bc1c0c1 Kevin Townsend
42 8208cc49 Gé Vissers
    Matrix(const Matrix &m)
43 4bc1c0c1 Kevin Townsend
    {
44 8208cc49 Gé Vissers
        for (int ij = 0; ij < N*N; ++ij)
45 4bc1c0c1 Kevin Townsend
        {
46 8208cc49 Gé Vissers
            _cell_data[ij] = m._cell_data[ij];
47 4bc1c0c1 Kevin Townsend
        }
48
    }
49
50
    ~Matrix()
51
    {
52
    }
53
54 8208cc49 Gé Vissers
    Matrix& operator=(const Matrix& m)
55 4bc1c0c1 Kevin Townsend
    {
56 8208cc49 Gé Vissers
        for (int ij = 0; ij < N*N; ++ij)
57 4bc1c0c1 Kevin Townsend
        {
58 8208cc49 Gé Vissers
            _cell_data[ij] = m._cell_data[ij];
59 4bc1c0c1 Kevin Townsend
        }
60 9f03e367 Gé Vissers
        return *this;
61 4bc1c0c1 Kevin Townsend
    }
62
63 9f03e367 Gé Vissers
    Vector<N> row_to_vector(int i) const
64 4bc1c0c1 Kevin Townsend
    {
65
        Vector<N> ret;
66 9f03e367 Gé Vissers
        for (int j = 0; j < N; j++)
67 4bc1c0c1 Kevin Townsend
        {
68 9f03e367 Gé Vissers
            ret[j] = cell(i, j);
69 4bc1c0c1 Kevin Townsend
        }
70
        return ret;
71
    }
72
73 9f03e367 Gé Vissers
    Vector<N> col_to_vector(int j) const
74 4bc1c0c1 Kevin Townsend
    {
75
        Vector<N> ret;
76 9f03e367 Gé Vissers
        for (int i = 0; i < N; i++)
77 4bc1c0c1 Kevin Townsend
        {
78 9f03e367 Gé Vissers
            ret[i] = cell(i, j);
79 4bc1c0c1 Kevin Townsend
        }
80
        return ret;
81
    }
82
83 9f03e367 Gé Vissers
    void vector_to_row(const Vector<N>& v, int i)
84 4bc1c0c1 Kevin Townsend
    {
85 9f03e367 Gé Vissers
        for (int j = 0; j < N; j++)
86 4bc1c0c1 Kevin Townsend
        {
87 9f03e367 Gé Vissers
            cell(i, j) = v[j];
88 4bc1c0c1 Kevin Townsend
        }
89
    }
90
91 9f03e367 Gé Vissers
    void vector_to_col(const Vector<N>& v, int j)
92 4bc1c0c1 Kevin Townsend
    {
93 9f03e367 Gé Vissers
        for (int i = 0; i < N; i++)
94 4bc1c0c1 Kevin Townsend
        {
95 9f03e367 Gé Vissers
            cell(i, j) = v[i];
96 4bc1c0c1 Kevin Townsend
        }
97
    }
98
99 9c729628 Gé Vissers
    double operator()(int i, int j) const
100 4bc1c0c1 Kevin Townsend
    {
101 9c729628 Gé Vissers
        return cell(i, j);
102
    }
103
    double& operator()(int i, int j)
104
    {
105
        return cell(i, j);
106 4bc1c0c1 Kevin Townsend
    }
107
108 9c729628 Gé Vissers
    double cell(int i, int j) const
109
    {
110
        return _cell_data[i*N+j];
111
    }
112
    double& cell(int i, int j)
113 4bc1c0c1 Kevin Townsend
    {
114 9c729628 Gé Vissers
        return _cell_data[i*N+j];
115 4bc1c0c1 Kevin Townsend
    }
116
117
118 364879d2 Gé Vissers
    Matrix operator+(const Matrix& m) const
119 4bc1c0c1 Kevin Townsend
    {
120
        Matrix ret;
121 364879d2 Gé Vissers
        for (int ij = 0; ij < N*N; ++ij)
122 4bc1c0c1 Kevin Townsend
        {
123 364879d2 Gé Vissers
            ret._cell_data[ij] = _cell_data[ij] + m._cell_data[ij];
124 4bc1c0c1 Kevin Townsend
        }
125
        return ret;
126
    }
127
128 364879d2 Gé Vissers
    Matrix operator-(const Matrix& m) const
129 4bc1c0c1 Kevin Townsend
    {
130
        Matrix ret;
131 364879d2 Gé Vissers
        for (int ij = 0; ij < N*N; ++ij)
132 4bc1c0c1 Kevin Townsend
        {
133 364879d2 Gé Vissers
            ret._cell_data[ij] = _cell_data[ij] - m._cell_data[ij];
134 4bc1c0c1 Kevin Townsend
        }
135
        return ret;
136
    }
137
138 364879d2 Gé Vissers
    Matrix operator*(double scalar) const
139 4bc1c0c1 Kevin Townsend
    {
140
        Matrix ret;
141 364879d2 Gé Vissers
        for (int ij = 0; ij < N*N; ++ij)
142 4bc1c0c1 Kevin Townsend
        {
143 364879d2 Gé Vissers
            ret._cell_data[ij] = _cell_data[ij] * scalar;
144 4bc1c0c1 Kevin Townsend
        }
145
        return ret;
146
    }
147
148 771690b8 Gé Vissers
    Matrix operator*(const Matrix& m) const
149 4bc1c0c1 Kevin Townsend
    {
150
        Matrix ret;
151 771690b8 Gé Vissers
        for (int i = 0; i < N; i++)
152 4bc1c0c1 Kevin Townsend
        {
153 771690b8 Gé Vissers
            Vector<N> row = row_to_vector(i);
154
            for (int j = 0; j < N; j++)
155 4bc1c0c1 Kevin Townsend
            {
156 b5f89f32 Gé Vissers
                ret(i, j) = row.dot(m.col_to_vector(j));
157 4bc1c0c1 Kevin Townsend
            }
158
        }
159
        return ret;
160
    }
161
162 b5f89f32 Gé Vissers
    Matrix transpose() const
163 4bc1c0c1 Kevin Townsend
    {
164
        Matrix ret;
165 b5f89f32 Gé Vissers
        for (int i = 0; i < N; i++)
166 4bc1c0c1 Kevin Townsend
        {
167 b5f89f32 Gé Vissers
            for (int j = 0; j < N; j++)
168 4bc1c0c1 Kevin Townsend
            {
169 b5f89f32 Gé Vissers
                ret(j, i) = cell(i, j);
170 4bc1c0c1 Kevin Townsend
            }
171
        }
172
        return ret;
173
    }
174
175
    Matrix<N-1> minor_matrix(int row, int col)
176
    {
177
        int colCount = 0, rowCount = 0;
178
        Matrix<N-1> ret;
179
        for(int i = 0; i < N; i++ )
180
        {
181
            if( i != row )
182
            {
183
                for(int j = 0; j < N; j++ )
184
                {
185
                    if( j != col )
186
                    {
187
                        ret(rowCount, colCount) = cell(i, j);
188
                        colCount++;
189
                    }
190
                }
191
                rowCount++;
192
            }
193
        }
194
        return ret;
195
    }
196
197
    double determinant()
198
    {
199
        if(N == 1)
200
            return cell(0, 0);
201
202
        float det = 0.0;
203
        for(int i = 0; i < N; i++ )
204
        {
205
            Matrix<N-1> minor = minor_matrix(0, i);
206
            det += (i%2==1?-1.0:1.0) * cell(0, i) * minor.determinant();
207
        }
208
        return det;
209
    }
210
211
    Matrix invert()
212
    {
213
        Matrix ret;
214
        float det = determinant();
215
216
        for(int x = 0; x < N; x++)
217
        {
218
            for(int y = 0; y < N; y++)
219
            {
220
                Matrix<N-1> minor = minor_matrix(y, x);
221
                ret(x, y) = det*minor.determinant();
222
                if( (x+y)%2 == 1)
223
                    ret(x, y) = -ret(x, y);
224
            }
225
        }
226
        return ret;
227
    }
228
229
private:
230 d964148c Tony DiCola
    double  _cell_data[N*N];
231 4bc1c0c1 Kevin Townsend
};
232
233
234
};
235
236
#endif