18 #pragma GCC optimize("O3") 23 #if CONFIG_HAL_BOARD == HAL_BOARD_SITL 44 float* ret =
new float[n*n];
45 memset(ret,0.0
f,n*n*
sizeof(
float));
47 for(uint8_t i = 0; i < n; i++) {
48 for(uint8_t j = 0; j < n; j++) {
49 for(uint8_t k = 0;k < n; k++) {
50 ret[i*n + j] += A[i*n + k] * B[k*n + j];
57 static inline void swap(
float &a,
float &b)
76 for(uint8_t i = 0;i<n;i++){
77 for(uint8_t j=0;j<n;j++) {
78 pivot[i*n+j] =
static_cast<float>(i==j);
82 for(uint8_t i = 0;i < n; i++) {
84 for(uint8_t j=i;j<n;j++){
85 if(fabsf(A[j*n + i]) > fabsf(A[max_j*n + i])) {
91 for(uint8_t k = 0; k < n; k++) {
92 swap(pivot[i*n + k], pivot[max_j*n + k]);
109 for(
int i = 0; i < n; i++) {
110 out[i*n + i] = 1/L[i*n + i];
111 for (
int j = i+1; j < n; j++) {
112 for (
int k = i; k < j; k++) {
113 out[j*n + i] -= L[j*n + k] * out[k*n + i];
115 out[j*n + i] /= L[j*n + j];
131 for(
int i = n-1; i >= 0; i--) {
132 out[i*n + i] = 1/U[i*n + i];
133 for (
int j = i - 1; j >= 0; j--) {
134 for (
int k = i; k > j; k--) {
135 out[j*n + i] -= U[j*n + k] * out[k*n + i];
137 out[j*n + i] /= U[j*n + j];
153 memset(L,0,n*n*
sizeof(
float));
154 memset(U,0,n*n*
sizeof(
float));
155 memset(P,0,n*n*
sizeof(
float));
158 float *APrime =
mat_mul(P,A,n);
159 for(uint8_t i = 0; i < n; i++) {
162 for(uint8_t i = 0; i < n; i++) {
163 for(uint8_t j = 0; j < n; j++) {
165 U[j*n + i] = APrime[j*n + i];
166 for(uint8_t k = 0; k < j; k++) {
167 U[j*n + i] -= L[j*n + k] * U[k*n + i];
171 L[j*n + i] = APrime[j*n + i];
172 for(uint8_t k = 0; k < i; k++) {
173 L[j*n + i] -= L[j*n + k] * U[k*n + i];
175 L[j*n + i] /= U[i*n + i];
200 float *L_inv =
new float[n*n];
201 float *U_inv =
new float[n*n];
203 memset(L_inv,0,n*n*
sizeof(
float));
206 memset(U_inv,0,n*n*
sizeof(
float));
213 float *inv_unpivoted =
mat_mul(U_inv,L_inv,n);
214 float *inv_pivoted =
mat_mul(inv_unpivoted, P, n);
217 for(uint8_t i = 0; i < n; i++) {
218 for(uint8_t j = 0; j < n; j++) {
219 if(isnan(inv_pivoted[i*n+j]) || isinf(inv_pivoted[i*n+j])){
224 memcpy(inv,inv_pivoted,n*n*
sizeof(
float));
227 delete[] inv_pivoted;
228 delete[] inv_unpivoted;
247 float det = m[0] * (m[4] * m[8] - m[7] * m[5]) -
248 m[1] * (m[3] * m[8] - m[5] * m[6]) +
249 m[2] * (m[3] * m[7] - m[4] * m[6]);
250 if (
is_zero(det) || isinf(det)) {
254 float invdet = 1 / det;
256 inv[0] = (m[4] * m[8] - m[7] * m[5]) * invdet;
257 inv[1] = (m[2] * m[7] - m[1] * m[8]) * invdet;
258 inv[2] = (m[1] * m[5] - m[2] * m[4]) * invdet;
259 inv[3] = (m[5] * m[6] - m[3] * m[8]) * invdet;
260 inv[4] = (m[0] * m[8] - m[2] * m[6]) * invdet;
261 inv[5] = (m[3] * m[2] - m[0] * m[5]) * invdet;
262 inv[6] = (m[3] * m[7] - m[6] * m[4]) * invdet;
263 inv[7] = (m[6] * m[1] - m[0] * m[7]) * invdet;
264 inv[8] = (m[0] * m[4] - m[3] * m[1]) * invdet;
266 for(uint8_t i = 0; i < 9; i++){
287 #if CONFIG_HAL_BOARD == HAL_BOARD_SITL 288 int old = fedisableexcept(FE_OVERFLOW);
290 hal.
console->
printf(
"inverse4x4(): warning: error on disabling FE_OVERFLOW floating point exception\n");
294 inv[0] = m[5] * m[10] * m[15] -
295 m[5] * m[11] * m[14] -
296 m[9] * m[6] * m[15] +
297 m[9] * m[7] * m[14] +
298 m[13] * m[6] * m[11] -
299 m[13] * m[7] * m[10];
301 inv[4] = -m[4] * m[10] * m[15] +
302 m[4] * m[11] * m[14] +
303 m[8] * m[6] * m[15] -
304 m[8] * m[7] * m[14] -
305 m[12] * m[6] * m[11] +
306 m[12] * m[7] * m[10];
308 inv[8] = m[4] * m[9] * m[15] -
309 m[4] * m[11] * m[13] -
310 m[8] * m[5] * m[15] +
311 m[8] * m[7] * m[13] +
312 m[12] * m[5] * m[11] -
315 inv[12] = -m[4] * m[9] * m[14] +
316 m[4] * m[10] * m[13] +
317 m[8] * m[5] * m[14] -
318 m[8] * m[6] * m[13] -
319 m[12] * m[5] * m[10] +
322 inv[1] = -m[1] * m[10] * m[15] +
323 m[1] * m[11] * m[14] +
324 m[9] * m[2] * m[15] -
325 m[9] * m[3] * m[14] -
326 m[13] * m[2] * m[11] +
327 m[13] * m[3] * m[10];
329 inv[5] = m[0] * m[10] * m[15] -
330 m[0] * m[11] * m[14] -
331 m[8] * m[2] * m[15] +
332 m[8] * m[3] * m[14] +
333 m[12] * m[2] * m[11] -
334 m[12] * m[3] * m[10];
336 inv[9] = -m[0] * m[9] * m[15] +
337 m[0] * m[11] * m[13] +
338 m[8] * m[1] * m[15] -
339 m[8] * m[3] * m[13] -
340 m[12] * m[1] * m[11] +
343 inv[13] = m[0] * m[9] * m[14] -
344 m[0] * m[10] * m[13] -
345 m[8] * m[1] * m[14] +
346 m[8] * m[2] * m[13] +
347 m[12] * m[1] * m[10] -
350 inv[2] = m[1] * m[6] * m[15] -
351 m[1] * m[7] * m[14] -
352 m[5] * m[2] * m[15] +
353 m[5] * m[3] * m[14] +
354 m[13] * m[2] * m[7] -
357 inv[6] = -m[0] * m[6] * m[15] +
358 m[0] * m[7] * m[14] +
359 m[4] * m[2] * m[15] -
360 m[4] * m[3] * m[14] -
361 m[12] * m[2] * m[7] +
364 inv[10] = m[0] * m[5] * m[15] -
365 m[0] * m[7] * m[13] -
366 m[4] * m[1] * m[15] +
367 m[4] * m[3] * m[13] +
368 m[12] * m[1] * m[7] -
371 inv[14] = -m[0] * m[5] * m[14] +
372 m[0] * m[6] * m[13] +
373 m[4] * m[1] * m[14] -
374 m[4] * m[2] * m[13] -
375 m[12] * m[1] * m[6] +
378 inv[3] = -m[1] * m[6] * m[11] +
379 m[1] * m[7] * m[10] +
380 m[5] * m[2] * m[11] -
381 m[5] * m[3] * m[10] -
385 inv[7] = m[0] * m[6] * m[11] -
386 m[0] * m[7] * m[10] -
387 m[4] * m[2] * m[11] +
388 m[4] * m[3] * m[10] +
392 inv[11] = -m[0] * m[5] * m[11] +
394 m[4] * m[1] * m[11] -
399 inv[15] = m[0] * m[5] * m[10] -
401 m[4] * m[1] * m[10] +
406 det = m[0] * inv[0] + m[1] * inv[4] + m[2] * inv[8] + m[3] * inv[12];
408 #if CONFIG_HAL_BOARD == HAL_BOARD_SITL 409 if (old >= 0 && feenableexcept(old) < 0) {
410 hal.
console->
printf(
"inverse4x4(): warning: error on restoring floating exception mask\n");
414 if (
is_zero(det) || isinf(det)){
420 for (i = 0; i < 16; i++)
421 invOut[i] = inv[i] * det;
float * mat_mul(float *A, float *B, uint8_t n)
AP_HAL::UARTDriver * console
static void swap(float &a, float &b)
static void mat_pivot(float *A, float *pivot, uint8_t n)
bool inverse3x3(float m[], float invOut[])
const AP_HAL::HAL & hal
-*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
virtual void printf(const char *,...) FMT_PRINTF(2
bool inverse(float x[], float y[], uint16_t dim)
bool is_zero(const T fVal1)
static bool mat_inverse(float *A, float *inv, uint8_t n)
static void mat_back_sub(float *U, float *out, uint8_t n)
bool inverse4x4(float m[], float invOut[])
static void mat_LU_decompose(float *A, float *L, float *U, float *P, uint8_t n)
static void mat_forward_sub(float *L, float *out, uint8_t n)