osqp_rust_sys/src32/lin_sys/direct/qdldl/
qdldl_interface.rs

1extern "C" {
2    fn malloc(_: ::std::os::raw::c_ulong) -> *mut ::std::os::raw::c_void;
3    fn calloc(_: ::std::os::raw::c_ulong, _: ::std::os::raw::c_ulong) -> *mut ::std::os::raw::c_void;
4    fn free(_: *mut ::std::os::raw::c_void);
5    fn printf(_: *const ::std::os::raw::c_char, _: ...) -> ::std::os::raw::c_int;
6    fn QDLDL_etree(
7        n: QDLDL_int,
8        Ap: *const QDLDL_int,
9        Ai: *const QDLDL_int,
10        work: *mut QDLDL_int,
11        Lnz: *mut QDLDL_int,
12        etree: *mut QDLDL_int,
13    ) -> QDLDL_int;
14    fn QDLDL_factor(
15        n: QDLDL_int,
16        Ap: *const QDLDL_int,
17        Ai: *const QDLDL_int,
18        Ax: *const QDLDL_float,
19        Lp: *mut QDLDL_int,
20        Li: *mut QDLDL_int,
21        Lx: *mut QDLDL_float,
22        D: *mut QDLDL_float,
23        Dinv: *mut QDLDL_float,
24        Lnz: *const QDLDL_int,
25        etree: *const QDLDL_int,
26        bwork: *mut QDLDL_bool,
27        iwork: *mut QDLDL_int,
28        fwork: *mut QDLDL_float,
29    ) -> QDLDL_int;
30    fn QDLDL_solve(
31        n: QDLDL_int,
32        Lp: *const QDLDL_int,
33        Li: *const QDLDL_int,
34        Lx: *const QDLDL_float,
35        Dinv: *const QDLDL_float,
36        x: *mut QDLDL_float,
37    );
38    fn amd_order(
39        n: ::std::os::raw::c_int,
40        Ap: *const ::std::os::raw::c_int,
41        Ai: *const ::std::os::raw::c_int,
42        P: *mut ::std::os::raw::c_int,
43        Control: *mut c_float,
44        Info: *mut c_float,
45    ) -> ::std::os::raw::c_int;
46    fn csc_spfree(A: *mut csc);
47    fn csc_pinv(p: *const c_int, n: c_int) -> *mut c_int;
48    fn csc_symperm(
49        A: *const csc,
50        pinv: *const c_int,
51        AtoC: *mut c_int,
52        values: c_int,
53    ) -> *mut csc;
54    fn form_KKT(
55        P: *const csc,
56        A: *const csc,
57        format: c_int,
58        param1: c_float,
59        param2: *mut c_float,
60        PtoKKT: *mut c_int,
61        AtoKKT: *mut c_int,
62        Pdiag_idx: *mut *mut c_int,
63        Pdiag_n: *mut c_int,
64        param2toKKT: *mut c_int,
65    ) -> *mut csc;
66    fn update_KKT_param2(
67        KKT: *mut csc,
68        param2: *const c_float,
69        param2toKKT: *const c_int,
70        m: c_int,
71    );
72    fn update_KKT_A(KKT: *mut csc, A: *const csc, AtoKKT: *const c_int);
73    fn update_KKT_P(
74        KKT: *mut csc,
75        P: *const csc,
76        PtoKKT: *const c_int,
77        param1: c_float,
78        Pdiag_idx: *const c_int,
79        Pdiag_n: c_int,
80    );
81}
82pub type c_int = ::std::os::raw::c_int;
83pub type c_float = ::std::os::raw::c_double;
84pub type QDLDL_int = ::std::os::raw::c_int;
85pub type QDLDL_float = ::std::os::raw::c_double;
86pub type QDLDL_bool = ::std::os::raw::c_uchar;
87pub type linsys_solver_type = ::std::os::raw::c_uint;
88pub const MKL_PARDISO_SOLVER: linsys_solver_type = 1;
89pub const QDLDL_SOLVER: linsys_solver_type = 0;
90pub type osqp_error_type = ::std::os::raw::c_uint;
91pub const OSQP_WORKSPACE_NOT_INIT_ERROR: osqp_error_type = 7;
92pub const OSQP_MEM_ALLOC_ERROR: osqp_error_type = 6;
93pub const OSQP_NONCVX_ERROR: osqp_error_type = 5;
94pub const OSQP_LINSYS_SOLVER_INIT_ERROR: osqp_error_type = 4;
95pub const OSQP_LINSYS_SOLVER_LOAD_ERROR: osqp_error_type = 3;
96pub const OSQP_SETTINGS_VALIDATION_ERROR: osqp_error_type = 2;
97pub const OSQP_DATA_VALIDATION_ERROR: osqp_error_type = 1;
98#[derive(Copy, Clone)]
99#[repr(C)]
100pub struct csc {
101    pub nzmax: c_int,
102    pub m: c_int,
103    pub n: c_int,
104    pub p: *mut c_int,
105    pub i: *mut c_int,
106    pub x: *mut c_float,
107    pub nz: c_int,
108}
109#[derive(Copy, Clone)]
110#[repr(C)]
111pub struct qdldl {
112    pub type_0: linsys_solver_type,
113    pub solve: Option::<unsafe extern "C" fn(*mut qdldl, *mut c_float) -> c_int>,
114    pub free: Option::<unsafe extern "C" fn(*mut qdldl) -> ()>,
115    pub update_matrices: Option::<
116        unsafe extern "C" fn(*mut qdldl, *const csc, *const csc) -> c_int,
117    >,
118    pub update_rho_vec: Option::<
119        unsafe extern "C" fn(*mut qdldl, *const c_float) -> c_int,
120    >,
121    pub nthreads: c_int,
122    pub L: *mut csc,
123    pub Dinv: *mut c_float,
124    pub P: *mut c_int,
125    pub bp: *mut c_float,
126    pub sol: *mut c_float,
127    pub rho_inv_vec: *mut c_float,
128    pub sigma: c_float,
129    pub polish: c_int,
130    pub n: c_int,
131    pub m: c_int,
132    pub Pdiag_idx: *mut c_int,
133    pub Pdiag_n: c_int,
134    pub KKT: *mut csc,
135    pub PtoKKT: *mut c_int,
136    pub AtoKKT: *mut c_int,
137    pub rhotoKKT: *mut c_int,
138    pub D: *mut QDLDL_float,
139    pub etree: *mut QDLDL_int,
140    pub Lnz: *mut QDLDL_int,
141    pub iwork: *mut QDLDL_int,
142    pub bwork: *mut QDLDL_bool,
143    pub fwork: *mut QDLDL_float,
144}
145pub type qdldl_solver = qdldl;
146pub const c_calloc: unsafe extern "C" fn(
147    ::std::os::raw::c_ulong,
148    ::std::os::raw::c_ulong,
149) -> *mut ::std::os::raw::c_void = calloc;
150pub const c_malloc: unsafe extern "C" fn(::std::os::raw::c_ulong) -> *mut ::std::os::raw::c_void = malloc;
151pub const c_print: unsafe extern "C" fn(*const ::std::os::raw::c_char, ...) -> ::std::os::raw::c_int = printf;
152pub const c_free: unsafe extern "C" fn(*mut ::std::os::raw::c_void) -> () = free;
153pub const OSQP_NULL: ::std::os::raw::c_int = 0 as ::std::os::raw::c_int;
154pub const AMD_INFO: ::std::os::raw::c_int = 20 as ::std::os::raw::c_int;
155#[no_mangle]
156pub unsafe extern "C" fn free_linsys_solver_qdldl(mut s: *mut qdldl_solver) {
157    if !s.is_null() {
158        if !((*s).L).is_null() {
159            csc_spfree((*s).L);
160        }
161        if !((*s).P).is_null() {
162            free((*s).P as *mut ::std::os::raw::c_void);
163        }
164        if !((*s).Dinv).is_null() {
165            free((*s).Dinv as *mut ::std::os::raw::c_void);
166        }
167        if !((*s).bp).is_null() {
168            free((*s).bp as *mut ::std::os::raw::c_void);
169        }
170        if !((*s).sol).is_null() {
171            free((*s).sol as *mut ::std::os::raw::c_void);
172        }
173        if !((*s).rho_inv_vec).is_null() {
174            free((*s).rho_inv_vec as *mut ::std::os::raw::c_void);
175        }
176        if !((*s).Pdiag_idx).is_null() {
177            free((*s).Pdiag_idx as *mut ::std::os::raw::c_void);
178        }
179        if !((*s).KKT).is_null() {
180            csc_spfree((*s).KKT);
181        }
182        if !((*s).PtoKKT).is_null() {
183            free((*s).PtoKKT as *mut ::std::os::raw::c_void);
184        }
185        if !((*s).AtoKKT).is_null() {
186            free((*s).AtoKKT as *mut ::std::os::raw::c_void);
187        }
188        if !((*s).rhotoKKT).is_null() {
189            free((*s).rhotoKKT as *mut ::std::os::raw::c_void);
190        }
191        if !((*s).D).is_null() {
192            free((*s).D as *mut ::std::os::raw::c_void);
193        }
194        if !((*s).etree).is_null() {
195            free((*s).etree as *mut ::std::os::raw::c_void);
196        }
197        if !((*s).Lnz).is_null() {
198            free((*s).Lnz as *mut ::std::os::raw::c_void);
199        }
200        if !((*s).iwork).is_null() {
201            free((*s).iwork as *mut ::std::os::raw::c_void);
202        }
203        if !((*s).bwork).is_null() {
204            free((*s).bwork as *mut ::std::os::raw::c_void);
205        }
206        if !((*s).fwork).is_null() {
207            free((*s).fwork as *mut ::std::os::raw::c_void);
208        }
209        free(s as *mut ::std::os::raw::c_void);
210    }
211}
212unsafe extern "C" fn LDL_factor(
213    mut A: *mut csc,
214    mut p: *mut qdldl_solver,
215    mut nvar: c_int,
216) -> c_int {
217    let mut sum_Lnz: c_int = 0;
218    let mut factor_status: c_int = 0;
219    sum_Lnz = QDLDL_etree((*A).n, (*A).p, (*A).i, (*p).iwork, (*p).Lnz, (*p).etree);
220    if sum_Lnz < 0 as ::std::os::raw::c_int {
221        printf(
222            b"ERROR in %s: \0" as *const u8 as *const ::std::os::raw::c_char,
223            (*::std::mem::transmute::<&[u8; 11], &[::std::os::raw::c_char; 11]>(b"LDL_factor\0"))
224                .as_ptr(),
225        );
226        printf(
227            b"Error in KKT matrix LDL factorization when computing the elimination tree.\0"
228                as *const u8 as *const ::std::os::raw::c_char,
229        );
230        printf(b"\n\0" as *const u8 as *const ::std::os::raw::c_char);
231        if sum_Lnz == -(1 as ::std::os::raw::c_int) {
232            printf(
233                b"ERROR in %s: \0" as *const u8 as *const ::std::os::raw::c_char,
234                (*::std::mem::transmute::<
235                    &[u8; 11],
236                    &[::std::os::raw::c_char; 11],
237                >(b"LDL_factor\0"))
238                    .as_ptr(),
239            );
240            printf(
241                b"Matrix is not perfectly upper triangular.\0" as *const u8
242                    as *const ::std::os::raw::c_char,
243            );
244            printf(b"\n\0" as *const u8 as *const ::std::os::raw::c_char);
245        } else if sum_Lnz == -(2 as ::std::os::raw::c_int) {
246            printf(
247                b"ERROR in %s: \0" as *const u8 as *const ::std::os::raw::c_char,
248                (*::std::mem::transmute::<
249                    &[u8; 11],
250                    &[::std::os::raw::c_char; 11],
251                >(b"LDL_factor\0"))
252                    .as_ptr(),
253            );
254            printf(
255                b"Integer overflow in L nonzero count.\0" as *const u8
256                    as *const ::std::os::raw::c_char,
257            );
258            printf(b"\n\0" as *const u8 as *const ::std::os::raw::c_char);
259        }
260        return sum_Lnz;
261    }
262    let ref mut fresh0 = (*(*p).L).i;
263    *fresh0 = malloc(
264        (::std::mem::size_of::<c_int>() as ::std::os::raw::c_ulong)
265            .wrapping_mul(sum_Lnz as ::std::os::raw::c_ulong),
266    ) as *mut c_int;
267    let ref mut fresh1 = (*(*p).L).x;
268    *fresh1 = malloc(
269        (::std::mem::size_of::<c_float>() as ::std::os::raw::c_ulong)
270            .wrapping_mul(sum_Lnz as ::std::os::raw::c_ulong),
271    ) as *mut c_float;
272    (*(*p).L).nzmax = sum_Lnz;
273    factor_status = QDLDL_factor(
274        (*A).n,
275        (*A).p,
276        (*A).i,
277        (*A).x,
278        (*(*p).L).p,
279        (*(*p).L).i,
280        (*(*p).L).x,
281        (*p).D,
282        (*p).Dinv,
283        (*p).Lnz,
284        (*p).etree,
285        (*p).bwork,
286        (*p).iwork,
287        (*p).fwork,
288    );
289    if factor_status < 0 as ::std::os::raw::c_int {
290        printf(
291            b"ERROR in %s: \0" as *const u8 as *const ::std::os::raw::c_char,
292            (*::std::mem::transmute::<&[u8; 11], &[::std::os::raw::c_char; 11]>(b"LDL_factor\0"))
293                .as_ptr(),
294        );
295        printf(
296            b"Error in KKT matrix LDL factorization when computing the nonzero elements. There are zeros in the diagonal matrix\0"
297                as *const u8 as *const ::std::os::raw::c_char,
298        );
299        printf(b"\n\0" as *const u8 as *const ::std::os::raw::c_char);
300        return factor_status;
301    } else {
302        if factor_status < nvar {
303            printf(
304                b"ERROR in %s: \0" as *const u8 as *const ::std::os::raw::c_char,
305                (*::std::mem::transmute::<
306                    &[u8; 11],
307                    &[::std::os::raw::c_char; 11],
308                >(b"LDL_factor\0"))
309                    .as_ptr(),
310            );
311            printf(
312                b"Error in KKT matrix LDL factorization when computing the nonzero elements. The problem seems to be non-convex\0"
313                    as *const u8 as *const ::std::os::raw::c_char,
314            );
315            printf(b"\n\0" as *const u8 as *const ::std::os::raw::c_char);
316            return -(2 as ::std::os::raw::c_int);
317        }
318    }
319    return 0 as ::std::os::raw::c_int;
320}
321unsafe extern "C" fn permute_KKT(
322    mut KKT: *mut *mut csc,
323    mut p: *mut qdldl_solver,
324    mut Pnz: c_int,
325    mut Anz: c_int,
326    mut m: c_int,
327    mut PtoKKT: *mut c_int,
328    mut AtoKKT: *mut c_int,
329    mut rhotoKKT: *mut c_int,
330) -> c_int {
331    let mut info: *mut c_float = 0 as *mut c_float;
332    let mut amd_status: c_int = 0;
333    let mut Pinv: *mut c_int = 0 as *mut c_int;
334    let mut KKT_temp: *mut csc = 0 as *mut csc;
335    let mut KtoPKPt: *mut c_int = 0 as *mut c_int;
336    let mut i: c_int = 0;
337    info = malloc(
338        (AMD_INFO as ::std::os::raw::c_ulong)
339            .wrapping_mul(::std::mem::size_of::<c_float>() as ::std::os::raw::c_ulong),
340    ) as *mut c_float;
341    amd_status = amd_order(
342        (**KKT).n,
343        (**KKT).p as *const ::std::os::raw::c_int,
344        (**KKT).i as *const ::std::os::raw::c_int,
345        (*p).P,
346        0 as *mut c_float,
347        info,
348    );
349    if amd_status < 0 as ::std::os::raw::c_int {
350        free(info as *mut ::std::os::raw::c_void);
351        return amd_status;
352    }
353    Pinv = csc_pinv((*p).P, (**KKT).n);
354    if PtoKKT.is_null() && AtoKKT.is_null() && rhotoKKT.is_null() {
355        KKT_temp = csc_symperm(*KKT, Pinv, OSQP_NULL as *mut c_int, 1 as ::std::os::raw::c_int);
356    } else {
357        KtoPKPt = malloc(
358            (*((**KKT).p).offset((**KKT).n as isize) as ::std::os::raw::c_ulong)
359                .wrapping_mul(::std::mem::size_of::<c_int>() as ::std::os::raw::c_ulong),
360        ) as *mut c_int;
361        KKT_temp = csc_symperm(*KKT, Pinv, KtoPKPt, 1 as ::std::os::raw::c_int);
362        if !PtoKKT.is_null() {
363            i = 0 as ::std::os::raw::c_int;
364            while i < Pnz {
365                *PtoKKT
366                    .offset(
367                        i as isize,
368                    ) = *KtoPKPt.offset(*PtoKKT.offset(i as isize) as isize);
369                i += 1;
370            }
371        }
372        if !AtoKKT.is_null() {
373            i = 0 as ::std::os::raw::c_int;
374            while i < Anz {
375                *AtoKKT
376                    .offset(
377                        i as isize,
378                    ) = *KtoPKPt.offset(*AtoKKT.offset(i as isize) as isize);
379                i += 1;
380            }
381        }
382        if !rhotoKKT.is_null() {
383            i = 0 as ::std::os::raw::c_int;
384            while i < m {
385                *rhotoKKT
386                    .offset(
387                        i as isize,
388                    ) = *KtoPKPt.offset(*rhotoKKT.offset(i as isize) as isize);
389                i += 1;
390            }
391        }
392        free(KtoPKPt as *mut ::std::os::raw::c_void);
393    }
394    csc_spfree(*KKT);
395    *KKT = KKT_temp;
396    free(Pinv as *mut ::std::os::raw::c_void);
397    free(info as *mut ::std::os::raw::c_void);
398    return 0 as ::std::os::raw::c_int;
399}
400#[no_mangle]
401pub unsafe extern "C" fn init_linsys_solver_qdldl(
402    mut sp: *mut *mut qdldl_solver,
403    mut P: *const csc,
404    mut A: *const csc,
405    mut sigma: c_float,
406    mut rho_vec: *const c_float,
407    mut polish: c_int,
408) -> c_int {
409    let mut KKT_temp: *mut csc = 0 as *mut csc;
410    let mut i: c_int = 0;
411    let mut n_plus_m: c_int = 0;
412    let mut s: *mut qdldl_solver = 0 as *mut qdldl_solver;
413    s = calloc(
414        1 as ::std::os::raw::c_int as ::std::os::raw::c_ulong,
415        ::std::mem::size_of::<qdldl_solver>() as ::std::os::raw::c_ulong,
416    ) as *mut qdldl_solver;
417    *sp = s;
418    (*s).n = (*P).n;
419    (*s).m = (*A).m;
420    n_plus_m = (*s).n + (*s).m;
421    (*s).sigma = sigma;
422    (*s).polish = polish;
423    let ref mut fresh2 = (*s).solve;
424    *fresh2 = Some(
425        solve_linsys_qdldl
426            as unsafe extern "C" fn(*mut qdldl_solver, *mut c_float) -> c_int,
427    );
428    let ref mut fresh3 = (*s).free;
429    *fresh3 = Some(
430        free_linsys_solver_qdldl as unsafe extern "C" fn(*mut qdldl_solver) -> (),
431    );
432    let ref mut fresh4 = (*s).update_matrices;
433    *fresh4 = Some(
434        update_linsys_solver_matrices_qdldl
435            as unsafe extern "C" fn(*mut qdldl_solver, *const csc, *const csc) -> c_int,
436    );
437    let ref mut fresh5 = (*s).update_rho_vec;
438    *fresh5 = Some(
439        update_linsys_solver_rho_vec_qdldl
440            as unsafe extern "C" fn(*mut qdldl_solver, *const c_float) -> c_int,
441    );
442    (*s).type_0 = QDLDL_SOLVER;
443    (*s).nthreads = 1 as ::std::os::raw::c_int;
444    let ref mut fresh6 = (*s).L;
445    *fresh6 = malloc(::std::mem::size_of::<csc>() as ::std::os::raw::c_ulong) as *mut csc;
446    (*(*s).L).m = n_plus_m;
447    (*(*s).L).n = n_plus_m;
448    (*(*s).L).nz = -(1 as ::std::os::raw::c_int);
449    let ref mut fresh7 = (*s).Dinv;
450    *fresh7 = malloc(
451        (::std::mem::size_of::<QDLDL_float>() as ::std::os::raw::c_ulong)
452            .wrapping_mul(n_plus_m as ::std::os::raw::c_ulong),
453    ) as *mut QDLDL_float;
454    let ref mut fresh8 = (*s).D;
455    *fresh8 = malloc(
456        (::std::mem::size_of::<QDLDL_float>() as ::std::os::raw::c_ulong)
457            .wrapping_mul(n_plus_m as ::std::os::raw::c_ulong),
458    ) as *mut QDLDL_float;
459    let ref mut fresh9 = (*s).P;
460    *fresh9 = malloc(
461        (::std::mem::size_of::<QDLDL_int>() as ::std::os::raw::c_ulong)
462            .wrapping_mul(n_plus_m as ::std::os::raw::c_ulong),
463    ) as *mut QDLDL_int;
464    let ref mut fresh10 = (*s).bp;
465    *fresh10 = malloc(
466        (::std::mem::size_of::<QDLDL_float>() as ::std::os::raw::c_ulong)
467            .wrapping_mul(n_plus_m as ::std::os::raw::c_ulong),
468    ) as *mut QDLDL_float;
469    let ref mut fresh11 = (*s).sol;
470    *fresh11 = malloc(
471        (::std::mem::size_of::<QDLDL_float>() as ::std::os::raw::c_ulong)
472            .wrapping_mul(n_plus_m as ::std::os::raw::c_ulong),
473    ) as *mut QDLDL_float;
474    let ref mut fresh12 = (*s).rho_inv_vec;
475    *fresh12 = malloc(
476        (::std::mem::size_of::<c_float>() as ::std::os::raw::c_ulong)
477            .wrapping_mul((*s).m as ::std::os::raw::c_ulong),
478    ) as *mut c_float;
479    let ref mut fresh13 = (*s).etree;
480    *fresh13 = malloc(
481        (n_plus_m as ::std::os::raw::c_ulong)
482            .wrapping_mul(::std::mem::size_of::<QDLDL_int>() as ::std::os::raw::c_ulong),
483    ) as *mut QDLDL_int;
484    let ref mut fresh14 = (*s).Lnz;
485    *fresh14 = malloc(
486        (n_plus_m as ::std::os::raw::c_ulong)
487            .wrapping_mul(::std::mem::size_of::<QDLDL_int>() as ::std::os::raw::c_ulong),
488    ) as *mut QDLDL_int;
489    let ref mut fresh15 = (*(*s).L).p;
490    *fresh15 = malloc(
491        ((n_plus_m + 1 as ::std::os::raw::c_int) as ::std::os::raw::c_ulong)
492            .wrapping_mul(::std::mem::size_of::<QDLDL_int>() as ::std::os::raw::c_ulong),
493    ) as *mut c_int;
494    let ref mut fresh16 = (*(*s).L).i;
495    *fresh16 = OSQP_NULL as *mut c_int;
496    let ref mut fresh17 = (*(*s).L).x;
497    *fresh17 = OSQP_NULL as *mut c_float;
498    let ref mut fresh18 = (*s).iwork;
499    *fresh18 = malloc(
500        (::std::mem::size_of::<QDLDL_int>() as ::std::os::raw::c_ulong)
501            .wrapping_mul((3 as ::std::os::raw::c_int * n_plus_m) as ::std::os::raw::c_ulong),
502    ) as *mut QDLDL_int;
503    let ref mut fresh19 = (*s).bwork;
504    *fresh19 = malloc(
505        (::std::mem::size_of::<QDLDL_bool>() as ::std::os::raw::c_ulong)
506            .wrapping_mul(n_plus_m as ::std::os::raw::c_ulong),
507    ) as *mut QDLDL_bool;
508    let ref mut fresh20 = (*s).fwork;
509    *fresh20 = malloc(
510        (::std::mem::size_of::<QDLDL_float>() as ::std::os::raw::c_ulong)
511            .wrapping_mul(n_plus_m as ::std::os::raw::c_ulong),
512    ) as *mut QDLDL_float;
513    if polish != 0 {
514        i = 0 as ::std::os::raw::c_int;
515        while i < (*A).m {
516            *((*s).rho_inv_vec).offset(i as isize) = sigma;
517            i += 1;
518        }
519        KKT_temp = form_KKT(
520            P,
521            A,
522            0 as ::std::os::raw::c_int,
523            sigma,
524            (*s).rho_inv_vec,
525            OSQP_NULL as *mut c_int,
526            OSQP_NULL as *mut c_int,
527            OSQP_NULL as *mut *mut c_int,
528            OSQP_NULL as *mut c_int,
529            OSQP_NULL as *mut c_int,
530        );
531        if !KKT_temp.is_null() {
532            permute_KKT(
533                &mut KKT_temp,
534                s,
535                OSQP_NULL,
536                OSQP_NULL,
537                OSQP_NULL,
538                OSQP_NULL as *mut c_int,
539                OSQP_NULL as *mut c_int,
540                OSQP_NULL as *mut c_int,
541            );
542        }
543    } else {
544        let ref mut fresh21 = (*s).PtoKKT;
545        *fresh21 = malloc(
546            (*((*P).p).offset((*P).n as isize) as ::std::os::raw::c_ulong)
547                .wrapping_mul(::std::mem::size_of::<c_int>() as ::std::os::raw::c_ulong),
548        ) as *mut c_int;
549        let ref mut fresh22 = (*s).AtoKKT;
550        *fresh22 = malloc(
551            (*((*A).p).offset((*A).n as isize) as ::std::os::raw::c_ulong)
552                .wrapping_mul(::std::mem::size_of::<c_int>() as ::std::os::raw::c_ulong),
553        ) as *mut c_int;
554        let ref mut fresh23 = (*s).rhotoKKT;
555        *fresh23 = malloc(
556            ((*A).m as ::std::os::raw::c_ulong)
557                .wrapping_mul(::std::mem::size_of::<c_int>() as ::std::os::raw::c_ulong),
558        ) as *mut c_int;
559        i = 0 as ::std::os::raw::c_int;
560        while i < (*A).m {
561            *((*s).rho_inv_vec)
562                .offset(i as isize) = 1.0f64 / *rho_vec.offset(i as isize);
563            i += 1;
564        }
565        KKT_temp = form_KKT(
566            P,
567            A,
568            0 as ::std::os::raw::c_int,
569            sigma,
570            (*s).rho_inv_vec,
571            (*s).PtoKKT,
572            (*s).AtoKKT,
573            &mut (*s).Pdiag_idx,
574            &mut (*s).Pdiag_n,
575            (*s).rhotoKKT,
576        );
577        if !KKT_temp.is_null() {
578            permute_KKT(
579                &mut KKT_temp,
580                s,
581                *((*P).p).offset((*P).n as isize),
582                *((*A).p).offset((*A).n as isize),
583                (*A).m,
584                (*s).PtoKKT,
585                (*s).AtoKKT,
586                (*s).rhotoKKT,
587            );
588        }
589    }
590    if KKT_temp.is_null() {
591        printf(
592            b"ERROR in %s: \0" as *const u8 as *const ::std::os::raw::c_char,
593            (*::std::mem::transmute::<
594                &[u8; 25],
595                &[::std::os::raw::c_char; 25],
596            >(b"init_linsys_solver_qdldl\0"))
597                .as_ptr(),
598        );
599        printf(
600            b"Error forming and permuting KKT matrix\0" as *const u8
601                as *const ::std::os::raw::c_char,
602        );
603        printf(b"\n\0" as *const u8 as *const ::std::os::raw::c_char);
604        free_linsys_solver_qdldl(s);
605        *sp = OSQP_NULL as *mut qdldl_solver;
606        return OSQP_LINSYS_SOLVER_INIT_ERROR as ::std::os::raw::c_int;
607    }
608    if LDL_factor(KKT_temp, s, (*P).n) < 0 as ::std::os::raw::c_int {
609        csc_spfree(KKT_temp);
610        free_linsys_solver_qdldl(s);
611        *sp = OSQP_NULL as *mut qdldl_solver;
612        return OSQP_NONCVX_ERROR as ::std::os::raw::c_int;
613    }
614    if polish != 0 {
615        csc_spfree(KKT_temp);
616    } else {
617        let ref mut fresh24 = (*s).KKT;
618        *fresh24 = KKT_temp;
619    }
620    return 0 as ::std::os::raw::c_int;
621}
622#[no_mangle]
623pub unsafe extern "C" fn permute_x(
624    mut n: c_int,
625    mut x: *mut c_float,
626    mut b: *const c_float,
627    mut P: *const c_int,
628) {
629    let mut j: c_int = 0;
630    j = 0 as ::std::os::raw::c_int;
631    while j < n {
632        *x.offset(j as isize) = *b.offset(*P.offset(j as isize) as isize);
633        j += 1;
634    }
635}
636#[no_mangle]
637pub unsafe extern "C" fn permutet_x(
638    mut n: c_int,
639    mut x: *mut c_float,
640    mut b: *const c_float,
641    mut P: *const c_int,
642) {
643    let mut j: c_int = 0;
644    j = 0 as ::std::os::raw::c_int;
645    while j < n {
646        *x.offset(*P.offset(j as isize) as isize) = *b.offset(j as isize);
647        j += 1;
648    }
649}
650unsafe extern "C" fn LDLSolve(
651    mut x: *mut c_float,
652    mut b: *mut c_float,
653    mut L: *const csc,
654    mut Dinv: *const c_float,
655    mut P: *const c_int,
656    mut bp: *mut c_float,
657) {
658    permute_x((*L).n, bp, b, P);
659    QDLDL_solve((*L).n, (*L).p, (*L).i, (*L).x, Dinv, bp);
660    permutet_x((*L).n, x, bp, P);
661}
662#[no_mangle]
663pub unsafe extern "C" fn solve_linsys_qdldl(
664    mut s: *mut qdldl_solver,
665    mut b: *mut c_float,
666) -> c_int {
667    let mut j: c_int = 0;
668    if (*s).polish != 0 {
669        LDLSolve(b, b, (*s).L, (*s).Dinv, (*s).P, (*s).bp);
670    } else {
671        LDLSolve((*s).sol, b, (*s).L, (*s).Dinv, (*s).P, (*s).bp);
672        j = 0 as ::std::os::raw::c_int;
673        while j < (*s).n {
674            *b.offset(j as isize) = *((*s).sol).offset(j as isize);
675            j += 1;
676        }
677        j = 0 as ::std::os::raw::c_int;
678        while j < (*s).m {
679            let ref mut fresh25 = *b.offset((j + (*s).n) as isize);
680            *fresh25
681                += *((*s).rho_inv_vec).offset(j as isize)
682                    * *((*s).sol).offset((j + (*s).n) as isize);
683            j += 1;
684        }
685    }
686    return 0 as ::std::os::raw::c_int;
687}
688#[no_mangle]
689pub unsafe extern "C" fn update_linsys_solver_matrices_qdldl(
690    mut s: *mut qdldl_solver,
691    mut P: *const csc,
692    mut A: *const csc,
693) -> c_int {
694    update_KKT_P((*s).KKT, P, (*s).PtoKKT, (*s).sigma, (*s).Pdiag_idx, (*s).Pdiag_n);
695    update_KKT_A((*s).KKT, A, (*s).AtoKKT);
696    return (QDLDL_factor(
697        (*(*s).KKT).n,
698        (*(*s).KKT).p,
699        (*(*s).KKT).i,
700        (*(*s).KKT).x,
701        (*(*s).L).p,
702        (*(*s).L).i,
703        (*(*s).L).x,
704        (*s).D,
705        (*s).Dinv,
706        (*s).Lnz,
707        (*s).etree,
708        (*s).bwork,
709        (*s).iwork,
710        (*s).fwork,
711    ) < 0 as ::std::os::raw::c_int) as ::std::os::raw::c_int;
712}
713#[no_mangle]
714pub unsafe extern "C" fn update_linsys_solver_rho_vec_qdldl(
715    mut s: *mut qdldl_solver,
716    mut rho_vec: *const c_float,
717) -> c_int {
718    let mut i: c_int = 0;
719    i = 0 as ::std::os::raw::c_int;
720    while i < (*s).m {
721        *((*s).rho_inv_vec).offset(i as isize) = 1.0f64 / *rho_vec.offset(i as isize);
722        i += 1;
723    }
724    update_KKT_param2((*s).KKT, (*s).rho_inv_vec, (*s).rhotoKKT, (*s).m);
725    return (QDLDL_factor(
726        (*(*s).KKT).n,
727        (*(*s).KKT).p,
728        (*(*s).KKT).i,
729        (*(*s).KKT).x,
730        (*(*s).L).p,
731        (*(*s).L).i,
732        (*(*s).L).x,
733        (*s).D,
734        (*s).Dinv,
735        (*s).Lnz,
736        (*s).etree,
737        (*s).bwork,
738        (*s).iwork,
739        (*s).fwork,
740    ) < 0 as ::std::os::raw::c_int) as ::std::os::raw::c_int;
741}