use std::ffi::CStr;
use std::os::raw::c_char;
use std::os::raw::c_double;
use crate::symbolic::core::Expr;
use crate::symbolic::polynomial::expr_to_sparse_poly;
use crate::symbolic::polynomial::sparse_poly_to_expr;
use crate::symbolic::real_roots::count_real_roots_in_interval;
use crate::symbolic::real_roots::isolate_real_roots;
use crate::symbolic::real_roots::sturm_sequence;
#[unsafe(no_mangle)]
pub extern "C" fn rssn_sturm_sequence_handle(
expr_ptr: *const Expr,
var_ptr: *const c_char,
) -> *mut Vec<Expr> {
if expr_ptr.is_null() || var_ptr.is_null() {
return std::ptr::null_mut();
}
unsafe {
let expr = &*expr_ptr;
let var_cstr = CStr::from_ptr(var_ptr);
let var_str = match var_cstr.to_str() {
| Ok(s) => s,
| Err(_) => return std::ptr::null_mut(),
};
let poly = expr_to_sparse_poly(expr, &[var_str]);
let seq = sturm_sequence(&poly, var_str);
let expr_seq: Vec<Expr> = seq.into_iter().map(|p| sparse_poly_to_expr(&p)).collect();
Box::into_raw(Box::new(expr_seq))
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_count_real_roots_in_interval_handle(
expr_ptr: *const Expr,
var_ptr: *const c_char,
a: c_double,
b: c_double,
) -> i64 {
if expr_ptr.is_null() || var_ptr.is_null() {
return -1;
}
unsafe {
let expr = &*expr_ptr;
let var_cstr = CStr::from_ptr(var_ptr);
let var_str = match var_cstr.to_str() {
| Ok(s) => s,
| Err(_) => return -1,
};
let poly = expr_to_sparse_poly(expr, &[var_str]);
match count_real_roots_in_interval(&poly, var_str, a, b) {
| Ok(count) => count as i64,
| Err(_) => -1,
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_isolate_real_roots_handle(
expr_ptr: *const Expr,
var_ptr: *const c_char,
precision: c_double,
) -> *mut Vec<(f64, f64)> {
if expr_ptr.is_null() || var_ptr.is_null() {
return std::ptr::null_mut();
}
unsafe {
let expr = &*expr_ptr;
let var_cstr = CStr::from_ptr(var_ptr);
let var_str = match var_cstr.to_str() {
| Ok(s) => s,
| Err(_) => return std::ptr::null_mut(),
};
let poly = expr_to_sparse_poly(expr, &[var_str]);
match isolate_real_roots(&poly, var_str, precision) {
| Ok(roots) => Box::into_raw(Box::new(roots)),
| Err(_) => std::ptr::null_mut(),
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_free_expr_vec_handle(ptr: *mut Vec<Expr>) {
if !ptr.is_null() {
unsafe {
let _ = Box::from_raw(ptr);
}
}
}
#[unsafe(no_mangle)]
pub extern "C" fn rssn_free_interval_vec_handle(ptr: *mut Vec<(f64, f64)>) {
if !ptr.is_null() {
unsafe {
let _ = Box::from_raw(ptr);
}
}
}