Пример #1
0
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) ;
}
Пример #2
0
/*
 * 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;
}