#include "camd_internal.h"
GLOBAL Int CAMD_order
(
Int n,
const Int Ap [ ],
const Int Ai [ ],
Int P [ ],
double Control [ ],
double Info [ ],
const Int C [ ]
)
{
Int *Len, *S, nz, i, *Pinv, info, status, *Rp, *Ri, *Cp, *Ci, ok ;
size_t nzaat, slen ;
double mem = 0 ;
#ifndef NDEBUG
CAMD_debug_init ("camd") ;
#endif
info = Info != (double *) NULL ;
if (info)
{
for (i = 0 ; i < CAMD_INFO ; i++)
{
Info [i] = EMPTY ;
}
Info [CAMD_N] = n ;
Info [CAMD_STATUS] = CAMD_OK ;
}
if (Ai == (Int *) NULL || Ap == (Int *) NULL || P == (Int *) NULL || n < 0)
{
if (info) Info [CAMD_STATUS] = CAMD_INVALID ;
return (CAMD_INVALID) ;
}
if (n == 0)
{
return (CAMD_OK) ;
}
nz = Ap [n] ;
if (info)
{
Info [CAMD_NZ] = nz ;
}
if (nz < 0)
{
if (info) Info [CAMD_STATUS] = CAMD_INVALID ;
return (CAMD_INVALID) ;
}
if ((size_t) n >= SIZE_T_MAX / sizeof (Int)
|| (size_t) nz >= SIZE_T_MAX / sizeof (Int))
{
if (info) Info [CAMD_STATUS] = CAMD_OUT_OF_MEMORY ;
return (CAMD_OUT_OF_MEMORY) ;
}
status = CAMD_valid (n, n, Ap, Ai) ;
if (status == CAMD_INVALID)
{
if (info) Info [CAMD_STATUS] = CAMD_INVALID ;
return (CAMD_INVALID) ;
}
Len = SuiteSparse_malloc (n, sizeof (Int)) ;
Pinv = SuiteSparse_malloc (n, sizeof (Int)) ;
mem += n ;
mem += n ;
if (!Len || !Pinv)
{
SuiteSparse_free (Len) ;
SuiteSparse_free (Pinv) ;
if (info) Info [CAMD_STATUS] = CAMD_OUT_OF_MEMORY ;
return (CAMD_OUT_OF_MEMORY) ;
}
if (status == CAMD_OK_BUT_JUMBLED)
{
CAMD_DEBUG1 (("Matrix is jumbled\n")) ;
Rp = SuiteSparse_malloc (n+1, sizeof (Int)) ;
Ri = SuiteSparse_malloc (nz, sizeof (Int)) ;
mem += (n+1) ;
mem += MAX (nz,1) ;
if (!Rp || !Ri)
{
SuiteSparse_free (Rp) ;
SuiteSparse_free (Ri) ;
SuiteSparse_free (Len) ;
SuiteSparse_free (Pinv) ;
if (info) Info [CAMD_STATUS] = CAMD_OUT_OF_MEMORY ;
return (CAMD_OUT_OF_MEMORY) ;
}
CAMD_preprocess (n, Ap, Ai, Rp, Ri, Len, Pinv) ;
Cp = Rp ;
Ci = Ri ;
}
else
{
Rp = NULL ;
Ri = NULL ;
Cp = (Int *) Ap ;
Ci = (Int *) Ai ;
}
nzaat = CAMD_aat (n, Cp, Ci, Len, P, Info) ;
CAMD_DEBUG1 (("nzaat: %g\n", (double) nzaat)) ;
ASSERT ((MAX (nz-n, 0) <= nzaat) && (nzaat <= 2 * (size_t) nz)) ;
S = NULL ;
slen = nzaat ;
ok = ((slen + nzaat/5) >= slen) ;
slen += nzaat/5 ;
for (i = 0 ; ok && i < 8 ; i++)
{
ok = ((slen + n+1) > slen) ;
slen += (n+1) ;
}
mem += slen ;
ok = ok && (slen < SIZE_T_MAX / sizeof (Int)) ;
ok = ok && (slen < Int_MAX) ;
if (ok)
{
S = SuiteSparse_malloc (slen, sizeof (Int)) ;
}
CAMD_DEBUG1 (("slen %g\n", (double) slen)) ;
if (!S)
{
SuiteSparse_free (Rp) ;
SuiteSparse_free (Ri) ;
SuiteSparse_free (Len) ;
SuiteSparse_free (Pinv) ;
if (info) Info [CAMD_STATUS] = CAMD_OUT_OF_MEMORY ;
return (CAMD_OUT_OF_MEMORY) ;
}
if (info)
{
Info [CAMD_MEMORY] = mem * sizeof (Int) ;
}
CAMD_1 (n, Cp, Ci, P, Pinv, Len, slen, S, Control, Info, C) ;
SuiteSparse_free (Rp) ;
SuiteSparse_free (Ri) ;
SuiteSparse_free (Len) ;
SuiteSparse_free (Pinv) ;
SuiteSparse_free (S) ;
if (info) Info [CAMD_STATUS] = status ;
return (status) ;
}