1extern "C" {
2 pub type OSQP_TIMER;
3 fn vec_set_scalar(a: *mut c_float, sc: c_float, n: c_int);
4 fn vec_mult_scalar(a: *mut c_float, sc: c_float, n: c_int);
5 fn vec_norm_inf(v: *const c_float, l: c_int) -> c_float;
6 fn vec_mean(a: *const c_float, n: c_int) -> c_float;
7 fn vec_ew_recipr(a: *const c_float, b: *mut c_float, n: c_int);
8 fn vec_ew_prod(a: *const c_float, b: *const c_float, c: *mut c_float, n: c_int);
9 fn vec_ew_sqrt(a: *mut c_float, n: c_int);
10 fn vec_ew_max_vec(a: *const c_float, b: *const c_float, c: *mut c_float, n: c_int);
11 fn mat_mult_scalar(A: *mut csc, sc: c_float);
12 fn mat_premult_diag(A: *mut csc, d: *const c_float);
13 fn mat_postmult_diag(A: *mut csc, d: *const c_float);
14 fn mat_inf_norm_cols(M: *const csc, E: *mut c_float);
15 fn mat_inf_norm_rows(M: *const csc, E: *mut c_float);
16 fn mat_inf_norm_cols_sym_triu(M: *const csc, E: *mut c_float);
17}
18pub type c_int = ::std::os::raw::c_longlong;
19pub type c_float = ::std::os::raw::c_double;
20pub type linsys_solver_type = ::std::os::raw::c_uint;
21pub const MKL_PARDISO_SOLVER: linsys_solver_type = 1;
22pub const QDLDL_SOLVER: linsys_solver_type = 0;
23#[derive(Copy, Clone)]
24#[repr(C)]
25pub struct csc {
26 pub nzmax: c_int,
27 pub m: c_int,
28 pub n: c_int,
29 pub p: *mut c_int,
30 pub i: *mut c_int,
31 pub x: *mut c_float,
32 pub nz: c_int,
33}
34#[derive(Copy, Clone)]
35#[repr(C)]
36pub struct linsys_solver {
37 pub type_0: linsys_solver_type,
38 pub solve: Option::<unsafe extern "C" fn(*mut LinSysSolver, *mut c_float) -> c_int>,
39 pub free: Option::<unsafe extern "C" fn(*mut LinSysSolver) -> ()>,
40 pub update_matrices: Option::<
41 unsafe extern "C" fn(*mut LinSysSolver, *const csc, *const csc) -> c_int,
42 >,
43 pub update_rho_vec: Option::<
44 unsafe extern "C" fn(*mut LinSysSolver, *const c_float) -> c_int,
45 >,
46 pub nthreads: c_int,
47}
48pub type LinSysSolver = linsys_solver;
49pub type OSQPTimer = OSQP_TIMER;
50#[derive(Copy, Clone)]
51#[repr(C)]
52pub struct OSQPScaling {
53 pub c: c_float,
54 pub D: *mut c_float,
55 pub E: *mut c_float,
56 pub cinv: c_float,
57 pub Dinv: *mut c_float,
58 pub Einv: *mut c_float,
59}
60#[derive(Copy, Clone)]
61#[repr(C)]
62pub struct OSQPSolution {
63 pub x: *mut c_float,
64 pub y: *mut c_float,
65}
66#[derive(Copy, Clone)]
67#[repr(C)]
68pub struct OSQPInfo {
69 pub iter: c_int,
70 pub status: [::std::os::raw::c_char; 32],
71 pub status_val: c_int,
72 pub status_polish: c_int,
73 pub obj_val: c_float,
74 pub pri_res: c_float,
75 pub dua_res: c_float,
76 pub setup_time: c_float,
77 pub solve_time: c_float,
78 pub update_time: c_float,
79 pub polish_time: c_float,
80 pub run_time: c_float,
81 pub rho_updates: c_int,
82 pub rho_estimate: c_float,
83}
84#[derive(Copy, Clone)]
85#[repr(C)]
86pub struct OSQPPolish {
87 pub Ared: *mut csc,
88 pub n_low: c_int,
89 pub n_upp: c_int,
90 pub A_to_Alow: *mut c_int,
91 pub A_to_Aupp: *mut c_int,
92 pub Alow_to_A: *mut c_int,
93 pub Aupp_to_A: *mut c_int,
94 pub x: *mut c_float,
95 pub z: *mut c_float,
96 pub y: *mut c_float,
97 pub obj_val: c_float,
98 pub pri_res: c_float,
99 pub dua_res: c_float,
100}
101#[derive(Copy, Clone)]
102#[repr(C)]
103pub struct OSQPData {
104 pub n: c_int,
105 pub m: c_int,
106 pub P: *mut csc,
107 pub A: *mut csc,
108 pub q: *mut c_float,
109 pub l: *mut c_float,
110 pub u: *mut c_float,
111}
112#[derive(Copy, Clone)]
113#[repr(C)]
114pub struct OSQPSettings {
115 pub rho: c_float,
116 pub sigma: c_float,
117 pub scaling: c_int,
118 pub adaptive_rho: c_int,
119 pub adaptive_rho_interval: c_int,
120 pub adaptive_rho_tolerance: c_float,
121 pub adaptive_rho_fraction: c_float,
122 pub max_iter: c_int,
123 pub eps_abs: c_float,
124 pub eps_rel: c_float,
125 pub eps_prim_inf: c_float,
126 pub eps_dual_inf: c_float,
127 pub alpha: c_float,
128 pub linsys_solver: linsys_solver_type,
129 pub delta: c_float,
130 pub polish: c_int,
131 pub polish_refine_iter: c_int,
132 pub verbose: c_int,
133 pub scaled_termination: c_int,
134 pub check_termination: c_int,
135 pub warm_start: c_int,
136 pub time_limit: c_float,
137}
138#[derive(Copy, Clone)]
139#[repr(C)]
140pub struct OSQPWorkspace {
141 pub data: *mut OSQPData,
142 pub linsys_solver: *mut LinSysSolver,
143 pub pol: *mut OSQPPolish,
144 pub rho_vec: *mut c_float,
145 pub rho_inv_vec: *mut c_float,
146 pub constr_type: *mut c_int,
147 pub x: *mut c_float,
148 pub y: *mut c_float,
149 pub z: *mut c_float,
150 pub xz_tilde: *mut c_float,
151 pub x_prev: *mut c_float,
152 pub z_prev: *mut c_float,
153 pub Ax: *mut c_float,
154 pub Px: *mut c_float,
155 pub Aty: *mut c_float,
156 pub delta_y: *mut c_float,
157 pub Atdelta_y: *mut c_float,
158 pub delta_x: *mut c_float,
159 pub Pdelta_x: *mut c_float,
160 pub Adelta_x: *mut c_float,
161 pub D_temp: *mut c_float,
162 pub D_temp_A: *mut c_float,
163 pub E_temp: *mut c_float,
164 pub settings: *mut OSQPSettings,
165 pub scaling: *mut OSQPScaling,
166 pub solution: *mut OSQPSolution,
167 pub info: *mut OSQPInfo,
168 pub timer: *mut OSQPTimer,
169 pub first_run: c_int,
170 pub clear_update_time: c_int,
171 pub rho_update_from_solve: c_int,
172 pub summary_printed: c_int,
173}
174pub const MIN_SCALING: ::std::os::raw::c_double = 1e-04f64;
175pub const MAX_SCALING: ::std::os::raw::c_double = 1e+04f64;
176#[no_mangle]
177pub unsafe extern "C" fn limit_scaling(mut D: *mut c_float, mut n: c_int) {
178 let mut i: c_int = 0;
179 i = 0 as ::std::os::raw::c_int as c_int;
180 while i < n {
181 *D
182 .offset(
183 i as isize,
184 ) = if *D.offset(i as isize) < MIN_SCALING {
185 1.0f64
186 } else {
187 *D.offset(i as isize)
188 };
189 *D
190 .offset(
191 i as isize,
192 ) = if *D.offset(i as isize) > MAX_SCALING {
193 MAX_SCALING
194 } else {
195 *D.offset(i as isize)
196 };
197 i += 1;
198 }
199}
200#[no_mangle]
201pub unsafe extern "C" fn compute_inf_norm_cols_KKT(
202 mut P: *const csc,
203 mut A: *const csc,
204 mut D: *mut c_float,
205 mut D_temp_A: *mut c_float,
206 mut E: *mut c_float,
207 mut n: c_int,
208) {
209 mat_inf_norm_cols_sym_triu(P, D);
210 mat_inf_norm_cols(A, D_temp_A);
211 vec_ew_max_vec(D, D_temp_A, D, n);
212 mat_inf_norm_rows(A, E);
213}
214#[no_mangle]
215pub unsafe extern "C" fn scale_data(mut work: *mut OSQPWorkspace) -> c_int {
216 let mut i: c_int = 0;
217 let mut n: c_int = 0;
218 let mut m: c_int = 0;
219 let mut c_temp: c_float = 0.;
220 let mut inf_norm_q: c_float = 0.;
221 n = (*(*work).data).n;
222 m = (*(*work).data).m;
223 (*(*work).scaling).c = 1.0f64;
224 vec_set_scalar((*(*work).scaling).D, 1.0f64, (*(*work).data).n);
225 vec_set_scalar((*(*work).scaling).Dinv, 1.0f64, (*(*work).data).n);
226 vec_set_scalar((*(*work).scaling).E, 1.0f64, (*(*work).data).m);
227 vec_set_scalar((*(*work).scaling).Einv, 1.0f64, (*(*work).data).m);
228 i = 0 as ::std::os::raw::c_int as c_int;
229 while i < (*(*work).settings).scaling {
230 compute_inf_norm_cols_KKT(
231 (*(*work).data).P,
232 (*(*work).data).A,
233 (*work).D_temp,
234 (*work).D_temp_A,
235 (*work).E_temp,
236 n,
237 );
238 limit_scaling((*work).D_temp, n);
239 limit_scaling((*work).E_temp, m);
240 vec_ew_sqrt((*work).D_temp, n);
241 vec_ew_sqrt((*work).E_temp, m);
242 vec_ew_recipr((*work).D_temp, (*work).D_temp, n);
243 vec_ew_recipr((*work).E_temp, (*work).E_temp, m);
244 mat_premult_diag((*(*work).data).P, (*work).D_temp);
245 mat_postmult_diag((*(*work).data).P, (*work).D_temp);
246 mat_premult_diag((*(*work).data).A, (*work).E_temp);
247 mat_postmult_diag((*(*work).data).A, (*work).D_temp);
248 vec_ew_prod((*work).D_temp, (*(*work).data).q, (*(*work).data).q, n);
249 vec_ew_prod((*(*work).scaling).D, (*work).D_temp, (*(*work).scaling).D, n);
250 vec_ew_prod((*(*work).scaling).E, (*work).E_temp, (*(*work).scaling).E, m);
251 mat_inf_norm_cols_sym_triu((*(*work).data).P, (*work).D_temp);
252 c_temp = vec_mean((*work).D_temp, n);
253 inf_norm_q = vec_norm_inf((*(*work).data).q, n);
254 limit_scaling(&mut inf_norm_q, 1 as ::std::os::raw::c_int as c_int);
255 c_temp = if c_temp > inf_norm_q { c_temp } else { inf_norm_q };
256 limit_scaling(&mut c_temp, 1 as ::std::os::raw::c_int as c_int);
257 c_temp = 1.0f64 / c_temp;
258 mat_mult_scalar((*(*work).data).P, c_temp);
259 vec_mult_scalar((*(*work).data).q, c_temp, n);
260 let ref mut fresh0 = (*(*work).scaling).c;
261 *fresh0 *= c_temp;
262 i += 1;
263 }
264 (*(*work).scaling).cinv = 1.0f64 / (*(*work).scaling).c;
265 vec_ew_recipr((*(*work).scaling).D, (*(*work).scaling).Dinv, (*(*work).data).n);
266 vec_ew_recipr((*(*work).scaling).E, (*(*work).scaling).Einv, (*(*work).data).m);
267 vec_ew_prod(
268 (*(*work).scaling).E,
269 (*(*work).data).l,
270 (*(*work).data).l,
271 (*(*work).data).m,
272 );
273 vec_ew_prod(
274 (*(*work).scaling).E,
275 (*(*work).data).u,
276 (*(*work).data).u,
277 (*(*work).data).m,
278 );
279 return 0 as ::std::os::raw::c_int as c_int;
280}
281#[no_mangle]
282pub unsafe extern "C" fn unscale_data(mut work: *mut OSQPWorkspace) -> c_int {
283 mat_mult_scalar((*(*work).data).P, (*(*work).scaling).cinv);
284 mat_premult_diag((*(*work).data).P, (*(*work).scaling).Dinv);
285 mat_postmult_diag((*(*work).data).P, (*(*work).scaling).Dinv);
286 vec_mult_scalar((*(*work).data).q, (*(*work).scaling).cinv, (*(*work).data).n);
287 vec_ew_prod(
288 (*(*work).scaling).Dinv,
289 (*(*work).data).q,
290 (*(*work).data).q,
291 (*(*work).data).n,
292 );
293 mat_premult_diag((*(*work).data).A, (*(*work).scaling).Einv);
294 mat_postmult_diag((*(*work).data).A, (*(*work).scaling).Dinv);
295 vec_ew_prod(
296 (*(*work).scaling).Einv,
297 (*(*work).data).l,
298 (*(*work).data).l,
299 (*(*work).data).m,
300 );
301 vec_ew_prod(
302 (*(*work).scaling).Einv,
303 (*(*work).data).u,
304 (*(*work).data).u,
305 (*(*work).data).m,
306 );
307 return 0 as ::std::os::raw::c_int as c_int;
308}
309#[no_mangle]
310pub unsafe extern "C" fn unscale_solution(mut work: *mut OSQPWorkspace) -> c_int {
311 vec_ew_prod(
312 (*(*work).scaling).D,
313 (*(*work).solution).x,
314 (*(*work).solution).x,
315 (*(*work).data).n,
316 );
317 vec_ew_prod(
318 (*(*work).scaling).E,
319 (*(*work).solution).y,
320 (*(*work).solution).y,
321 (*(*work).data).m,
322 );
323 vec_mult_scalar((*(*work).solution).y, (*(*work).scaling).cinv, (*(*work).data).m);
324 return 0 as ::std::os::raw::c_int as c_int;
325}