diff --git a/src/libksupport/src/kernel/api.rs b/src/libksupport/src/kernel/api.rs index 836e81e..46ad3db 100644 --- a/src/libksupport/src/kernel/api.rs +++ b/src/libksupport/src/kernel/api.rs @@ -1,10 +1,12 @@ 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 libm; use log::{info, warn}; +use nalgebra::{DMatrix, linalg}; + #[cfg(has_drtio)] use super::subkernel; 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()); } +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::::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)]) +} + macro_rules! api { ($i:ident) => ({ extern { static $i: u8; } @@ -319,6 +341,10 @@ pub fn resolve(required: &[u8]) -> Option { } api!(yn = yn) }, + + // linalg + api!(linalg_try_invert_to = linalg_try_invert_to), + api!(linalg_wilkinson_shift = linalg_wilkinson_shift), ]; api.iter() .find(|&&(exported, _)| exported.as_bytes() == required)