osqp_rust_sys/src64/src/
scaling.rs

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}