1pub use cxx::Exception;
2
3pub use ffi::*;
4
5#[cxx::bridge(namespace = "quadprogpp")]
6mod ffi {
7 unsafe extern "C++" {
8 include!("quadprogpp-sys/include/wrapper.hpp");
9
10 type VectorF64;
12
13 fn new_vector(n: u32) -> UniquePtr<VectorF64>;
15
16 unsafe fn new_vector_from_ptr(a: *const f64, n: u32) -> UniquePtr<VectorF64>;
23
24 unsafe fn vector_index(v: &VectorF64, i: u32) -> f64;
30
31 type MatrixF64;
33
34 unsafe fn new_matrix_from_ptr(a: *const f64, n: u32, m: u32) -> UniquePtr<MatrixF64>;
41 }
42
43 unsafe extern "C++" {
44 fn solve_quadprog(
46 G: Pin<&mut MatrixF64>,
47 g0: Pin<&mut VectorF64>,
48 CE: &MatrixF64,
49 ce0: &VectorF64,
50 CI: &MatrixF64,
51 ci0: &VectorF64,
52 x: Pin<&mut VectorF64>,
53 ) -> Result<f64>;
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use approx::assert_ulps_eq;
60
61 use super::*;
62
63 #[test]
64 #[allow(clippy::many_single_char_names, non_snake_case)]
65 fn test() {
66 let n = 2;
67 let m = 1;
68 let p = 3;
69 let mut G =
70 unsafe { new_matrix_from_ptr([4.0, -2.0, -2.0, 4.0].as_ptr() as *const f64, n, n) };
71 let mut g0 = unsafe { new_vector_from_ptr([6.0, 0.0].as_ptr() as *const f64, n) };
72 let CE = unsafe { new_matrix_from_ptr([1.0, 1.0].as_ptr() as *const f64, n, m) };
73 let ce0 = unsafe { new_vector_from_ptr([-3.0].as_ptr() as *const f64, m) };
74 let CI = unsafe {
75 new_matrix_from_ptr([1.0, 0.0, 1.0, 0.0, 1.0, 1.0].as_ptr() as *const f64, n, p)
76 };
77 let ci0 = unsafe { new_vector_from_ptr([0.0, 0.0, -2.0].as_ptr() as *const f64, p) };
78 let mut x = new_vector(n);
79 let r =
80 solve_quadprog(G.pin_mut(), g0.pin_mut(), &CE, &ce0, &CI, &ci0, x.pin_mut()).unwrap();
81 assert_ulps_eq!(r, 12.0);
82 assert_ulps_eq!(unsafe { vector_index(&x, 0) }, 1.0);
83 assert_ulps_eq!(unsafe { vector_index(&x, 1) }, 2.0);
84 }
85}