void amdtest (cholmod_sparse *A) { double Control [AMD_CONTROL], Info [AMD_INFO], alpha ; Int *P, *Cp, *Ci, *Sp, *Si, *Bp, *Bi, *Ep, *Ei, *Fp, *Fi, *Len, *Nv, *Next, *Head, *Elen, *Deg, *Wi, *W, *Flag ; cholmod_sparse *C, *B, *S, *E, *F ; Int i, j, n, nrow, ncol, ok, cnz, bnz, p, trial, sorted ; /* ---------------------------------------------------------------------- */ /* get inputs */ /* ---------------------------------------------------------------------- */ printf ("\nAMD test\n") ; if (A == NULL) { return ; } if (A->stype) { B = CHOLMOD(copy) (A, 0, 0, cm) ; } else { B = CHOLMOD(aat) (A, NULL, 0, 0, cm) ; } if (A->nrow != A->ncol) { F = CHOLMOD(copy_sparse) (B, cm) ; OK (F->nrow == F->ncol) ; CHOLMOD(sort) (F, cm) ; } else { /* A is square and unsymmetric, and may have entries in A+A' that * are not in A */ F = CHOLMOD(copy_sparse) (A, cm) ; CHOLMOD(sort) (F, cm) ; } C = CHOLMOD(copy_sparse) (B, cm) ; nrow = C->nrow ; ncol = C->ncol ; n = nrow ; OK (nrow == ncol) ; Cp = C->p ; Ci = C->i ; Bp = B->p ; Bi = B->i ; /* ---------------------------------------------------------------------- */ /* S = sorted form of B, using AMD_preprocess */ /* ---------------------------------------------------------------------- */ cnz = CHOLMOD(nnz) (C, cm) ; S = CHOLMOD(allocate_sparse) (n, n, cnz, TRUE, TRUE, 0, CHOLMOD_PATTERN, cm); Sp = S->p ; Si = S->i ; W = CHOLMOD(malloc) (n, sizeof (Int), cm) ; Flag = CHOLMOD(malloc) (n, sizeof (Int), cm) ; AMD_preprocess (n, Bp, Bi, Sp, Si, W, Flag) ; /* ---------------------------------------------------------------------- */ /* allocate workspace for amd */ /* ---------------------------------------------------------------------- */ P = CHOLMOD(malloc) (n+1, sizeof (Int), cm) ; Len = CHOLMOD(malloc) (n, sizeof (Int), cm) ; Nv = CHOLMOD(malloc) (n, sizeof (Int), cm) ; Next = CHOLMOD(malloc) (n, sizeof (Int), cm) ; Head = CHOLMOD(malloc) (n+1, sizeof (Int), cm) ; Elen = CHOLMOD(malloc) (n, sizeof (Int), cm) ; Deg = CHOLMOD(malloc) (n, sizeof (Int), cm) ; Wi = CHOLMOD(malloc) (n, sizeof (Int), cm) ; /* ---------------------------------------------------------------------- */ for (sorted = 0 ; sorted <= 1 ; sorted++) { if (sorted) CHOLMOD(sort) (C, cm) ; Cp = C->p ; Ci = C->i ; /* ------------------------------------------------------------------ */ /* order C with AMD_order */ /* ------------------------------------------------------------------ */ AMD_defaults (Control) ; AMD_defaults (NULL) ; AMD_control (Control) ; AMD_control (NULL) ; AMD_info (NULL) ; ok = AMD_order (n, Cp, Ci, P, Control, Info) ; printf ("amd return value: "ID"\n", ok) ; AMD_info (Info) ; OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ; OK (CHOLMOD(print_perm) (P, n, n, "AMD permutation", cm)) ; /* no dense rows/cols */ alpha = Control [AMD_DENSE] ; Control [AMD_DENSE] = -1 ; AMD_control (Control) ; ok = AMD_order (n, Cp, Ci, P, Control, Info) ; printf ("amd return value: "ID"\n", ok) ; AMD_info (Info) ; OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ; OK (CHOLMOD(print_perm) (P, n, n, "AMD permutation (alpha=-1)", cm)) ; /* many dense rows/cols */ Control [AMD_DENSE] = 0 ; AMD_control (Control) ; ok = AMD_order (n, Cp, Ci, P, Control, Info) ; printf ("amd return value: "ID"\n", ok) ; AMD_info (Info) ; OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ; OK (CHOLMOD(print_perm) (P, n, n, "AMD permutation (alpha=0)", cm)) ; Control [AMD_DENSE] = alpha ; /* no aggressive absorption */ Control [AMD_AGGRESSIVE] = FALSE ; AMD_control (Control) ; ok = AMD_order (n, Cp, Ci, P, Control, Info) ; printf ("amd return value: "ID"\n", ok) ; AMD_info (Info) ; OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ; OK (CHOLMOD(print_perm) (P, n, n, "AMD permutation (no agg) ", cm)) ; Control [AMD_AGGRESSIVE] = TRUE ; /* ------------------------------------------------------------------ */ /* order F with AMD_order */ /* ------------------------------------------------------------------ */ Fp = F->p ; Fi = F->i ; ok = AMD_order (n, Fp, Fi, P, Control, Info) ; printf ("amd return value: "ID"\n", ok) ; AMD_info (Info) ; OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ; OK (CHOLMOD(print_perm) (P, n, n, "F: AMD permutation", cm)) ; /* ------------------------------------------------------------------ */ /* order S with AMD_order */ /* ------------------------------------------------------------------ */ ok = AMD_order (n, Sp, Si, P, Control, Info) ; printf ("amd return value: "ID"\n", ok) ; AMD_info (Info) ; OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ; OK (CHOLMOD(print_perm) (P, n, n, "AMD permutation", cm)) ; /* ------------------------------------------------------------------ */ /* order E with AMD_2, which destroys its contents */ /* ------------------------------------------------------------------ */ E = CHOLMOD(copy) (B, 0, -1, cm) ; /* remove diagonal entries */ bnz = CHOLMOD(nnz) (E, cm) ; /* add the bare minimum extra space to E */ ok = CHOLMOD(reallocate_sparse) (bnz + n, E, cm) ; OK (ok) ; Ep = E->p ; Ei = E->i ; for (j = 0 ; j < n ; j++) { Len [j] = Ep [j+1] - Ep [j] ; } printf ("calling AMD_2:\n") ; if (n > 0) { AMD_2 (n, Ep, Ei, Len, E->nzmax, Ep [n], Nv, Next, P, Head, Elen, Deg, Wi, Control, Info) ; AMD_info (Info) ; OK (CHOLMOD(print_perm) (P, n, n, "AMD2 permutation", cm)) ; } /* ------------------------------------------------------------------ */ /* error tests */ /* ------------------------------------------------------------------ */ ok = AMD_order (n, Cp, Ci, P, Control, Info) ; OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ; ok = AMD_order (-1, Cp, Ci, P, Control, Info) ; OK (ok == AMD_INVALID); ok = AMD_order (0, Cp, Ci, P, Control, Info) ; OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ; ok = AMD_order (n, NULL, Ci, P, Control, Info) ; OK (ok == AMD_INVALID); ok = AMD_order (n, Cp, NULL, P, Control, Info) ; OK (ok == AMD_INVALID); ok = AMD_order (n, Cp, Ci, NULL, Control, Info) ; OK (ok == AMD_INVALID); if (n > 0) { printf ("AMD error tests:\n") ; p = Cp [n] ; Cp [n] = -1 ; ok = AMD_order (n, Cp, Ci, P, Control, Info) ; OK (ok == AMD_INVALID) ; if (Size_max/2 == Int_max) { Cp [n] = Int_max ; ok = AMD_order (n, Cp, Ci, P, Control, Info) ; printf ("AMD status is "ID"\n", ok) ; OK (ok == AMD_OUT_OF_MEMORY) ; } Cp [n] = p ; ok = AMD_order (n, Cp, Ci, P, Control, Info) ; OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ; if (Cp [n] > 0) { printf ("Mangle column zero:\n") ; i = Ci [0] ; Ci [0] = -1 ; ok = AMD_order (n, Cp, Ci, P, Control, Info) ; AMD_info (Info) ; OK (ok == AMD_INVALID) ; Ci [0] = i ; } } ok = AMD_valid (n, n, Sp, Si) ; OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ; ok = AMD_valid (-1, n, Sp, Si) ; OK (ok == AMD_INVALID) ; ok = AMD_valid (n, -1, Sp, Si) ; OK (ok == AMD_INVALID) ; ok = AMD_valid (n, n, NULL, Si) ; OK (ok == AMD_INVALID) ; ok = AMD_valid (n, n, Sp, NULL) ; OK (ok == AMD_INVALID) ; if (n > 0 && Sp [n] > 0) { p = Sp [n] ; Sp [n] = -1 ; ok = AMD_valid (n, n, Sp, Si) ; OK (ok == AMD_INVALID) ; Sp [n] = p ; p = Sp [0] ; Sp [0] = -1 ; ok = AMD_valid (n, n, Sp, Si) ; OK (ok == AMD_INVALID) ; Sp [0] = p ; p = Sp [1] ; Sp [1] = -1 ; ok = AMD_valid (n, n, Sp, Si) ; OK (ok == AMD_INVALID) ; Sp [1] = p ; i = Si [0] ; Si [0] = -1 ; ok = AMD_valid (n, n, Sp, Si) ; OK (ok == AMD_INVALID) ; Si [0] = i ; } ok = AMD_valid (n, n, Sp, Si) ; OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ; AMD_preprocess (n, Bp, Bi, Sp, Si, W, Flag) ; ok = AMD_valid (n, n, Sp, Si) ; OK (ok == AMD_OK) ; if (n > 0 && Bp [n] > 0) { p = Bp [n] ; Bp [n] = -1 ; ok = AMD_valid (n, n, Bp, Bi) ; OK (ok == AMD_INVALID) ; Bp [n] = p ; p = Bp [1] ; Bp [1] = -1 ; ok = AMD_valid (n, n, Bp, Bi) ; OK (ok == AMD_INVALID) ; Bp [1] = p ; i = Bi [0] ; Bi [0] = -1 ; ok = AMD_valid (n, n, Bp, Bi) ; OK (ok == AMD_INVALID) ; Bi [0] = i ; } AMD_preprocess (n, Bp, Bi, Sp, Si, W, Flag) ; Info [AMD_STATUS] = 777 ; AMD_info (Info) ; /* ------------------------------------------------------------------ */ /* memory tests */ /* ------------------------------------------------------------------ */ if (n > 0) { amd_malloc = cm->malloc_memory ; amd_free = cm->free_memory ; ok = AMD_order (n, Cp, Ci, P, Control, Info) ; OK (sorted ? (ok == AMD_OK) : (ok >= AMD_OK)) ; test_memory_handler ( ) ; amd_malloc = cm->malloc_memory ; amd_free = cm->free_memory ; for (trial = 0 ; trial < 6 ; trial++) { my_tries = trial ; printf ("AMD memory trial "ID"\n", trial) ; ok = AMD_order (n, Cp, Ci, P, Control, Info) ; AMD_info (Info) ; OK (ok == AMD_OUT_OF_MEMORY || (sorted ? (ok == AMD_OK) : (ok >= AMD_OK))) ; } normal_memory_handler ( ) ; OK (CHOLMOD(print_perm) (P, n, n, "AMD2 permutation", cm)) ; amd_malloc = cm->malloc_memory ; amd_free = cm->free_memory ; } CHOLMOD(free_sparse) (&E, cm) ; } /* ---------------------------------------------------------------------- */ /* free everything */ /* ---------------------------------------------------------------------- */ CHOLMOD(free) (n, sizeof (Int), Len, cm) ; CHOLMOD(free) (n, sizeof (Int), Nv, cm) ; CHOLMOD(free) (n, sizeof (Int), Next, cm) ; CHOLMOD(free) (n+1, sizeof (Int), Head, cm) ; CHOLMOD(free) (n, sizeof (Int), Elen, cm) ; CHOLMOD(free) (n, sizeof (Int), Deg, cm) ; CHOLMOD(free) (n, sizeof (Int), Wi, cm) ; CHOLMOD(free) (n+1, sizeof (Int), P, cm) ; CHOLMOD(free) (n, sizeof (Int), W, cm) ; CHOLMOD(free) (n, sizeof (Int), Flag, cm) ; CHOLMOD(free_sparse) (&S, cm) ; CHOLMOD(free_sparse) (&B, cm) ; CHOLMOD(free_sparse) (&C, cm) ; CHOLMOD(free_sparse) (&F, cm) ; }
/* * Sets up all data structures needed. * Replace by codegen */ pwork* ECOS_setup(idxint n, idxint m, idxint p, idxint l, idxint ncones, idxint* q, pfloat* Gpr, idxint* Gjc, idxint* Gir, pfloat* Apr, idxint* Ajc, idxint* Air, pfloat* c, pfloat* h, pfloat* b) { idxint i, j, k, cidx, conesize, lnz, amd_result, nK, *Ljc, *Lir, *P, *Pinv, *Sign; pwork* mywork; double Control [AMD_CONTROL], Info [AMD_INFO]; pfloat rx, ry, rz, *Lpr; spmat *At, *Gt, *KU; #if PROFILING > 0 timer tsetup; #endif #if PROFILING > 1 timer tcreatekkt; timer tmattranspose; timer tordering; #endif #if PROFILING > 0 tic(&tsetup); #endif #if PRINTLEVEL > 2 PRINTTEXT("\n"); PRINTTEXT(" *******************************************************************************\n"); PRINTTEXT(" * ECOS: Embedded Conic Solver - Sparse Interior Point method for SOCPs *\n"); PRINTTEXT(" * *\n"); PRINTTEXT(" * NOTE: The solver is based on L. Vandenberghe's 'The CVXOPT linear and quad- *\n"); PRINTTEXT(" * ratic cone program solvers', March 20, 2010. Available online: *\n"); PRINTTEXT(" * [http://abel.ee.ucla.edu/cvxopt/documentation/coneprog.pdf] *\n"); PRINTTEXT(" * *\n"); PRINTTEXT(" * This code uses T.A. Davis' sparse LDL package and AMD code. *\n"); PRINTTEXT(" * [http://www.cise.ufl.edu/research/sparse] *\n"); PRINTTEXT(" * *\n"); PRINTTEXT(" * Written during a summer visit at Stanford University with S. Boyd. *\n"); PRINTTEXT(" * *\n"); PRINTTEXT(" * (C) Alexander Domahidi, Automatic Control Laboratory, ETH Zurich, 2012-13. *\n"); PRINTTEXT(" * Email: [email protected] *\n"); PRINTTEXT(" *******************************************************************************\n"); PRINTTEXT("\n\n"); PRINTTEXT("PROBLEM SUMMARY:\n"); PRINTTEXT(" Primal variables (n): %d\n", (int)n); PRINTTEXT("Equality constraints (p): %d\n", (int)p); PRINTTEXT(" Conic variables (m): %d\n", (int)m); PRINTTEXT("- - - - - - - - - - - - - - -\n"); PRINTTEXT(" Size of LP cone: %d\n", (int)l); PRINTTEXT(" Number of SOCs: %d\n", (int)ncones); for( i=0; i<ncones; i++ ){ PRINTTEXT(" Size of SOC #%02d: %d\n", (int)(i+1), (int)q[i]); } #endif /* get work data structure */ mywork = (pwork *)MALLOC(sizeof(pwork)); #if PRINTLEVEL > 2 PRINTTEXT("Memory allocated for WORK struct\n"); #endif /* dimensions */ mywork->n = n; mywork->m = m; mywork->p = p; mywork->D = l + ncones; #if PRINTLEVEL > 2 PRINTTEXT("Set dimensions\n"); #endif /* variables */ mywork->x = (pfloat *)MALLOC(n*sizeof(pfloat)); mywork->y = (pfloat *)MALLOC(p*sizeof(pfloat)); mywork->z = (pfloat *)MALLOC(m*sizeof(pfloat)); mywork->s = (pfloat *)MALLOC(m*sizeof(pfloat)); mywork->lambda = (pfloat *)MALLOC(m*sizeof(pfloat)); mywork->dsaff_by_W = (pfloat *)MALLOC(m*sizeof(pfloat)); mywork->dsaff = (pfloat *)MALLOC(m*sizeof(pfloat)); mywork->dzaff = (pfloat *)MALLOC(m*sizeof(pfloat)); mywork->saff = (pfloat *)MALLOC(m*sizeof(pfloat)); mywork->zaff = (pfloat *)MALLOC(m*sizeof(pfloat)); mywork->W_times_dzaff = (pfloat *)MALLOC(m*sizeof(pfloat)); #if PRINTLEVEL > 2 PRINTTEXT("Memory allocated for variables\n"); #endif /* best iterates so far */ mywork->best_x = (pfloat *)MALLOC(n*sizeof(pfloat)); mywork->best_y = (pfloat *)MALLOC(p*sizeof(pfloat)); mywork->best_z = (pfloat *)MALLOC(m*sizeof(pfloat)); mywork->best_s = (pfloat *)MALLOC(m*sizeof(pfloat)); mywork->best_info = (stats *)MALLOC(sizeof(stats)); /* cones */ mywork->C = (cone *)MALLOC(sizeof(cone)); #if PRINTLEVEL > 2 PRINTTEXT("Memory allocated for cone struct\n"); #endif /* LP cone */ mywork->C->lpc = (lpcone *)MALLOC(sizeof(lpcone)); mywork->C->lpc->p = l; if( l > 0 ){ mywork->C->lpc->w = (pfloat *)MALLOC(l*sizeof(pfloat)); mywork->C->lpc->v = (pfloat *)MALLOC(l*sizeof(pfloat)); mywork->C->lpc->kkt_idx = (idxint *)MALLOC(l*sizeof(idxint)); #if PRINTLEVEL > 2 PRINTTEXT("Memory allocated for LP cone\n"); #endif } else { mywork->C->lpc->w = NULL; mywork->C->lpc->v = NULL; mywork->C->lpc->kkt_idx = NULL; #if PRINTLEVEL > 2 PRINTTEXT("No LP cone present, pointers filled with NULL\n"); #endif } /* Second-order cones */ mywork->C->soc = (socone *)MALLOC(ncones*sizeof(socone)); mywork->C->nsoc = ncones; cidx = 0; for( i=0; i<ncones; i++ ){ conesize = (idxint)q[i]; mywork->C->soc[i].p = conesize; mywork->C->soc[i].a = 0; mywork->C->soc[i].eta = 0; mywork->C->soc[i].q = (pfloat *)MALLOC((conesize-1)*sizeof(pfloat)); mywork->C->soc[i].skbar = (pfloat *)MALLOC((conesize)*sizeof(pfloat)); mywork->C->soc[i].zkbar = (pfloat *)MALLOC((conesize)*sizeof(pfloat)); #if CONEMODE == 0 mywork->C->soc[i].Didx = (idxint *)MALLOC((conesize)*sizeof(idxint)); #endif #if CONEMODE > 0 mywork->C->soc[i].colstart = (idxint *)MALLOC((conesize)*sizeof(idxint)); #endif cidx += conesize; } #if PRINTLEVEL > 2 PRINTTEXT("Memory allocated for second-order cones\n"); #endif /* info struct */ mywork->info = (stats *)MALLOC(sizeof(stats)); #if PROFILING > 1 mywork->info->tfactor = 0; mywork->info->tkktsolve = 0; mywork->info->tfactor_t1 = 0; mywork->info->tfactor_t2 = 0; #endif #if PRINTLEVEL > 2 PRINTTEXT("Memory allocated for info struct\n"); #endif #if defined EQUILIBRATE && EQUILIBRATE > 0 /* equilibration vector */ mywork->xequil = (pfloat *)MALLOC(n*sizeof(pfloat)); mywork->Aequil = (pfloat *)MALLOC(p*sizeof(pfloat)); mywork->Gequil = (pfloat *)MALLOC(m*sizeof(pfloat)); #if PRINTLEVEL > 2 PRINTTEXT("Memory allocated for equilibration vectors\n"); #endif #endif /* settings */ mywork->stgs = (settings *)MALLOC(sizeof(settings)); mywork->stgs->maxit = MAXIT; mywork->stgs->gamma = GAMMA; mywork->stgs->delta = DELTA; mywork->stgs->eps = EPS; mywork->stgs->nitref = NITREF; mywork->stgs->abstol = ABSTOL; mywork->stgs->feastol = FEASTOL; mywork->stgs->reltol = RELTOL; mywork->stgs->abstol_inacc = ATOL_INACC; mywork->stgs->feastol_inacc = FTOL_INACC; mywork->stgs->reltol_inacc = RTOL_INACC; mywork->stgs->verbose = VERBOSE; #if PRINTLEVEL > 2 PRINTTEXT("Written settings\n"); #endif mywork->c = c; mywork->h = h; mywork->b = b; #if PRINTLEVEL > 2 PRINTTEXT("Hung pointers for c, h and b into WORK struct\n"); #endif /* Store problem data */ if(Apr && Ajc && Air) { mywork->A = createSparseMatrix(p, n, Ajc[n], Ajc, Air, Apr); } else { mywork->A = NULL; } if (Gpr && Gjc && Gir) { mywork->G = createSparseMatrix(m, n, Gjc[n], Gjc, Gir, Gpr); } else { /* create an empty sparse matrix */ mywork->G = createSparseMatrix(m, n, 0, Gjc, Gir, Gpr); } #if defined EQUILIBRATE && EQUILIBRATE > 0 set_equilibration(mywork); #if PRINTLEVEL > 2 PRINTTEXT("Done equilibrating\n"); #endif #endif #if PROFILING > 1 mywork->info->ttranspose = 0; tic(&tmattranspose); #endif if(mywork->A) At = transposeSparseMatrix(mywork->A); else At = NULL; #if PROFILING > 1 mywork->info->ttranspose += toc(&tmattranspose); #endif #if PRINTLEVEL > 2 PRINTTEXT("Transposed A\n"); #endif #if PROFILING > 1 tic(&tmattranspose); #endif Gt = transposeSparseMatrix(mywork->G); #if PROFILING > 1 mywork->info->ttranspose += toc(&tmattranspose); #endif #if PRINTLEVEL > 2 PRINTTEXT("Transposed G\n"); #endif /* set up KKT system */ #if PROFILING > 1 tic(&tcreatekkt); #endif createKKT_U(Gt, At, mywork->C, &Sign, &KU); #if PROFILING > 1 mywork->info->tkktcreate = toc(&tcreatekkt); #endif #if PRINTLEVEL > 2 PRINTTEXT("Created upper part of KKT matrix K\n"); #endif /* * Set up KKT system related data * (L comes later after symbolic factorization) */ nK = KU->n; #if DEBUG > 0 dumpSparseMatrix(KU, "KU0.txt"); #endif #if PRINTLEVEL > 2 PRINTTEXT("Dimension of KKT matrix: %d\n", (int)nK); PRINTTEXT("Non-zeros in KKT matrix: %d\n", (int)KU->nnz); #endif /* allocate memory in KKT system */ mywork->KKT = (kkt *)MALLOC(sizeof(kkt)); mywork->KKT->D = (pfloat *)MALLOC(nK*sizeof(pfloat)); mywork->KKT->Parent = (idxint *)MALLOC(nK*sizeof(idxint)); mywork->KKT->Pinv = (idxint *)MALLOC(nK*sizeof(idxint)); mywork->KKT->work1 = (pfloat *)MALLOC(nK*sizeof(pfloat)); mywork->KKT->work2 = (pfloat *)MALLOC(nK*sizeof(pfloat)); mywork->KKT->work3 = (pfloat *)MALLOC(nK*sizeof(pfloat)); mywork->KKT->work4 = (pfloat *)MALLOC(nK*sizeof(pfloat)); mywork->KKT->work5 = (pfloat *)MALLOC(nK*sizeof(pfloat)); mywork->KKT->work6 = (pfloat *)MALLOC(nK*sizeof(pfloat)); mywork->KKT->Flag = (idxint *)MALLOC(nK*sizeof(idxint)); mywork->KKT->Pattern = (idxint *)MALLOC(nK*sizeof(idxint)); mywork->KKT->Lnz = (idxint *)MALLOC(nK*sizeof(idxint)); mywork->KKT->RHS1 = (pfloat *)MALLOC(nK*sizeof(pfloat)); mywork->KKT->RHS2 = (pfloat *)MALLOC(nK*sizeof(pfloat)); mywork->KKT->dx1 = (pfloat *)MALLOC(mywork->n*sizeof(pfloat)); mywork->KKT->dx2 = (pfloat *)MALLOC(mywork->n*sizeof(pfloat)); mywork->KKT->dy1 = (pfloat *)MALLOC(mywork->p*sizeof(pfloat)); mywork->KKT->dy2 = (pfloat *)MALLOC(mywork->p*sizeof(pfloat)); mywork->KKT->dz1 = (pfloat *)MALLOC(mywork->m*sizeof(pfloat)); mywork->KKT->dz2 = (pfloat *)MALLOC(mywork->m*sizeof(pfloat)); mywork->KKT->Sign = (idxint *)MALLOC(nK*sizeof(idxint)); mywork->KKT->PKPt = newSparseMatrix(nK, nK, KU->nnz); mywork->KKT->PK = (idxint *)MALLOC(KU->nnz*sizeof(idxint)); #if PRINTLEVEL > 2 PRINTTEXT("Created memory for KKT-related data\n"); #endif /* calculate ordering of KKT matrix using AMD */ P = (idxint *)MALLOC(nK*sizeof(idxint)); #if PROFILING > 1 tic(&tordering); #endif AMD_defaults(Control); amd_result = AMD_order(nK, KU->jc, KU->ir, P, Control, Info); #if PROFILING > 1 mywork->info->torder = toc(&tordering); #endif if( amd_result == AMD_OK ){ #if PRINTLEVEL > 2 PRINTTEXT("AMD ordering successfully computed.\n"); AMD_info(Info); #endif } else { #if PRINTLEVEL > 2 PRINTTEXT("Problem in AMD ordering, exiting.\n"); AMD_info(Info); #endif return NULL; } /* calculate inverse permutation and permutation mapping of KKT matrix */ pinv(nK, P, mywork->KKT->Pinv); Pinv = mywork->KKT->Pinv; #if DEBUG > 0 dumpDenseMatrix_i(P, nK, 1, "P.txt"); dumpDenseMatrix_i(mywork->KKT->Pinv, nK, 1, "PINV.txt"); #endif permuteSparseSymmetricMatrix(KU, mywork->KKT->Pinv, mywork->KKT->PKPt, mywork->KKT->PK); /* permute sign vector */ for( i=0; i<nK; i++ ){ mywork->KKT->Sign[Pinv[i]] = Sign[i]; } #if PRINTLEVEL > 3 PRINTTEXT("P = ["); for( i=0; i<nK; i++ ){ PRINTTEXT("%d ", (int)P[i]); } PRINTTEXT("];\n"); PRINTTEXT("Pinv = ["); for( i=0; i<nK; i++ ){ PRINTTEXT("%d ", (int)Pinv[i]); } PRINTTEXT("];\n"); PRINTTEXT("Sign = ["); for( i=0; i<nK; i++ ){ PRINTTEXT("%+d ", (int)Sign[i]); } PRINTTEXT("];\n"); PRINTTEXT("SignP = ["); for( i=0; i<nK; i++ ){ PRINTTEXT("%+d ", (int)mywork->KKT->Sign[i]); } PRINTTEXT("];\n"); #endif /* symbolic factorization */ Ljc = (idxint *)MALLOC((nK+1)*sizeof(idxint)); #if PRINTLEVEL > 2 PRINTTEXT("Allocated memory for cholesky factor L\n"); #endif LDL_symbolic2( mywork->KKT->PKPt->n, /* A and L are n-by-n, where n >= 0 */ mywork->KKT->PKPt->jc, /* input of size n+1, not modified */ mywork->KKT->PKPt->ir, /* input of size nz=Ap[n], not modified */ Ljc, /* output of size n+1, not defined on input */ mywork->KKT->Parent, /* output of size n, not defined on input */ mywork->KKT->Lnz, /* output of size n, not defined on input */ mywork->KKT->Flag /* workspace of size n, not defn. on input or output */ ); /* assign memory for L */ lnz = Ljc[nK]; #if PRINTLEVEL > 2 PRINTTEXT("Nonzeros in L, excluding diagonal: %d\n", (int)lnz) ; #endif Lir = (idxint *)MALLOC(lnz*sizeof(idxint)); Lpr = (pfloat *)MALLOC(lnz*sizeof(pfloat)); mywork->KKT->L = createSparseMatrix(nK, nK, lnz, Ljc, Lir, Lpr); #if PRINTLEVEL > 2 PRINTTEXT("Created Cholesky factor of K in KKT struct\n"); #endif /* permute KKT matrix - we work on this one from now on */ permuteSparseSymmetricMatrix(KU, mywork->KKT->Pinv, mywork->KKT->PKPt, NULL); #if DEBUG > 0 dumpSparseMatrix(mywork->KKT->PKPt, "PKPt.txt"); #endif #if CONEMODE > 0 /* zero any off-diagonal elements in (permuted) scalings in KKT matrix */ for (i=0; i<mywork->C->nsoc; i++) { for (j=1; j<mywork->C->soc[i].p; j++) { for (k=0; k<j; k++) { mywork->KKT->PKPt->pr[mywork->KKT->PK[mywork->C->soc[i].colstart[j]+k]] = 0; } } } #endif #if DEBUG > 0 dumpSparseMatrix(mywork->KKT->PKPt, "PKPt0.txt"); #endif /* set up RHSp for initialization */ k = 0; j = 0; for( i=0; i<n; i++ ){ mywork->KKT->RHS1[Pinv[k++]] = 0; } for( i=0; i<p; i++ ){ mywork->KKT->RHS1[Pinv[k++]] = b[i]; } for( i=0; i<l; i++ ){ mywork->KKT->RHS1[Pinv[k++]] = h[i]; j++; } for( l=0; l<ncones; l++ ){ for( i=0; i < mywork->C->soc[l].p; i++ ){ mywork->KKT->RHS1[Pinv[k++]] = h[j++]; } #if CONEMODE == 0 mywork->KKT->RHS1[Pinv[k++]] = 0; mywork->KKT->RHS1[Pinv[k++]] = 0; #endif } #if PRINTLEVEL > 2 PRINTTEXT("Written %d entries of RHS1\n", (int)k); #endif /* set up RHSd for initialization */ for( i=0; i<n; i++ ){ mywork->KKT->RHS2[Pinv[i]] = -c[i]; } for( i=n; i<nK; i++ ){ mywork->KKT->RHS2[Pinv[i]] = 0; } /* get scalings of problem data */ rx = norm2(c, n); mywork->resx0 = MAX(1, rx); ry = norm2(b, p); mywork->resy0 = MAX(1, ry); rz = norm2(h, m); mywork->resz0 = MAX(1, rz); /* get memory for residuals */ mywork->rx = (pfloat *)MALLOC(n*sizeof(pfloat)); mywork->ry = (pfloat *)MALLOC(p*sizeof(pfloat)); mywork->rz = (pfloat *)MALLOC(m*sizeof(pfloat)); /* clean up */ mywork->KKT->P = P; FREE(Sign); if(At) freeSparseMatrix(At); freeSparseMatrix(Gt); freeSparseMatrix(KU); #if PROFILING > 0 mywork->info->tsetup = toc(&tsetup); #endif return mywork; }