kernel/api: add nalgebra::linalg methods #308

Merged
sb10q merged 1 commits from :add_nalgebra_functions into master 2024-07-22 16:53:07 +08:00
1 changed files with 27 additions and 1 deletions

View File

@ -1,10 +1,12 @@
use alloc::vec; use alloc::vec;
use core::{ffi::VaList, ptr, str}; use core::{ffi::VaList, ptr, str, slice};
use libc::{c_char, c_int, size_t}; use libc::{c_char, c_int, size_t};
use libm; use libm;
use log::{info, warn}; use log::{info, warn};
use nalgebra::{DMatrix, linalg};
#[cfg(has_drtio)] #[cfg(has_drtio)]
use super::subkernel; use super::subkernel;
use super::{cache, use super::{cache,
@ -38,6 +40,26 @@ unsafe extern "C" fn rtio_log(fmt: *const c_char, mut args: ...) {
rtio::write_log(buf.as_slice()); rtio::write_log(buf.as_slice());
} }
unsafe extern "C" fn linalg_try_invert_to(dim0: usize, dim1: usize, data: *mut f64) -> i8 {
let data_slice = unsafe { slice::from_raw_parts_mut(data, dim0 * dim1) };
let matrix = DMatrix::from_row_slice(dim0, dim1, data_slice);
let mut inverted_matrix = DMatrix::<f64>::zeros(dim0, dim1);
if linalg::try_invert_to(matrix, &mut inverted_matrix) {
data_slice.copy_from_slice(inverted_matrix.transpose().as_slice());
1
} else {
0
}
}
unsafe extern "C" fn linalg_wilkinson_shift(dim0: usize, dim1: usize, data: *mut f64) -> f64 {
let data_slice = slice::from_raw_parts_mut(data, dim0 * dim1);
let matrix = DMatrix::from_row_slice(dim0, dim1, data_slice);
linalg::wilkinson_shift(matrix[(0, 0)], matrix[(1, 1)], matrix[(0, 1)])
Outdated
Review

I don't think crashing the firmware in response to incorrect user input is a sensible thing to do.

I don't think crashing the firmware in response to incorrect user input is a sensible thing to do.
Outdated
Review

And isn't this check expensive?

And isn't this check expensive?

I can move this check to nac3core during code generation. The function can work under the assumption that the received input is of correct type (Other checks like having square matrix for linalg_try_invert_to or having a 2x2 matrix for linalg_wilkinson_shift are implemented in this manner).

I can move this check to nac3core during code generation. The function can work under the assumption that the received input is of correct type (Other checks like having square matrix for `linalg_try_invert_to` or having a 2x2 matrix for `linalg_wilkinson_shift` are implemented in this manner).
Outdated
Review

OK.

OK.

Revised

Revised
}
macro_rules! api { macro_rules! api {
($i:ident) => ({ ($i:ident) => ({
extern { static $i: u8; } extern { static $i: u8; }
@ -319,6 +341,10 @@ pub fn resolve(required: &[u8]) -> Option<u32> {
} }
api!(yn = yn) api!(yn = yn)
}, },
// linalg
api!(linalg_try_invert_to = linalg_try_invert_to),
api!(linalg_wilkinson_shift = linalg_wilkinson_shift),
]; ];
api.iter() api.iter()
.find(|&&(exported, _)| exported.as_bytes() == required) .find(|&&(exported, _)| exported.as_bytes() == required)