FancySafeBot 0.0.1
A safe robotics library
Loading...
Searching...
No Matches
fsb_linalg.h
1#pragma once
2
3#include <cmath>
4#include <cstddef>
5
6#include "openblas/lapack.h"
7#include "fsb_types.h"
8
16#define FSB_MAX(a, b) (((a) > (b)) ? (a) : (b))
17#define FSB_MIN(a, b) (((a) < (b)) ? (a) : (b))
18
19namespace fsb {
20
24enum class LinalgErrorType : uint8_t
25{
29 ERROR_NONE = 0,
33 ERROR_INPUT = 1,
37 ERROR_MEMORY = 2,
45 ERROR_QUERY = 4,
53 SINGULAR = 6,
55};
56
69 Span<const Real> mat, size_t dim,
70 Span<Real> mat_chol);
71
88 Span<const Real> mat, size_t dim,
89 Span<const Real> b_vec, size_t nrhs,
90 Span<Real> work,
91 Span<Real> x_vec);
92
104 Span<const Real> mat, size_t dim,
105 Span<Real> work);
106
123 Span<const Real> mat, size_t dim,
124 Span<const Real> y_vec, size_t nrhs,
125 Span<Real> work,
126 Span<lapack_int> iwork,
127 Span<Real> x_vec);
128
145 Span<const Real> mat, size_t rows, size_t cols,
146 Span<Real> work,
147 Span<Real> inv_mat);
148
166 Span<const Real> mat, size_t rows, size_t cols,
167 Span<const Real> b_vec, size_t nrhs,
168 Span<Real> work,
169 Span<Real> x_vec);
170
194 Span<const Real> mat, size_t rows, size_t cols,
195 bool u_full, bool v_full,
196 Span<Real> work,
197 Span<Real> unitary_u,
198 Span<Real> sing_val,
199 Span<Real> unitary_vt);
200
218 Span<const Real> mat, size_t dim,
219 Span<Real> work,
220 Span<Real> val_real,
221 Span<Real> val_imag,
222 Span<Real> vec_real,
223 Span<Real> vec_imag);
224
241 Span<const Real> mat, size_t dim,
242 Span<Real> work,
243 Span<Real> val,
244 Span<Real> vec);
245
246template <size_t MaxMat, size_t MaxWorkLen, size_t MaxU, size_t MaxS, size_t MaxVT>
247inline LinalgErrorType linalg_svd_array(
248 const Array<MaxMat>& mat, size_t rows, size_t cols,
249 bool u_full, bool v_full,
250 Array<MaxWorkLen>& work, size_t work_len,
251 Array<MaxU>& unitary_u,
252 Array<MaxS>& sing_val, size_t s_dim,
253 Array<MaxVT>& unitary_vt)
254{
255 return linalg_svd(
256 mat.active(rows * cols), rows, cols,
257 u_full, v_full,
258 work.active(work_len),
259 unitary_u.active(rows * rows),
260 sing_val.active(s_dim),
261 unitary_vt.active(s_dim * cols));
262}
263
264template <size_t MaxMat, size_t MaxWorkLen, size_t MaxEig, size_t MaxVec>
265inline LinalgErrorType linalg_matrix_eig_array(
266 const Array<MaxMat>& mat, size_t dim,
267 Array<MaxWorkLen>& work, size_t work_len,
268 Array<MaxEig>& val_real,
269 Array<MaxEig>& val_imag,
270 Array<MaxVec>& vec_real,
271 Array<MaxVec>& vec_imag)
272{
273 return linalg_matrix_eig(
274 mat.active(dim * dim), dim,
275 work.active(work_len),
276 val_real.active(dim),
277 val_imag.active(dim),
278 vec_real.active(dim * dim),
279 vec_imag.active(dim * dim));
280}
281
282template <size_t MaxMat, size_t MaxWorkLen, size_t MaxEig, size_t MaxVec>
283inline LinalgErrorType linalg_sym_lt_eig_array(
284 const Array<MaxMat>& mat, size_t dim,
285 Array<MaxWorkLen>& work, size_t work_len,
286 Array<MaxEig>& val,
287 Array<MaxVec>& vec)
288{
289 return linalg_sym_lt_eig(
290 mat.active(dim * dim), dim,
291 work.active(work_len),
292 val.active(dim),
293 vec.active(dim * dim));
294}
295
296template <size_t MaxMat>
297inline LinalgErrorType linalg_cholesky_decomposition_array(
298 const Array<MaxMat>& mat, size_t dim,
299 Array<MaxMat>& mat_chol)
300{
302 mat.active(dim * dim), dim,
303 mat_chol.active(dim * dim));
304}
305
306template <size_t MaxMat, size_t MaxWorkLen>
307inline bool linalg_is_posdef_array(
308 const Array<MaxMat>& mat, size_t dim,
309 Array<MaxWorkLen>& work, size_t work_len)
310{
311 return linalg_is_posdef(mat.active(dim * dim), dim, work.active(work_len));
312}
313
314template <size_t MaxMat, size_t MaxVec, size_t MaxWorkLen>
315inline LinalgErrorType linalg_cholesky_solve_array(
316 const Array<MaxMat>& mat, size_t dim,
317 const Array<MaxVec>& b_vec, size_t nrhs,
318 Array<MaxWorkLen>& work, size_t work_len,
319 Array<MaxVec>& x_vec)
320{
322 mat.active(dim * dim), dim,
323 b_vec.active(dim * nrhs), nrhs,
324 work.active(work_len),
325 x_vec.active(dim * nrhs));
326}
327
328template <size_t MaxMat, size_t MaxVec, size_t MaxWorkLen, size_t MaxIWorkLen>
329inline LinalgErrorType linalg_matrix_sqr_solve_array(
330 const Array<MaxMat>& mat, size_t dim,
331 const Array<MaxVec>& y_vec, size_t nrhs,
332 Array<MaxWorkLen>& work, size_t work_len,
333 Array<MaxIWorkLen, lapack_int>& iwork, size_t iwork_len,
334 Array<MaxVec>& x_vec)
335{
337 mat.active(dim * dim), dim,
338 y_vec.active(dim * nrhs), nrhs,
339 work.active(work_len),
340 iwork.active(iwork_len),
341 x_vec.active(dim * nrhs));
342}
343
344template <size_t MaxMat, size_t MaxInv, size_t MaxWorkLen>
345inline LinalgErrorType linalg_pseudoinverse_array(
346 const Array<MaxMat>& mat, size_t rows, size_t cols,
347 Array<MaxWorkLen>& work, size_t work_len,
348 Array<MaxInv>& inv_mat)
349{
351 mat.active(rows * cols), rows, cols,
352 work.active(work_len),
353 inv_mat.active(cols * rows));
354}
355
356template <size_t MaxMat, size_t MaxB, size_t MaxX, size_t MaxWorkLen>
357inline LinalgErrorType linalg_leastsquares_solve_array(
358 const Array<MaxMat>& mat, size_t rows, size_t cols,
359 const Array<MaxB>& b_vec, size_t nrhs,
360 Array<MaxWorkLen>& work, size_t work_len,
361 Array<MaxX>& x_vec)
362{
364 mat.active(rows * cols), rows, cols,
365 b_vec.active(rows * nrhs), nrhs,
366 work.active(work_len),
367 x_vec.active(cols * nrhs));
368}
369
374} // namespace fsb
LinalgErrorType linalg_svd(Span< const Real > mat, size_t rows, size_t cols, bool u_full, bool v_full, Span< Real > work, Span< Real > unitary_u, Span< Real > sing_val, Span< Real > unitary_vt)
SVD decomposition.
Definition fsb_linalg.cpp:11
LinalgErrorType linalg_matrix_sqr_solve(Span< const Real > mat, size_t dim, Span< const Real > y_vec, size_t nrhs, Span< Real > work, Span< lapack_int > iwork, Span< Real > x_vec)
Solve a square linear system A * x = b using LU factorization.
Definition fsb_linalg.cpp:345
LinalgErrorType linalg_pseudoinverse(Span< const Real > mat, size_t rows, size_t cols, Span< Real > work, Span< Real > inv_mat)
Moore-Penrose pseudoinverse via SVD.
Definition fsb_linalg.cpp:409
LinalgErrorType linalg_leastsquares_solve(Span< const Real > mat, size_t rows, size_t cols, Span< const Real > b_vec, size_t nrhs, Span< Real > work, Span< Real > x_vec)
Solve an overdetermined or underdetermined least-squares problem.
Definition fsb_linalg.cpp:497
LinalgErrorType linalg_cholesky_solve(Span< const Real > mat, size_t dim, Span< const Real > b_vec, size_t nrhs, Span< Real > work, Span< Real > x_vec)
Cholesky solve.
Definition fsb_linalg.cpp:259
LinalgErrorType linalg_cholesky_decomposition(Span< const Real > mat, size_t dim, Span< Real > mat_chol)
Cholesky factorization for a symmetric positive definite matrix.
Definition fsb_linalg.cpp:218
bool linalg_is_posdef(Span< const Real > mat, size_t dim, Span< Real > work)
Check if a symmetric matrix (lower triangular storage) is positive definite.
Definition fsb_linalg.cpp:318
LinalgErrorType
Error codes for linear algebra functions.
Definition fsb_linalg.h:25
LinalgErrorType linalg_sym_lt_eig(Span< const Real > mat, size_t dim, Span< Real > work, Span< Real > val, Span< Real > vec)
Eigenvalue decomposition for a real symmetric matrix (lower triangular storage)
Definition fsb_linalg.cpp:607
LinalgErrorType linalg_matrix_eig(Span< const Real > mat, size_t dim, Span< Real > work, Span< Real > val_real, Span< Real > val_imag, Span< Real > vec_real, Span< Real > vec_imag)
Eigenvalue decomposition for a general square matrix.
Definition fsb_linalg.cpp:126
@ ERROR_QUERY
Work query failed.
@ ERROR_INPUT
Input value error.
@ ERROR_CONVERGE
Solution did not converge.
@ ERROR_NOT_FULL_RANK
Matrix is not full rank.
@ SINGULAR
Input matrix is singular.
@ ERROR_MEMORY
Not enough memory.
@ NOT_POSITIVE_DEFINITE
Matrix not positive definite.