WarpTwin
Documentation for WarpTwin models and classes.
Loading...
Searching...
No Matches
matrixmath.hpp
Go to the documentation of this file.
1/******************************************************************************
2* Copyright (c) ATTX LLC 2024. All Rights Reserved.
3*
4* This software and associated documentation (the "Software") are the
5* proprietary and confidential information of ATTX, LLC. The Software is
6* furnished under a license agreement between ATTX and the user organization
7* and may be used or copied only in accordance with the terms of the agreement.
8* Refer to 'license/attx_license.adoc' for standard license terms.
9*
10* EXPORT CONTROL NOTICE: THIS SOFTWARE MAY INCLUDE CONTENT CONTROLLED UNDER THE
11* INTERNATIONAL TRAFFIC IN ARMS REGULATIONS (ITAR) OR THE EXPORT ADMINISTRATION
12* REGULATIONS (EAR99). No part of the Software may be used, reproduced, or
13* transmitted in any form or by any means, for any purpose, without the express
14* written permission of ATTX, LLC.
15******************************************************************************/
16/*
17Matrix math header file
18-----------------------
19This file defines basic functions for mathematical operations on
20the matrix class
21Rather than raising an error on fail cases (i.e. divide by zero),
22the following libraries are designed to check for errors and return
23corresponding codes.
24
25Note: The naming convention observed for matrix math is as follows:
26- Capital letters represent matrices
27- Lowercase letters represent scalars
28- All vectors are 1-dimensional matrices for the purpose of math
29- Pass by reference return values are all named "result"
30- The letter used in math indicates the order of operations - A/a
31 comes first, then B/b. A/a or B/b always represent the "other"
32 value in an operation
33
34Author: Alex Reynolds
35*/
36
37#ifndef CORE_MATRIXMATH_HPP
38#define CORE_MATRIXMATH_HPP
39
40#include "Matrix.hpp"
41#include "clockwerkerrors.h"
42
43namespace clockwerk {
44
48
57 template<uint32 R1, uint32 C1R2, uint32 C2>
58 void multiply(const Matrix<R1, C1R2> &A, const Matrix<C1R2, C2> &B, Matrix<R1, C2> &result) {
68 if(static_cast<const void*>(&A) == static_cast<const void*>(&result)) {
69 Matrix<R1, C1R2> a_cpy = A;
70 uint32 i, j, k;
71 for(i = 0; i < R1; i++) {
72 for(j = 0; j < C2; j++) {
73 result.values[i][j] = 0.0;
74 for(k = 0; k < C1R2; k++) {
76 result.values[i][j] += a_cpy.values[i][k]*B.values[k][j];
77 }
78 }
79 }
80
81 return;
82 }
83 if(static_cast<const void*>(&B) == static_cast<const void*>(&result)) {
84 Matrix<C1R2, C2> b_cpy = B;
85 uint32 i, j, k;
86 for(i = 0; i < R1; i++) {
87 for(j = 0; j < C2; j++) {
88 result.values[i][j] = 0.0;
89 for(k = 0; k < C1R2; k++) {
91 result.values[i][j] += A.values[i][k]*b_cpy.values[k][j];
92 }
93 }
94 }
95
96 return;
97 }
98
103 uint32 i, j, k;
104 for(i = 0; i < R1; i++) {
105 for(j = 0; j < C2; j++) {
106 result.values[i][j] = 0.0;
107 for(k = 0; k < C1R2; k++) {
109 result.values[i][j] += A.values[i][k]*B.values[k][j];
110 }
111 }
112 }
113 }
114
120 template<uint32 R, uint32 C>
121 void multiply(const floating_point &a, const Matrix<R, C> &A, Matrix<R, C> &result) {
127
132 uint32 i, j;
133 for(i = 0; i < R; i++) {
134 for(j = 0; j < C; j++) {
135 result.values[i][j] = a*A.values[i][j];
136 }
137 }
138 }
139
145 template<uint32 R, uint32 C>
146 void eMultiply(const Matrix<R, C> &A, const Matrix<R, C> &B, Matrix<R, C> &result) {
152
157 uint32 i, j;
158 for(i = 0; i < R; i++) {
159 for(j = 0; j < C; j++) {
160 result.values[i][j] = A.values[i][j]*B.values[i][j];
161 }
162 }
163 }
164
170 template<uint32 R, uint32 C>
171 void add(const floating_point &a, const Matrix<R, C> &A, Matrix<R, C> &result) {
177
182 uint32 i, j;
183 for(i = 0; i < R; i++) {
184 for(j = 0; j < C; j++) {
185 result.values[i][j] = a + A.values[i][j];
186 }
187 }
188 }
189
195 template<uint32 R, uint32 C>
196 void eAdd(const Matrix<R, C> &A, const Matrix<R, C> &B, Matrix<R, C> &result) {
202
207 uint32 i, j;
208 for(i = 0; i < R; i++) {
209 for(j = 0; j < C; j++) {
210 result.values[i][j] = A.values[i][j] + B.values[i][j];
211 }
212 }
213 }
214
220 template<uint32 R, uint32 C>
227
232 uint32 i, j;
233 for(i = 0; i < R; i++) {
234 for(j = 0; j < C; j++) {
235 result.values[i][j] = A.values[i][j] - B.values[i][j];
236 }
237 }
238 }
239
246 template<uint32 R1, uint32 C1R2, uint32 C2>
249 Matrix<R1, C2> result;
250 multiply(A, B, result);
251 return result;
252 }
253
256 template<uint32 R, uint32 C>
257 Matrix<R, C> operator*(const floating_point &a, const Matrix<R, C> &A) {
259 Matrix<R, C> result;
260 multiply(a, A, result);
261 return result;
262 }
263 template<uint32 R, uint32 C>
264 Matrix<R, C> operator*(const Matrix<R, C> &A, const floating_point &a) {
266 Matrix<R, C> result;
267 multiply(a, A, result);
268 return result;
269 }
270
273 template<uint32 R, uint32 C>
276 Matrix<R, C> result;
277 eAdd(A, B, result);
278 return result;
279 }
280
283 template<uint32 R, uint32 C>
284 Matrix<R, C> operator+(const floating_point &a, const Matrix<R, C> &A) {
286 Matrix<R, C> result;
287 add(a, A, result);
288 return result;
289 }
290 template<uint32 R, uint32 C>
291 Matrix<R, C> operator+(const Matrix<R, C> &A, const floating_point &a) {
293 Matrix<R, C> result;
294 add(a, A, result);
295 return result;
296 }
297
299 template<uint32 R, uint32 C>
302 Matrix<R, C> result;
303 eSubtract(A, B, result);
304 return result;
305 }
306
314 template <uint32 M, uint32 K>
315 int16 cholSolve(const Matrix<M, M> &A, const Matrix<M, K> &B, Matrix<M, K> &X) {
316 // Cholesky decompose: this = Rᵀ R (upper triangular R, MATLAB convention)
317 Matrix<M, M> R;
318 int16 err = A.chol(R);
319 if (err) { return err; }
320
321 // Solve column by column: for each column b of B, solve Rᵀ R x = b
322 floating_point Y[M]; // scratch for forward solve
323
324 for (uint32 col = 0; col < K; col++) {
325 // Forward solve: Rᵀ y = b (Rᵀ is lower triangular)
326 for (uint32 i = 0; i < M; i++) {
327 floating_point sum = B.get(i, col);
328 for (uint32 k = 0; k < i; k++) {
329 sum -= R.get(k, i) * Y[k]; // Rᵀ[i][k] = R[k][i]
330 }
331 err = safeDivide(sum, R.get(i, i), Y[i]);
332 if(err) {return err;}
333 }
334
335 // Back solve: R x = y (R is upper triangular)
336 for (int32 i = M - 1; i >= 0; i--) {
337 floating_point sum = Y[i];
338 for (uint32 k = i + 1; k < M; k++) {
339 sum -= R.get(i, k) * X.get(k, col);
340 }
341 floating_point tmp;
342 err = safeDivide(sum, R.get(i, i), tmp);
343 if(err) {return err;}
344 X.set(i, col, tmp);
345 }
346 }
347
348 return NO_ERROR;
349 }
350
351}
352
353#endif
Matrix math implementation.
Definition Matrix.hpp:55
std::array< std::array< floating_point, C >, R > values
Definition Matrix.hpp:213
int16 get(uint32 row, uint32 col, floating_point &result) const
Function to get a single value in the matrix.
Definition Matrix.hpp:394
int16 set(uint32 row, uint32 col, const floating_point &value)
Function to set a single value in the matrix.
Definition Matrix.hpp:381
int16 chol(Matrix< R, C > &retval) const
Take the cholesky decomposition of this matrix.
Definition Matrix.hpp:569
#define NO_ERROR
Error code in the case where matrix math executed successfully.
Definition clockwerkerrors.h:34
Definition CircularBuffer.hpp:28
void eSubtract(Matrix< R, C > A, Matrix< R, C > B, Matrix< R, C > &result)
Function to subtract B from A, element-wise.
Definition matrixmath.hpp:221
Matrix< R, C > operator+(const Matrix< R, C > &A, const Matrix< R, C > &B)
Overload of matrix addition - Two matrices.
Definition matrixmath.hpp:274
Matrix< R1, C2 > operator*(const Matrix< R1, C1R2 > &A, const Matrix< C1R2, C2 > &B)
Overload of matrix multiplication - Two matrices.
Definition matrixmath.hpp:247
void eAdd(const Matrix< R, C > &A, const Matrix< R, C > &B, Matrix< R, C > &result)
Function to add two matrices element-wise.
Definition matrixmath.hpp:196
void eMultiply(const Matrix< R, C > &A, const Matrix< R, C > &B, Matrix< R, C > &result)
Function to multiply two matrices element-wise.
Definition matrixmath.hpp:146
Matrix< R, C > operator-(const Matrix< R, C > &A, const Matrix< R, C > &B)
Returns value – less efficient in some cases.
Definition matrixmath.hpp:300
void add(const floating_point &a, const Matrix< R, C > &A, Matrix< R, C > &result)
Function to add a scalar to a matrix.
Definition matrixmath.hpp:171
int16 cholSolve(const Matrix< M, M > &A, const Matrix< M, K > &B, Matrix< M, K > &X)
Perform cholesky solve Ax=b on square, posdef matrix A and put the solution in X.
Definition matrixmath.hpp:315
int16 safeDivide(float a, float b, float &result)
Overloaded functions to perform safe division.
Definition safemath.cpp:24
void multiply(const Matrix< R1, C1R2 > &A, const Matrix< C1R2, C2 > &B, Matrix< R1, C2 > &result)
Function to multiply two matrices.
Definition matrixmath.hpp:58