Exemplo n.º 1
0
int kth_smallest_idx(elem_type a[], int n, int k) {
	register unsigned int i, j, l, m;
	register elem_type x;

	l = 0;
	m = n - 1;
	while (l < m) {
		x = a[k];
		i = l;
		j = m;
		do {
			while (a[i] < x)
				i++;
			while (x < a[j])
				j--;
			if (i <= j) {
				ELEM_SWAP(a[i], a[j]);
				i++;
				j--;
			}
		} while (i <= j);
		if (j < k)
			l = i;
		if (k < i)
			m = j;
	}
	return k;
}
Exemplo n.º 2
0
void fmat_rev(fmat_t *s) {
  uint_t i,j;
  for (i=0; i< s->height; i++) {
    for (j=0; j< FLOOR(s->length/2); j++) {
      ELEM_SWAP(s->data[i][j], s->data[i][s->length-1-j]);
    }
  }
}
Exemplo n.º 3
0
void
fvec_shift (fvec_t * s)
{
  uint_t j;
  for (j = 0; j < s->length / 2; j++) {
    ELEM_SWAP (s->data[j], s->data[j + s->length / 2]);
  }
}
Exemplo n.º 4
0
float median(float arr[], int n)
{
   int low, high;
   int median;
   int middle, ll, hh;

   low = 0;
   high = n - 1;
   median = (low + high) / 2;
   for (;;) {
      if (high <= low)          /* One element only */
         return arr[median];

      if (high == low + 1) {    /* Two elements only */
         if (arr[low] > arr[high])
            ELEM_SWAP(arr[low], arr[high]);
         return arr[median];
      }

      /* Find median of low, middle and high items; swap into position low */
      middle = (low + high) / 2;
      if (arr[middle] > arr[high])
         ELEM_SWAP(arr[middle], arr[high]);
      if (arr[low] > arr[high])
         ELEM_SWAP(arr[low], arr[high]);
      if (arr[middle] > arr[low])
         ELEM_SWAP(arr[middle], arr[low]);

      /* Swap low item (now in position middle) into position (low+1) */
      ELEM_SWAP(arr[middle], arr[low + 1]);

      /* Nibble from each end towards middle, swapping items when stuck */
      ll = low + 1;
      hh = high;
      for (;;) {
         do
            ll++;
         while (arr[low] > arr[ll]);
         do
            hh--;
         while (arr[hh] > arr[low]);

         if (hh < ll)
            break;

         ELEM_SWAP(arr[ll], arr[hh]);
      }

      /* Swap middle item (in position low) back into correct position */
      ELEM_SWAP(arr[low], arr[hh]);

      /* Re-set active partition */
      if (hh <= median)
         low = ll;
      if (hh >= median)
         high = hh - 1;
   }
}
Exemplo n.º 5
0
void
fvec_ishift (fvec_t * s)
{
  uint_t half = s->length / 2, start = half, j;
  // if length is odd, middle element is moved to the beginning
  if (2 * half < s->length) start ++;
#ifndef HAVE_ATLAS
  for (j = 0; j < half; j++) {
    ELEM_SWAP (s->data[j], s->data[j + start]);
  }
#else
  aubio_cblas_swap(half, s->data, 1, s->data + start, 1);
#endif
  if (start != half) {
    for (j = 0; j < half; j++) {
      ELEM_SWAP (s->data[half], s->data[j]);
    }
  }
}
Exemplo n.º 6
0
double kth_smallest_double (double x[], int N, int k)

{

	register int i, j, l, m;
    
	register double tmp;

    l = 0;
    m = N - 1;
    
    while (l < m) {
    
        tmp = x[k];
        
       	i = l;
        j = m;
        
        do {
        
            while (x[i] < tmp) i++;
            while (tmp < x[j]) j--;
            
            if (i<=j) {
                ELEM_SWAP(x[i],x[j]);
                i++;
                j--;
            }
            
        } while (i <= j);
        
        if (j < k) l = i;
        if (k < i) m = j;
        
    }
    
    return x[k];
    
}
Exemplo n.º 7
0
int kth_smallest(int a[], int n, int k) {
	register i,j,l,m ;
	register int x, t;

    l=0 ; m=n-1 ;
    while (l<m) {
        x=a[k] ;
        i=l ;
        j=m ;
        do {
            while (a[i]<x) i++ ;
            while (x<a[j]) j-- ;
            if (i<=j) {
            	ELEM_SWAP(a[i],a[j]) ;
                i++ ; j-- ;
            }
        } while (i<=j) ;
        if (j<k) l=i ;
        if (k<i) m=j ;
    }
    return a[k] ;
}
Exemplo n.º 8
0
Arquivo: median.c Projeto: jobovy/nemo
real kth_smallest(int n, real  *x,  int k)
{
  register int i,j,l,m;
  register real xi;

  l=0 ; m=n-1 ;
  while (l<m) {
    xi=x[k] ;
    i=l ;
    j=m ;
    do {
      while (x[i]<xi) i++ ;
      while (xi<x[j]) j-- ;
      if (i<=j) {
	ELEM_SWAP(x[i],x[j]) ;
	i++ ; j-- ;
      }
    } while (i<=j) ;
    if (j<k) l=i ;
    if (k<i) m=j ;
  }
  return x[k] ;
}
Exemplo n.º 9
0
static elem_type
kth_smallest(elem_type a[], int n, int k)
{
  int i,j,l,m ;
  elem_type x ;

  l=0 ; m=n-1 ;
  while (l<m) {
    x=a[2*k+1] ;
    i=l ;
    j=m ;
    do {
      while (a[2*i+1]<x) i++ ;
      while (x<a[2*j+1]) j-- ;
      if (i<=j) {
        ELEM_SWAP(a[2*i+1],a[2*j+1]) ;
        i++ ; j-- ;
      }
    } while (i<=j) ;
    if (j<k) l=i ;
    if (k<i) m=j ;
  }
  return a[2*k+1] ;
}
Exemplo n.º 10
0
unsigned char median_uint8(unsigned char x[], int N) 

{

	register int low, median, high;
        
	register int middle, ll, hh;

	// set location values
	
    low = 0;
    high = N - 1;
    median = (low + high) / 2;
    
    for (;;) {
    
    	// one element only
    	
        if (high <= low)
        
            return x[median];
            
		// two elements only
		
        if (high == low + 1) {
        
            if (x[low] > x[high]) {
                ELEM_SWAP(x[low], x[high]);
           	}
           	
            return x[median];
            
        }

	    // find median of low, middle and high items, swap into position low
	    
	    middle = (low + high) / 2;
	    
	    if (x[middle] > x[high]) {
	    	ELEM_SWAP(x[middle], x[high]);
	    }
	    
	    if (x[low] > x[high]) {
	    	ELEM_SWAP(x[low], x[high]);
	    }
	    
	    if (x[middle] > x[low]) {
	    	ELEM_SWAP(x[middle], x[low]);
	    }

	    // swap low item (now in position middle) into position (low + 1)
	    
	    ELEM_SWAP(x[middle], x[low + 1]);

	    // nibble from each end towards middle, swapping items when stuck
	    
	    ll = low + 1;
	    hh = high;
    
	    for (;;) {
	    
	        do ll++; while (x[low] > x[ll]);
	        do hh--; while (x[hh]  > x[low]);

	        if (hh < ll) {
	        	break;
	        }

	        ELEM_SWAP(x[ll], x[hh]);
	        
	    }

	    // swap middle item (in position low) back into correct position
	    
	    ELEM_SWAP(x[low], x[hh]);

	    // reset active partition
	    
	    if (hh <= median) {
	        low = ll;
	    }
	        
        if (hh >= median) {
        	high = hh - 1;
        }
	        
	}
	    
}
Exemplo n.º 11
0
Arquivo: fvec.c Projeto: aubio/aubio
void fvec_rev(fvec_t *s) {
  uint_t j;
  for (j=0; j< FLOOR((smpl_t)s->length/2); j++) {
    ELEM_SWAP(s->data[j], s->data[s->length-1-j]);
  }
}
Exemplo n.º 12
0
float
PyMedian(float* a, int n)
{
    /* Get the median of an array "a" with length "n"
     * using the Quickselect algorithm. Returns a float.
     * This Quickselect routine is based on the algorithm described in
     * "Numerical recipes in C", Second Edition, Cambridge University Press,
     * 1992, Section 8.5, ISBN 0-521-43108-5
     * This code by Nicolas Devillard - 1998. Public domain.
     */

    PyDoc_STRVAR(PyMedian__doc__, "PyMedian(a, n) -> float\n\n"
        "Get the median of array a of length n using the Quickselect "
        "algorithm.");

    /* Make a copy of the array so that we don't alter the input array */
    float* arr = (float *) malloc(n * sizeof(float));
    /* Indices of median, low, and high values we are considering */
    int low = 0;
    int high = n - 1;
    int median = (low + high) / 2;
    /* Running indices for the quick select algorithm */
    int middle, ll, hh;
    /* The median to return */
    float med;

    /* running index i */
    int i;
    /* Copy the input data into the array we work with */
    for (i = 0; i < n; i++) {
        arr[i] = a[i];
    }

    /* Start an infinite loop */
    while (true) {

        /* Only One or two elements left */
        if (high <= low + 1) {
            /* Check if we need to swap the two elements */
            if ((high == low + 1) && (arr[low] > arr[high]))
                ELEM_SWAP(arr[low], arr[high]);
            med = arr[median];
            free(arr);
            return med;
        }

        /* Find median of low, middle and high items;
         * swap into position low */
        middle = (low + high) / 2;
        if (arr[middle] > arr[high])
            ELEM_SWAP(arr[middle], arr[high]);
        if (arr[low] > arr[high])
            ELEM_SWAP(arr[low], arr[high]);
        if (arr[middle] > arr[low])
            ELEM_SWAP(arr[middle], arr[low]);

        /* Swap low item (now in position middle) into position (low+1) */
        ELEM_SWAP(arr[middle], arr[low + 1]);

        /* Nibble from each end towards middle,
         * swap items when stuck */
        ll = low + 1;
        hh = high;
        while (true) {
            do
                ll++;
            while (arr[low] > arr[ll]);
            do
                hh--;
            while (arr[hh] > arr[low]);

            if (hh < ll)
                break;

            ELEM_SWAP(arr[ll], arr[hh]);
        }

        /* Swap middle item (in position low) back into
         * the correct position */
        ELEM_SWAP(arr[low], arr[hh]);

        /* Re-set active partition */
        if (hh <= median)
            low = ll;
        if (hh >= median)
            high = hh - 1;
    }

}
Exemplo n.º 13
0
/*Type of Cut Strategy is defined as:
 * (useAltCut, useVertical) = (true, true)  => Alternating Cuts
 * (useAltCut, useVertical) = (true, false) => Horizontal Cuts*
 * (useAltCut, useVertical) = (false, true)  => Vertical Cuts
 * */
void delaunay(Vertex **ppVertices, long numVertices, Edge **ppLe, Edge **ppRe,
		bool useAltCuts, bool useVertical) {
    NOT_NULL(ppVertices);
    
    if(numVertices == 2) {
        Edge *pA = Edge::makeEdge();
        if(*ppVertices[0] > *ppVertices[1]) {
            ELEM_SWAP(ppVertices[0], ppVertices[1]);
        }
        pA->setOrg(ppVertices[0]);
        pA->setDest(ppVertices[1]);
        *ppLe = pA;
        *ppRe = pA->Sym();
    }
    else if(numVertices == 3) {
        Edge *pA = Edge::makeEdge(),
             *pB = Edge::makeEdge(),
             *pC = 0;

        if(*ppVertices[0] > *ppVertices[1]) {
            ELEM_SWAP(ppVertices[0], ppVertices[1]);
        }
        if(*ppVertices[1] > *ppVertices[2]) {
            ELEM_SWAP(ppVertices[1], ppVertices[2]);
        }

        Edge::splice(pA->Sym(), pB);
        pA->setOrg(ppVertices[0]);
        pA->setDest(ppVertices[1]);
        pB->setOrg(ppVertices[1]);
        pB->setDest(ppVertices[2]);
        
        REAL ccw = orient2d(ppVertices[0]->Pos(), ppVertices[1]->Pos(), ppVertices[2]->Pos());
        if(ccw > 0) {
            pC = Edge::connect(pB, pA);
            *ppLe = pA;
            *ppRe = pB->Sym();
        }
        else if(ccw < 0) {
            pC = Edge::connect(pB, pA);
            *ppLe = pC->Sym();
            *ppRe = pC;
        }
        else {
            *ppLe = pA;
            *ppRe = pB->Sym();
        }
    }
    else {
        long middle = std::floor(numVertices/2);
        Edge *pLdo = 0, 
             *pLdi = 0, 
             *pRdi = 0, 
             *pRdo = 0;

        //These vertices are used for merging a horizontal cut
        Vertex *pBotMax = 0, //highest vertex of bottom half
               *pTopMin = 0, //lowest vertex of top half
               *pMin    = 0, //Lexicographically max vertex
               *pMax    = 0; //Lexicographically min vertex
        
        //Find median partition by X or Y, depending on whether we're using a vertical cut
        std::nth_element(ppVertices, ppVertices+middle, ppVertices+numVertices, useVertical ? Vertex::lessX : Vertex::lessY);

        //Recursive calls
        delaunay(ppVertices, middle, &pLdo, &pLdi, useAltCuts, useAltCuts ? !useVertical : useVertical);
        delaunay(ppVertices+middle, numVertices - middle, &pRdi, &pRdo, useAltCuts, useAltCuts ? !useVertical : useVertical);
        
        //Modify ldi be highest in bottom half and rdi to be lowest in top half
        if(!useVertical) {
            pBotMax = ppVertices[0];
            pTopMin = ppVertices[middle];
            pMin    = (*ppVertices[0] < *ppVertices[middle]) ? ppVertices[0] : ppVertices[middle];
            pMax    = (*ppVertices[0] > *ppVertices[middle]) ? ppVertices[0] : ppVertices[middle];;
            for(long i=1; i < middle; i++) {
                if(*ppVertices[i] < *pMin) {
                    pMin = ppVertices[i];
                }
                else if(*ppVertices[i] > *pMax) {
                    pMax = ppVertices[i];
                }
                
                if(ppVertices[i]->gtY(*pBotMax)) {
                    pBotMax = ppVertices[i];
                }
            }
            for(long i=middle+1; i < numVertices; i++) {
                if(*ppVertices[i] < *pMin) {
                    pMin = ppVertices[i];
                }
                else if(*ppVertices[i] > *pMax) {
                    pMax = ppVertices[i];
                }
                
                if(ppVertices[i]->ltY(*pTopMin)) {
                    pTopMin = ppVertices[i];
                }
            }
            
            pLdi = pBotMax->getCWHullEdge();
            pRdi = pTopMin->getCCWHullEdge();
        }
        
        
        //Compute the lower common tangent of two sets of vertices
        while (1) {
            if(pLdi->leftOf(pRdi->Org())) {
                pLdi = pLdi->Lnext();
            }
            else if(pRdi->rightOf(pLdi->Org())) {
                pRdi = pRdi->Rprev();
            }
            else {
                break;
            }
        }

        // Create a first cross edge pBasel from pRdi.origin to pLdi.origin
        Edge *pBasel = Edge::connect(pRdi->Sym(), pLdi);

        if(pLdi->Org() == pLdo->Org()) {
            pLdo = pBasel->Sym();
        }
        if(pRdi->Org() == pRdo->Org()) {
            pRdo = pBasel;
        }

        //Merging two halves
        while(1) {
            //Locate the first Left point pLcand to be encou
        	Edge *pLcand = pBasel->Sym()->Onext();
            bool leftFinished  = !pLcand->valid(pBasel);
            if(!leftFinished) {
                while(incircle(pBasel->Dest()->Pos(), 
                               pBasel->Org()->Pos(), 
                               pLcand->Dest()->Pos(),  
                               pLcand->Onext()->Dest()->Pos()) > 0) {
                
                    Edge *pT = pLcand->Onext();
                    Edge::deleteEdge(pLcand);
                    pLcand = pT;
                }
            }
            
            //Symmetrically locate the first R point to be hit
            Edge *pRcand = pBasel->Oprev();
            bool rightFinished = !pRcand->valid(pBasel);
            if(!rightFinished) {
                while(incircle(pBasel->Dest()->Pos(), 
                               pBasel->Org()->Pos(), 
                               pRcand->Dest()->Pos(),  
                               pRcand->Oprev()->Dest()->Pos()) > 0) {
                
                    Edge *pT = pRcand->Oprev();
                    Edge::deleteEdge(pRcand);
                    pRcand = pT;
                }
            }

            //both are invalid, pBasel is upper common tangent
            if(leftFinished && rightFinished) {
                break;
            }
            //the next cross edge is to be connected to either pLcand.dest or pRcand.dest
            if(leftFinished || 
               (!rightFinished && incircle(pLcand->Dest()->Pos(), 
                                                  pLcand->Org()->Pos(), 
                                                  pRcand->Org()->Pos(), 
                                                  pRcand->Dest()->Pos()) > 0)) {
                pBasel = Edge::connect(pRcand, pBasel->Sym());
            }
            else {
                pBasel = Edge::connect(pBasel->Sym(), pLcand->Sym());
            }
        }

        //Modify pLdo and pRdo if we merging a horizontal cut
        if(!useVertical) {
            pLdo = pMin->getCCWHullEdge();
            pRdo = pMax->getCWHullEdge();
        }

        *ppLe = pLdo;
        *ppRe = pRdo;
    }
    return;
}
Exemplo n.º 14
0
inline double Median(TYPE arr[], int n)
{
   #define ELEM_SWAP(a,b) { register TYPE t=(a);(a)=(b);(b)=t; }

   int low    = 0;
   int high   = n-1;
   const int median = n / 2;

   for (;;)
   {
      if (high <= low)        // One element only
         break;
      
      if (high == low + 1)    // Two elements only
      {
         if (arr[low] > arr[high])
            ELEM_SWAP(arr[low], arr[high]);
         break;
      }
      
      // Find median of low, middle and high items; swap into position low
      const int middle = (low + high) / 2;
      if (arr[middle] > arr[high])
         ELEM_SWAP(arr[middle], arr[high]);
      if (arr[low] > arr[high])
         ELEM_SWAP(arr[low], arr[high]);
      if (arr[middle] > arr[low])
         ELEM_SWAP(arr[middle], arr[low]);
      
      // Swap low item (now in position middle) into position (low+1)
      ELEM_SWAP(arr[middle], arr[low+1]);
      
      // Nibble from each end towards middle, swapping items when stuck
      int ll = low + 1;
      int hh = high;
      for (;;)
      {
         do ll++;
         while (arr[low] > arr[ll]);

         do hh--;
         while (arr[hh]  > arr[low]);
         
         if (hh < ll)
            break;
         
         ELEM_SWAP(arr[ll], arr[hh]);
      }
      
      // Swap middle item (in position low) back into correct position
      ELEM_SWAP(arr[low], arr[hh]);
      
      // Re-set active partition
      if (hh <= median)
         low = ll;
      if (hh >= median)
         high = hh - 1;
   }

   #undef ELEM_SWAP

   double medianval;

   if (n%2)
      medianval = arr[median];
   else
   {
      // otherwise we find the value to average with by maximising low partition
      TYPE max = arr[0];
      for (int i = 1; i < median; i++)
      {
         if (arr[i] > max)
            max = arr[i];
      }

      medianval = (double(arr[median])+max)/2;
   }
   return medianval;
}
Exemplo n.º 15
0
inline double MedianSelect(TYPE arr[], int n)
{
   #define ELEM_SWAP(a,b) { register TYPE t=(a);(a)=(b);(b)=t; }

   int low  = 0;
   int high = n-1;
   int m    = n/2;

   for (;;)
   {
      if (high <= low)        // One element only
         break;
      
      if (high == low + 1)    // Two elements only
      {
         if (arr[low] > arr[high])
            ELEM_SWAP(arr[low], arr[high]);
         break;
      }
      
      // Find median of low, middle and high items; swap into position low
      const int middle = (low + high) / 2;
      if (arr[middle] > arr[high])
         ELEM_SWAP(arr[middle], arr[high]);
      if (arr[low] > arr[high])
         ELEM_SWAP(arr[low], arr[high]);
      if (arr[middle] > arr[low])
         ELEM_SWAP(arr[middle], arr[low]);
      
      // Swap low item (now in position middle) into position (low+1)
      ELEM_SWAP(arr[middle], arr[low+1]);
      
      // Nibble from each end towards middle, swapping items when stuck
      int ll = low + 1;
      int hh = high;
      for (;;)
      {
         do ll++;
         while (arr[low] > arr[ll]);

         do hh--;
         while (arr[hh]  > arr[low]);
         
         if (hh < ll)
            break;
         
         ELEM_SWAP(arr[ll], arr[hh]);
      }
      
      // Swap middle item (in position low) back into correct position
      ELEM_SWAP(arr[low], arr[hh]);
      
      // Re-set active partition
      if (hh <= m)
         low = ll;
      if (hh >= m)
         high = hh - 1;
   }

   #undef ELEM_SWAP
   // BUG BUG -- this routine works fine if the result is arr[n/2],
   //            but for even number of items this is incorrect.
   ASSERT(FALSE);
   return MedianOf(arr, n);
}
Exemplo n.º 16
0
void *calcPrefixSum(void* tid) {
	int left, i, j, right, depth = 0, cnt1, cnt2;
	int  prev_lt, prev_end, pstart;
	int first, last,  group, s, e, rem, barr_id;
	int k1, k2,  med;
	int thread_id = *(int *)tid;
	 int *from = input1, *to = input2, *tp;
	register int t;

	while(1) {
#ifndef DEBUG
	printf("\nThread id: %d pstart: %d pend: %d start: %d end: %d first_thread:%d last_thread: %d\n", ps_msg[thread_id].thread_id, ps_msg[thread_id].pstart, ps_msg[thread_id].pend, ps_msg[thread_id].start, ps_msg[thread_id].end, ps_msg[thread_id].first_thread, ps_msg[thread_id].last_thread);
#endif
	barr_id = ps_msg[thread_id].first_thread;
	
         if(barr_id == ps_msg[thread_id].last_thread) {
#ifndef DEBUG
		printf("\n\nThread %d: RETURNED\n\n", thread_id);
#endif
		qsort(from+ps_msg[thread_id].pstart, ps_msg[thread_id].pend-ps_msg[thread_id].pstart+1, sizeof(int), comp);
		if(depth % 2 != 0)
			memcpy((void*)(to+ps_msg[thread_id].pstart), (void*)(from+ps_msg[thread_id].pstart), (ps_msg[thread_id].pend-ps_msg[thread_id].pstart+1)*sizeof(int));
		return NULL;
	}
	
	med = median(from+ps_msg[thread_id].start, ps_msg[thread_id].end-ps_msg[thread_id].start+1);
	medians[thread_id] = med;
#ifndef DEBUG
	printf("Thread %d: %d\n", thread_id, medians[thread_id]);
#endif
	pthread_barrier_wait(&cbarr[barr_id]);	
	
	if(thread_id == barr_id) {
		med = median(medians+barr_id, ps_msg[thread_id].last_thread-barr_id+1);
		pivots[barr_id] = med;
#ifndef DEBUG
		printf("Global pivot: %d\n", pivots[barr_id]);
#endif
	}
	
	pthread_barrier_wait(&cbarr[barr_id]);
	
	/* local rearrangement in each chunk with in the partition 
	 * Dutch National Flag - 2 partitioning */
	i = ps_msg[thread_id].start;
#ifndef DEBUG
	printf("Start: Thread %d: barr_id: %d loop from %d to %d\n", thread_id, barr_id,ps_msg[thread_id].start,ps_msg[thread_id].end);
#endif	
	for(cnt1 = 0, j = ps_msg[thread_id].end; i <= j;) {
		if(from[i] >= pivots[barr_id]) {
			if(from[j] < pivots[barr_id])
				ELEM_SWAP(from[i], from[j]);
			j--;
		} else {
			i++;
			cnt1++;
		}
	}

	sum1[thread_id] = cnt1;
	cnt2 = (ps_msg[thread_id].end - ps_msg[thread_id].start + 1) - cnt1;
	sum2[thread_id] = cnt2;

#ifndef DEBUG	
	printf("\nLocal Rearragement on thread: %d cnt1: %d cnt2: %d\n",thread_id, cnt1, cnt2);
	for(i = ps_msg[thread_id].start; i <= ps_msg[thread_id].end; i++){
		printf("%d ",from[i]);
	}
	printf("\n");
	printf(" Thread %d: waiting on %d \n", thread_id, barr_id);
#endif

	pthread_barrier_wait(&cbarr[barr_id]);
	
	if(thread_id == barr_id) {
#ifndef DEBUG
		printf("\nTotal Local Rearragement on %d cnt1: %d cnt2: %d: \n",thread_id, cnt1, cnt2);
		for(i = ps_msg[thread_id].pstart; i <= ps_msg[thread_id].pend; i++){
			printf("%d ",from[i]);
		}
		printf("\n");
		printf("Before Prefix Sum1: ");
		for(i = barr_id; i <= ps_msg[thread_id].last_thread; i++){
			printf("%d ",sum1[i]);
		}
		printf("\n");
#endif
		for(k1 = 0, k2 = 0, i = barr_id; i <= ps_msg[thread_id].last_thread; i++) {
			k2 += sum1[i];
			sum1[i] = k1;
			k1 = k2;
		}
		pivots_indices[barr_id] = ps_msg[barr_id].pstart + k2;
#ifndef DEBUG
		printf("New pivot index is %d\n",pivots_indices[barr_id]);
		printf("Prefix Sum1: ");
		for(i = barr_id; i <= ps_msg[thread_id].last_thread; i++){
			printf("%d ",sum1[i]);
		}
		printf("\n");
#endif
	} else if(thread_id == ps_msg[thread_id].last_thread) {
#ifndef DEBUG
		printf("Before Prefix Sum2: ");
		for(i = barr_id; i <= ps_msg[thread_id].last_thread; i++){
			printf("%d ",sum2[i]);
		}
		printf("\n");
#endif
		for(k1 = 0, k2 = 0,i = barr_id; i <= ps_msg[thread_id].last_thread; i++) {
			k2 += sum2[i];
			sum2[i] = k1;
			k1 = k2;
		}
#ifndef DEBUG
		printf("Prefix Sum2: ");
		for(i = barr_id; i <= ps_msg[thread_id].last_thread; i++){
			printf("%d ",sum2[i]);
		}
		printf("\n");	
#endif	
	}
	pthread_barrier_wait(&cbarr[barr_id]);

	/* Copy elements to a new array */

	i = ps_msg[thread_id].start;
	pstart = ps_msg[thread_id].pstart;
	if(cnt1 != 0) {
#ifndef DEBUG
		printf("c1-Thread: %d copying to pstart:%d+%d from %d elements-%d to %d\n",thread_id, pstart, sum1[thread_id], i,cnt1, pstart+sum1[thread_id]);
#endif
		memcpy((void*)(to+pstart+sum1[thread_id]), (void*)(from+i), cnt1*sizeof(int));
	}
	if(cnt2 != 0) {
#ifndef DEBUG
		printf("c2-Thread: %d copying to pstart:%d+%d from %d elements-%d to %d\n",thread_id, pstart+pivots_indices[barr_id], sum2[thread_id], i+cnt1, cnt2, pivots_indices[barr_id]+sum2[thread_id]);
#endif
		memcpy((void*)(to+pivots_indices[barr_id]+sum2[thread_id]),(void*)(from+i+cnt1), cnt2*sizeof(int));
	}
	pthread_barrier_wait(&cbarr[barr_id]);

	tp = from;
	from = to;
	to   = tp;

	if(thread_id == barr_id) {
		
		prev_end = ps_msg[thread_id].pend;
		prev_lt  = ps_msg[thread_id].last_thread;
#ifndef DEBUG
		printf("Final: ");
		for(i = ps_msg[thread_id].pstart; i <= ps_msg[thread_id].pend; i++){
			printf("%d ",from[i]);
		}
		printf("\n");
#endif
		med = ps_msg[thread_id].last_thread - barr_id + 1;
		k1     = pivots_indices[barr_id] - ps_msg[thread_id].start; 
		k2     = prev_end - pivots_indices[barr_id] + 1; 
		first  = round(((double)k1/(k1+k2))*med);
		first  = (first == 0)?1:first;
		last   = med - first;
	
		group = k1/first;
		rem  = k1%first;
#ifndef DEBUG		
		printf("\n---------Thread: %d First Paritioning: k:%d group:%d rem:%d first: %d last: %d------------\n", thread_id, k1, group1, rem1, first, last);
		printf("loop from: %d to %d\n", barr_id, barr_id+first);
#endif	
		cnt1 = barr_id + first;
		for(i = barr_id, s = 0, e = ps_msg[thread_id].start-1; i < cnt1; i++) {
			s = e + 1;
			e = s + group - 1;
			if(rem > 0) {
				rem--;
				e++;
			}
			ps_msg[i].pstart = ps_msg[thread_id].pstart;
			ps_msg[i].pend   = pivots_indices[barr_id]-1;
			ps_msg[i].start  = s;
			ps_msg[i].end    = e;
			ps_msg[i].first_thread = barr_id;
			ps_msg[i].last_thread  = cnt1-1;
		}

#ifndef DEBUG
		printf("\n---------Thread: %d Second Paritioning: k:%d group:%d rem:%d first: %d last: %d------------\n", thread_id, k2, group2, rem2, first, last);
		printf("loop from: %d to %d\n",  barr_id+first,barr_id+first+last);
#endif
	
		cnt1 += last;		
		group = k2/last;
		rem   = k2%last;

		for(i = (barr_id+first), e = pivots_indices[barr_id]-1; i < cnt1; i++) {
			s = e + 1;
			e = s + group - 1;
			if(rem > 0) {
				rem--;
				e++;
			}
			ps_msg[i].pstart = pivots_indices[barr_id];
			ps_msg[i].pend   = prev_end;
			ps_msg[i].start = s;
			ps_msg[i].end   = e;
			ps_msg[i].first_thread = barr_id+first;
			ps_msg[i].last_thread  = cnt1-1;
		}

#ifndef DEBUG
		for(i = 0; i < num_threads; i++) {
			printf("Thread id: %d pstart: %d pend: %d start: %d end: %d first_thread:%d last_thread: %d\n", ps_msg[i].thread_id, ps_msg[i].pstart, ps_msg[i].pend, ps_msg[i].start, ps_msg[i].end, ps_msg[i].first_thread, ps_msg[i].last_thread);
		}
		printf("cbarr: %d %d\n",barr_id, first);
		printf("cbarr: %d %d\n",barr_id+first, last);
#endif
		pthread_barrier_destroy(&cbarr[barr_id]);
		pthread_barrier_init(&cbarr[barr_id], NULL, first);
		pthread_barrier_destroy(&cbarr[barr_id+first]);
		
		pthread_barrier_init(&cbarr[barr_id+first], NULL, last);
		for(i = barr_id+1; i <= prev_lt; i++) {
			pthread_barrier_wait(&obarr[i]);
		}
		//printf("Thread id: %d Master thread done !!\n", thread_id);
	} else {
		pthread_barrier_wait(&obarr[thread_id]);
		//printf("Thread %d done with a level\n",thread_id);
	  }
		depth++;
	}
}