#![allow(non_snake_case)]
use super::types::*;
use crate::solver::{
core::{
cones::{SupportedConeT, SupportedConeT::*},
IPSolver,
},
implementations::default::*,
};
use num_traits::FromPrimitive;
use serde_json::*;
use std::{ffi::CStr, os::raw::c_void};
fn to_ptr(solver: Box<DefaultSolver<f64>>) -> *mut c_void {
Box::into_raw(solver) as *mut c_void
}
fn from_ptr(ptr: *mut c_void) -> Box<DefaultSolver<f64>> {
unsafe { Box::from_raw(ptr as *mut DefaultSolver<f64>) }
}
fn ccall_arrays_to_cones(
cones_enums: &VectorJLRS<u8>,
cones_ints: &VectorJLRS<u64>,
cones_floats: &VectorJLRS<f64>,
) -> Vec<SupportedConeT<f64>> {
let mut cones: Vec<SupportedConeT<f64>> = Vec::new();
assert_eq!(cones_enums.len(), cones_ints.len());
assert_eq!(cones_enums.len(), cones_floats.len());
let cones_enums = Vec::from(cones_enums);
let cones_ints = Vec::from(cones_ints);
let _cones_floats = Vec::from(cones_floats);
for i in 0..cones_enums.len() {
let cone = match FromPrimitive::from_u8(cones_enums[i]) {
Some(ConeEnumJLRS::ZeroConeT) => ZeroConeT(cones_ints[i] as usize),
Some(ConeEnumJLRS::NonnegativeConeT) => NonnegativeConeT(cones_ints[i] as usize),
Some(ConeEnumJLRS::SecondOrderConeT) => SecondOrderConeT(cones_ints[i] as usize),
Some(ConeEnumJLRS::ExponentialConeT) => ExponentialConeT(),
Some(ConeEnumJLRS::PowerConeT) => PowerConeT(_cones_floats[i]),
None => panic!("Received unrecognized cone type"),
};
cones.push(cone)
}
cones
}
#[no_mangle]
pub(crate) extern "C" fn solver_new_jlrs(
P: &CscMatrixJLRS,
q: &VectorJLRS<f64>,
A: &CscMatrixJLRS,
b: &VectorJLRS<f64>,
cones_enums: &VectorJLRS<u8>,
cones_ints: &VectorJLRS<u64>,
cones_floats: &VectorJLRS<f64>,
json_settings: *const std::os::raw::c_char,
) -> *mut c_void {
let P = P.to_CscMatrix();
let A = A.to_CscMatrix();
let q = Vec::from(q);
let b = Vec::from(b);
let cones = ccall_arrays_to_cones(cones_enums, cones_ints, cones_floats);
let settings = settings_from_json(json_settings);
let solver = DefaultSolver::new(&P, &q, &A, &b, &cones, settings);
to_ptr(Box::new(solver))
}
#[no_mangle]
pub(crate) extern "C" fn solver_solve_jlrs(ptr: *mut c_void) -> SolutionJLRS {
let mut solver = from_ptr(ptr);
solver.solve();
let out = SolutionJLRS::from(&solver.solution);
std::mem::forget(solver);
out
}
#[no_mangle]
pub(crate) extern "C" fn solver_get_info_jlrs(ptr: *mut c_void) -> DefaultInfo<f64> {
let solver = from_ptr(ptr);
let info = solver.info.clone();
std::mem::forget(solver);
info
}
#[no_mangle]
pub(crate) extern "C" fn solver_drop_jlrs(ptr: *mut c_void) {
drop(from_ptr(ptr));
}
pub(crate) fn settings_from_json(json: *const std::os::raw::c_char) -> DefaultSettings<f64> {
let json = unsafe {
let slice = CStr::from_ptr(json);
slice.to_str().unwrap()
};
let mut settings: DefaultSettings<f64> = from_str(json).unwrap();
if settings.time_limit > f64::MAX * 0.9999 {
settings.time_limit = f64::INFINITY;
}
settings
}