quadprogpp_sys/
lib.rs

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        /// A vector type whose element type is f64.
11        type VectorF64;
12
13        /// Creates a new zero-filled [`VectorF64`] of length `n`.
14        fn new_vector(n: u32) -> UniquePtr<VectorF64>;
15
16        /// Creates a new [`VectorF64`] from a pointer to the array and its length. Note that it
17        /// copies the data.
18        ///
19        /// # Safety
20        ///
21        /// This is unsafe due to the use of a raw pointer.
22        unsafe fn new_vector_from_ptr(a: *const f64, n: u32) -> UniquePtr<VectorF64>;
23
24        /// Performs indexing operation on the vector.
25        ///
26        /// # Safety
27        ///
28        /// This is unsafe because the index range isn't checked.
29        unsafe fn vector_index(v: &VectorF64, i: u32) -> f64;
30
31        /// A 2D matrix type whose element type is f64.
32        type MatrixF64;
33
34        /// Creates a new `n x m` [`MatrixF64`] from a pointer to a row-major array and its shape.
35        /// Note that it copies the data.
36        ///
37        /// # Safety
38        ///
39        /// This is unsafe due to the use of a raw pointer.
40        unsafe fn new_matrix_from_ptr(a: *const f64, n: u32, m: u32) -> UniquePtr<MatrixF64>;
41    }
42
43    unsafe extern "C++" {
44        /// Sovles a quadratic programming problem.
45        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}