abc/src/opt/fxu/fxuSingle.c
/**Function*************************************************************

  Synopsis    [Computes and adds all single-cube divisors to storage.]

  Description [This procedure should be called once when the matrix is
  already contructed before the process of logic extraction begins..]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Function
Synopsis    [Computes and adds all single-cube divisors to storage.]

Description [This procedure should be called once when the matrix is
already contructed before the process of logic extraction begins..]




Function Synopsis [ Computes and adds all single - cube divisors to storage . ] Description [ This procedure should be called once when the matrix is already contructed before the process of logic extraction begins .. ]
void Fxu_MatrixComputeSingles( Fxu_Matrix * p, int fUse0, int nSingleMax )
{
    Fxu_Var * pVar;
    Vec_Ptr_t * vSingles;
    int i, k;
    p->nWeightLimit = 1 - fUse0;
    vSingles = Vec_PtrAlloc( 10000 );
    Fxu_MatrixForEachVariable( p, pVar )
        Fxu_MatrixComputeSinglesOneCollect( p, pVar, vSingles );
    p->nSingleTotal = Vec_PtrSize(vSingles) / 3;
    if ( Vec_PtrSize(vSingles) > nSingleMax )
    {
        int * pWeigtCounts, nDivCount, Weight, i, c;;
        assert( Vec_PtrSize(vSingles) % 3 == 0 );
        pWeigtCounts = ABC_ALLOC( int, 1000 );
        memset( pWeigtCounts, 0, sizeof(int) * 1000 );
        for ( i = 2; i < Vec_PtrSize(vSingles); i += 3 )
        {
            Weight = (int)(ABC_PTRUINT_T)Vec_PtrEntry(vSingles, i);
            if ( Weight >= 999 )
                pWeigtCounts[999]++;
            else
                pWeigtCounts[Weight]++;
        }
        nDivCount = 0;
        for ( c = 999; c >= 0; c-- )
        {
            nDivCount += pWeigtCounts[c];
            if ( nDivCount >= nSingleMax )
                break;
        }
        ABC_FREE( pWeigtCounts );
        k = 0;
        for ( i = 2; i < Vec_PtrSize(vSingles); i += 3 )
        {
            Weight = (int)(ABC_PTRUINT_T)Vec_PtrEntry(vSingles, i);
            if ( Weight < c )
                continue;
            Vec_PtrWriteEntry( vSingles, k++, Vec_PtrEntry(vSingles, i-2) );
            Vec_PtrWriteEntry( vSingles, k++, Vec_PtrEntry(vSingles, i-1) );
            Vec_PtrWriteEntry( vSingles, k++, Vec_PtrEntry(vSingles, i) );
            if ( k/3 == nSingleMax )
                break;
        }
        Vec_PtrShrink( vSingles, k );
        p->nWeightLimit = c;
    }
    assert( Vec_PtrSize(vSingles) % 3 == 0 );
    for ( i = 0; i < Vec_PtrSize(vSingles); i += 3 )
    {
        Fxu_MatrixAddSingle( p, 
            (Fxu_Var *)Vec_PtrEntry(vSingles,i), 
            (Fxu_Var *)Vec_PtrEntry(vSingles,i+1), 
            (int)(ABC_PTRUINT_T)Vec_PtrEntry(vSingles,i+2) );
    }
    Vec_PtrFree( vSingles );
}
void Fxu_MatrixComputeSingles ( Fxu_Matrix * p , int fUse0 , int nSingleMax ) { Fxu_Var * pVar ; Vec_Ptr_t * vSingles ; int i , k ; p -> nWeightLimit = 1 - fUse0 ; vSingles = Vec_PtrAlloc ( 10000 ) ; Fxu_MatrixForEachVariable ( p , pVar ) Fxu_MatrixComputeSinglesOneCollect ( p , pVar , vSingles ) ; p -> nSingleTotal = Vec_PtrSize ( vSingles ) / 3 ; if ( Vec_PtrSize ( vSingles ) > nSingleMax ) { int * pWeigtCounts , nDivCount , Weight , i , c ; ; assert ( Vec_PtrSize ( vSingles ) % 3 == 0 ) ; pWeigtCounts = ABC_ALLOC ( int , 1000 ) ; memset ( pWeigtCounts , 0 , sizeof ( int ) * 1000 ) ; for ( i = 2 ; i < Vec_PtrSize ( vSingles ) ; i += 3 ) { Weight = ( int ) ( ABC_PTRUINT_T ) Vec_PtrEntry ( vSingles , i ) ; if ( Weight >= 999 ) pWeigtCounts [ 999 ] ++ ; else pWeigtCounts [ Weight ] ++ ; } nDivCount = 0 ; for ( c = 999 ; c >= 0 ; c -- ) { nDivCount += pWeigtCounts [ c ] ; if ( nDivCount >= nSingleMax ) break ; } ABC_FREE ( pWeigtCounts ) ; k = 0 ; for ( i = 2 ; i < Vec_PtrSize ( vSingles ) ; i += 3 ) { Weight = ( int ) ( ABC_PTRUINT_T ) Vec_PtrEntry ( vSingles , i ) ; if ( Weight < c ) continue ; Vec_PtrWriteEntry ( vSingles , k ++ , Vec_PtrEntry ( vSingles , i - 2 ) ) ; Vec_PtrWriteEntry ( vSingles , k ++ , Vec_PtrEntry ( vSingles , i - 1 ) ) ; Vec_PtrWriteEntry ( vSingles , k ++ , Vec_PtrEntry ( vSingles , i ) ) ; if ( k / 3 == nSingleMax ) break ; } Vec_PtrShrink ( vSingles , k ) ; p -> nWeightLimit = c ; } assert ( Vec_PtrSize ( vSingles ) % 3 == 0 ) ; for ( i = 0 ; i < Vec_PtrSize ( vSingles ) ; i += 3 ) { Fxu_MatrixAddSingle ( p , ( Fxu_Var * ) Vec_PtrEntry ( vSingles , i ) , ( Fxu_Var * ) Vec_PtrEntry ( vSingles , i + 1 ) , ( int ) ( ABC_PTRUINT_T ) Vec_PtrEntry ( vSingles , i + 2 ) ) ; } Vec_PtrFree ( vSingles ) ; }
Function
Synopsis    [Computes and adds all single-cube divisors to storage.]
Function Synopsis [ Computes and adds all single - cube divisors to storage . ]
// set the weight limit // iterate through columns in the matrix and collect single-cube divisors // check if divisors should be filtered // count how many divisors have the given weight // select the bound on the weight (above this bound, singles will be included) // collect singles with the given costs // adjust the weight limit // collect the selected divisors