// -----------------------------------------------------------------------------
// CMoveObject::GetParametersL
// Retrieve the parameters of the request
// -----------------------------------------------------------------------------
//
void CMoveObject::GetParametersL()
    {
    PRINT( _L( "MM MTP => CMoveObject::GetParametersL" ) );

    __ASSERT_DEBUG( iRequestChecker, Panic( EMmMTPDpRequestCheckNull ) );

    TUint32 objectHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter1 );
    iStorageId = Request().Uint32( TMTPTypeRequest::ERequestParameter2 );
    iNewParentHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter3 );
    PRINT3( _L( "MM MTP <> objectHandle = 0x%x, iStorageId = 0x%x, iNewParentHandle = 0x%x" ),
        objectHandle,
        iStorageId,
        iNewParentHandle );

    // not taking owernship
    iObjectInfo = iRequestChecker->GetObjectInfo( objectHandle );
    __ASSERT_DEBUG( iObjectInfo, Panic( EMmMTPDpObjectNull ) );

    if ( iNewParentHandle == KMTPHandleNone )
        {
        SetDefaultParentObjectL();
        }
    else
        {
        CMTPObjectMetaData* parentObject = iRequestChecker->GetObjectInfo( iNewParentHandle );
        __ASSERT_DEBUG( parentObject, Panic( EMmMTPDpObjectNull ) );

        delete iDest;
        iDest = NULL;
        iDest = parentObject->DesC( CMTPObjectMetaData::ESuid ).AllocL();
        PRINT1( _L( "MM MTP <> CMoveObject::GetParametersL iDest = %S" ), iDest );
        }
    PRINT( _L( "MM MTP <= CMoveObject::GetParametersL" ) );
    }
static int L_is_packed (cholmod_factor *L, cholmod_common *Common)
{
    Int j ;
    Int *Lnz = L->nz ;
    Int *Lp = L->p ;
    Int n = L->n ;

    if (L->xtype == CHOLMOD_PATTERN || L->is_super)
    {
	return (TRUE) ;
    }

    if (Lnz == NULL || Lp == NULL)
    {
	return (TRUE) ;
    }

    for (j = 0 ; j < n ; j++)
    {
	PRINT3 (("j: "ID" Lnz "ID" Lp[j+1] "ID" Lp[j] "ID"\n", j, Lnz [j],
		Lp [j+1], Lp [j])) ;
	if (Lnz [j] != (Lp [j+1] - Lp [j]))
	{
	    PRINT2 (("L is not packed\n")) ;
	    return (FALSE) ;
	}
    }
    return (TRUE) ;
}
// -----------------------------------------------------------------------------
// CGetPartialObject::VerifyParametersL
// Verify if the parameter of the request (i.e. offset) is good.
// -----------------------------------------------------------------------------
//
TBool CGetPartialObject::VerifyParametersL()
    {
    PRINT( _L( "MM MTP => CGetPartialObject::VerifyParametersL" ) );

    __ASSERT_DEBUG( iRequestChecker, Panic( EMmMTPDpRequestCheckNull ) );
    TBool result = EFalse;
    iObjectHandle = Request().Uint32( TMTPTypeRequest::ERequestParameter1 );
    iOffset = Request().Uint32( TMTPTypeRequest::ERequestParameter2 );
    iPartialDataLength = Request().Uint32( TMTPTypeRequest::ERequestParameter3 );

    PRINT3( _L( "MM MTP <> CGetPartialObject::VerifyParametersL iObjectHandle = 0x%x, iOffset = 0x%x, iMaxLength = 0x%x " ),
        iObjectHandle,
        iOffset,
        iPartialDataLength );

    //get object info, but do not have the ownship of the object
    CMTPObjectMetaData* objectInfo = iRequestChecker->GetObjectInfo( iObjectHandle );
    __ASSERT_DEBUG( objectInfo, Panic( EMmMTPDpObjectNull ) );

    const TDesC& suid( objectInfo->DesC( CMTPObjectMetaData::ESuid ) );
    PRINT1( _L( "MM MTP <> CGetPartialObject::VerifyParametersL suid = %S" ), &suid );

    TEntry fileEntry;
    User::LeaveIfError( iFramework.Fs().Entry( suid, fileEntry ) );
    if ( iOffset < fileEntry.FileSize() )
        {
        result = ETrue;
        }

    PRINT1( _L( "MM MTP <= CGetPartialObject::VerifyParametersL result = %d" ), result );
    return result;
    }
Exemple #4
0
EnergyToBeat::~EnergyToBeat ()
{
  LOG("EnergyToBeat:");
  PRINT3(m_pos, m_vel, m_acc);
  PRINT(m_norm);
  PRINT2(m_pos_mean, m_pos_variance);
}
Exemple #5
0
static void dump_col
(
    char *w, Int j, Int p1, Int p2, Int *Li, double *Lx, Int n,
    cholmod_common *Common
)
{
    Int p, row, lastrow ;

    if (CHOLMOD(dump) < -1)
    {
	/* no checks if debug level is -2 or less */
	return ;
    }

    PRINT3 (("\n\nDUMP COL==== j = "ID"  %s: p1="ID" p2="ID" \n", j, w, p1,p2));
    lastrow = -1 ;
    for (p = p1 ; p < p2 ; p++)
    {
	PRINT3 (("   "ID": ", p)) ;
	row = Li [p] ;
	PRINT3 ((""ID"  ", Li [p])) ;
	PRINT3 (("%g ", Lx [p])) ;
	PRINT3 (("\n")) ;
	ASSERT (row > lastrow && row < n) ;
	lastrow = row ;
    }
    ASSERT (p1 < p2) ;
    ASSERT (Li [p1] == j) ;
    PRINT3 (("\n")) ;
}
Exemple #6
0
//=========================================================================
// getEMIFSpeed(): return C67 EMIF speed
//=========================================================================
double getEMIFSpeed()
{
    int m,d;
    double g;
    setC6xBase(DDR_PLL_REGS);
    m=PLL_MULT;
    d=PLL_DIV3;    
    d&=0xFF;
    d+=1;
    g= 40.0e6*m/d;
    PRINT3("MULT:%d DIV3:%d EMIF:%d MHz",m,d,(int)g/1e6);
    return g;
}
Exemple #7
0
static void dump_set (Int s, Int **Set_ps1, Int **Set_ps2, Int j, Int n,
	cholmod_common *Common)
{
    Int *p, len, i, ilast ;

    if (CHOLMOD(dump) < -1)
    {
	/* no checks if debug level is -2 or less */
	return ;
    }

    len = Set_ps2 [s] - Set_ps1 [s] ;
    PRINT2 (("Set s: "ID" len: "ID":", s, len)) ;
    ASSERT (len > 0) ;
    ilast = j ;
    for (p = Set_ps1 [s] ; p < Set_ps2 [s] ; p++)
    {
	i = *p ;
	PRINT3 ((" "ID"", i)) ;
	ASSERT (i > ilast && i < n) ;
	ilast = i ;
    }
    PRINT3 (("\n")) ;
}
// -----------------------------------------------------------------------------
// CMmMtpDpMetadataAccessWrapper::RemoveDummyFiles
// Remove all dummy file of which format is "pla" and "alb", and leave the "m3u"
// -----------------------------------------------------------------------------
//
void CMmMtpDpMetadataAccessWrapper::RemoveDummyFiles()
    {
    PRINT( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::RemoveDummyFiles" ) );

    TInt count = iAbstractMediaArray->Count();
    PRINT1( _L( "MM MTP => CMmMtpDpMetadataAccessWrapper::RemoveDummyFiles, count = %d" ), count );
    // Check if playlist file is a dummy file or an imported file
    for ( TInt i = 0; i < count; i++ )
        {
        TPtrC fileName( (*iAbstractMediaArray)[i] );
        PRINT1( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::RemoveDummyFiles, fileName = %S" ), &fileName );
        
        TMTPFormatCode format = MmMtpDpUtility::FormatFromFilename( fileName );
        PRINT1( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::RemoveDummyFiles, format = 0x%x" ), format );
        if ( format == EMTPFormatCodeAbstractAudioAlbum )
            {
            // delete the abstract album if its size is zero
            TEntry entry;
            TInt err = iFs.Entry( fileName, entry );
            if ( err == KErrNone && entry.iSize == 0 )
                {
                TRAP( err, iMmMtpDpMetadataMpxAccess->DeleteObjectL( fileName, EMPXAbstractAlbum ) );
                if( err == KErrNone )
                    {
                    err = iFs.Delete( fileName );
                    }
                }
            PRINT3( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::RemoveDummyFile filename = %S, err %d, entry.iSize = %d" ),
                &fileName, err, entry.iSize );
            }
        else
            {
            TInt err = iFs.Delete( fileName );

            PRINT2( _L( "MM MTP <> CMmMtpDpMetadataAccessWrapper::RemoveDummyFile filename = %S, err %d" ),
                &fileName,
                err );
            }
        }
    PRINT( _L( "MM MTP <= CMmMtpDpMetadataAccessWrapper::RemoveDummyFiles" ) );
    }
// ---------------------------------------------------------------------------
// CMediaMtpDataProvider::GetDefaultStorageIdL
//
// ---------------------------------------------------------------------------
//
TUint32 CMediaMtpDataProvider::GetDefaultStorageIdL() const
    {
    TInt driveNum = -1;
    TInt err = DriveInfo::GetDefaultDrive( DriveInfo::EDefaultMassStorage, driveNum );
    PRINT2( _L( "MM MTP <> GetDefaultDrive, driveNum = %d, err = %d" ), driveNum, err );

    TDriveInfo driveInfo;
    User::LeaveIfError( Framework().Fs().Drive( driveInfo, driveNum ) );
    PRINT3( _L( "driveInfo.iType = 0x%x, driveInfo.iDriveAtt = 0x%x, driveInfo.iMediaAtt = 0x%x" ),
        driveInfo.iType, driveInfo.iDriveAtt, driveInfo.iMediaAtt );
    if( driveInfo.iType == EMediaNotPresent || driveInfo.iType == EMediaUnknown )
        {
        err = DriveInfo::GetDefaultDrive( DriveInfo::EDefaultRemovableMassStorage, driveNum );
        User::LeaveIfError( Framework().Fs().Drive( driveInfo, driveNum ) );
        if( driveInfo.iType == EMediaNotPresent || driveInfo.iType == EMediaUnknown )
            {
            err = DriveInfo::GetDefaultDrive( DriveInfo::EDefaultPhoneMemory, driveNum );
            PRINT( _L( "MM MTP <> Memory card doesn't exist, set PhoneMemory to default" ) );
            }
        }

    return Framework().StorageMgr().FrameworkStorageId( TDriveNumber( driveNum ) );
    }
Exemple #10
0
cholmod_sparse *CHOLMOD(submatrix)
(
    /* ---- input ---- */
    cholmod_sparse *A,	/* matrix to subreference */
    Int *rset,		/* set of row indices, duplicates OK */
    SuiteSparse_long rsize,	/* size of rset, or -1 for ":" */
    Int *cset,		/* set of column indices, duplicates OK */
    SuiteSparse_long csize,	/* size of cset, or -1 for ":" */
    int values,		/* if TRUE compute the numerical values of C */
    int sorted,		/* if TRUE then return C with sorted columns */
    /* --------------- */
    cholmod_common *Common
)
{
    double aij = 0 ;
    double *Ax, *Cx ;
    Int *Ap, *Ai, *Anz, *Ci, *Cp, *Head, *Rlen, *Rnext, *Iwork ;
    cholmod_sparse *C ;
    Int packed, ancol, anrow, cnrow, cncol, nnz, i, j, csorted, ilast, p,
	pend, pdest, ci, cj, head, nr, nc ;
    size_t s ;
    int ok = TRUE ;

    /* ---------------------------------------------------------------------- */
    /* check inputs */
    /* ---------------------------------------------------------------------- */

    RETURN_IF_NULL_COMMON (NULL) ;
    RETURN_IF_NULL (A, NULL) ;
    values = (values && (A->xtype != CHOLMOD_PATTERN)) ;
    RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN,
	    values ? CHOLMOD_REAL : CHOLMOD_ZOMPLEX, NULL) ;
    if (A->stype != 0)
    {
	/* A must be unsymmetric */
	ERROR (CHOLMOD_INVALID, "symmetric upper or lower case not supported") ;
	return (NULL) ;
    }
    Common->status = CHOLMOD_OK ;

    /* ---------------------------------------------------------------------- */
    /* allocate workspace */
    /* ---------------------------------------------------------------------- */

    ancol = A->ncol ;
    anrow = A->nrow ;
    nr = rsize ;
    nc = csize ;
    if (rset == NULL)
    {
	/* nr = 0 denotes rset = [ ], nr < 0 denotes rset = 0:anrow-1 */
	nr = (nr < 0) ? (-1) : 0 ;
    }
    if (cset == NULL)
    {
	/* nr = 0 denotes cset = [ ], nr < 0 denotes cset = 0:ancol-1 */
	nc = (nc < 0) ? (-1) : 0 ;
    }
    cnrow = (nr < 0) ? anrow : nr ;  /* negative rset means rset = 0:anrow-1 */
    cncol = (nc < 0) ? ancol : nc ;  /* negative cset means cset = 0:ancol-1 */

    if (nr < 0 && nc < 0)
    {

	/* ------------------------------------------------------------------ */
	/* C = A (:,:), use cholmod_copy instead */
	/* ------------------------------------------------------------------ */

	/* workspace: Iwork (max (C->nrow,C->ncol)) */
	PRINT1 (("submatrix C = A (:,:)\n")) ;
	C = CHOLMOD(copy) (A, 0, values, Common) ;
	if (Common->status < CHOLMOD_OK)
	{
	    /* out of memory */
	    return (NULL) ;
	}
	return (C) ;
    }
    PRINT1 (("submatrix nr "ID" nc "ID" Cnrow "ID" Cncol "ID""
	    "  Anrow "ID" Ancol "ID"\n", nr, nc, cnrow, cncol, anrow, ancol)) ;

    /* s = MAX3 (anrow+MAX(0,nr), cncol, cnrow) ; */
    s = CHOLMOD(add_size_t) (anrow, MAX (0,nr), &ok) ;
    if (!ok)
    {
	ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
	return (NULL) ;
    }
    s = MAX3 (s, ((size_t) cncol), ((size_t) cnrow)) ;

    CHOLMOD(allocate_work) (anrow, s, 0, Common) ;
    if (Common->status < CHOLMOD_OK)
    {
	/* out of memory */
	return (NULL) ;
    }

    ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ;

    /* ---------------------------------------------------------------------- */
    /* get inputs */
    /* ---------------------------------------------------------------------- */

    Ap  = A->p ;
    Anz = A->nz ;
    Ai  = A->i ;
    Ax  = A->x ;
    packed = A->packed ;

    /* ---------------------------------------------------------------------- */
    /* get workspace */
    /* ---------------------------------------------------------------------- */

    Head  = Common->Head ;	    /* size anrow */
    Iwork = Common->Iwork ;
    Rlen  = Iwork ;		    /* size anrow (i/i/l) */
    Rnext = Iwork + anrow ;	    /* size nr (i/i/l), not used if nr < 0 */

    /* ---------------------------------------------------------------------- */
    /* construct inverse of rset and compute nnz (C) */
    /* ---------------------------------------------------------------------- */

    PRINT1 (("nr "ID" nc "ID"\n", nr, nc)) ;
    PRINT1 (("anrow "ID" ancol "ID"\n", anrow, ancol)) ;
    PRINT1 (("cnrow "ID" cncol "ID"\n", cnrow, cncol)) ;
    DEBUG (for (i = 0 ; i < nr ; i++) PRINT2 (("rset ["ID"] = "ID"\n",
		    i, rset [i])));
    DEBUG (for (i = 0 ; i < nc ; i++) PRINT2 (("cset ["ID"] = "ID"\n",
		    i, cset [i])));

    /* C is sorted if A and rset are sorted, or if C has one row or less */
    csorted = A->sorted || (cnrow <= 1) ;

    if (!check_subset (rset, nr, anrow))
    {
	ERROR (CHOLMOD_INVALID, "invalid rset") ;
	return (NULL) ;
    }

    if (!check_subset (cset, nc, ancol))
    {
	ERROR (CHOLMOD_INVALID, "invalid cset") ;
	return (NULL) ;
    }

    nnz = 0 ;
    if (nr < 0)
    {
	/* C = A (:,cset) where cset = [ ] or cset is not empty */
	ASSERT (IMPLIES (cncol > 0, cset != NULL)) ;
	for (cj = 0 ; cj < cncol ; cj++)
	{
	    /* construct column cj of C, which is column j of A */
	    j = cset [cj] ;
	    nnz += (packed) ? (Ap [j+1] - Ap [j]) : MAX (0, Anz [j]) ;
	}
    }
    else
    {
	/* C = A (rset,cset), where rset is not empty but cset might be empty */
	/* create link lists in reverse order to preserve natural order */
	ilast = anrow ;
	for (ci = nr-1 ; ci >= 0 ; ci--)
	{
	    /* row i of A becomes row ci of C; add ci to ith link list */
	    i = rset [ci] ;
	    head = Head [i] ;
	    Rlen [i] = (head == EMPTY) ? 1 : (Rlen [i] + 1) ;
	    Rnext [ci] = head ;
	    Head [i] = ci ;
	    if (i > ilast)
	    {
		/* row indices in columns of C will not be sorted */
		csorted = FALSE ;
	    }
	    ilast = i ;
	}

#ifndef NDEBUG
	for (i = 0 ; i < anrow ; i++)
	{
	    Int k = 0 ;
	    Int rlen = (Head [i] != EMPTY) ? Rlen [i] : -1 ;
	    PRINT1 (("Row "ID" Rlen "ID": ", i, rlen)) ;
	    for (ci = Head [i] ; ci != EMPTY ; ci = Rnext [ci])
	    {
		k++ ;
		PRINT2 ((""ID" ", ci)) ;
	    }
	    PRINT1 (("\n")) ;
	    ASSERT (IMPLIES (Head [i] != EMPTY, k == Rlen [i])) ;
	}
#endif

	/* count nonzeros in C */
	for (cj = 0 ; cj < cncol ; cj++)
	{
	    /* count rows in column cj of C, which is column j of A */
	    j = (nc < 0) ? cj : (cset [cj]) ;
	    p = Ap [j] ;
	    pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
	    for ( ; p < pend ; p++)
	    {
		/* row i of A becomes multiple rows (ci) of C */
		i = Ai [p] ;
		ASSERT (i >= 0 && i < anrow) ;
		if (Head [i] != EMPTY)
		{
		    nnz += Rlen [i] ;
		}
	    }
	}
    }
    PRINT1 (("nnz (C) "ID"\n", nnz)) ;

    /* rset and cset are now valid */
    DEBUG (CHOLMOD(dump_subset) (rset, rsize, anrow, "rset", Common)) ;
    DEBUG (CHOLMOD(dump_subset) (cset, csize, ancol, "cset", Common)) ;

    /* ---------------------------------------------------------------------- */
    /* allocate C */
    /* ---------------------------------------------------------------------- */

    C = CHOLMOD(allocate_sparse) (cnrow, cncol, nnz, csorted, TRUE, 0,
	    values ? A->xtype : CHOLMOD_PATTERN, Common) ;
    if (Common->status < CHOLMOD_OK)
    {
	/* out of memory */
	for (i = 0 ; i < anrow ; i++)
	{
	    Head [i] = EMPTY ;
	}
	ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ;
	return (NULL) ;
    }

    Cp = C->p ;
    Ci = C->i ;
    Cx = C->x ;

    /* ---------------------------------------------------------------------- */
    /* C = A (rset,cset) */
    /* ---------------------------------------------------------------------- */

    pdest = 0 ;
    if (nnz == 0)
    {
	/* C has no nonzeros */
	for (cj = 0 ; cj <= cncol ; cj++)
	{
	    Cp [cj] = 0 ;
	}
    }
    else if (nr < 0)
    {
	/* C = A (:,cset), where cset is not empty */
	for (cj = 0 ; cj < cncol ; cj++)
	{
	    /* construct column cj of C, which is column j of A */
	    PRINT1 (("construct cj = j = "ID"\n", cj)) ;
	    j = cset [cj] ;
	    Cp [cj] = pdest ;
	    p = Ap [j] ;
	    pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
	    for ( ; p < pend ; p++)
	    {
		Ci [pdest] = Ai [p] ;
		if (values)
		{
		    Cx [pdest] = Ax [p] ;
		}
		pdest++ ;
		ASSERT (pdest <= nnz) ;
	    }
	}
    }
    else
    {
	/* C = A (rset,cset), where rset is not empty but cset might be empty */
	for (cj = 0 ; cj < cncol ; cj++)
	{
	    /* construct column cj of C, which is column j of A */
	    PRINT1 (("construct cj = "ID"\n", cj)) ;
	    j = (nc < 0) ? cj : (cset [cj]) ;
	    PRINT1 (("cj = "ID"\n", j)) ;
	    Cp [cj] = pdest ;
	    p = Ap [j] ;
	    pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
	    for ( ; p < pend ; p++)
	    {
		/* row (Ai [p]) of A becomes multiple rows (ci) of C */
		PRINT2 (("i: "ID" becomes: ", Ai [p])) ;
		if (values)
		{
		    aij = Ax [p] ;
		}
		for (ci = Head [Ai [p]] ; ci != EMPTY ; ci = Rnext [ci])
		{
		    PRINT3 ((""ID" ", ci)) ;
		    Ci [pdest] = ci ;
		    if (values)
		    {
			Cx [pdest] = aij ;
		    }
		    pdest++ ;
		    ASSERT (pdest <= nnz) ;
		}
		PRINT2 (("\n")) ;
	    }
	}
    }
    Cp [cncol] = pdest ;
    ASSERT (nnz == pdest) ;

    /* ---------------------------------------------------------------------- */
    /* clear workspace */
    /* ---------------------------------------------------------------------- */

    for (ci = 0 ; ci < nr ; ci++)
    {
	Head [rset [ci]] = EMPTY ;
    }

    ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ;

    /* ---------------------------------------------------------------------- */
    /* sort C, if requested */
    /* ---------------------------------------------------------------------- */

    ASSERT (CHOLMOD(dump_sparse) (C , "C before sort", Common) >= 0) ;

    if (sorted && !csorted)
    {
	/* workspace: Iwork (max (C->nrow,C->ncol)) */
	if (!CHOLMOD(sort) (C, Common))
	{
	    /* out of memory */
	    CHOLMOD(free_sparse) (&C, Common) ;
	    ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ;
	    return (NULL) ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* return result */
    /* ---------------------------------------------------------------------- */

    ASSERT (CHOLMOD(dump_sparse) (C , "Final C", Common) >= 0) ;
    ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ;
    return (C) ;
}
Exemple #11
0
SuiteSparse_long CHOLMOD(metis_bisector)	/* returns separator size */
(
    /* ---- input ---- */
    cholmod_sparse *A,	/* matrix to bisect */
    Int *Anw,		/* size A->nrow, node weights */
    Int *Aew,		/* size nz, edge weights */
    /* ---- output --- */
    Int *Partition,	/* size A->nrow */
    /* --------------- */
    cholmod_common *Common
)
{
    Int *Ap, *Ai ;
    idxtype *Mp, *Mi, *Mnw, *Mew, *Mpart ;
    Int n, nleft, nright, j, p, csep, total_weight, lightest, nz ;
    int Opt [8], nn, csp ;
    size_t n1 ;
    DEBUG (Int nsep) ;

    /* ---------------------------------------------------------------------- */
    /* check inputs */
    /* ---------------------------------------------------------------------- */

    RETURN_IF_NULL_COMMON (EMPTY) ;
    RETURN_IF_NULL (A, EMPTY) ;
    RETURN_IF_NULL (Anw, EMPTY) ;
    RETURN_IF_NULL (Aew, EMPTY) ;
    RETURN_IF_NULL (Partition, EMPTY) ;
    RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, EMPTY) ;
    if (A->stype || A->nrow != A->ncol)
    {
	/* A must be square, with both upper and lower parts present */
	ERROR (CHOLMOD_INVALID, "matrix must be square, symmetric,"
		" and with both upper/lower parts present") ;
	return (EMPTY) ;
    }
    Common->status = CHOLMOD_OK ;

    /* ---------------------------------------------------------------------- */
    /* quick return */
    /* ---------------------------------------------------------------------- */

    n = A->nrow ;
    if (n == 0)
    {
	return (0) ;
    }
    n1 = ((size_t) n) + 1 ;

    /* ---------------------------------------------------------------------- */
    /* get inputs */
    /* ---------------------------------------------------------------------- */

    Ap = A->p ;
    Ai = A->i ;
    nz = Ap [n] ;

    /* ---------------------------------------------------------------------- */
    /* METIS does not have a 64-bit integer version */
    /* ---------------------------------------------------------------------- */

#ifdef LONG
    if (sizeof (Int) > sizeof (idxtype) && MAX (n,nz) > INT_MAX / sizeof (int))
    {
	/* CHOLMOD's matrix is too large for METIS */
	return (EMPTY) ;
    }
#endif

    /* ---------------------------------------------------------------------- */
    /* set default options */
    /* ---------------------------------------------------------------------- */

    Opt [0] = 0 ;	/* use defaults */
    Opt [1] = 3 ;	/* matching type */
    Opt [2] = 1 ;	/* init. partitioning algo*/
    Opt [3] = 2 ;	/* refinement algorithm */
    Opt [4] = 0 ;	/* no debug */
    Opt [5] = 0 ;	/* unused */
    Opt [6] = 0 ;	/* unused */
    Opt [7] = -1 ;	/* random seed */

    DEBUG (for (j = 0 ; j < n ; j++) ASSERT (Anw [j] > 0)) ;

    /* ---------------------------------------------------------------------- */
    /* copy Int to METIS idxtype, if necessary */
    /* ---------------------------------------------------------------------- */

    DEBUG (for (j = 0 ; j < nz ; j++) ASSERT (Aew [j] > 0)) ;
    if (sizeof (Int) == sizeof (idxtype))
    {
	/* this is the typical case */
	Mi    = (idxtype *) Ai ;
	Mew   = (idxtype *) Aew ;
	Mp    = (idxtype *) Ap ;
	Mnw   = (idxtype *) Anw ;
	Mpart = (idxtype *) Partition ;
    }
    else
    {
	/* idxtype and Int differ; copy the graph into the METIS idxtype */
	Mi    = CHOLMOD(malloc) (nz, sizeof (idxtype), Common) ;
	Mew   = CHOLMOD(malloc) (nz, sizeof (idxtype), Common) ;
	Mp    = CHOLMOD(malloc) (n1, sizeof (idxtype), Common) ;
	Mnw   = CHOLMOD(malloc) (n,  sizeof (idxtype), Common) ;
	Mpart = CHOLMOD(malloc) (n,  sizeof (idxtype), Common) ;
	if (Common->status < CHOLMOD_OK)
	{
	    CHOLMOD(free) (nz, sizeof (idxtype), Mi,    Common) ;
	    CHOLMOD(free) (nz, sizeof (idxtype), Mew,   Common) ;
	    CHOLMOD(free) (n1, sizeof (idxtype), Mp,    Common) ;
	    CHOLMOD(free) (n,  sizeof (idxtype), Mnw,   Common) ;
	    CHOLMOD(free) (n,  sizeof (idxtype), Mpart, Common) ;
	    return (EMPTY) ;
	}
	for (p = 0 ; p < nz ; p++)
	{
	    Mi [p] = Ai [p] ;
	}
	for (p = 0 ; p < nz ; p++)
	{
	    Mew [p] = Aew [p] ;
	}
	for (j = 0 ; j <= n ; j++)
	{
	    Mp [j] = Ap [j] ;
	}
	for (j = 0 ; j <  n ; j++)
	{
	    Mnw [j] = Anw [j] ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* METIS workaround: try to ensure METIS doesn't run out of memory */
    /* ---------------------------------------------------------------------- */

    if (!metis_memory_ok (n, nz, Common))
    {
	/* METIS might ask for too much memory and thus terminate the program */
	if (sizeof (Int) != sizeof (idxtype))
	{
	    CHOLMOD(free) (nz, sizeof (idxtype), Mi,    Common) ;
	    CHOLMOD(free) (nz, sizeof (idxtype), Mew,   Common) ;
	    CHOLMOD(free) (n1, sizeof (idxtype), Mp,    Common) ;
	    CHOLMOD(free) (n,  sizeof (idxtype), Mnw,   Common) ;
	    CHOLMOD(free) (n,  sizeof (idxtype), Mpart, Common) ;
	}
	return (EMPTY) ;
    }

    /* ---------------------------------------------------------------------- */
    /* partition the graph */
    /* ---------------------------------------------------------------------- */

#ifndef NDEBUG
    PRINT1 (("Metis graph, n = "ID"\n", n)) ;
    for (j = 0 ; j < n ; j++)
    {
	Int ppp ;
	PRINT2 (("M(:,"ID") node weight "ID"\n", j, (Int) Mnw [j])) ;
	ASSERT (Mnw [j] > 0) ;
	for (ppp = Mp [j] ; ppp < Mp [j+1] ; ppp++)
	{
	    PRINT3 ((" "ID" : "ID"\n", (Int) Mi [ppp], (Int) Mew [ppp])) ;
	    ASSERT (Mi [ppp] != j) ;
	    ASSERT (Mew [ppp] > 0) ;
	}
    }
#endif

    nn = n ;
    METIS_NodeComputeSeparator (&nn, Mp, Mi, Mnw, Mew, Opt, &csp, Mpart) ;
    n = nn ;
    csep = csp ;

    PRINT1 (("METIS csep "ID"\n", csep)) ;

    /* ---------------------------------------------------------------------- */
    /* copy the results back from idxtype, if required */
    /* ---------------------------------------------------------------------- */

    if (sizeof (Int) != sizeof (idxtype))
    {
	for (j = 0 ; j < n ; j++)
	{
	    Partition [j] = Mpart [j] ;
	}
	CHOLMOD(free) (nz, sizeof (idxtype), Mi,    Common) ;
	CHOLMOD(free) (nz, sizeof (idxtype), Mew,   Common) ;
	CHOLMOD(free) (n1, sizeof (idxtype), Mp,    Common) ;
	CHOLMOD(free) (n,  sizeof (idxtype), Mnw,   Common) ;
	CHOLMOD(free) (n,  sizeof (idxtype), Mpart, Common) ;
    }

    /* ---------------------------------------------------------------------- */
    /* ensure a reasonable separator */
    /* ---------------------------------------------------------------------- */

    /* METIS can return a valid separator with no nodes in (for example) the
     * left part.  In this case, there really is no separator.  CHOLMOD
     * prefers, in this case, for all nodes to be in the separator (and both
     * left and right parts to be empty).  Also, if the graph is unconnected,
     * METIS can return a valid empty separator.  CHOLMOD prefers at least one
     * node in the separator.  Note that cholmod_nested_dissection only calls
     * this routine on connected components, but cholmod_bisect can call this
     * routine for any graph. */

    if (csep == 0)
    {
	/* The separator is empty, select lightest node as separator.  If
	 * ties, select the highest numbered node. */
	lightest = 0 ;
	for (j = 0 ; j < n ; j++)
	{
	    if (Anw [j] <= Anw [lightest])
	    {
		lightest = j ;
	    }
	}
	PRINT1 (("Force "ID" as sep\n", lightest)) ;
	Partition [lightest] = 2 ;
	csep = Anw [lightest] ;
    }

    /* determine the node weights in the left and right part of the graph */
    nleft = 0 ;
    nright = 0 ;
    DEBUG (nsep = 0) ;
    for (j = 0 ; j < n ; j++)
    {
	PRINT1 (("Partition ["ID"] = "ID"\n", j, Partition [j])) ;
	if (Partition [j] == 0)
	{
	    nleft += Anw [j] ;
	}
	else if (Partition [j] == 1)
	{
	    nright += Anw [j] ;
	}
#ifndef NDEBUG
	else
	{
	    ASSERT (Partition [j] == 2) ;
	    nsep += Anw [j] ;
	}
#endif
    }
    ASSERT (csep == nsep) ;

    total_weight = nleft + nright + csep ;

    if (csep < total_weight)
    {
	/* The separator is less than the whole graph.  Make sure the left and
	 * right parts are either both empty or both non-empty. */
	PRINT1 (("nleft "ID" nright "ID" csep "ID" tot "ID"\n",
		nleft, nright, csep, total_weight)) ;
	ASSERT (nleft + nright + csep == total_weight) ;
	ASSERT (nleft > 0 || nright > 0) ;
	if ((nleft == 0 && nright > 0) || (nleft > 0 && nright == 0))
	{
	    /* left or right is empty; put all nodes in the separator */
	    PRINT1 (("Force all in sep\n")) ;
	    csep = total_weight ;
	    for (j = 0 ; j < n ; j++)
	    {
		Partition [j] = 2 ;
	    }
	}
    }

    ASSERT (CHOLMOD(dump_partition) (n, Ap, Ai, Anw, Partition, csep, Common)) ;

    /* ---------------------------------------------------------------------- */
    /* return the sum of the weights of nodes in the separator */
    /* ---------------------------------------------------------------------- */

    return (csep) ;
}
// -----------------------------------------------------------------------------
// CMoveObject::SetPreviousPropertiesL
// Set the object properties after doing the move
// -----------------------------------------------------------------------------
//
void CMoveObject::SetPreviousPropertiesL()
    {
    PRINT( _L( "MM MTP => CMoveObject::SetPreviousPropertiesL" ) );

    iPropertyList->ResetCursor();
    const TInt count = iPropertyList->NumberOfElements();
    for ( TInt i = 0; i < count; i++ )
        {
        CMTPTypeObjectPropListElement& element = iPropertyList->GetNextElementL();

        TUint32 handle = element.Uint32L( CMTPTypeObjectPropListElement::EObjectHandle );
        TUint16 propertyCode = element.Uint16L( CMTPTypeObjectPropListElement::EPropertyCode );
        TUint16 dataType = element.Uint16L( CMTPTypeObjectPropListElement::EDatatype );
        PRINT3( _L( "MM MTP <> CMoveObject::SetPreviousPropertiesL = 0x%x, propertyCode = 0x%x, dataType = 0x%x" ),
            handle,
            propertyCode,
            dataType );

        switch ( propertyCode )
            {
            case EMTPObjectPropCodeStorageID:
            case EMTPObjectPropCodeObjectFormat:
            case EMTPObjectPropCodeProtectionStatus:
            case EMTPObjectPropCodeObjectSize:
            case EMTPObjectPropCodeObjectFileName:
            case EMTPObjectPropCodeParentObject:
            case EMTPObjectPropCodePersistentUniqueObjectIdentifier:
            case EMTPObjectPropCodeDateCreated:
            case EMTPObjectPropCodeDateModified:
            case EMTPObjectPropCodeDateAdded:
                break;

            case EMTPObjectPropCodeNonConsumable:
                iObjectInfo->SetUint( CMTPObjectMetaData::ENonConsumable,
                    element.Uint8L( CMTPTypeObjectPropListElement::EValue ) );
                iFramework.ObjectMgr().ModifyObjectL( *iObjectInfo );
                break;

            case EMTPObjectPropCodeName:
            case EMTPObjectPropCodeAlbumArtist:
                {
                CMTPTypeString *stringData = CMTPTypeString::NewLC( element.StringL( CMTPTypeObjectPropListElement::EValue ) ); // + stringData

                iDpConfig.PropSettingUtility()->SetMetaDataToWrapper( iDpConfig,
                    propertyCode,
                    *stringData,
                    *iObjectInfo );

                CleanupStack::PopAndDestroy( stringData ); // - stringData
                }
                break;

            default:
                {
                iDpConfig.PropSettingUtility()->SetSpecificObjectPropertyL( iDpConfig,
                    propertyCode,
                    *iObjectInfo,
                    element );
                }
                break;
            }
        } // end of for loop

    PRINT( _L( "MM MTP <= CMoveObject::SetPreviousPropertiesL" ) );
    }
Exemple #13
0
int CHOLMOD(updown_mark)
(
    /* ---- input ---- */
    int update,		/* TRUE for update, FALSE for downdate */
    cholmod_sparse *C,	/* the incoming sparse update */
    Int *colmark,	/* Int array of size n.  See cholmod_updown.c */
    /* ---- in/out --- */
    cholmod_factor *L,	/* factor to modify */
    cholmod_dense *X,	/* solution to Lx=b (size n-by-1) */
    cholmod_dense *DeltaB,  /* change in b, zero on output */
    Int *rowmark,	/* Int array of size n.  See cholmod_updown.c */
    /* --------------- */
    cholmod_common *Common
)
{
    double xj, fl ;
    double *Lx, *W, *Xx, *Nx ;
    Int *Li, *Lp, *Lnz, *Cp, *Ci, *Cnz, *Head, *Flag, *Stack, *Lnext, *Iwork,
	*Set_ps1 [32], *Set_ps2 [32], *ps1, *ps2 ;
    size_t maxrank ;
    Path_type OrderedPath [32], Path [32] ;
    Int n, wdim, k1, k2, npaths, i, j, row, packed, ccol, p, cncol, do_solve,
	mark, jj, j2, kk, nextj, p1, p2, c, use_rowmark, use_colmark, newlnz,
	k, newpath, path_order, w_order, scattered, path, newparent, pp1, pp2,
	smax, maxrow, row1, nsets, s, p3, newlnz1, Set [32], top, len, lnz, m,
	botrow ;
    DEBUG (Int oldparent) ;

    /* ---------------------------------------------------------------------- */
    /* check inputs */
    /* ---------------------------------------------------------------------- */

    RETURN_IF_NULL_COMMON (FALSE) ;
    RETURN_IF_NULL (C, FALSE) ;
    RETURN_IF_NULL (L, FALSE) ;
    RETURN_IF_XTYPE_INVALID (L, CHOLMOD_PATTERN, CHOLMOD_REAL, FALSE) ;
    RETURN_IF_XTYPE_INVALID (C, CHOLMOD_REAL, CHOLMOD_REAL, FALSE) ;
    n = L->n ;
    cncol = C->ncol ;
    Common->modfl = 0 ;
    if (!(C->sorted))
    {
	ERROR (CHOLMOD_INVALID, "C must have sorted columns") ;
	return (FALSE) ;
    }
    if (n != (Int) (C->nrow))
    {
	ERROR (CHOLMOD_INVALID, "C and L dimensions do not match") ;
	return (FALSE) ;
    }
    do_solve = (X != NULL) && (DeltaB != NULL) ;
    if (do_solve)
    {
	RETURN_IF_XTYPE_INVALID (X, CHOLMOD_REAL, CHOLMOD_REAL, FALSE) ;
	RETURN_IF_XTYPE_INVALID (DeltaB, CHOLMOD_REAL, CHOLMOD_REAL, FALSE) ;
	Xx = X->x ;
	Nx = DeltaB->x ;
	if (X->nrow != L->n || X->ncol != 1 || DeltaB->nrow != L->n ||
		DeltaB->ncol != 1 || Xx == NULL || Nx == NULL)
	{
	    ERROR (CHOLMOD_INVALID, "X and/or DeltaB invalid") ;
	    return (FALSE) ;
	}
    }
    else
    {
	Xx = NULL ;
	Nx = NULL ;
    }
    Common->status = CHOLMOD_OK ;

    fl = 0 ;
    use_rowmark = (rowmark != NULL) ;
    use_colmark = (colmark != NULL) ;

    /* ---------------------------------------------------------------------- */
    /* allocate workspace */
    /* ---------------------------------------------------------------------- */

    /* Note: cholmod_rowadd and cholmod_rowdel use the second n doubles in
     * Common->Xwork for Cx, and then perform a rank-1 update here, which uses
     * the first n doubles in Common->Xwork.   Both the rowadd and rowdel
     * routines allocate enough workspace so that Common->Xwork isn't destroyed
     * below.  Also, both cholmod_rowadd and cholmod_rowdel use the second n
     * ints in Common->Iwork for Ci.
     */

    /* make sure maxrank is in the proper range */
    maxrank = CHOLMOD(maxrank) (n, Common) ;
    k = MIN (cncol, (Int) maxrank) ;	/* maximum k is wdim */
    wdim = Power2 [k] ;		/* number of columns needed in W */
    ASSERT (wdim <= (Int) maxrank) ;
    PRINT1 (("updown wdim final "ID" k "ID"\n", wdim, k)) ;
    CHOLMOD(allocate_work) (n, n, wdim * n, Common) ;
    if (Common->status < CHOLMOD_OK || maxrank == 0)
    {
	/* out of memory, L is returned unchanged */
	return (FALSE) ;
    }

    /* ---------------------------------------------------------------------- */
    /* convert to simplicial numeric LDL' factor, if not already */
    /* ---------------------------------------------------------------------- */

    if (L->xtype == CHOLMOD_PATTERN || L->is_super || L->is_ll) 
    {
	/* can only update/downdate a simplicial LDL' factorization */
	CHOLMOD(change_factor) (CHOLMOD_REAL, FALSE, FALSE, FALSE, FALSE, L,
		Common) ;
	if (Common->status < CHOLMOD_OK)
	{
	    /* out of memory, L is returned unchanged */
	    return (FALSE) ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* get inputs */
    /* ---------------------------------------------------------------------- */

    mark = CHOLMOD(clear_flag) (Common) ;

    PRINT1 (("updown, rank %ld update %d\n", (long) C->ncol, update)) ;
    DEBUG (CHOLMOD(dump_factor) (L, "input L for updown", Common)) ;
    ASSERT (CHOLMOD(dump_sparse) (C, "input C for updown", Common) >= 0) ;

    Ci = C->i ;
    Cp = C->p ;
    Cnz = C->nz ;
    packed = C->packed ;
    ASSERT (IMPLIES (!packed, Cnz != NULL)) ;

    /* ---------------------------------------------------------------------- */
    /* quick return */
    /* ---------------------------------------------------------------------- */

    if (cncol <= 0 || n == 0)
    {
	/* nothing to do */
	return (TRUE) ;
    }

    /* ---------------------------------------------------------------------- */
    /* get L */
    /* ---------------------------------------------------------------------- */

    Li = L->i ;
    Lx = L->x ;
    Lp = L->p ;
    Lnz = L->nz ;
    Lnext = L->next ;
    ASSERT (Lnz != NULL) ;

    /* ---------------------------------------------------------------------- */
    /* get workspace */
    /* ---------------------------------------------------------------------- */

    Flag = Common->Flag ;	/* size n, Flag [i] <= mark must hold */
    Head = Common->Head ;	/* size n, Head [i] == EMPTY must hold */
    W = Common->Xwork ;		/* size n-by-wdim, zero on input and output*/

    /* note that Iwork [n .. 2*n-1] (i/i/l) may be in use in rowadd/rowdel: */
    Iwork = Common->Iwork ;
    Stack = Iwork ;		/* size n, uninitialized (i/i/l) */

    /* ---------------------------------------------------------------------- */
    /* entire rank-cncol update, done as a sequence of rank-k updates */
    /* ---------------------------------------------------------------------- */

    ps1 = NULL ;
    ps2 = NULL ;

    for (k1 = 0 ; k1 < cncol ; k1 += k)
    {

	/* ------------------------------------------------------------------ */
	/* get the next k columns of C for the update/downdate */
	/* ------------------------------------------------------------------ */

	/* the last update/downdate might be less than rank-k */
	if (k > cncol - k1)
	{
	    k = cncol - k1 ;
	    wdim = Power2 [k] ;
	}
	k2 = k1 + k - 1 ;

	/* workspaces are in the following state, on input and output */
	ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, wdim, Common)) ;

	/* ------------------------------------------------------------------ */
	/* create a zero-length path for each column of W */
	/* ------------------------------------------------------------------ */

	nextj = n ;
	path = 0 ;
	for (ccol = k1 ; ccol <= k2 ; ccol++)
	{
	    PRINT1 (("Column ["ID"]: "ID"\n", path, ccol)) ;
	    ASSERT (ccol >= 0 && ccol <= cncol) ;
	    pp1 = Cp [ccol] ;
	    pp2 = (packed) ? (Cp [ccol+1]) : (pp1 + Cnz [ccol]) ;
	    /* get the row index j of the first entry in C (:,ccol) */
	    if (pp2 > pp1)
	    {
		/* Column ccol of C has at least one entry. */
		j = Ci [pp1] ;
	    }
	    else
	    {
		/* Column ccol of C is empty.  Pretend it has one entry in
		 * the last column with numerical value of zero. */
		j = n-1 ;
	    }
	    ASSERT (j >= 0 && j < n) ;

	    /* find first column to work on */
	    nextj = MIN (nextj, j) ;

	    Path [path].ccol = ccol ;	/* which column of C this path is for */
	    Path [path].start = EMPTY ;	/* paths for C have zero length */
	    Path [path].end = EMPTY ;
	    Path [path].parent = EMPTY ;    /* no parent yet */
	    Path [path].rank = 1 ;	    /* one column of W */
	    Path [path].c = EMPTY ;	    /* no child of this path (case A) */
	    Path [path].next = Head [j] ;   /* this path is pending at col j */
	    Path [path].pending = j ;	    /* this path is pending at col j */
	    Head [j] = path ;		    /* this path is pending at col j */
	    PRINT1(("Path "ID" starts: start "ID" end "ID" parent "ID" c "ID""
		    "j "ID" ccol "ID"\n", path, Path [path].start,
		    Path [path].end, Path [path].parent,
		    Path [path].c, j, ccol)) ;
	    path++ ;
	}

	/* we start with paths 0 to k-1.  Next one (now unused) is npaths */
	npaths = k ;

	j = nextj ;
	ASSERT (j < n) ;
	scattered = FALSE ;

	/* ------------------------------------------------------------------ */
	/* symbolic update of columns of L */
	/* ------------------------------------------------------------------ */

	while (j < n)
	{
	    ASSERT (j >= 0 && j < n && Lnz [j] > 0) ;

	    /* the old column, Li [p1..p2-1].  D (j,j) is stored in Lx [p1] */
	    p1 = Lp [j] ;
	    newlnz = Lnz [j] ;
	    p2 = p1 + newlnz  ;

#ifndef NDEBUG
	    PRINT1 (("\n=========Column j="ID" p1 "ID" p2 "ID" lnz "ID" \n",
			j, p1, p2, newlnz)) ;
	    dump_col ("Old", j, p1, p2, Li, Lx, n, Common) ;
	    oldparent = (Lnz [j] > 1) ? (Li [p1 + 1]) : EMPTY ;
	    ASSERT (CHOLMOD(dump_work) (TRUE, FALSE, 0, Common)) ;
	    ASSERT (!scattered) ;
	    PRINT1 (("Col "ID": Checking paths, npaths: "ID"\n", j, npaths)) ;
	    for (kk = 0 ; kk < npaths ; kk++)
	    {
		Int kk2, found, j3 = Path [kk].pending ;
		PRINT2 (("Path "ID" pending at "ID".\n", kk, j3)) ;
		if (j3 != EMPTY)
		{
		    /* Path kk must be somewhere in link list for column j3 */
		    ASSERT (Head [j3] != EMPTY) ;
		    PRINT3 (("    List at "ID": ", j3)) ;
		    found = FALSE ;
		    for (kk2 = Head [j3] ; kk2 != EMPTY ; kk2 = Path [kk2].next)
		    {
			PRINT3 ((""ID" ", kk2)) ;
			ASSERT (Path [kk2].pending == j3) ;
			found = found || (kk2 == kk) ;
		    }
		    PRINT3 (("\n")) ;
		    ASSERT (found) ;
		}
	    }
	    PRINT1 (("\nCol "ID": Paths at this column, head "ID"\n",
			j, Head [j]));
	    ASSERT (Head [j] != EMPTY) ;
	    for (kk = Head [j] ; kk != EMPTY ; kk = Path [kk].next)
	    {
		PRINT1 (("path "ID": (c="ID" j="ID") npaths "ID"\n",
			    kk, Path[kk].c, j, npaths)) ;
		ASSERT (kk >= 0 && kk < npaths) ;
		ASSERT (Path [kk].pending == j) ;
	    }
#endif

	    /* -------------------------------------------------------------- */
	    /* update/downdate of forward solve, Lx=b */
	    /* -------------------------------------------------------------- */

	    if (do_solve)
	    {
		xj = Xx [j] ;
		if (IS_NONZERO (xj))
		{
		    xj = Xx [j] ;
		    /* This is first time column j has been seen for entire */
		    /* rank-k update/downdate. */

		    /* DeltaB += Lold (j:botrow-1,j) * X (j) */
		    Nx [j] += xj ;			/* diagonal of L */
		    botrow = (use_rowmark) ? (rowmark [j]) : n ;
		    for (p = p1 + 1 ; p < p2 ; p++)
		    {
			i = Li [p] ;
			if (i >= botrow)
			{
			    break ;
			}
			Nx [i] += Lx [p] * xj ;
		    }

		    /* clear X[j] to flag col j of Lold as having been seen.  If
		     * X (j) was initially zero, then the above code is never
		     * executed for column j.  This is safe, since if xj=0 the
		     * code above does not do anything anyway.  */
		    Xx [j] = 0.0 ;
		}
	    }

	    /* -------------------------------------------------------------- */
	    /* start a new path at this column if two or more paths merge */
	    /* -------------------------------------------------------------- */

	    /* get the first old path at column j */
	    path = Head [j] ;

	    newpath =
		/* start a new path if paths have merged */
		(Path [path].next != EMPTY)
		/* or if j is the first node on a path (case A). */
		|| (Path [path].c == EMPTY) ;

	    if (newpath)
	    {
		path = npaths++ ;
		ASSERT (npaths <= 3*k) ;
		Path [path].ccol = EMPTY ; /* no single col of C for this path*/
		Path [path].start = j ;	   /* path starts at this column j */
		Path [path].end = EMPTY ;  /* don't know yet where it ends */
		Path [path].parent = EMPTY ;/* don't know parent path yet */
		Path [path].rank = 0 ;	/* rank is sum of child path ranks */
		PRINT1 (("Path "ID" starts: start "ID" end "ID" parent "ID"\n",
		path, Path [path].start, Path [path].end, Path [path].parent)) ;
	    }

	    /* -------------------------------------------------------------- */
	    /* for each path kk pending at column j */
	    /* -------------------------------------------------------------- */

	    /* make a list of the sets that need to be merged into column j */
	    nsets = 0 ;

	    for (kk = Head [j] ; kk != EMPTY ; kk = Path [kk].next)
	    {

		/* ---------------------------------------------------------- */
		/* path kk is at (c,j) */
		/* ---------------------------------------------------------- */

		c = Path [kk].c ;
		ASSERT (c < j) ;
		PRINT1 (("TUPLE on path "ID" (c="ID" j="ID")\n", kk, c, j)) ;
		ASSERT (Path [kk].pending == j) ;

		if (newpath)
		{
		    /* finalize path kk and find rank of this path */
		    Path [kk].end = c ;	/* end of old path is previous node c */
		    Path [kk].parent = path ;	/* parent is this path */
		    Path [path].rank += Path [kk].rank ;    /* sum up ranks */
		    Path [kk].pending = EMPTY ;
		    PRINT1 (("Path "ID" done:start "ID" end "ID" parent "ID"\n",
		    kk, Path [kk].start, Path [kk].end, Path [kk].parent)) ;
		}

		if (c == EMPTY)
		{

		    /* ------------------------------------------------------ */
		    /* CASE A: first node in path */
		    /* ------------------------------------------------------ */

		    /* update:  add pattern of incoming column */

		    /* Column ccol of C is in Ci [pp1 ... pp2-1] */
		    ccol = Path [kk].ccol ;
		    pp1 = Cp [ccol] ;
		    pp2 = (packed) ? (Cp [ccol+1]) : (pp1 + Cnz [ccol]) ;
		    PRINT1 (("Case A, ccol = "ID" len "ID"\n", ccol, pp2-pp1)) ;
		    ASSERT (IMPLIES (pp2 > pp1, Ci [pp1] == j)) ;

		    if (!scattered)
		    {
			/* scatter the original pattern of column j of L */
			for (p = p1 ; p < p2 ; p++)
			{
			    Flag [Li [p]] = mark ;
			}
			scattered = TRUE ;
		    }

		    /* scatter column ccol of C (skip first entry, j) */
		    newlnz1 = newlnz ;
		    for (p = pp1 + 1 ; p < pp2 ; p++)
		    {
			row = Ci [p] ;
			if (Flag [row] < mark)
			{
			    /* this is a new entry in Lj' */
			    Flag [row] = mark ;
			    newlnz++ ;
			}
		    }
		    if (newlnz1 != newlnz)
		    {
			/* column ccol of C adds something to column j of L */
			Set [nsets++] = FLIP (ccol) ;
		    }

		}
		else if (Head [c] == 1)
		{

		    /* ------------------------------------------------------ */
		    /* CASE B: c is old, but changed, child of j */
		    /* CASE C: new child of j */
		    /* ------------------------------------------------------ */

		    /* Head [c] is 1 if col c of L has new entries,
		     * EMPTY otherwise */
		    Flag [c] = 0 ;
		    Head [c] = EMPTY ;

		    /* update: add Lc' */

		    /* column c of L is in Li [pp1 .. pp2-1] */
		    pp1 = Lp [c] ;
		    pp2 = pp1 + Lnz [c] ;
		    PRINT1 (("Case B/C: c = "ID"\n", c)) ;
		    DEBUG (dump_col ("Child", c, pp1, pp2, Li, Lx, n, Common)) ;
		    ASSERT (j == Li [pp1 + 1]) ; /* j is new parent of c */

		    if (!scattered)
		    {
			/* scatter the original pattern of column j of L */
			for (p = p1 ; p < p2 ; p++)
			{
			    Flag [Li [p]] = mark ;
			}
			scattered = TRUE ;
		    }

		    /* scatter column c of L (skip first two entries, c and j)*/
		    newlnz1 = newlnz ;
		    for (p = pp1 + 2 ; p < pp2 ; p++)
		    {
			row = Li [p] ;
			if (Flag [row] < mark)
			{
			    /* this is a new entry in Lj' */
			    Flag [row] = mark ;
			    newlnz++ ;
			}
		    }
		    PRINT2 (("\n")) ;

		    if (newlnz1 != newlnz)
		    {
			/* column c of L adds something to column j of L */
			Set [nsets++] = c ;
		    }
		}
	    }

	    /* -------------------------------------------------------------- */
	    /* update the pattern of column j of L */
	    /* -------------------------------------------------------------- */

	    /* Column j of L will be in Li/Lx [p1 .. p3-1] */
	    p3 = p1 + newlnz ;
	    ASSERT (IMPLIES (nsets == 0, newlnz == Lnz [j])) ;
	    PRINT1 (("p1 "ID" p2 "ID" p3 "ID" nsets "ID"\n", p1, p2, p3,nsets));

	    /* -------------------------------------------------------------- */
	    /* ensure we have enough space for the longer column */
	    /* -------------------------------------------------------------- */

	    if (nsets > 0 && p3 > Lp [Lnext [j]])
	    {
		PRINT1 (("Col realloc: j "ID" newlnz "ID"\n", j, newlnz)) ;
		if (!CHOLMOD(reallocate_column) (j, newlnz, L, Common))
		{
		    /* out of memory, L is now simplicial symbolic */
		    CHOLMOD(clear_flag) (Common) ;
		    for (j = 0 ; j <= n ; j++)
		    {
			Head [j] = EMPTY ;
		    }
		    ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, wdim, Common)) ;
		    return (FALSE) ;
		}
		/* L->i and L->x may have moved.  Column j has moved too */
		Li = L->i ;
		Lx = L->x ;
		p1 = Lp [j] ;
		p2 = p1 + Lnz [j] ;
		p3 = p1 + newlnz ;
	    }

	    /* -------------------------------------------------------------- */
	    /* create set pointers */
	    /* -------------------------------------------------------------- */

	    for (s = 0 ; s < nsets ; s++)
	    {
		/* Pattern of Set s is *(Set_ps1 [s] ... Set_ps2 [s]-1) */
		c = Set [s] ;
		if (c < EMPTY)
		{
		    /* column ccol of C, skip first entry (j) */
		    ccol = FLIP (c) ;
		    pp1 = Cp [ccol] ;
		    pp2 = (packed) ? (Cp [ccol+1]) : (pp1 + Cnz [ccol]) ;
		    ASSERT (pp2 - pp1 > 1) ;
		    Set_ps1 [s] = &(Ci [pp1 + 1]) ;
		    Set_ps2 [s] = &(Ci [pp2]) ;
		    PRINT1 (("set "ID" is ccol "ID"\n", s, ccol)) ;
		}
		else
		{
		    /* column c of L, skip first two entries (c and j)  */
		    pp1 = Lp [c] ;
		    pp2 = pp1 + Lnz [c]  ;
		    ASSERT (Lnz [c] > 2) ;
		    Set_ps1 [s] = &(Li [pp1 + 2]) ;
		    Set_ps2 [s] = &(Li [pp2]) ;
		    PRINT1 (("set "ID" is L "ID"\n", s, c)) ;
		}
		DEBUG (dump_set (s, Set_ps1, Set_ps2, j, n, Common)) ;
	    }

	    /* -------------------------------------------------------------- */
	    /* multiset merge */
	    /* -------------------------------------------------------------- */

	    /* Merge the sets into a single sorted set, Lj'.  Before the merge
	     * starts, column j is located in Li/Lx [p1 ... p2-1] and the
	     * space Li/Lx [p2 ... p3-1] is empty.  p1 is Lp [j], p2 is
	     * Lp [j] + Lnz [j] (the old length of the column), and p3 is
	     * Lp [j] + newlnz (the new and longer length of the column).
	     *
	     * The sets 0 to nsets-1 are defined by the Set_ps1 and Set_ps2
	     * pointers.  Set s is located in *(Set_ps1 [s] ... Set_ps2 [s]-1).
	     * It may be a column of C, or a column of L.  All row indices i in
	     * the sets are in the range i > j and i < n.  All sets are sorted.
	     *
	     * The merge into column j of L is done in place.
	     *
	     * During the merge, p2 and p3 are updated.  Li/Lx [p1..p2-1]
	     * reflects the indices of the old column j of L that are yet to
	     * be merged into the new column.  Entries in their proper place in
	     * the new column j of L are located in Li/Lx [p3 ... p1+newlnz-1].
	     * The merge finishes when p2 == p3.
	     *
	     * During the merge, set s consumed as it is merged into column j of
	     * L.  Its unconsumed contents are *(Set_ps1 [s] ... Set_ps2 [s]-1).
	     * When a set is completely consumed, it is removed from the set of
	     * sets, and nsets is decremented.
	     *
	     * The multiset merge and 2-set merge finishes when p2 == p3.
	     */

	    PRINT1 (("Multiset merge p3 "ID" p2 "ID" nsets "ID"\n",
			p3, p2, nsets)) ;

	    while (p3 > p2 && nsets > 1)
	    {

#ifndef NDEBUG
		PRINT2 (("\nMultiset merge.  nsets = "ID"\n", nsets)) ;
		PRINT2 (("Source col p1 = "ID", p2 = "ID", p3= "ID"\n",
			    p1, p2, p3)) ;
		for (p = p1 + 1 ; p < p2 ; p++)
		{
		    PRINT2 (("    p: "ID" source row "ID" %g\n",
				p, Li[p], Lx[p])) ;
		    ASSERT (Li [p] > j && Li [p] < n) ;
		}
		PRINT2 (("---\n")) ;
		for (p = p3 ; p < p1 + newlnz ; p++)
		{
		    PRINT2 (("    p: "ID" target row "ID" %g\n",
				p, Li[p], Lx[p])) ;
		    ASSERT (Li [p] > j && Li [p] <  n) ;
		}
		for (s = 0 ; s < nsets ; s++)
		{
		    dump_set (s, Set_ps1, Set_ps2, j, n, Common) ;
		}
#endif

		/* get the entry at the tail end of source column Lj */
		row1 = Li [p2 - 1] ;
		ASSERT (row1 >= j && p2 >= p1) ;

		/* find the largest row in all the sets */
		maxrow = row1 ;
		smax = EMPTY ;
		for (s = nsets-1 ; s >= 0 ; s--)
		{
		    ASSERT (Set_ps1 [s] < Set_ps2 [s]) ;
		    row = *(Set_ps2 [s] - 1) ;
		    if (row == maxrow)
		    {
			/* skip past this entry in set s (it is a duplicate) */
			Set_ps2 [s]-- ;
			if (Set_ps1 [s] == Set_ps2 [s])
			{
			    /* nothing more in this set */
			    nsets-- ;
			    Set_ps1 [s] = Set_ps1 [nsets] ;
			    Set_ps2 [s] = Set_ps2 [nsets] ;
			    if (smax == nsets)
			    {
				/* Set smax redefined; it is now this set */
				smax = s ;
			    }
			}
		    }
		    else if (row > maxrow)
		    {
			maxrow = row ;
			smax = s ;
		    }
		}
		ASSERT (maxrow > j) ;

		/* move the row onto the stack of the target column */
		if (maxrow == row1)
		{
		    /* next entry is in Lj, move to the bottom of Lj' */
		    ASSERT (smax == EMPTY) ;
		    p2-- ;
		    p3-- ;
		    Li [p3] = maxrow ;
		    Lx [p3] = Lx [p2] ;
		}
		else
		{
		    /* new entry in Lj' */
		    ASSERT (smax >= 0 && smax < nsets) ;
		    Set_ps2 [smax]-- ;
		    p3-- ;
		    Li [p3] = maxrow ;
		    Lx [p3] = 0.0 ;
		    if (Set_ps1 [smax] == Set_ps2 [smax])
		    {
			/* nothing more in this set */
			nsets-- ;
			Set_ps1 [smax] = Set_ps1 [nsets] ;
			Set_ps2 [smax] = Set_ps2 [nsets] ;
			PRINT1 (("Set "ID" now empty\n", smax)) ;
		    }
		}
	    }

	    /* -------------------------------------------------------------- */
	    /* 2-set merge: */
	    /* -------------------------------------------------------------- */

	    /* This the same as the multi-set merge, except there is only one
	     * set s = 0 left.  The source column j and the set 0 are being
	     * merged into the target column j. */

	    if (nsets > 0)
	    {
		ps1 = Set_ps1 [0] ;
		ps2 = Set_ps2 [0] ;
	    }

	    while (p3 > p2)
	    {

#ifndef NDEBUG
		PRINT2 (("\n2-set merge.\n")) ;
		ASSERT (nsets == 1) ;
		PRINT2 (("Source col p1 = "ID", p2 = "ID", p3= "ID"\n",
			    p1, p2, p3)) ;
		for (p = p1 + 1 ; p < p2 ; p++)
		{
		    PRINT2 (("    p: "ID" source row "ID" %g\n",
				p, Li[p], Lx[p])) ;
		    ASSERT (Li [p] > j && Li [p] < n) ;
		}
		PRINT2 (("---\n")) ;
		for (p = p3 ; p < p1 + newlnz ; p++)
		{
		    PRINT2 (("    p: "ID" target row "ID" %g\n",
				p, Li[p], Lx[p])) ;
		    ASSERT (Li [p] > j && Li [p] <  n) ;
		}
		dump_set (0, Set_ps1, Set_ps2, j, n, Common) ;
#endif

		if (p2 == p1 + 1)
		{
		    /* the top of Lj is empty; copy the set and quit */
		    while (p3 > p2)
		    {
			/* new entry in Lj' */
			row = *(--ps2) ;
			p3-- ;
			Li [p3] = row ;
			Lx [p3] = 0.0 ;
		    }
		}
		else
		{
		    /* get the entry at the tail end of Lj */
		    row1 = Li [p2 - 1] ;
		    ASSERT (row1 > j && row1 < n) ;
		    /* get the entry at the tail end of the incoming set */
		    ASSERT (ps1 < ps2) ;
		    row = *(ps2-1) ;
		    ASSERT (row > j && row1 < n) ;
		    /* move the larger of the two entries to the target set */
		    if (row1 >= row)
		    {
			/* next entry is in Lj, move to the bottom */
			if (row1 == row)
			{
			    /* skip past this entry in the set */
			    ps2-- ;
			}
			p2-- ;
			p3-- ;
			Li [p3] = row1 ;
			Lx [p3] = Lx [p2] ;
		    }
		    else
		    {
			/* new entry in Lj' */
			ps2-- ;
			p3-- ;
			Li [p3] = row ;
			Lx [p3] = 0.0 ;
		    }
		}
	    }

	    /* -------------------------------------------------------------- */
	    /* The new column j of L is now in Li/Lx [p1 ... p2-1] */
	    /* -------------------------------------------------------------- */

	    p2 = p1 + newlnz ;
	    DEBUG (dump_col ("After merge: ", j, p1, p2, Li, Lx, n, Common)) ;

	    fl += Path [path].rank * (6 + 4 * (double) newlnz) ;

	    /* -------------------------------------------------------------- */
	    /* clear Flag; original pattern of column j L no longer marked */
	    /* -------------------------------------------------------------- */

	    mark = CHOLMOD(clear_flag) (Common) ;
	    scattered = FALSE ;

	    /* -------------------------------------------------------------- */
	    /* find the new parent */
	    /* -------------------------------------------------------------- */

	    newparent = (newlnz > 1) ? (Li [p1 + 1]) : EMPTY ;
	    PRINT1 (("\nNew parent, Lnz: "ID": "ID" "ID"\n",
			j, newparent,newlnz));
	    ASSERT (oldparent == EMPTY || newparent <= oldparent) ;

	    /* -------------------------------------------------------------- */
	    /* go to the next node in the path */
	    /* -------------------------------------------------------------- */

	    /* path moves to (j,nextj) unless j is a root */
	    nextj = (newparent == EMPTY) ? n : newparent ;

	    /* place path at head of list for nextj, or terminate the path */
	    PRINT1 (("\n j = "ID" nextj = "ID"\n\n", j, nextj)) ;
	    Path [path].c = j ;
	    if (nextj < n)
	    {
		/* put path on link list of pending paths at column nextj */
		Path [path].next = Head [nextj] ;
		Path [path].pending = nextj ;
		Head [nextj] = path ;
		PRINT1 (("Path "ID" continues to ("ID","ID").  Rank "ID"\n",
		    path, Path [path].c, nextj, Path [path].rank)) ;
	    }
	    else
	    {
		/* path has ended here, at a root */
		Path [path].next = EMPTY ;
		Path [path].pending = EMPTY ;
		Path [path].end = j ;
		PRINT1 (("Path "ID" ends at root ("ID").  Rank "ID"\n",
		    path, Path [path].end, Path [path].rank)) ;
	    }

	    /* The link list Head [j] can now be emptied.  Set Head [j] to 1
	     * if column j has changed (it is no longer used as a link list). */
	    PRINT1 (("column "ID", oldlnz = "ID"\n", j, Lnz [j])) ;
	    Head [j] = (Lnz [j] != newlnz) ? 1 : EMPTY ;
	    Lnz [j] = newlnz ;
	    PRINT1 (("column "ID", newlnz = "ID"\n", j, newlnz)) ;
	    DEBUG (dump_col ("New", j, p1, p2, Li, Lx, n, Common)) ;

	    /* move to the next column */
	    if (k == Path [path].rank)
	    {
		/* only one path left */
		j = nextj ;
	    }
	    else
	    {
		/* The current path is moving from column j to column nextj
		 * (nextj is n if the path has ended).  However, there may be
		 * other paths pending in columns j+1 to nextj-1.  There are
		 * two methods for looking for the next column with a pending
		 * update.  The first one looks at all columns j+1 to nextj-1
		 * for a non-empty link list.  This can be costly if j and
		 * nextj differ by a large amount (it can be O(n), but this
		 * entire routine may take Omega(1) time).  The second method
		 * looks at all paths and finds the smallest column at which any
		 * path is pending.  It takes O(# of paths), which is bounded
		 * by 23: one for each column of C (up to 8), and then 15 for a
		 * balanced binary tree with 8 leaves.  However, if j and
		 * nextj differ by a tiny amount (nextj is often j+1 near
		 * the end of the matrix), looking at columns j+1 to nextj
		 * would be faster.  Both methods give the same answer. */

		if (nextj - j < npaths)
		{
		    /* there are fewer columns to search than paths */
		    PRINT1 (("check j="ID" to nextj="ID"\n", j, nextj)) ;
		    for (j2 = j + 1 ; j2 < nextj ; j2++)
		    {
			PRINT1 (("check j="ID" "ID"\n", j2, Head [j2])) ;
			if (Head [j2] != EMPTY)
			{
			    PRINT1 (("found, j="ID"\n", j2)) ;
			    ASSERT (Path [Head [j2]].pending == j2) ;
			    break ;
			}
		    }
		}
		else
		{
		    /* there are fewer paths than columns to search */
		    j2 = nextj ;
		    for (kk = 0 ; kk < npaths ; kk++)
		    {
			jj = Path [kk].pending ;
			PRINT2 (("Path "ID" pending at "ID"\n", kk, jj)) ;
			if (jj != EMPTY) j2 = MIN (j2, jj) ;
		    }
		}
		j = j2 ;
	    }
	}

	/* ensure workspaces are back to the values required on input */
	ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, TRUE, Common)) ;

	/* ------------------------------------------------------------------ */
	/* depth-first-search of tree to order the paths */
	/* ------------------------------------------------------------------ */

	/* create lists of child paths */
	PRINT1 (("\n\nDFS search:\n\n")) ;
	for (path = 0 ; path < npaths ; path++)
	{
	    Path [path].c = EMPTY ;	    /* first child of path */
	    Path [path].next = EMPTY ;	    /* next sibling of path */
	    Path [path].order = EMPTY ;	    /* path is not ordered yet */
	    Path [path].wfirst = EMPTY ;    /* 1st column of W not found yet */

#ifndef NDEBUG
	    j = Path [path].start ;
	    PRINT1 (("Path "ID" : start "ID" end "ID" parent "ID" ccol "ID"\n", 
	    path, j, Path [path].end, Path [path].parent, Path [path].ccol)) ;
	    for ( ; ; )
	    {
		PRINT1 (("	column "ID"\n", j)) ;
		ASSERT (j == EMPTY || (j >= 0 && j < n)) ;
		if (j == Path [path].end)
		{
		    break ;
		}
		ASSERT (j >= 0 && j < n) ;
		j = (Lnz [j] > 1) ? (Li [Lp [j] + 1]) : EMPTY ;
	    }
#endif
	}

	for (path = 0 ; path < npaths ; path++)
	{
	    p = Path [path].parent ;	/* add path to child list of parent */
	    if (p != EMPTY)
	    {
		ASSERT (p < npaths) ;
		Path [path].next = Path [p].c ;
		Path [p].c = path ;
	    }
	}

	path_order = k ;
	w_order = 0 ;
	for (path = npaths-1 ; path >= 0 ; path--)
	{
	    if (Path [path].order == EMPTY)
	    {
		/* this path is the root of a subtree of Tbar */
		PRINT1 (("Root path "ID"\n", path)) ;
		ASSERT (path >= k) ;
		dfs (Path, k, path, &path_order, &w_order, 0, npaths) ;
	    }
	}
	ASSERT (path_order == npaths) ;
	ASSERT (w_order == k) ;

	/* reorder the paths */
	for (path = 0 ; path < npaths ; path++)
	{
	    /* old order is path, new order is Path [path].order */
	    OrderedPath [Path [path].order] = Path [path] ;
	}

#ifndef NDEBUG
	for (path = 0 ; path < npaths ; path++)
	{
	    PRINT1 (("Ordered Path "ID": start "ID" end "ID" wfirst "ID" rank "
		    ""ID" ccol "ID"\n", path, OrderedPath [path].start,
		    OrderedPath [path].end, OrderedPath [path].wfirst,
		    OrderedPath [path].rank, OrderedPath [path].ccol)) ;
	    if (path < k)
	    {
		ASSERT (OrderedPath [path].ccol >= 0) ;
	    }
	    else
	    {
		ASSERT (OrderedPath [path].ccol == EMPTY) ;
	    }
	}
#endif

	/* ------------------------------------------------------------------ */
	/* numeric update/downdate for all paths */
	/* ------------------------------------------------------------------ */

	ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, wdim, Common)) ;

	switch (wdim)
	{
	    case 1:
		updown_1_r (update, C, k, L, W, OrderedPath, npaths, Common) ;
		break ;
	    case 2:
		updown_2_r (update, C, k, L, W, OrderedPath, npaths, Common) ;
		break ;
	    case 4:
		updown_4_r (update, C, k, L, W, OrderedPath, npaths, Common) ;
		break ;
	    case 8:
		updown_8_r (update, C, k, L, W, OrderedPath, npaths, Common) ;
		break ;
	}

	ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, wdim, Common)) ;
    }

    /* ---------------------------------------------------------------------- */
    /* update/downdate the forward solve */
    /* ---------------------------------------------------------------------- */

    if (do_solve)
    {

	/* We now have DeltaB += Lold (:,j) * X (j) for all columns j in union
	 * of all paths seen during the entire rank-cncol update/downdate. For
	 * each j in path, do DeltaB -= Lnew (:,j)*DeltaB(j) 
	 * in topological order. */

#ifndef NDEBUG
	PRINT1 (("\ndo_solve, DeltaB + Lold(:,Path)*X(Path):\n")) ;
	for (i = 0 ; i < n ; i++)
	{
	    PRINT1 (("do_solve: "ID" %30.20e\n", i, Nx [i])) ;
	}
#endif

	/* Note that the downdate, if it deleted entries, would need to compute
	 * the Stack prior to doing any downdates. */

	/* find the union of all the paths in the new L */
	top = n ;	/* "top" is stack pointer, not a row or column index */
	for (ccol = 0 ; ccol < cncol ; ccol++)
	{

	    /* -------------------------------------------------------------- */
	    /* j = first row index of C (:,ccol) */
	    /* -------------------------------------------------------------- */

	    pp1 = Cp [ccol] ;
	    pp2 = (packed) ? (Cp [ccol+1]) : (pp1 + Cnz [ccol]) ;
	    if (pp2 > pp1)
	    {
		/* Column ccol of C has at least one entry. */
		j = Ci [pp1] ;
	    }
	    else
	    {
		/* Column ccol of C is empty */
		j = n-1 ;
	    }
	    PRINT1 (("\ndo_solve:      ccol= "ID"\n", ccol)) ;
	    ASSERT (j >= 0 && j < n) ;
	    len = 0 ;

	    /* -------------------------------------------------------------- */
	    /* find the new rowmark */
	    /* -------------------------------------------------------------- */

	    /* Each column of C can redefine the region of L that takes part in
	     * the update/downdate of the triangular solve Lx=b.  If
	     * i = colmark [ccol] for column C(:,ccol), then i = rowmark [j] is
	     * redefined for all columns along the path modified by C(:,ccol).
	     * If more than one column modifies any given column j of L, then
	     * the rowmark of j is determined by the colmark of the least-
	     * numbered column that affects column j.  That is, if both
	     * C(:,ccol1) and C(:,ccol2) affect column j of L, then
	     * rowmark [j] = colmark [MIN (ccol1, ccol2)].
	     *
	     * rowmark [j] is not modified if rowmark or colmark are NULL,
	     * or if colmark [ccol] is EMPTY.
	     */

	    botrow = (use_colmark && use_rowmark) ? (colmark [ccol]) : EMPTY ;

	    /* -------------------------------------------------------------- */
	    /* traverse from j towards root, stopping if node already visited */
	    /* -------------------------------------------------------------- */

	    while (j != EMPTY && Flag [j] < mark)
	    {
		PRINT1 (("do_solve: subpath j= "ID"\n", j)) ;
		ASSERT (j >= 0 && j < n) ;
		Stack [len++] = j ;		/* place j on the stack */
		Flag [j] = mark ;		/* flag j as visited */

		/* redefine the parts of column j of L that take part in
		 * the triangular solve. */
		if (botrow != EMPTY)
		{
		    /* update rowmark to keep track of botrow for col j */
		    rowmark [j] = botrow ;
		}

		/* go up the tree, to the parent of j */
		j = (Lnz [j] > 1) ? (Li [Lp [j] + 1]) : EMPTY ;
	    }

	    /* -------------------------------------------------------------- */
	    /* move the path down to the bottom of the stack */
	    /* -------------------------------------------------------------- */

	    ASSERT (len <= top) ;
	    while (len > 0)
	    {
		Stack [--top] = Stack [--len] ;
	    }
	}

#ifndef NDEBUG
	/* Union of paths now in Stack [top..n-1] in topological order */
	PRINT1 (("\nTopological order:\n")) ;
	for (i = top ; i < n ; i++)
	{
	    PRINT1 (("column "ID" in full path\n", Stack [i])) ;
	}
#endif

	/* Do the forward solve for the full path part of L */
	for (m = top ; m < n ; m++)
	{
	    j = Stack [m] ;
	    ASSERT (j >= 0 && j < n) ;
	    PRINT1 (("do_solve: path j= "ID"\n", j)) ;
	    p1 = Lp [j] ;
	    lnz = Lnz [j] ;
	    p2 = p1 + lnz ;
	    xj = Nx [j] ;

	    /* copy new solution onto old one, for all cols in full path */
	    Xx [j] = xj ;
	    Nx [j] = 0. ;

	    /* DeltaB -= Lnew (j+1:botrow-1,j) * deltab(j) */
	    botrow = (use_rowmark) ? (rowmark [j]) : n ;
	    for (p = p1 + 1 ; p < p2 ; p++)
	    {
		i = Li [p] ;
		if (i >= botrow)
		{
		    break ;
		}
		Nx [i] -= Lx [p] * xj ;
	    }
	}

	/* clear the Flag */
	mark = CHOLMOD(clear_flag) (Common) ;
    }

    /* ---------------------------------------------------------------------- */
    /* successful update/downdate */
    /* ---------------------------------------------------------------------- */

    Common->modfl = fl ;
    DEBUG (for (j = 0 ; j < n ; j++) ASSERT (IMPLIES (do_solve, Nx[j] == 0.))) ;
    ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, TRUE, Common)) ;
    DEBUG (CHOLMOD(dump_factor) (L, "output L for updown", Common)) ;
    return (TRUE) ;
}
Exemple #14
0
void main()
{
	char c2;
	int done, high,i, in, low;
	int x,y=1,z;
	int c;
	printstr("if then else(6 line block repeated)\n");
	printstr("x = 5\nx = 5\nx = 1\nx = 7	z = 0\nx = 3	z = 0\nx = 3	z = 1\n");
	if (y!=0) x=5;
	PRINT1(d,x);

	if (y==0) x=3;
	else x=5;
	PRINT1(d,x);

	x=1;
	if (y<00) if (y>0) x=3;
	else x=5;
	PRINT1(d,x);

	if (z=y<0) x=3;
	else if (y==0) x=5;
	else x=7;
	PRINT2(d,x,z);

	if (z=(y==0)) x=5; x=3;
	PRINT2(d,x,z);

	if (x=z=y) x=3;
	PRINT2(d,x,z);

	printstr("for & while(just look for checkfail msgs)\n");

	x=y=0;
	while (y<10) ++y; x+=y;;
	PRINT2(d,x,y); check2(x==10,y==10);

	x=y=0;
	while (y<10) x+= ++y;
	PRINT2(d,x,y); check2(x==55,y==10);

	y=1;;
	while (y<10) {
		x=y++; z=++y;
	}
	PRINT3(d,x,y,z); check3(x==9,y==11,z==11);

	for (y=1; y<10; y++) x=y;
	PRINT2(d,x,y);
	check2(x==9,y==10);

	for (y=1; (x=y)<10; y++) ;
	PRINT2(d,x,y); check2(x==10,y==10);

	for (x=0, y=1000; y>1; x++, y/=10)
	PRINT2(d,x,y);
	check2(x==3,y==1);
printstr(" nested statements(look for checkfails)\n");
#define ENUF 3
#define EOS '\0'
#define NEXT(i) input[i++]
#define FALSE 0
#define TRUE 1

	i=low=in=high=0;
	while( c=NEXT(i) !=EOS )
		if( c<'0' ) low++;
		else if( c>'9' ) high++;
		else in++;
	PRINT3 (d,low, in, high) ; check3(low==25,in==0, high==0);
	i=low=in=high=0; done=FALSE;
	while( (c=NEXT(i))!=EOS && !done )
		if( c<'0' ) low++;
		else if( c>'9' ) high++;
		else in++;
		if( low>=ENUF|| high>=ENUF|| in>=ENUF )
			done = TRUE;
	PRINT3(d,low,in,high); check3(low==3,in==6, high==16);

	i=low=in=high=0; done=FALSE;
	while( (c=NEXT(i))!=EOS && !done )
		if( c<'0' ) done=(++low==ENUF);
		else if( c>'9' ) done = (++high==ENUF);
		else done =(++in==ENUF);
	PRINT3(d,low,in,high); check3(low==0,in==0, high==3);

	printstr("switch/break/continue(prints SWITCH SWAMP\n");
	for( i=2; (c2=inpu2[i])!='\0'; i++) {
		switch(c2) {
			case 'a': putchar('i'); continue;
			case '1': break;
			case 1: while( (c2=inpu2[++i])!='\1'  && c2!='\0');
			case 9: putchar('S');
			case 'E': case 'L': continue;
			default: putchar(c2); continue;
		}
		putchar(' ');
	}
	putchar('\n');
printstr("And we're done\n");
}
// -----------------------------------------------------------------------------
// CSendObject::DoHandleResponsePhaseInfoL
// Handle Response - Checks whether the request was successful
// -----------------------------------------------------------------------------
//
TBool CSendObject::DoHandleResponsePhaseInfoL()
    {
    PRINT( _L( "MM MTP => CSendObject::DoHandleResponsePhaseInfoL" ) );

    TBool result = ETrue;

    // cache the width and height of video file
    iObjectFormat = iObjectInfo->Uint16L( CMTPTypeObjectInfo::EObjectFormat );
    iWidth = iObjectInfo->Uint32L( CMTPTypeObjectInfo::EImagePixWidth );
    iHeight = iObjectInfo->Uint32L( CMTPTypeObjectInfo::EImagePixWidth );
    PRINT3( _L("MM MTP <> CSendObject::DoHandleResponsePhaseInfoL iObjectFormat = 0x%x, iWidth = %d, iHeight = %d"),
        iObjectFormat,
        iWidth,
        iHeight );

    delete iDateMod;
    iDateMod = NULL;
    iDateMod = iObjectInfo->StringCharsL( CMTPTypeObjectInfo::EDateModified ).AllocL();

    // check if storage is full
    iObjectSize = iObjectInfo->Uint32L( CMTPTypeObjectInfo::EObjectCompressedSize );
    PRINT1( _L("MM MTP <> CSendObject::DoHandleResponsePhaseInfoL, iObjectSize = %Lu"), iObjectSize );

    if ( IsTooLarge( iObjectSize ) )
        {
        SendResponseL( EMTPRespCodeObjectTooLarge );
        Rollback();
        result = EFalse;
        }

    if ( result )
        {
        iProtectionStatus = iObjectInfo->Uint16L( CMTPTypeObjectInfo::EProtectionStatus );
        PRINT1( _L( "MM MTP <> CSendObject::DoHandleResponsePhaseInfoL iProtectionStatus = %d" ), iProtectionStatus );
        if ( iProtectionStatus != EMTPProtectionNoProtection
            && iProtectionStatus != EMTPProtectionReadOnly )
            {
            SendResponseL( EMTPRespCodeParameterNotSupported );
            Rollback();
            result = EFalse;
            }
        }

    if ( result )
        {
        result = GetFullPathNameL( iObjectInfo->StringCharsL( CMTPTypeObjectInfo::EFilename ) );
        if ( !result )
            {
            // File and/or parent pathname invalid.
            SendResponseL( EMTPRespCodeInvalidDataset );
            Rollback();
            }
        }

    if ( result )
        {
        if ( ExistsL( iFullPath ) )
            {
            SendResponseL( EMTPRespCodeAccessDenied );
            Rollback();
            result = EFalse;
            }
        }

    if ( result )
        {
        if ( KErrNone != ReserveObjectL() )
            {
            result = EFalse;
            }
        }
    PRINT1( _L( "MM MTP <= CSendObject::DoHandleResponsePhaseInfoL result = %d" ), result );

    return result;
    }
Exemple #16
0
Masker::~Masker ()
{
  PRINT3(min(m_time), mean(m_time), max(m_time));
}
Exemple #17
0
int main(void)
{
	float x = 1.1, y = 2.2, z = 3.3;
	PRINT3(x, y, z);
	return 0;
}