Beispiel #1
0
/**
 * Check if the EVDEV supports EV_ABS or EV_REL..
 */
gcc_pure
static bool
IsPointerDevice(int fd)
{
  assert(fd >= 0);

  unsigned long features[BitsToInts<unsigned long>(std::max(EV_ABS, EV_REL))];
  if (ioctl(fd, EVIOCGBIT(0, sizeof(features)), features) < 0)
    return false;

  return CheckBit(features, EV_ABS) || CheckBit(features, EV_REL);
}
 /// <summary>
 /// read the value of an individual pin.
 /// </summary>
 /// <param name="pin">1 - 16</param>
 /// <returns>0 = logic level low, 1 = logic level high</returns>
 bool ABElectronics_IOPi::ReadPin(byte pin)
 {
     pin = (byte)(pin - 1);
     if (pin >= 0 && pin < 8)
     {
         portaval = ReadI2CByte(GPIOA);
         return CheckBit(portaval, pin);
     }
     else if (pin >= 8 && pin < 16)
     {
         portbval = ReadI2CByte(GPIOB);
         return CheckBit(portbval, (byte)(pin - 8));
     }
     else
     {
          // default
     }
 }
Beispiel #3
0
static int CompressAndCrosscheckClusterVis( int clusternum )
{
    int		optimized = 0;
    byte	compressed[MAX_MAP_LEAFS/8];
//
// compress the bit string
//
    byte *uncompressed = uncompressedvis + clusternum*leafbytes;
    for ( int i = 0; i < portalclusters; i++ )
    {
        if ( i == clusternum )
            continue;

        if ( CheckBit( uncompressed, i ) )
        {
            byte *other = uncompressedvis + i*leafbytes;
            if ( !CheckBit( other, clusternum ) )
            {
                ClearBit( uncompressed, i );
                optimized++;
            }
        }
    }
    int numbytes = CompressVis( uncompressed, compressed );

    byte *dest = vismap_p;
    vismap_p += numbytes;

    if (vismap_p > vismap_end)
        Error ("Vismap expansion overflow");

    dvis->bitofs[clusternum][DVIS_PVS] = dest-vismap;

    memcpy( dest, compressed, numbytes );

    // check vis data
    DecompressVis( vismap + dvis->bitofs[clusternum][DVIS_PVS], compressed );

    return optimized;
}
Beispiel #4
0
Bool CheckKmerInBloomFilter(BloomFilter* const bf, const Kmer word) {
    uint128_t last_hash = bf->seed;
    uint idx;
    uint128_t hash;
    for (idx = 0; idx < bf->num_hash_functions; idx++) {
        if (MurmurHash3_128((char*)&word, 
                            sizeof(Kmer), 
                            last_hash, 
                            &hash) == FALSE) {
            PrintThenDie("could not ascertain hash for kmer");
        }
        if (CheckBit(bf->bs, hash % bf->num_bits) == 0) { 
            return FALSE;
        }
        last_hash = hash;
    }
    return TRUE;    
}
Beispiel #5
0
/*
===============
ClusterMerge

Merges the portal visibility for a leaf
===============
*/
void ClusterMerge (int clusternum)
{
    leaf_t		*leaf;
//	byte		portalvector[MAX_PORTALS/8];
    byte		portalvector[MAX_PORTALS/4];      // 4 because portal bytes is * 2
    byte		uncompressed[MAX_MAP_LEAFS/8];
    int			i, j;
    int			numvis;
    portal_t	*p;
    int			pnum;

    // OR together all the portalvis bits

    memset (portalvector, 0, portalbytes);
    leaf = &leafs[clusternum];
    for (i=0 ; i<leaf->numportals ; i++)
    {
        p = leaf->portals[i];
        if (p->status != stat_done)
            Error ("portal not done %d %d %d\n", i, p, portals);
        for (j=0 ; j<portallongs ; j++)
            ((long *)portalvector)[j] |= ((long *)p->portalvis)[j];
        pnum = p - portals;
        SetBit( portalvector, pnum );
    }

    // convert portal bits to leaf bits
    numvis = LeafVectorFromPortalVector (portalvector, uncompressed);

    if ( CheckBit( uncompressed, clusternum ) )
        Warning("WARNING: Cluster portals saw into cluster\n");

    SetBit( uncompressed, clusternum );
    numvis++;		// count the leaf itself

    // save uncompressed for PHS calculation
    memcpy (uncompressedvis + clusternum*leafbytes, uncompressed, leafbytes);

    qprintf ("cluster %4i : %4i visible\n", clusternum, numvis);
    totalvis += numvis;
}
Beispiel #6
0
/*
==============
LeafVectorFromPortalVector
==============
*/
int LeafVectorFromPortalVector (byte *portalbits, byte *leafbits)
{
    int			i;
    portal_t	*p;
    int			c_leafs;


    memset (leafbits, 0, leafbytes);

    for (i=0 ; i<g_numportals*2 ; i++)
    {
        if ( CheckBit( portalbits, i ) )
        {
            p = portals+i;
            SetBit( leafbits, p->leaf );
        }
    }

    c_leafs = CountBits (leafbits, portalclusters);

    return c_leafs;
}
Beispiel #7
0
void AddKmerToBloomFilter(BloomFilter* const bf, const Kmer word) {
    uint128_t last_hash = bf->seed;
    uint idx;
    uint128_t hash;
    Bool is_added = FALSE;
    for (idx = 0; idx < bf->num_hash_functions; idx++){
        if (MurmurHash3_128((char*)&word, 
                            sizeof(Kmer), 
                            last_hash, 
                            &hash) == FALSE) {
            PrintThenDie("could not ascertain hash for kmer");
        }
        if(SetBit(bf->bs, hash % bf->num_bits) == FALSE){
            assert(CheckBit(bf->bs, hash % bf->num_bits) > 0);
            bf->num_set_bits += 1;
            is_added = TRUE;
        }
        last_hash = hash;
    }

    if (is_added == TRUE) {
        bf->num_entries_added += 1;
    }
}
/*This implements the MC21 perfect matching*/
match_size_t FindPerfectMatch(Match_t *M,SparseGraph *G){
	unsigned int match_size=0;
	assert(G && M);
	node_t n = G->order;
	node_t *colind=G->colind;colind--;
	node_t *rowptr=G->rowptr;rowptr--;
	node_t *m = M->m;m--;
	BitArray_t *col_marker = CreateBitArray(n);
	BitArray_t *matched_row = CreateBitArray(n);
	node_t *p = (node_t *) malloc(sizeof(node_t)*n);p--;
	node_t *m_inv = (node_t *) malloc(sizeof(node_t)*n);m_inv--;
	node_t i,j,k,i1,jend;node_t m_inv_prev;char aug_extend=0;

	match_size=0;
	for(i=1;i<=n;i++){
		m_inv[i]=0;
	}
	for(j=1;j<=n;j++){
		if(m[j]){
			m_inv[m[j]]=j;
			match_size++;
		}
	}
	for(i=1;i<=n;i++){
		/*Augmenting path at any unmatched node*/
		if(m_inv[i]){
			continue;
		}
		i1 = i; p[i1]=0; jend=0;
		ResetAllBits(col_marker);
		while(i1 && !jend){
			for(k=0;k<(rowptr[i1+1]-rowptr[i1]);k++){
				j = colind[rowptr[i1]+k];
				if(!m[j]){
					jend=j;
					break;
				}
			}
			if(jend){
				/*Found an unmatched node*/
				break;
			}
			aug_extend=0;
			for(k=0;k<(rowptr[i1+1]-rowptr[i1]) && !jend;k++){
				j = colind[rowptr[i1]+k];
				if(!CheckBit(col_marker,j) && m[j]){
					p[m[j]]=i1;
					m_inv[m[j]]=j;
					SetBit(col_marker,j);
					i1 = m[j];
					aug_extend = 1;
					break;
				}
			}
			if(!aug_extend){
				/*Unable to find a unmarked matched node*/
				i1 = p[i1];
			}
		}
		if(i1){
			/*Augmenting path is found so augment*/
			j = jend; 
			printf("Augmenting the path {");
			while(i1){
				m_inv_prev = m_inv[i1];
				m[j] = i1; m_inv[i1] = j;
				printf("(%u,%u)",i1,j);
				j = m_inv_prev;
				i1 = p[i1];
			}
			printf("}\n");
			match_size++;
			printf("Match Size: %u\n",match_size);
		}else{
			/*the matching is maximum*/
			break;
		}
	}
	FreeBitArray(col_marker); FreeBitArray(matched_row);
	free(++m_inv); free(++p);
	printf("Done freeing\n");
	return match_size;
}
size_t WeightedMatching(RowStarts *rowptr,ColIndices *colind,ValueType *C,
ValueType *C1,ValueType *dist,ValueType *u,ValueType *v,Indices *p,
Indices *m_inv,Indices *m, Indices n,CompareFunction cmpFunc){

	size_t i,j,i1,jend,k,m_inv_prev;
	size_t match_size=0;
	ValueType curr_shortest_path = (ValueType)0;
	ValueType curr_aug_path = GetMaxTypeValue<ValueType>(); 
	ValueType dist1; Indices itrace;
	BitArray_t *col_marker = CreateBitArray(n);
	BitArray_t *heap_marker = CreateBitArray(n);
	C--;m--;C1--;dist--;u--;v--;p--;m_inv--;
	rowptr--;colind--;
#if BINARY_HEAP
	Heap *bin_heap = NewBinaryHeap(cmpFunc,n,GetDistKeyID);  
	ValueType *dist_ptr = NULL;
#endif
	assert(C1 && dist && u && v && p);
	ComputeInitialExtremeMatch<ValueType,Indices>(u,v,C1,C,m,m_inv,colind,rowptr,n,dist);
	match_size=0;
	for(i=1;i<=n;i++){
		if(m_inv[i]){
			match_size++;
			continue;
		}
		/*
		 *Aim is to find a value for jend such that the path
		 *from i-->jend is the shortest
		 */
		i1 = i; p[i1] = 0; jend=0; itrace=i;
		ResetAllBits(col_marker);
		ResetAllBits(heap_marker);
#if BINARY_HEAP
		bin_heap->n = 0;
		dist_base = (unsigned long)&(dist[1]);
#endif
		curr_shortest_path=(ValueType)0;
		curr_aug_path=GetMaxTypeValue<ValueType>();
		while(1){
			for(k=rowptr[i1];k<rowptr[i1+1];k++){
				j = colind[k];
				if(CheckBit(col_marker,j)){
					continue;
				}
				dist1 = curr_shortest_path + C1[k];
				/*Prune any dist1's > curr_aug_path, since
				 *all the costs>0 
				 */
				if(*((long long int *)&dist1) < *((long long int *)&curr_aug_path)){
					if(!m[j]){
						/*we need itrace because, the last i1 which
						 *we explore may not actually give the shortest 
						 *augmenting path.*/
						jend = j; itrace = i1;
						curr_aug_path = dist1;
					}else if(*((long long int *)&dist1) < *((long long int *)&(dist[j]))){ 
						/*Update the dist*/
						dist[j] = dist1; p[m[j]] = i1;
#if SIMPLE_HEAP
						SetBit(heap_marker,j);
#elif BINARY_HEAP
						if(CheckBit(heap_marker,j)){
							DecreaseKey(bin_heap,j);
						}else{
							InsertHeap(bin_heap,&(dist[j]));
							SetBit(heap_marker,j);
						}
#endif
					}
				}
			}
			if(*((long long int *)&curr_aug_path) <= *((long long int *)&curr_shortest_path)){ 
				break;
			}
			/*We now have a heap of matched cols, so pick the min*/
#ifdef SIMPLE_HEAP
			j = SimplePickMin(heap_marker,dist,n);
			if(j){
				curr_shortest_path = dist[j]; 
				UnsetBit(heap_marker,j); 
#elif BINARY_HEAP
			dist_ptr = (ValueType *) HeapDelete(bin_heap);
			if(dist_ptr){
				assert((unsigned long)dist_ptr >= (unsigned long)&dist[1]);
				j = ((((unsigned long)dist_ptr -
					(unsigned long)&dist[1]))/sizeof(double))+1;
				assert(j>=1 && j<=n);
				curr_shortest_path = dist[j]; 
				UnsetBit(heap_marker,j); 
#endif
				SetBit(col_marker,j);
				i1 = m[j];
			}else{
				break;
			}
		}
		if(jend){ /*We found a shortest augmenting path*/
			j=jend;
			node_t itrace_prev;
			//printf("Shortest augmenting Path {");
			while(itrace){
				m_inv_prev = m_inv[itrace];
				m[j] = itrace; m_inv[itrace]=j;
				//printf("(%u,%u)",itrace,j);
				j=m_inv_prev;
				itrace_prev = itrace;
				itrace = p[itrace];
				if(itrace){
				//	printf("(%u,%u)",itrace_prev,m_inv_prev);
				}
			}
			match_size++;
			//printf("}\n");
			/*Update the cost with new match m*/
			for(j=1;j<=n;j++){
				if(CheckBit(col_marker,j)){
					u[j] = (u[j]+dist[j])-curr_aug_path;
					/*Reset the dist values*/
				}
			}
			for(i1=1;i1<=n;i1++){
				if(!m_inv[i1]) continue;
				j = m_inv[i1];
				for(k=rowptr[i1];k<rowptr[i1+1];k++){
					if(colind[k] == j){
						v[i1] = C[k] - u[j];
					}
				}
			}
			/*Update the cost*/
			for(i1=1;i1<=n;i1++){
				for(k=rowptr[i1];k<rowptr[i1+1];k++){
					j = colind[k];
					C1[k] = C[k]-(u[j]+v[i1]);
				}
				/*The index should be j rather than i1 but just 
				 *avoiding another loop*/
				dist[i1] = GetMaxTypeValue<double>();
			}
		}
	}
	FreeBitArray(col_marker);
	FreeBitArray(heap_marker);
#ifdef BINARY_HEAP	
	FreeHeap(bin_heap);
#endif

	return match_size;
}
/*O(n) time picking the maximum from the heap_marker */
node_t SimplePickMin(BitArray_t *bit_heap,double *dist,node_t n){
	node_t min_j=0;node_t j; 
	double curr_min = MAX_DOUBLE_VALUE; 
	for(j=1;j<=n;j++){
		if(CheckBit(bit_heap,j) && dist[j] < curr_min){
			min_j = j;
			curr_min = dist[j];
		}
	}
	return min_j;
}
Beispiel #10
0
void NvCheckForErrors(void) 
{
  UINT32 val=PMC_Read(INTR_0);
  /* Has an interrupt been raised ???? */  
  /*if(val==0) return;*/
  /*  Info("An Interrupt has been raised.\n");*/
  CheckBit(val,PMC,INTR_0_PAUDIO);
  CheckBit(val,PMC,INTR_0_PDMA);
  CheckBit(val,PMC,INTR_0_PFIFO);
  CheckBit(val,PMC,INTR_0_PGRAPH);
  CheckBit(val,PMC,INTR_0_PRM);
  CheckBit(val,PMC,INTR_0_PTIMER);
  CheckBit(val,PMC,INTR_0_PFB);
  CheckBit(val,PMC,INTR_0_SOFTWARE);

  val=PGRAPH_Read(INTR_0);
  CheckBit(val,PGRAPH,INTR_0_RESERVED);
  CheckBit(val,PGRAPH,INTR_0_CONTEXT_SWITCH);
  /* CheckBit(val,PGRAPH,INTR_0_VBLANK);*/
  CheckBit(val,PGRAPH,INTR_0_RANGE);
  CheckBit(val,PGRAPH,INTR_0_METHOD_COUNT);
  CheckBit(val,PGRAPH,INTR_0_SOFTWARE);
  CheckBit(val,PGRAPH,INTR_0_COMPLEX_CLIP);
  CheckBit(val,PGRAPH,INTR_0_NOTIFY);

  val=PFIFO_Read(INTR_0);
  CheckBit(val,PFIFO,INTR_0_CACHE_ERROR);
  CheckBit(val,PFIFO,INTR_0_RUNOUT);
  CheckBit(val,PFIFO,INTR_0_RUNOUT_OVERFLOW);
}
Beispiel #11
0
//2 utf8 dom
//1 utf8
//0 not utf8
int IsUtf8(char* buf,int size)
{
	int i;
	int u8 = 0;
	int u8len = 0;
	int firstbyte = 0;
	const char BOM[3] = {0xef,0xbb,0xbf};

	if(size == 0)
	{
		return 0;
	}
	if(size >= 3 && strncmp(buf,BOM,3) == 0)
	{
		return 2;
	}

	for(i=0;i<size;i++)
	{
		//should be binrary file.
		if(buf[i] == 0)
		{
			return 0;
		}


		if(firstbyte == 0)
		{
			//pure ascii
			if((buf[i]&0xff) <= 127)
			{
				u8 = 0;
				u8len = 0;
			}
			//unknow char
			else if((buf[i]&0xff) > 0xef)
			{
				u8 = 0;
				u8len = 0;
			}
			else
			{
				firstbyte = 1;
				//111*****
				if(CheckBit(buf[i],7) == 1 && CheckBit(buf[i],6) == 1)
				{
					u8 = 1;
					u8len++;
				}
				else
				{
					i++;
					firstbyte = 0;
					u8 = 0;
					u8len = 0;
				}
			}
		}
		else
		{
			if((buf[i]&0xff) <= 127 || (buf[i]&0xff) > 0xef)
			{
				firstbyte = 0;
				
				if(u8 == 1 && u8len % 3 != 0)
				{
					u8 = 0;
				}
				else if(u8 == 1 && u8len % 3 == 0)
				{
					//so we mark it utf8
					break;
				}
			}
			else
			{
				u8len++;
			}
		}
	}

	//check tail loop
	if(u8 == 1 && u8len % 3 != 0)
	{
		u8 = 0;
	}

	return u8;
}
Beispiel #12
0
//-----------------------------------------------------------------------------
// Using the PVS, compute the visible fog volumes from each leaf
//-----------------------------------------------------------------------------
static void CalcVisibleFogVolumes()
{
    byte	uncompressed[MAX_MAP_LEAFS/8];

    int i, j, k;

    // Clear the contents flags for water testing
    for (i = 0; i < numleafs; ++i)
    {
        dleafs[i].contents &= ~CONTENTS_TESTFOGVOLUME;
        g_LeafMinDistToWater[i] = 65535;
    }

    for (i = 0; i < numleafs; ++i)
    {
        // If we've already discovered that this leaf needs testing,
        // no need to go through the work again...
        if (dleafs[i].contents & CONTENTS_TESTFOGVOLUME)
        {
            Assert((dleafs[i].contents & (CONTENTS_SLIME | CONTENTS_WATER)) == 0);
            continue;
        }

        // Don't bother checking fog volumes from solid leaves
        if (dleafs[i].contents & CONTENTS_SOLID)
            continue;

        // Look only for leaves which are visible from leaves that have fluid in them.
        if ( dleafs[i].leafWaterDataID == -1 )
            continue;

        // Don't bother about looking from CONTENTS_SLIME; we're not going to treat that as interesting.
        // because slime is opaque
        if ( dleafs[i].contents & CONTENTS_SLIME )
            continue;

        // First get the vis data..
        int cluster = dleafs[i].cluster;
        if (cluster < 0)
            continue;

        DecompressVis( &dvisdata[dvis->bitofs[cluster][DVIS_PVS]], uncompressed );

        // Iterate over all potentially visible clusters from this leaf
        for (j = 0; j < dvis->numclusters; ++j)
        {
            // Don't need to bother if this is the same as the current cluster
            if (j == cluster)
                continue;

            if ( !CheckBit( uncompressed, j ) )
                continue;

            // Found a visible cluster, now iterate over all leaves
            // inside that cluster
            for (k = 0; k < g_ClusterLeaves[j].leafCount; ++k)
            {
                int nClusterLeaf = g_ClusterLeaves[j].leafs[k];

                // Don't bother checking fog volumes from solid leaves
                if ( dleafs[nClusterLeaf].contents & CONTENTS_SOLID )
                    continue;

                // Don't bother checking from any leaf that's got fluid in it
                if ( dleafs[nClusterLeaf].leafWaterDataID != -1 )
                    continue;

                // Here, we've found a case where a non-liquid leaf is visible from a liquid leaf
                // So, in this case, we have to do the expensive test during rendering.
                dleafs[nClusterLeaf].contents |= CONTENTS_TESTFOGVOLUME;
            }
        }
    }
}
Beispiel #13
0
static float CalcDistanceFromLeafToWater( int leafNum )
{
    byte	uncompressed[MAX_MAP_LEAFS/8];

    int j, k;

    // If we know that this one doesn't see a water surface then don't bother doing anything.
    if( ((dleafs[leafNum].contents & CONTENTS_TESTFOGVOLUME) == 0) && ( dleafs[leafNum].leafWaterDataID == -1 ) )
        return 65535; // FIXME: make a define for this.

    // First get the vis data..
    int cluster = dleafs[leafNum].cluster;
    if (cluster < 0)
        return 65535; // FIXME: make a define for this.

    DecompressVis( &dvisdata[dvis->bitofs[cluster][DVIS_PVS]], uncompressed );

    float minDist = 65535.0f; // FIXME: make a define for this.

    Vector leafMin, leafMax;

    leafMin[0] = ( float )dleafs[leafNum].mins[0];
    leafMin[1] = ( float )dleafs[leafNum].mins[1];
    leafMin[2] = ( float )dleafs[leafNum].mins[2];
    leafMax[0] = ( float )dleafs[leafNum].maxs[0];
    leafMax[1] = ( float )dleafs[leafNum].maxs[1];
    leafMax[2] = ( float )dleafs[leafNum].maxs[2];

    /*
    	CUtlVector<listplane_t> temp;

    	// build a convex solid out of the planes so that we can get at the triangles.
    	for( j = dleafs[i].firstleafbrush; j < dleafs[i].firstleafbrush + dleafs[i].numleafbrushes; j++ )
    	{
    		dbrush_t *pBrush = &dbrushes[j];
    		for( k = pBrush->firstside; k < pBrush->firstside + pBrush->numsides; k++ )
    		{
    			dbrushside_t *pside = dbrushsides + k;
    			dplane_t *pplane = dplanes + pside->planenum;
    			AddListPlane( &temp, pplane->normal[0], pplane->normal[1], pplane->normal[2], pplane->dist );
    		}
    		CPhysConvex *pConvex = physcollision->ConvexFromPlanes( (float *)temp.Base(), temp.Count(), VPHYSICS_MERGE );
    		ConvertConvexToCollide(  &pConvex,
    			temp.RemoveAll();
    	}
    */

    // Iterate over all potentially visible clusters from this leaf
    for (j = 0; j < dvis->numclusters; ++j)
    {
        // Don't need to bother if this is the same as the current cluster
        if (j == cluster)
            continue;

        // If the cluster isn't in our current pvs, then get out of here.
        if ( !CheckBit( uncompressed, j ) )
            continue;

        // Found a visible cluster, now iterate over all leaves
        // inside that cluster
        for (k = 0; k < g_ClusterLeaves[j].leafCount; ++k)
        {
            int nClusterLeaf = g_ClusterLeaves[j].leafs[k];

            // Don't bother testing the ones that don't see a water boundary.
            if( ((dleafs[nClusterLeaf].contents & CONTENTS_TESTFOGVOLUME) == 0) && ( dleafs[nClusterLeaf].leafWaterDataID == -1 ) )
                continue;

            // Find the minimum distance between each surface on the boundary of the leaf
            // that we have the pvs for and each water surface in the leaf that we are testing.
            int nFirstFaceID = dleafs[nClusterLeaf].firstleafface;
            for( int leafFaceID = 0; leafFaceID < dleafs[nClusterLeaf].numleaffaces; ++leafFaceID )
            {
                int faceID = dleaffaces[nFirstFaceID + leafFaceID];
                dface_t *pFace = &dfaces[faceID];
                if( pFace->texinfo == -1 )
                    continue;

                texinfo_t *pTexInfo = &texinfo[pFace->texinfo];
                if( pTexInfo->flags & SURF_WARP )
                {
                    // Woo hoo!!!  We found a water face.
                    // compare the bounding box of the face with the bounding
                    // box of the leaf that we are looking from and see
                    // what the closest distance is.
                    // FIXME: this could be a face/face distance between the water
                    // face and the bounding volume of the leaf.

                    // Get the bounding box of the face
                    Vector faceMin, faceMax;
                    GetBoundsForFace( faceID, faceMin, faceMax );
                    float dist = GetMinDistanceBetweenBoundingBoxes( leafMin, leafMax, faceMin, faceMax );
                    if( dist < minDist )
                    {
                        minDist = dist;
                    }
                }
            }
        }
    }
    return minDist;
}
Beispiel #14
0
/*
================
CalcPAS

Calculate the PAS (Potentially Audible Set)
by ORing together all the PVS visible from a leaf
================
*/
void CalcPAS (void)
{
    int		i, j, k, l, index;
    int		bitbyte;
    long	*dest, *src;
    byte	*scan;
    int		count;
    byte	uncompressed[MAX_MAP_LEAFS/8];
    byte	compressed[MAX_MAP_LEAFS/8];

    Msg ("Building PAS...\n");

    count = 0;
    for (i=0 ; i<portalclusters ; i++)
    {
        scan = uncompressedvis + i*leafbytes;
        memcpy (uncompressed, scan, leafbytes);
        for (j=0 ; j<leafbytes ; j++)
        {
            bitbyte = scan[j];
            if (!bitbyte)
                continue;
            for (k=0 ; k<8 ; k++)
            {
                if (! (bitbyte & (1<<k)) )
                    continue;
                // OR this pvs row into the phs
                index = ((j<<3)+k);
                if (index >= portalclusters)
                    Error ("Bad bit in PVS");	// pad bits should be 0
                src = (long *)(uncompressedvis + index*leafbytes);
                dest = (long *)uncompressed;
                for (l=0 ; l<leaflongs ; l++)
                    ((long *)uncompressed)[l] |= src[l];
            }
        }
        for (j=0 ; j<portalclusters ; j++)
        {
            if ( CheckBit( uncompressed, j ) )
            {
                count++;
            }
        }

        //
        // compress the bit string
        //
        j = CompressVis (uncompressed, compressed);

        dest = (long *)vismap_p;
        vismap_p += j;

        if (vismap_p > vismap_end)
            Error ("Vismap expansion overflow");

        dvis->bitofs[i][DVIS_PAS] = (byte *)dest-vismap;

        memcpy (dest, compressed, j);
    }

    Msg ("Average clusters audible: %i\n", count/portalclusters);
}
size_t WeightedMatching(RowStarts rowptr,ColIndices colind,ValueTypePtr C,
ValueTypePtr dist,ValueTypePtr u,ValueTypePtr v,Indices *p,
Indices *m_inv,Indices *m, Indices n,CompareFunction cmpFunc){
	typedef typename std::iterator_traits<ValueTypePtr>::value_type ValueType;
	Indices i,j,i1,jend,k,m_inv_prev;
	Indices match_size=0; Indices k0,j0;
	ValueType curr_shortest_path = (ValueType)0;
	ValueType curr_aug_path = GetMaxTypeValue<ValueType>(curr_aug_path); 
	ValueType dist1; Indices itrace;
	/*Cost of the edges in the match if
	 *$(i,j) \in M$ then $clabel[i] = C[i][j]$*/
	Indices *clabel = new Indices[n];
	Indices *aug_label = new Indices[n];
	Indices *update_stack = new Indices[n];
	Indices update_stack_index;
	/*Save The Operations on the Heap.*/
	Indices save_heap_index;
	Indices *save_heap_op = new Indices[n];
#ifdef TURN_ON_SAVE_HEAP
	double close_factor = (double)1.0 + (double)1.0e-16;
#endif
	/*Force the write back to memory to avoid floating point issues*/
	ValueType force_mem_write[3];
#ifndef NO_LOCAL_PROFILING
	CreateProfilingClocks();
#endif

	/*Core Profiling Clock*/
	Clock *core_clk = CreateClock();
#ifdef USE_BIT_ARRAY
	BitArray_t *col_marker = CreateBitArray(n);
	BitArray_t *heap_marker = CreateBitArray(n);
#else
	Indices *col_marker = new Indices[n];
	unsigned int *heap_marker = NULL;
	col_marker--;
	for(i=1;i<=n;i++){ /*Do we need Initialization?*/
		col_marker[i] = (Indices)0;
	}
#endif
#if BINARY_HEAP
	Heap *bin_heap = NewBinaryHeap(cmpFunc,n,GetDistKeyID);  
	ValueType *dist_ptr = NULL;
	heap_marker = bin_heap->keyMap;
#endif
	/*Algorithm Uses 1-Indexing to be consistent*/
	C--;m--;dist--;u--;v--;p--;m_inv--;
	rowptr--;colind--;clabel--;save_heap_op--;
	update_stack--;aug_label--;
	assert(dist && u && v && p);
	ComputeInitialExtremeMatch<ValueType,Indices>(u,v,clabel,C,m,m_inv,colind,
		rowptr,n,dist);
	match_size=0; 

	StartClock(core_clk);

	for(i=1;i<=n;i++){
		if(m_inv[i]){
			match_size++;
			continue;
		}
		/*
		 *Aim is to find a value for jend such that the path
		 *from i-->jend is the shortest
		 */
		i1 = i; p[i1] = 0; jend=0; itrace=i;
#ifdef USE_BIT_ARRAY
		ResetAllBits(col_marker);
		ResetAllBits(heap_marker);
#endif

#if BINARY_HEAP
		bin_heap->n = 0;
		dist_base = (unsigned long)&(dist[1]);
#endif
		curr_shortest_path=(ValueType)0;
		curr_aug_path=GetMaxTypeValue<ValueType>(curr_aug_path);
		save_heap_index = (Indices)0;
		update_stack_index = (Indices)0;
		while(1){
			for(k=rowptr[i1]+1;k<(rowptr[i1+1]+1);k++){ 
				j = colind[k]+1; 
#ifdef USE_BIT_ARRAY
				if(CheckBit(col_marker,j)){
#else
				if(col_marker[j]==i){
#endif
					continue;
				}
				force_mem_write[k%3] = C[k]-(v[i1]+u[j]);
				dist1 = curr_shortest_path + force_mem_write[k%3];
				/*Prune any dist1's > curr_aug_path, since
				 *all the costs>0 
				 */
				if(dist1 < curr_aug_path){
					if(!m[j]){
						/*we need itrace because, the last i1 which
						 *we explore may not actually give the shortest 
						 *augmenting path.*/
						jend = j; itrace = i1;
						curr_aug_path = dist1;
						aug_label[j] = k;
					}else if(dist1 < dist[j]){ 
						/*Update the dist*/
						dist[j] = dist1; p[m[j]] = i1;
						aug_label[j] = k;
#if SIMPLE_HEAP

#ifdef USE_BIT_ARRAY
						SetBit(heap_marker,j);
#else
						heap_marker[j] = i;
#endif

#elif BINARY_HEAP /*SIMPLE_HEAP*/

#ifdef USE_BIT_ARRAY
						if(CheckBit(heap_marker,j)){
#else
						if(heap_marker[j]){
#endif
#ifndef NO_LOCAL_PROFILING
							StartClock(hupdate_clk);
#endif
							/*Call the decrease Key Operation*/
							DecreaseKey(bin_heap,j);

#ifndef NO_LOCAL_PROFILING
							StopClock(hupdate_clk);
							hupdate_ticks += GetClockTicks(hupdate_clk);
#endif
						}
#ifdef TURN_ON_SAVE_HEAP 
						else if(curr_shortest_path &&  
							dist[j] <= (curr_shortest_path)*(close_factor)){
							/*If dist[j] is close to root push it in
							 *save_heap_op*/
							 assert(save_heap_index < n);
							 save_heap_op[++save_heap_index] = j;
						}
#endif					
						else{
#ifndef NO_LOCAL_PROFILING
							StartClock(hins_clk);
#endif
							InsertHeap(bin_heap,&(dist[j]));
#ifndef NO_LOCAL_PROFILING
							StopClock(hins_clk);
							hins_ticks += GetClockTicks(hins_clk);
#endif
#ifdef USE_BIT_ARRAY
							SetBit(heap_marker,j);
#endif
						}
#endif /*SIMPLE_HEAP*/
					}
				}
			}
			if(curr_aug_path <= curr_shortest_path){ 
				break;
			}
			/*We now have a heap of matched cols, so pick the min*/
#ifdef SIMPLE_HEAP
			j = SimplePickMin(heap_marker,dist,n);
			if(j){
				curr_shortest_path = dist[j]; 
				UnsetBit(heap_marker,j); 
#elif BINARY_HEAP


#ifndef NO_LOCAL_PROFILING
			StartClock(hdel_clk);
#endif
			if(save_heap_index){
				j = save_heap_op[save_heap_index];
				save_heap_index--;
				curr_shortest_path = dist[j]; 
#ifdef USE_BIT_ARRAY
				SetBit(col_marker,j);
#else
				col_marker[j] = (Indices)i;
				update_stack[++update_stack_index]=j;
#endif /*#ifdef USE_BIT_ARRAY*/

				i1 = m[j];
			}else if(dist_ptr = (ValueType *) HeapDelete(bin_heap)) {
#ifndef NO_LOCAL_PROFILING
				StopClock(hdel_clk);
				hdel_ticks += GetClockTicks(hdel_clk);
#endif
				assert((unsigned long)dist_ptr >= (unsigned long)&dist[1]);
				j = ((((unsigned long)dist_ptr -
					(unsigned long)&dist[1]))/sizeof(ValueType))+1;
				assert(j>=1 && j<=n);
				curr_shortest_path = dist[j]; 
				heap_marker[j] = 0; /*Setting the keyMap in Heap to 0*/
#endif /*#ifdef SIMPLE_HEAP */


#ifdef USE_BIT_ARRAY
				SetBit(col_marker,j);
				update_stack[++update_stack_index]=j;
#else
				col_marker[j] = (Indices)i;
				update_stack[++update_stack_index]=j;
#endif /*#ifdef USE_BIT_ARRAY*/

				i1 = m[j];
			}else{
				break;
			}
		}
		/*We found a shortest augmenting path*/
		if(jend){ 
			unsigned long **harray = bin_heap->heapArray;
#ifndef NO_LOCAL_PROFILING
			StartClock(dual_clk);
#endif
			/*NOTE1: We need a very fast way to update
			 *the dual variables and also reset the dist[]
			 *we avoid linear scan where ever we can to update
			 *these dual variables*/
			while(update_stack_index){ /*Update u[j]: while*/
				j=update_stack[update_stack_index--];
				u[j] = (u[j]+dist[j])-curr_aug_path;
				if(m[j]){ /*See NOTE1*/
					i1 = m[j];
					v[i1] = C[clabel[i1]] - u[j];
				}
				dist[j] = MAX_DOUBLE_VALUE;
				if(bin_heap->n){
					dist_ptr = (double *)harray[bin_heap->n];
					j = ((((unsigned long)dist_ptr -
						(unsigned long)&dist[1]))/sizeof(ValueType))+1;
					heap_marker[j] = 0;
					*((double *)harray[bin_heap->n]) = MAX_DOUBLE_VALUE;
					bin_heap->n -= 1 ;
				}
			} /*Update u[j]: while*/
			
			/*Uncomment if you need to print augmenting path*/
			/*node_t itrace_prev;*/
			/*printf("Shortest augmenting Path {");*/

			j=jend;
			while(itrace){
				m_inv_prev = m_inv[itrace];
				m[j] = itrace; m_inv[itrace]=j;
				/*See NOTE1(above)*/
				clabel[itrace] = aug_label[j];
				v[itrace] = C[clabel[itrace]] - u[j];
				/*printf("(%u,%u)",itrace,j);*/
				j=m_inv_prev;
				/*itrace_prev = itrace;*/
				itrace = p[itrace];
				/*
				if(itrace){
					printf("(%u,%u)",itrace_prev,m_inv_prev);
				}*/
			}
			/*printf("}\n");*/
			/*There may some dist[] still in the heap*/
			while(bin_heap->n){
				dist_ptr = (double *)harray[bin_heap->n];
				j = ((((unsigned long)dist_ptr -
					(unsigned long)&dist[1]))/sizeof(ValueType))+1;
				heap_marker[j] = 0;
				*((double *)harray[bin_heap->n]) = MAX_DOUBLE_VALUE;
				bin_heap->n -= 1;
			}
			match_size++;
			/*End Dual Update*/
#ifndef NO_LOCAL_PROFILING
			StopClock(dual_clk);
			dual_ticks += GetClockTicks(dual_clk);
#endif
		} /*if(jend) : Found Augmeting Path*/
	} /*for(i=1;i<=n;i++): Main Outer Loop*/

	StopClock(core_clk);
	WeightedMatchTicks = GetClockTicks(core_clk);

#ifndef NO_LOCAL_PROFILING
	printf("Profile Summary\n");
	printf("HINS=(%d) HDEL=(%d) HUPDATE=(%d)\n",(int)hins_ticks,(int)hdel_ticks,
		(int)hupdate_ticks);
	printf("DUAL=(%d) \n",(int)dual_ticks);
#endif

#ifdef USE_BIT_ARRAY
	FreeBitArray(col_marker);
	FreeBitArray(heap_marker);
#else
	col_marker++;
	delete col_marker; 
#endif

#ifdef SIMPLE_HEAP
	heap_marker++;
	delete heap_marker;
#endif

	aug_label++;
	delete aug_label;
	save_heap_op++;
	delete save_heap_op;
	clabel++;
	delete clabel;
#ifdef BINARY_HEAP	
	FreeHeap(bin_heap);
#endif
	return match_size;
}
/*O(n) time picking the maximum from the heap_marker */
node_t SimplePickMin(BitArray_t *bit_heap,double *dist,node_t n){
	node_t min_j=0;node_t j; 
	double curr_min = HUGE_VAL; 
	for(j=1;j<=n;j++){
		if(CheckBit(bit_heap,j) && dist[j] < curr_min){
			min_j = j;
			curr_min = dist[j];
		}
	}
	return min_j;
}
#ifdef BINARY_HEAP 
inline keyid_t GetDistKeyID(void *dist_ptr){ assert((unsigned long)dist_ptr >= dist_base);
	return (((((unsigned long)dist_ptr-dist_base))/sizeof(double))+1);
}
#endif

BitArray_t* CreateBitArray(unsigned int size){
	div_t d = div(size,SIZE_OF_BYTE_IN_BITS);
	BitArray_t *bits = (BitArray_t *)malloc(sizeof(BitArray_t)*1);
	assert(bits);
	bits->size = (d.rem > 0)?(d.quot+1):d.quot;
	bits->ba = (char *)malloc(sizeof(char)*(bits->size));
	assert(bits->ba);
	memset(bits->ba,'\0',bits->size);
	return bits;
}