Exemplo n.º 1
0
double dselect(unsigned long k, unsigned long n, double *arr) {

  unsigned long i=0,ir=0,j=0,l=0,mid=0;
  double        a=0.0,dtmp;

  l=0;
  ir=n-1;
  for (;;) {
    if (ir<=l+1) {
      if (ir==l+1 && arr[ir]<arr[l]) { DSWAP(arr[l],arr[ir]); }
      return arr[k];
    }
    else {
      mid=(l+ir) >> 1; i=l+1;
      DSWAP(arr[mid],arr[i]);
      if (arr[i]>arr[ir]) { DSWAP(arr[i],arr[ir]); }
      if (arr[l]>arr[ir]) { DSWAP(arr[l],arr[ir]); }
      if (arr[i]>arr[l]) { DSWAP(arr[i],arr[l]); }
      j=ir; a=arr[l];
      for (;;) {
	do i++; while (arr[i]<a); do j--; while (arr[j]>a);
	if (j<i) break; DSWAP(arr[i],arr[j]);
      }
      arr[l]=arr[j]; arr[j]=a; if (j>=k) ir=j-1; if (j<=k) l=i;
    }
  }
}
Exemplo n.º 2
0
void 
F77_NAME(dswap)(const int *n, double *dx, const int *incx,
		double *dy, const int *incy)
{
    DSWAP(n, dx, incx, dy, incy);
}
Exemplo n.º 3
0
Arquivo: math.c Projeto: hankem/ISIS
/* quick-select median finder - order of input array is *not* preserved */
static int find_median (double *x, int n, double *xmed) /*{{{*/
{
   int med, lo, hi;

   if (x == NULL || n == 0 || xmed == NULL)
     return -1;

#define DSWAP(i,j) do {double t_=x[(i)]; x[(i)]=x[(j)]; x[(j)]=t_;} while (0)

   lo = 0;
   hi = n-1;
   med = (lo + hi)/2;

   for (;;)
     {
        int l, h, mid;

        /* one item left? */
        if (hi <= lo)
          {
             *xmed = x[med];
             return 0;
          }

        /* two items left? */
        if (hi == lo+1)
          {
             if (x[lo] > x[hi]) DSWAP(lo, hi);
             *xmed = x[med];
             return 0;
          }

        /* order the current (lo,hi) values and their midpoint */
        mid = (lo + hi) / 2;
        if (x[mid] > x[hi]) DSWAP(mid, hi);
        if (x[lo]  > x[hi]) DSWAP(lo, hi);
        if (x[mid] > x[lo]) DSWAP(mid, lo);

        /* swap middle value to a safe place (lo+1)
         * and process the items between [lo+2:hi]
         */
        DSWAP(mid, lo+1);

        /* scan the items between [lo+2, hi-1],
         * inward from each end,
         * swapping when necessary.
         */

        l = lo + 1;
        h = hi;
        for (;;)
          {
             while (x[++l] < x[lo])
               ;
             while (x[lo] < x[--h])
               ;

             if (h < l)
               break;

             DSWAP(l, h);
          }

        /* swap the current low value to the spot
         * where the scan pointers met
         */
        DSWAP(lo, h);

        /* update the endpoints, making sure that the median
         * is bracketed.
         */
        if (h <= med) lo = l;
        if (h >= med) hi = h - 1;
     }
#undef DSWAP
}
Exemplo n.º 4
0
void DCHDC(double *a, INT *plda, INT *pp, double *work, INT jpvt[],
		   INT *pjob, INT *info)
/*double a[lda][1], work[1];*/
{
	INT         pu, pl, j, k, l, maxl, jtemp;
	INT         inc = 1;
	double      temp;
	double      maxdia;
	double     *ak, *apl, *akk, *aj, *apu, *all, *amaxl;
	INT         swapk, negk, length;
	INT         lda = *plda, p = *pp, job = *pjob;

	/* ***first executable statement  dchdc */
	pl = 0;
	pu = -1;
	*info = p;

	if (job != 0)
	{
		/*         pivoting has been requested. rearrange the */
		/*         the elements according to jpvt. */

		ak = a;
		apl = a + pl*lda;
		for(k = 0;k < p ;k++)
		{
			akk = ak + k;
			swapk = jpvt[k] > 0;
			negk = jpvt[k] < 0;
			jpvt[k] = k+1;
			if (negk)
			{
				jpvt[k] = -jpvt[k];
			}

			if (swapk)
			{
				if (k != pl)
				{
					DSWAP(&pl, ak, &inc, apl, &inc);
					temp = *akk;
					*akk = apl[pl];
					apl[pl] = temp;
					aj = apl + lda;
					for(j = pl+1;j < p ;j++)
					{
						if (j < k)
						{
							temp = aj[pl];
							aj[pl] = ak[j];
							ak[j] = temp;
						}
						else if (j != k)
						{
							temp = aj[k];
							aj[k] = aj[pl];
							aj[pl] = temp;
						}
						aj += lda;
					} /*for(j = pl+1;j < p ;j++)*/

					jpvt[k] = jpvt[pl];
					jpvt[pl] = k + 1;
				} /*if (k != pl) */
				pl++;
				apl += lda;
			} /*if (swapk) */
			ak += lda;
		} /*for(k = 0;k < p ;k++)*/

		pu = p - 1;
		apu = ak = a + (p-1)*lda;

		for(k = p-1;k>=pl;k--)
		{
			akk = ak + k;
			if (jpvt[k] < 0)
			{
				jpvt[k] = -jpvt[k];
				if (pu != k)
				{
					DSWAP(&k, ak, &inc, apu, &inc);
					temp = *akk;
					*akk = apu[pu];
					apu[pu] = temp;
					aj = ak + lda;
					for(j = k+1;j < p ;j++)
					{
						if (j < pu)
						{
							temp = aj[k];
							aj[k] = apu[j];
							apu[j] = temp;
						}
						else if (j != pu)
						{
							temp = aj[k];
							aj[k] = aj[pu];
							aj[pu] = temp;
						}
						aj += lda;
					} /*for(j = k+1;j < p ;j++)*/

					jtemp = jpvt[k];
					jpvt[k] = jpvt[pu];
					jpvt[pu] = jtemp;
				} /*if (pu != k) */
				pu--;
				apu -= lda;
			} /*if (jpvt[k] < 0) */
			ak -= lda;
		} /*for(k = p-1;k>=pl;k--)*/
	} /*if (job != 0)*/

	ak = a;
	for(k = 0;k < p ;k++)
	{
		/*         reduction loop. */

		akk = ak + k;
		maxdia = *akk;
		maxl = k;

		/*         determine the pivot element. */

		if (k >= pl && k < pu)
		{
			all = akk + lda + 1;
			for(l = k+1;l <= pu ;l++)
			{
				if (*all > maxdia)
				{
					maxdia = *all;
					maxl = l;
				}
				all += lda + 1;
			}
		}

		/*         quit if the pivot element is not positive. */

		if (maxdia <= 0.0e0)
		{
			*info = k;
			break;
		}

		if (k != maxl)
		{
			amaxl = a + maxl*lda;
			/*            start the pivoting and update jpvt. */

			DSWAP(&k, ak, &inc, amaxl, &inc);
			amaxl[maxl] = *akk;
			*akk = maxdia;
			jtemp = jpvt[maxl];
			jpvt[maxl] = jpvt[k];
			jpvt[k] = jtemp;
		} /*if (k != maxl) */

		/*         reduction step. pivoting is contained across the rows. */

		work[k] = sqrt(*akk);
		*akk = work[k];
		aj = ak + lda;
		amaxl = a + maxl*lda;
		for(j = k+1;j < p ;j++)
		{
			if (k != maxl)
			{
				temp = aj[k];
				if (j < maxl)
				{
					aj[k] = amaxl[j];
					amaxl[j] = temp;
				}
				else if (j != maxl)
				{
					aj[k] = aj[maxl];
					aj[maxl] = temp;
				}
			} /*if (k != maxl)*/

			aj[k] /= work[k];
			work[j] = aj[k];
			temp = -aj[k];
			length = j - k;
			DAXPY(&length, &temp, work + k + 1, &inc, aj + k + 1, &inc);
			aj += lda;
		} /*for(j = k+1;j < p ;j++)*/
		incAndTest((p-k+3)*(p-k)/2,errorExit);
		ak += lda;
	}/*for(k = 0;k < p ;k++)*/
	/* fall through*/

  errorExit:
	;

} /*dchdc()*/