Beispiel #1
0
Graph* Stack_Graph(const Stack *stack, int conn, const int *range, 
		   Weight_Func_t *wf)
{
  int x, y, z;
  int offset = 0;
  int is_in_bound[26];
  int nbound;
  int i;
  int stack_range[6];

  if (range == NULL) {
    stack_range[0] = 0;
    stack_range[1] = stack->width - 1;
    stack_range[2] = 0;
    stack_range[3] = stack->height - 1;
    stack_range[4] = 0;
    stack_range[5] = stack->depth - 1;
  } else {
    stack_range[0] = imax2(0, range[0]);
    stack_range[1] = imin2(stack->width - 1, range[1]);
    stack_range[2] = imax2(0, range[2]);
    stack_range[3] = imin2(stack->height - 1, range[3]);
    stack_range[4] = imax2(0, range[4]);
    stack_range[5] = imin2(stack->depth - 1, range[5]);
  }
  
  int cdepth = stack_range[5] - stack_range[4];
  int cheight = stack_range[3] - stack_range[2];
  int cwidth = stack_range[1] - stack_range[0];
  
  int nvertex = (cwidth + 1) * (cheight + 1) * (cdepth + 1);

  Graph *graph = Make_Graph(nvertex, nvertex, TRUE);

  int neighbor[26];
  int scan_mask[26];
  Stack_Neighbor_Offset(conn, cwidth + 1, cheight + 1, neighbor);

  const double *dist = Stack_Neighbor_Dist(conn);
  const int *x_offset = Stack_Neighbor_X_Offset(conn);
  const int *y_offset = Stack_Neighbor_Y_Offset(conn);
  const int *z_offset = Stack_Neighbor_Z_Offset(conn);

  double args[3];

  for (i = 0; i < conn; i++) {
    scan_mask[i] = (neighbor[i] > 0);
  }

  for (z = 0; z <= cdepth; z++) {
    for (y = 0; y <= cheight; y++) {
      for (x = 0; x <= cwidth; x++) {
	nbound = Stack_Neighbor_Bound_Test(conn, cwidth, cheight, cdepth, 
					   x, y, z, is_in_bound);
	if (nbound == conn) {
	  for (i = 0; i < conn; i++) {
	    if (scan_mask[i] == 1) {
	      double weight = dist[i];
	      if (wf != NULL) {
		args[0] = dist[i];
		args[1] = Get_Stack_Pixel((Stack *)stack, x + stack_range[0], 
					  y + stack_range[2], 
					  z + stack_range[4], 0);
		args[2] = Get_Stack_Pixel((Stack *)stack, 
					  x + stack_range[0] + x_offset[i],
					  y + stack_range[2] + y_offset[i],
					  z + stack_range[4] + z_offset[i], 0);
		weight = wf(args);
	      }
	      Graph_Add_Weighted_Edge(graph, offset, offset + neighbor[i], 
				      weight);
	    }
	  }
	} else {
	  for (i = 0; i < conn; i++) {
	    if ((scan_mask[i] == 1) && is_in_bound[i]){
	      double weight = dist[i];
	      if (wf != NULL) {
		args[0] = dist[i];
		args[1] = Get_Stack_Pixel((Stack *)stack, x + stack_range[0], 
					  y + stack_range[2], 
					  z + stack_range[4], 0);
		args[2] = Get_Stack_Pixel((Stack *)stack, 
					  x + stack_range[0] + x_offset[i],
					  y + stack_range[2] + y_offset[i],
					  z + stack_range[4] + z_offset[i], 0);
		weight = wf(args);
	      }
	      Graph_Add_Weighted_Edge(graph, offset, offset + neighbor[i], 
				      weight);
	    }
	  }
	}
	offset++;
      }
    }
  }

  return graph;
}
Beispiel #2
0
Graph* Stack_Graph_W(const Stack *stack, Stack_Graph_Workspace *sgw)
{
  int x, y, z;
  int offset = 0;
  int is_in_bound[26];
  int nbound;
  int i;
  int stack_range[6];

  int *range = sgw->range;

  if (range == NULL) {
    stack_range[0] = 0;
    stack_range[1] = stack->width - 1;
    stack_range[2] = 0;
    stack_range[3] = stack->height - 1;
    stack_range[4] = 0;
    stack_range[5] = stack->depth - 1;
  } else {
    stack_range[0] = imax2(0, range[0]);
    stack_range[1] = imin2(stack->width - 1, range[1]);
    stack_range[2] = imax2(0, range[2]);
    stack_range[3] = imin2(stack->height - 1, range[3]);
    stack_range[4] = imax2(0, range[4]);
    stack_range[5] = imin2(stack->depth - 1, range[5]);
  }
  
  int cdepth = stack_range[5] - stack_range[4];
  int cheight = stack_range[3] - stack_range[2];
  int cwidth = stack_range[1] - stack_range[0];
  
  int nvertex = (cwidth + 1) * (cheight + 1) * (cdepth + 1);
  sgw->virtualVertex = nvertex;

  BOOL weighted = TRUE;
  if (sgw->sp_option == 1) {
    weighted = FALSE;
    sgw->intensity = darray_malloc(nvertex + 1);
    sgw->intensity[nvertex] = Infinity;
  }
  Graph *graph = Make_Graph(nvertex, nvertex, weighted);

  int neighbor[26];
  int scan_mask[26];
  Stack_Neighbor_Offset(sgw->conn, cwidth + 1, cheight + 1, neighbor);

  int org_neighbor[26];
  Stack_Neighbor_Offset(sgw->conn, Stack_Width(stack), Stack_Height(stack), 
      org_neighbor);

  double dist[26];
  Stack_Neighbor_Dist_R(sgw->conn, sgw->resolution, dist);
  //const double *dist = Stack_Neighbor_Dist(sgw->conn);
  const int *x_offset = Stack_Neighbor_X_Offset(sgw->conn);
  const int *y_offset = Stack_Neighbor_Y_Offset(sgw->conn);
  const int *z_offset = Stack_Neighbor_Z_Offset(sgw->conn);

  /* go forward */
  for (i = 0; i < sgw->conn; i++) {
    scan_mask[i] = (neighbor[i] > 0);
  }

#define STACK_GRAPH_ADD_EDGE(cond) \
  for (i = 0; i < sgw->conn; i++) { \
    if (cond) { \
      int nx = x + stack_range[0]; \
      int ny = y + stack_range[2]; \
      int nz = z + stack_range[4]; \
      if (Graph_Is_Weighted(graph)) { \
	double weight = dist[i]; \
	if (sgw->wf != NULL) { \
	  sgw->argv[0] = dist[i]; \
	  \
	  sgw->argv[1] = Get_Stack_Pixel((Stack *)stack, nx, ny, nz, 0); \
	  sgw->argv[2] = \
	  Get_Stack_Pixel((Stack *)stack, nx + x_offset[i], \
	      ny + y_offset[i], nz + z_offset[i], 0); \
	  weight = sgw->wf(sgw->argv); \
	} \
	Graph_Add_Weighted_Edge(graph, offset, offset + neighbor[i], \
	    weight); \
      } else { \
	Graph_Add_Edge(graph, offset, offset + neighbor[i]); \
	sgw->intensity[offset] = Get_Stack_Pixel((Stack*) stack, \
	      nx, ny, nz, 0); \
      } \
    } \
  }

  int groupVertexMap[256];
  for (i = 0; i < 256; ++i) {
    groupVertexMap[i] = 0;
  }

  int swidth = cwidth + 1;
  int sarea =  (cwidth + 1) * (cheight + 1);
  int area = stack->width * stack->height;
  for (z = 0; z <= cdepth; z++) {
    for (y = 0; y <= cheight; y++) {
      for (x = 0; x <= cwidth; x++) {
	nbound = Stack_Neighbor_Bound_Test_S(sgw->conn, cwidth, cheight, 
					     cdepth, 
					     x, y, z, is_in_bound);
	size_t offset2 = Stack_Subindex((size_t) offset, stack_range[0],
	    stack_range[2], stack_range[4],
	    swidth, sarea, stack->width, area);

#ifdef _DEBUG_2
        if (offset == 36629) {
          printf("debug here\n");
        }
#endif

	if (nbound == sgw->conn) {
	  STACK_GRAPH_ADD_EDGE((scan_mask[i] == 1) && 
              (sgw->signal_mask == NULL ? 1 : 
               ((sgw->signal_mask->array[offset2] > 0) &&
                (sgw->signal_mask->array[offset2+org_neighbor[i]] > 0))))
	} else {
	  STACK_GRAPH_ADD_EDGE((scan_mask[i] == 1) && is_in_bound[i] && 
	      (sgw->signal_mask == NULL ? 1 : 
	       ((sgw->signal_mask->array[offset2] > 0) &&
		(sgw->signal_mask->array[offset2+org_neighbor[i]]) >
		0)))
	}
	if (sgw->group_mask != NULL) {
          int groupId = sgw->group_mask->array[offset2];
	  if (groupId > 0) {
#ifdef _DEBUG_2
	    sgw->group_mask->array[offset2] = 2;
#endif
            int groupVertex = groupVertexMap[groupId];
            if (groupVertex <= 0) {
              groupVertex = nvertex++;
              groupVertexMap[groupId] = groupVertex;
            }

            Graph_Add_Weighted_Edge(graph, groupVertex, offset, 0.0);
	  }
	}

	offset++;
      }
    }
  }

  return graph;
}
Beispiel #3
0
static Rboolean
stem_leaf(double *x, int n, double scale, int width, double atom)
{
    double r, c, x1, x2;
    int mm, mu, k, i, j, hi, lo, xi;
    int ldigits, hdigits, ndigits, pdigits;

    R_rsort(x,n);

    if(n <= 1)
	return FALSE;

    Rprintf("\n");
    if(x[n-1] > x[0]) {
	r = atom+(x[n-1]-x[0])/scale;
	c = pow(10.,(11.-(int)(log10(r)+10)));
	mm = imin2(2, imax2(0, (int)(r*c/25)));
	k = 3*mm + 2 - 150/(n+50);
	if ((k-1)*(k-2)*(k-5)==0)
	    c *= 10.;
	/* need to ensure that x[i]*c does not integer overflow */
	x1 = fabs(x[0]); x2 = fabs(x[n-1]);
	if(x2 > x1) x1 = x2;
	while(x1*c > INT_MAX) c /= 10;
	if (k*(k-4)*(k-8)==0) mu = 5;
	if ((k-1)*(k-5)*(k-6)==0) mu = 20;
    } else {
	r = atom + fabs(x[0])/scale;
	c = pow(10.,(11.-(int)(log10(r)+10)));
	k = 2; /* not important what */
    }
    
    mu = 10;
    if (k*(k-4)*(k-8)==0) mu = 5;
    if ((k-1)*(k-5)*(k-6)==0) mu = 20;


    /* Find the print width of the stem. */

    lo = floor(x[0]  *c/mu)*mu;
    hi = floor(x[n-1]*c/mu)*mu;
    ldigits = (lo < 0) ? floor(log10(-lo))+1 : 0;
    hdigits = (hi > 0) ? floor(log10(hi))    : 0;
    ndigits = (ldigits < hdigits) ? hdigits : ldigits;

    /* Starting cell */

    if(lo < 0 && floor(x[0]*c) == lo)
	lo=lo-mu;
    hi = lo+mu;
    if(floor(x[0]*c+0.5) > hi) {
	lo = hi;
	hi = lo+mu;
    }

    /* Print out the info about the decimal place */

    pdigits= 1 - floor(log10(c)+0.5);

    Rprintf("  The decimal point is ");
    if(pdigits == 0)
	Rprintf("at the |\n\n");
    else
	Rprintf("%d digit(s) to the %s of the |\n\n",abs(pdigits),
		(pdigits > 0) ? "right" : "left");
    i = 0;
    do {
	if(lo < 0)
	    stem_print(hi,lo,ndigits);
	else
	    stem_print(lo,hi,ndigits);
	j = 0;
	do {
	    if(x[i] < 0)xi = x[i]*c - .5;
	    else	xi = x[i]*c + .5;

	    if( (hi == 0 && x[i] >= 0)||
		(lo <  0 && xi >  hi) ||
		(lo >= 0 && xi >= hi) )
		break;

	    j++;
	    if(j <= width-12) {
		Rprintf("%1d", abs(xi)%10);
	    }
	    i++;
	} while(i < n);
	if(j > width) {
	    Rprintf("+%d", j-width);
	}
	Rprintf("\n");
	if(i >= n)
	    break;
	hi += mu;
	lo += mu;
    } while(1);
    Rprintf("\n");
    return TRUE;
}
Beispiel #4
0
void findBestSplit(double *x, int *jdex, double *y, int mdim, int nsample,
        int ndstart, int ndend, int *msplit, double *decsplit,
        double *ubest, int *ndendl, int *jstat, int mtry,
        double sumnode, int nodecnt, int *cat) {
    int last, ncat[32], icat[32], lc, nl, nr, npopl, npopr;
    int i, j, kv, l;
    static int *mind, *ncase;
    static double *xt, *ut, *v, *yl;
    double sumcat[32], avcat[32], tavcat[32], ubestt;
    double crit, critmax, critvar, suml, sumr, d, critParent;
    
    
    if (in_findBestSplit==-99){
      free(ncase);
      free(mind); //had to remove this so that it wont crash for when mdim=0, strangely happened for replace=0
      free(v);
      free(yl);
      free(xt);
      free(ut);
     //	PRINTF("giving up mem in findBestSplit\n");
      return;
    }			
    
    if (in_findBestSplit==0){
    	in_findBestSplit=1;
		ut = (double *) calloc(nsample, sizeof(double));
		xt = (double *) calloc(nsample, sizeof(double));
		v  = (double *) calloc(nsample, sizeof(double));
		yl = (double *) calloc(nsample, sizeof(double));
		mind  = (int *) calloc(mdim+1, sizeof(int));   //seems that the sometimes i am asking for kv[10] and that causes problesmms
													   //so allocate 1 more. helps with not crashing in windows
		ncase = (int *) calloc(nsample, sizeof(int));
    }
    zeroDouble(ut, nsample);
    zeroDouble(xt, nsample);
    zeroDouble(v, nsample);
    zeroDouble(yl, nsample);
    zeroInt(mind, mdim);
    zeroInt(ncase, nsample);
    
    zeroDouble(avcat, 32);
    zeroDouble(tavcat, 32);
    
    /* START BIG LOOP */
    *msplit = -1;
    *decsplit = 0.0;
    critmax = 0.0;
    ubestt = 0.0;
    for (i=0; i < mdim; ++i) mind[i] = i;
    
    last = mdim - 1;
    for (i = 0; i < mtry; ++i) {
        critvar = 0.0;
        j = (int) (unif_rand() * (last+1));
        //PRINTF("j=%d, last=%d mind[j]=%d\n", j, last, mind[j]);fflush(stdout);
        kv = mind[j];
		//if(kv>100){
		//	1;
		//	getchar();
		//}
        swapInt(mind[j], mind[last]);
        /* mind[j] = mind[last];
         * mind[last] = kv; */
        last--;
        
        lc = cat[kv];
        if (lc == 1) {
            /* numeric variable */
            for (j = ndstart; j <= ndend; ++j) {
                xt[j] = x[kv + (jdex[j] - 1) * mdim];
                yl[j] = y[jdex[j] - 1];
            }
        } else {
            /* categorical variable */
            zeroInt(ncat, 32);
            zeroDouble(sumcat, 32);
            for (j = ndstart; j <= ndend; ++j) {
                l = (int) x[kv + (jdex[j] - 1) * mdim];
                sumcat[l - 1] += y[jdex[j] - 1];
                ncat[l - 1] ++;
            }
            /* Compute means of Y by category. */
            for (j = 0; j < lc; ++j) {
                avcat[j] = ncat[j] ? sumcat[j] / ncat[j] : 0.0;
            }
            /* Make the category mean the `pseudo' X data. */
            for (j = 0; j < nsample; ++j) {
                xt[j] = avcat[(int) x[kv + (jdex[j] - 1) * mdim] - 1];
                yl[j] = y[jdex[j] - 1];
            }
        }
        /* copy the x data in this node. */
        for (j = ndstart; j <= ndend; ++j) v[j] = xt[j];
        for (j = 1; j <= nsample; ++j) ncase[j - 1] = j;
        R_qsort_I(v, ncase, ndstart + 1, ndend + 1);
        if (v[ndstart] >= v[ndend]) continue;
        /* ncase(n)=case number of v nth from bottom */
        /* Start from the right and search to the left. */
        critParent = sumnode * sumnode / nodecnt;
        suml = 0.0;
        sumr = sumnode;
        npopl = 0;
        npopr = nodecnt;
        crit = 0.0;
        /* Search through the "gaps" in the x-variable. */
        for (j = ndstart; j <= ndend - 1; ++j) {
            d = yl[ncase[j] - 1];
            suml += d;
            sumr -= d;
            npopl++;
            npopr--;
            if (v[j] < v[j+1]) {
                crit = (suml * suml / npopl) + (sumr * sumr / npopr) -
                        critParent;
                if (crit > critvar) {
                    ubestt = (v[j] + v[j+1]) / 2.0;
                    critvar = crit;
                }
            }
        }
        if (critvar > critmax) {
            *ubest = ubestt;
            *msplit = kv + 1;
            critmax = critvar;
            for (j = ndstart; j <= ndend; ++j) {
                ut[j] = xt[j];
            }
            if (cat[kv] > 1) {
                for (j = 0; j < cat[kv]; ++j) tavcat[j] = avcat[j];
            }
        }
    }
    *decsplit = critmax;
    
    /* If best split can not be found, set to terminal node and return. */
    if (*msplit != -1) {
        nl = ndstart;
        for (j = ndstart; j <= ndend; ++j) {
            if (ut[j] <= *ubest) {
                nl++;
                ncase[nl-1] = jdex[j];
            }
        }
        *ndendl = imax2(nl - 1, ndstart);
        nr = *ndendl + 1;
        for (j = ndstart; j <= ndend; ++j) {
            if (ut[j] > *ubest) {
                if (nr >= nsample) break;
                nr++;
                ncase[nr - 1] = jdex[j];
            }
        }
        if (*ndendl >= ndend) *ndendl = ndend - 1;
        for (j = ndstart; j <= ndend; ++j) jdex[j] = ncase[j];
        
        lc = cat[*msplit - 1];
        if (lc > 1) {
            for (j = 0; j < lc; ++j) {
                icat[j] = (tavcat[j] < *ubest) ? 1 : 0;
            }
            *ubest = pack(lc, icat);
        }
    } else *jstat = 1;
    
}
Beispiel #5
0
void simdetect (
    int    *detect,     /* detector -1 single, 0 multi, 1 proximity, 2 count,... */
    double *gsb0val,    /* Parameter values (matrix nr= comb of g0,sigma,b nc=3) [naive animal] */
    double *gsb1val,    /* Parameter values (matrix nr= comb of g0,sigma,b nc=3) [caught before] */
    int    *cc0,        /* number of g0/sigma/b combinations for naive animals */
    int    *cc1,        /* number of g0/sigma/b combinations for caught before */
    int    *gsb0,       /* lookup which g0/sigma/b combination to use for given g, S, K
                           [naive animal] */
    int    *gsb1,       /* lookup which g0/sigma/b combination to use for given n, S, K 
                           [caught before] */
    int    *N,          /* number of animals */
    int    *ss,         /* number of occasions */
    int    *kk,         /* number of traps */
    int    *nmix,       /* number of classes */
    int    *knownclass, /* known membership of 'latent' classes */
    double *animals,    /* x,y points of animal range centres (first x, then y) */
    double *traps,      /* x,y locations of traps (first x, then y) */
    double *dist2,      /* distances squared (optional: -1 if unused) */
    double *Tsk,        /* ss x kk array of 0/1 usage codes or effort */
    int    *btype,      /* code for behavioural response 
                           0 none
                           1 individual
                           2 individual, trap-specific
                           3 trap-specific
                        */
    int    *Markov,     /* learned vs transient behavioural response 
                           0 learned
                           1 Markov 
                        */
    int    *binomN,     /* number of trials for 'count' detector modelled with binomial */
    double *miscparm,   /* detection threshold on transformed scale, etc. */
    int    *fn,         /* code 0 = halfnormal, 1 = hazard, 2 = exponential, 3 = uniform */
    int    *maxperpoly, /*  */
    int    *n,          /* number of individuals caught */
    int    *caught,     /* sequence number in session (0 if not caught) */
    double *detectedXY, /* x,y locations of detections  */
    double *signal,     /* vector of signal strengths, one per detection */
    int    *value,      /* return value array of trap locations n x s */
    int    *resultcode
)
{
    double d2val;
    double p;
    int    i,j,k,l,s;
    int    ik;
    int    nc = 0;
    int    nk = 0;             /* number of detectors (polygons or transects when *detect==6,7) */
    int    count = 0;
    int    *caughtbefore;
    int    *x;                 /* mixture class of animal i */
    double *pmix;
    double runif;
    int    wxi = 0;
    int    c = 0;
    int    gpar = 2;
    double g0 = 0;
    double sigma = 0;
    double z = 0;
    double Tski = 1.0;  
    double *work = NULL;
    double *noise = NULL;   /* detectfn 12,13 only */
    int    *sortorder = NULL;
    double *sortkey = NULL;

    /*
        *detect may take values -
       -1  single-catch traps
        0  multi-catch traps
        1  binary proximity detectors
        2  count  proximity detectors
        5  signal detectors
        6  polygon detectors
        7  transect detectors
    */
    /*========================================================*/
    /* 'single-catch only' declarations */
    int    tr_an_indx = 0;
    int    nanimals;
    int    ntraps;
    int    *occupied = NULL;
    int    *intrap = NULL;
    struct trap_animal *tran = NULL;
    double event_time;
    int    anum = 0;
    int    tnum = 0;
    int    nextcombo;
    int    finished;
    int    OK;

    /*========================================================*/
    /* 'multi-catch only' declarations */
    double *h = NULL;          /* multi-catch only */
    double *hsum = NULL;       /* multi-catch only */
    double *cump = NULL;       /* multi-catch only */

    /*========================================================*/
    /* 'polygon & transect only' declarations */
    int    nd = 0;
    int    cumk[maxnpoly+1];
    int    sumk;               /* total number of vertices */
    int    g=0;
    int    *gotcha;
    double xy[2];
    int    n1,n2,t;
    double par[3];
    int    np = 1;             /* n points each call of gxy */
    double w, ws;
    int    maxdet=1;
    double *cumd = NULL;
    struct rpoint *line = NULL;
    struct rpoint xyp;
    struct rpoint animal;
    double lx;
    double maxg = 0;
    double lambdak;  /* temp value for Poisson rate */
    double grx;      /* temp value for integral gr */
    double H;
    int    J;
    int    maybecaught;
    double dx,dy,d;
    double pks;
    double sumhaz;
    /*========================================================*/
    /* 'signal-strength only' declarations */
    double beta0;
    double beta1;
    double muS;
    double sdS;
    double muN = 0;
    double sdN = 1;
    double signalvalue;
    double noisevalue;
    double cut;
    double *ex;
    /*========================================================*/
    /* MAIN LINE */

    gotcha = &g;
    *resultcode = 1;
    caughtbefore = (int *) R_alloc(*N * *kk, sizeof(int));
    x = (int *) R_alloc(*N, sizeof(int));
    for (i=0; i<*N; i++) x[i] = 0;
    pmix = (double *) R_alloc(*nmix, sizeof(double));

    /* ------------------------------------------------------ */
    /* pre-compute distances */
    if (dist2[0] < 0) {
	dist2 = (double *) S_alloc(*kk * *N, sizeof(double));
	makedist2 (*kk, *N, traps, animals, dist2);
    }
    else {
	squaredist (*kk, *N, dist2);
    }
    /* ------------------------------------------------------ */

    if ((*detect < -1) || (*detect > 7)) return;

    if (*detect == -1) {                                   /* single-catch only */
        occupied = (int*) R_alloc(*kk, sizeof(int));
        intrap = (int*) R_alloc(*N, sizeof(int));
        tran = (struct trap_animal *) R_alloc(*N * *kk,
            sizeof(struct trap_animal));
	    /*  2*sizeof(int) + sizeof(double)); */
    }
    if (*detect == 0) {                                    /* multi-catch only */
        h = (double *) R_alloc(*N * *kk, sizeof(double));
        hsum = (double *) R_alloc(*N, sizeof(double));
        cump = (double *) R_alloc(*kk+1, sizeof(double));
        cump[0] = 0;
    }

    if (*detect == 5) {                                    /* signal only */
        maxdet = *N * *ss * *kk;
        if (!((*fn == 10) || (*fn == 11)))
            error ("simsecr not implemented for this combination of detector & detectfn");
    }

    if ((*detect == 3) || (*detect == 4) || (*detect == 6) || (*detect == 7)) {
        /* polygon or transect */
        cumk[0] = 0;
        for (i=0; i<maxnpoly; i++) {                       /* maxnpoly much larger than npoly */
            if (kk[i]<=0) break;
            cumk[i+1] = cumk[i] + kk[i];
            nk++;
        }
        sumk = cumk[nk];
        if ((*detect == 6) || (*detect == 7))
            maxdet = *N * *ss * nk * *maxperpoly;
        else 
            maxdet = *N * *ss;
    }
    else nk = *kk;

    if ((*detect == 4) || (*detect == 7)) {                            /* transect only */
        line = (struct rpoint *) R_alloc(sumk, sizeof(struct rpoint));
        cumd = (double *) R_alloc(sumk, sizeof(double));
        /* coordinates of vertices */
        for (i=0; i<sumk; i++) {
            line[i].x = traps[i];
            line[i].y = traps[i+sumk];
        }
        /* cumulative distance along line; all transects end on end */
        for (k=0; k<nk; k++) {
            cumd[cumk[k]] = 0;
            for (i=cumk[k]; i<(cumk[k+1]-1); i++) {
                cumd[i+1] = cumd[i] + distance(line[i], line[i+1]);
            }
        }
    }

    if ((*detect==3) || (*detect==4) || (*detect==5) || (*detect==6) || (*detect==7)) {
        work = (double*) R_alloc(maxdet*2, sizeof(double));   /* twice size needed for signal */
        sortorder = (int*) R_alloc(maxdet, sizeof(int));
        sortkey = (double*) R_alloc(maxdet, sizeof(double));
    }
    if ((*fn==12) || (*fn==13)) {
        noise = (double*) R_alloc(maxdet*2, sizeof(double));   /* twice size needed for signal */
    }

    GetRNGstate();

    gpar = 2;
    if ((*fn == 1) || (*fn == 3) || (*fn == 5)|| (*fn == 6) || (*fn == 7) || (*fn == 8) ||
        (*fn == 10) || (*fn == 11)) gpar ++;

    /* ------------------------------------------------------------------------- */
    /* mixture models */
    /* may be better to pass pmix */
    if (*nmix>1) {
        if (*nmix>2)
            error("simsecr nmix>2 not implemented");
        gpar++;   /* these models have one more detection parameter */
        for (i=0; i<*nmix; i++) {
            wxi = i4(0,0,0,i,*N,*ss,nk);
            c = gsb0[wxi] - 1;
            pmix[i] = gsb0val[*cc0 * (gpar-1) + c];    /* assuming 4-column gsb */
        }
        for (i=0; i<*N; i++) {
	    if (knownclass[i] > 1) 
		x[i] = knownclass[i] - 2;      /* knownclass=2 maps to x=0 etc. */
	    else
		x[i] = rdiscrete(*nmix, pmix) - 1;
        }
    }

    /* ------------------------------------------------------------------------- */
    /* zero caught status */
    for (i=0; i<*N; i++) 
        caught[i] = 0;    
    for (i=0; i<*N; i++) 
        for (k=0; k < nk; k++)
            caughtbefore[k * (*N-1) + i] = 0;

    /* ------------------------------------------------------------------------- */
    /* MAIN LOOP */
    for (s=0; s<*ss; s++) {

        /* ------------------ */
        /* single-catch traps */
        if (*detect == -1) {
            /* initialise day */
            tr_an_indx = 0;
            nanimals = *N;
            ntraps   = nk;
            for (i=0; i<*N; i++) intrap[i] = 0;
            for (k=0; k<nk; k++) occupied[k] = 0;
            nextcombo = 0;

            /* make tran */
            for (i=0; i<*N; i++) {  /* animals */
                for (k=0; k<nk; k++) { /* traps */
		    Tski = Tsk[s * nk + k];
		    if (fabs(Tski) > 1e-10) {
                        getpar (i, s, k, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
			    bswitch (*btype, *N, i, k, caughtbefore), 
                            gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);
			/* d2val = d2(i,k, animals, traps, *N, nk); */
			d2val = d2L(k, i, dist2, nk);
                        p = pfn(*fn, d2val, g0, sigma, z, miscparm, 1e20);  /* effectively inf w2 */

			if (fabs(Tski-1) > 1e-10) 
			    p = 1 - pow(1-p, Tski);
                        
                        event_time = randomtime(p);
                        if (event_time <= 1) {
                            tran[tr_an_indx].time   = event_time;
                            tran[tr_an_indx].animal = i;    /* 0..*N-1 */
                            tran[tr_an_indx].trap   = k;    /* 0..nk-1 */
                            tr_an_indx++;
                        }
                    }
                }
            }
            /* end of make tran */

            if (tr_an_indx > 1) probsort (tr_an_indx, tran);

            while ((nextcombo < tr_an_indx) && (nanimals>0) && (ntraps>0)) {
                    finished = 0;
                OK       = 0;
                    while ((1-finished)*(1-OK) > 0) {      /* until finished or OK */
                    if (nextcombo >= (tr_an_indx))
                            finished = 1;                  /* no more to process */
                    else {
                            anum = tran[nextcombo].animal;
                        tnum = tran[nextcombo].trap;
                            OK = (1-occupied[tnum]) * (1-intrap[anum]); /* not occupied and not intrap */
                        nextcombo++;
                        }
                }
                    if (finished==0) {
                       /* Record this capture */
                          occupied[tnum] = 1;
                      intrap[anum]   = tnum+1;         /* trap = k+1 */
                          nanimals--;
                      ntraps--;
                    }
            }
                for (i=0; i<*N; i++) {
                if (intrap[i]>0) {
                    if (caught[i]==0) {                    /* first capture of this animal */
                       nc++;
                       caught[i] = nc;                     /* nc-th animal to be captured */
                       for (j=0; j<*ss; j++)
                           value[*ss * (nc-1) + j] = 0;
                    }
                    value[*ss * (caught[i]-1) + s] = intrap[i];  /* trap = k+1 */
                }
            }
        }

        /* -------------------------------------------------------------------------- */
        /* multi-catch trap; only one site per occasion (drop last dimension of capt) */
        else if (*detect == 0) {
            for (i=0; i<*N; i++) {
                hsum[i] = 0;
                for (k=0; k<nk; k++) {
		    Tski = Tsk[s * nk + k];
		    if (fabs(Tski) > 1e-10) {
			getpar (i, s, k, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
				bswitch (*btype, *N, i, k, caughtbefore), 
				gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);
			/* d2val = d2(i,k, animals, traps, *N, nk); */
			d2val = d2L(k, i, dist2, nk);
			p = pfn(*fn, d2val, g0, sigma, z, miscparm, 1e20);
			h[k * *N + i] = - Tski * log(1 - p);
			hsum[i] += h[k * *N + i];
		    }
                }

                for (k=0; k<nk; k++) {
                    cump[k+1] = cump[k] + h[k * *N + i]/hsum[i];
                }
                if (Random() < (1-exp(-hsum[i]))) {
                    if (caught[i]==0)  {        /* first capture of this animal */
                        nc++;
                        caught[i] = nc;
                        for (j=0; j<*ss; j++)
                            value[*ss * (nc-1) + j] = 0;
                    }
                    /* find trap with probability proportional to p
                       searches cumulative distribution of p  */
                    runif = Random();
                    k = 0;
                    while ((runif > cump[k]) && (k<nk)) k++;
                    value[*ss * (caught[i]-1) + s] = k;  /* trap = k+1 */
                }
            }
        }

        /* -------------------------------------------------------------------------------- */
        /* the 'proximity' group of detectors 1:2 - proximity, count */
        else if ((*detect >= 1) && (*detect <= 2)) {
            for (i=0; i<*N; i++) {
                for (k=0; k<nk; k++) {
		    Tski = Tsk[s * nk + k];
		    if (fabs(Tski) > 1e-10) {
                        getpar (i, s, k, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
			    bswitch (*btype, *N, i, k, caughtbefore), 
                            gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);
			/* d2val = d2(i,k, animals, traps, *N, nk); */
			d2val = d2L(k, i, dist2, nk);
                        p = pfn(*fn, d2val, g0, sigma, z, miscparm, 1e20);

                        if (p < -0.1) { PutRNGstate(); return; }   /* error */

                        if (p>0) {
                            if (*detect == 1) {
				if (fabs(Tski-1) > 1e-10)
				    p = 1 - pow(1-p, Tski);
                                count = Random() < p;            /* binary proximity */
                            }
                            else if (*detect == 2) {             /* count proximity */
				if (*binomN == 1)
				    count = rcount(round(Tski), p, 1);
				else
				    count = rcount(*binomN, p, Tski);
                            }
                            if (count>0) {
                                if (caught[i]==0) {              /* first capture of this animal */
                                    nc++;
                                    caught[i] = nc;
                                    for (j=0; j<*ss; j++)
                                      for (l=0; l<nk; l++)
                                        value[*ss * ((nc-1) * nk + l) + j] = 0;
                                }
                                value[*ss * ((caught[i]-1) * nk + k) + s] = count;
                            }
                        }
                    }
                }
            }
        }

        /* -------------------------------------------------------------------------------- */
        /* exclusive polygon detectors  */
        else if (*detect == 3) {
            /* find maximum distance between animal and detector vertex */
            w = 0;
            J = cumk[nk];
            for (i = 0; i< *N; i++) {
                for (j = 0; j < J; j++) {
                    dx = animals[i] - traps[j];
                    dy = animals[*N + i] - traps[J + j];
        	    d = sqrt(dx*dx + dy*dy);
                    if (d > w) w = d;
                }
            } 

            for (i=0; i<*N; i++) {
                /* this implementation assumes NO VARIATION AMONG DETECTORS */
                getpar (i, s, 0, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
		    bswitch (*btype, *N, i, 0, caughtbefore), 
                    gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);

                maybecaught = Random() < g0;

                if (w > (10 * sigma)) 
                    ws = 10 * sigma;
                else 
                    ws = w;

                par[0] = 1;
                par[1] = sigma;
                par[2] = z;
                
                if (maybecaught) {
                    gxy (&np, fn, par, &ws, xy);                 /* simulate location */
                    xy[0] = xy[0] + animals[i];
                    xy[1] = xy[1] + animals[*N + i];
                    for (k=0; k<nk; k++) {                      /* each polygon */
			Tski = Tsk[s * nk + k];
			if (fabs(Tski) > 1e-10) {
                            n1 = cumk[k];
                            n2 = cumk[k+1]-1;
                            inside(xy, &n1, &n2, &sumk, traps, gotcha);  /* assume closed */
                            if (*gotcha > 0) {
                                if (caught[i]==0) {             /* first capture of this animal */
                                    nc++;
                                    caught[i] = nc;
                                    for (t=0; t<*ss; t++)
                                            value[*ss * (nc-1) + t] = 0;
                                }
                                nd++;
                                value[*ss * (caught[i]-1) + s] = k+1;
                                work[(nd-1)*2] = xy[0];
                                work[(nd-1)*2+1] = xy[1];
                                sortkey[nd-1] = (double) (s * *N + caught[i]);
                                break;   /* no need to look at more poly */
                            }
                        }
                    }
                }
            }
        }

        /* -------------------------------------------------------------------------------- */
        /* exclusive transect detectors  */
        else if (*detect == 4) {
	    ex = (double *) R_alloc(10 + 2 * maxvertices, sizeof(double));
            for (i=0; i<*N; i++) {                            /* each animal */
                animal.x = animals[i];
                animal.y = animals[i + *N];
                sumhaz = 0;
                /* ------------------------------------ */
                /* sum hazard */
                for (k=0; k<nk; k++) {            
		    Tski = Tsk[s * nk + k];
		    if (fabs(Tski) > 1e-10) {
                        getpar (i, s, k, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
				bswitch (*btype, *N, i, k, caughtbefore), 
				gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);
	                par[0] = g0;
                        par[1] = sigma;
                        par[2] = z;
                        n1 = cumk[k];
                        n2 = cumk[k+1]-1;
                        H = hintegral1(*fn, par);
                        sumhaz += -log(1 - par[0] * integral1D (*fn, i, 0, par, 1, traps, 
			    animals, n1, n2, sumk, *N, ex) / H);
                    }
                }
                /* ------------------------------------ */

                for (k=0; k<nk; k++) {                        /* each transect */
		    Tski = Tsk[s * nk + k];
		    if (fabs(Tski) > 1e-10) {
                        getpar (i, s, k, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
   			    bswitch (*btype, *N, i, k, caughtbefore), 
                            gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);
	                par[0] = g0;
                        par[1] = sigma;
                        par[2] = z;
                        n1 = cumk[k];
                        n2 = cumk[k+1]-1;
                        H = hintegral1(*fn, par);
                        lambdak = par[0] * integral1D (*fn, i, 0, par, 1, traps, animals,
						       n1, n2, sumk, *N, ex) / H;
    	                pks = (1 - exp(-sumhaz)) * (-log(1-lambdak)) / sumhaz;
                        count = Random() < pks;
                        maxg = 0;
                        if (count>0) {                       /* find maximum - approximate */
                            for (l=0; l<=100; l++) {
                                lx = (cumd[n2] - cumd[n1]) * l/100;
                                xyp = getxy (lx, cumd, line, sumk, n1);
                                grx = gr (fn, par, xyp, animal);
                                if (R_FINITE(grx))
                                    maxg = fmax2(maxg, grx);
                            }
                            for (l=n1; l<=n2; l++) {
                                xyp = line[l];
                                grx = gr (fn, par, xyp, animal);
                                if (R_FINITE(grx))
                                    maxg = fmax2(maxg, grx);
                            }
                            maxg= 1.2 * maxg;                 /* safety margin */
                            if (maxg<=0)
                                Rprintf("maxg error in simsecr\n"); /* not found */
                            *gotcha = 0;
                            l = 0;
                            while (*gotcha == 0) {
                                lx = Random() * (cumd[n2] - cumd[n1]);     /* simulate location */
                                xyp = getxy (lx, cumd, line, sumk, n1);
                                grx = gr (fn, par, xyp, animal);
                                if (Random() < (grx/maxg))    /* rejection sampling */
                                    *gotcha = 1;
                                l++;
                                if (l % 10000 == 0)
                                    R_CheckUserInterrupt();
                                if (l>1e8) *gotcha = 1;       /* give up and accept anything!!!! */
                            }
                            if (caught[i]==0) {               /* first capture of this animal */
                                nc++;
                                caught[i] = nc;
                                for (t=0; t<*ss; t++)
                                        value[*ss * (nc-1) + t] = 0;
                            }
                            nd++;
                            if (nd >= maxdet) {
                                *resultcode = 2;  /* error */
                                return;
                            }
                            value[*ss * (caught[i]-1) + s] = k+1;
                            work[(nd-1)*2] = xyp.x;
                            work[(nd-1)*2+1] = xyp.y;
                            sortkey[nd-1] = (double) (s * *N + caught[i]);
                        }
                        if (count>0) break;   /* no need to look further */
                    }
                }                                             /* end loop over transects */
            }                                                 /* end loop over animals */
        }

        /* -------------------------------------------------------------------------------- */
        /* polygon detectors  */
        else if (*detect == 6) {
            for (i=0; i<*N; i++) {
                /* this implementation assumes NO VARIATION AMONG DETECTORS */

                getpar (i, s, 0, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
		    bswitch (*btype, *N, i, 0, caughtbefore), 
                    gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);
                count = rcount(*binomN, g0, Tski);
                w = 10 * sigma;
                par[0] = 1;
                par[1] = sigma;
                par[2] = z;
                for (j=0; j<count; j++) {
                    gxy (&np, fn, par, &w, xy);                 /* simulate location */
                    xy[0] = xy[0] + animals[i];
                    xy[1] = xy[1] + animals[*N + i];
                    for (k=0; k<nk; k++) {                      /* each polygon */
			Tski = Tsk[s * nk + k];
			if (fabs(Tski) > 1e-10) {
                            n1 = cumk[k];
                            n2 = cumk[k+1]-1;
                            inside(xy, &n1, &n2, &sumk, traps, gotcha);  /* assume closed */
                            if (*gotcha > 0) {
                                if (caught[i]==0) {             /* first capture of this animal */
                                    nc++;
                                    caught[i] = nc;
                                    for (t=0; t<*ss; t++)
                                        for (l=0; l<nk; l++)
                                            value[*ss * ((nc-1) * nk + l) + t] = 0;
                                }
                                nd++;
                                if (nd > maxdet) {
                                    *resultcode = 2;
                                    return;  /* error */
                                }
                                value[*ss * ((caught[i]-1) * nk + k) + s]++;
                                work[(nd-1)*2] = xy[0];
                                work[(nd-1)*2+1] = xy[1];
                                sortkey[nd-1] = (double) (k * *N * *ss + s * *N + caught[i]);
                            }
                        }
                    }
                }
            }
        }

        /* -------------------------------------------------------------------------------- */
        /* transect detectors  */
        else if (*detect == 7) {
	    ex = (double *) R_alloc(10 + 2 * maxvertices, sizeof(double));
            for (i=0; i<*N; i++) {                            /* each animal */
                animal.x = animals[i];
                animal.y = animals[i + *N];
                for (k=0; k<nk; k++) {                        /* each transect */
		    Tski = Tsk[s * nk + k];
		    if (fabs(Tski) > 1e-10) {
                        getpar (i, s, k, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
 			    bswitch (*btype, *N, i, k, caughtbefore), 
                            gsb0, gsb0val, gsb1, gsb1val, &g0, &sigma, &z);
	                par[0] = g0;
                        par[1] = sigma;
                        par[2] = z;
                        n1 = cumk[k];
                        n2 = cumk[k+1]-1;
                        H = hintegral1(*fn, par);
                        lambdak = par[0] * integral1D (*fn, i, 0, par, 1, traps, animals,
						       n1, n2, sumk, *N, ex) / H;
                        count = rcount(*binomN, lambdak, Tski);  /* numb detections on transect */
                        maxg = 0;
                        if (count>0) {                       /* find maximum - approximate */
                            for (l=0; l<=100; l++) {
                                lx = (cumd[n2]-cumd[n1]) * l/100;
                                xyp = getxy (lx, cumd, line, sumk, n1);
                                grx = gr (fn, par, xyp, animal);
                                if (R_FINITE(grx))
                                    maxg = fmax2(maxg, grx);
                            }
                            for (l=n1; l<=n2; l++) {
                                xyp = line[l];
                                grx = gr (fn, par, xyp, animal);
                                if (R_FINITE(grx))
                                    maxg = fmax2(maxg, grx);
                            }
                            maxg= 1.2 * maxg;                 /* safety margin */
                            if (maxg<=0)
                                Rprintf("maxg error in simsecr\n"); /* not found */

                        }
                        for (j=0; j<count; j++) {
                            *gotcha = 0;
                            l = 0;
                            while (*gotcha == 0) {
                                lx = Random() * (cumd[n2]-cumd[n1]);     /* simulate location */
                                xyp = getxy (lx, cumd, line, sumk, n1);
                                grx = gr (fn, par, xyp, animal);
                                if (Random() < (grx/maxg))   /* rejection sampling */
                                    *gotcha = 1;
                                l++;
                                if (l % 10000 == 0)
                                    R_CheckUserInterrupt();
                                if (l>1e8) *gotcha = 1;        /* give up and accept anything!!!! */
                            }
                            if (caught[i]==0) {               /* first capture of this animal */
                                nc++;
                                caught[i] = nc;
                                for (t=0; t<*ss; t++)
                                    for (l=0; l<nk; l++)
                                        value[*ss * ((nc-1) * nk + l) + t] = 0;
                            }
                            nd++;
                            if (nd >= maxdet) {
                                *resultcode = 2;  /* error */
                                return;
                            }
                            value[*ss * ((caught[i]-1) * nk + k) + s]++;
                            work[(nd-1)*2] = xyp.x;
                            work[(nd-1)*2+1] = xyp.y;
                            sortkey[nd-1] = (double) (k * *N * *ss + s * *N + caught[i]);
                        }
                    }
                }                                             /* end loop over transects */
            }                                                 /* end loop over animals */
        }

        /* ------------------------ */
        /* signal strength detector */
        else if (*detect == 5) {
	    cut = miscparm[0];
	    if ((*fn == 12) || (*fn == 13)) {
		muN = miscparm[1];
		sdN = miscparm[2];
	    }
            for (i=0; i<*N; i++) {
                for (k=0; k<nk; k++) {
		    Tski = Tsk[s * nk + k];
		    if (fabs(Tski) > 1e-10) {
                        /* sounds not recaptured */
                        getpar (i, s, k, x[i], *N, *ss, nk, *cc0, *cc1, *fn, 
				0, gsb0, gsb0val, gsb0, gsb0val, &beta0, &beta1, &sdS);
                        /*
                        if ((*fn == 10) || (*fn == 12))
			    muS  = mufn (i, k, beta0, beta1, animals, traps, *N, nk, 0);
                        else
                            muS  = mufn (i, k, beta0, beta1, animals, traps, *N, nk, 1);
                        */
			if ((*fn == 10) || (*fn == 12))
			    muS  = mufnL (k, i, beta0, beta1, dist2, nk, 0);
			else
			    muS  = mufnL (k, i, beta0, beta1, dist2, nk, 1);

			signalvalue = norm_rand() * sdS + muS;
                        if ((*fn == 10) || (*fn == 11)) {
			    if (signalvalue > cut) {
				if (caught[i]==0) {        /* first capture of this animal */
				    nc++;
				    caught[i] = nc;
				    for (j=0; j<*ss; j++)
					for (l=0; l<nk; l++)
					    value[*ss * ((nc-1) * *kk + l) + j] = 0;
				}
				nd++;
				value[*ss * ((caught[i]-1) * *kk + k) + s] = 1;
				work[nd-1] = signalvalue;
				sortkey[nd-1] = (double) (k * *N * *ss + s * *N + caught[i]);
			    }
			}
			else {
			    noisevalue = norm_rand() * sdN + muN;
			    if ((signalvalue - noisevalue) > cut) {
				if (caught[i]==0) {        /* first capture of this animal */
				    nc++;
				    caught[i] = nc;
				    for (j=0; j<*ss; j++)
					for (l=0; l<nk; l++)
					    value[*ss * ((nc-1) * *kk + l) + j] = 0;
				}
				nd++;
				value[*ss * ((caught[i]-1) * *kk + k) + s] = 1;
				work[nd-1] = signalvalue;
				noise[nd-1] = noisevalue;
				sortkey[nd-1] = (double) (k * *N * *ss + s * *N + caught[i]);
			    }
			}
		    }
                }
            }
        }

	if ((*btype > 0) && (s < (*ss-1))) {
            /* update record of 'previous-capture' status */
            if (*btype == 1) {
                for (i=0; i<*N; i++) {
                    if (*Markov) 
                        caughtbefore[i] = 0;
                    for (k=0; k<nk; k++)
                        caughtbefore[i] = imax2 (value[i3(s, k, i, *ss, nk)], caughtbefore[i]);
                }
            }
            else if (*btype == 2) {
                for (i=0; i<*N; i++) {
                    for (k=0; k<nk; k++) {
                        ik = k * (*N-1) + i;
                        if (*Markov) 
                            caughtbefore[ik] = value[i3(s, k, i, *ss, nk)];
                        else 
                            caughtbefore[ik] = imax2 (value[i3(s, k, i, *ss, nk)], 
			        caughtbefore[ik]);
		    }
		}
            }
	    else {
                for (k=0;k<nk;k++) {
                    if (*Markov) 
                        caughtbefore[k] = 0;
                    for (i=0; i<*N; i++) 
                        caughtbefore[k] = imax2 (value[i3(s, k, i, *ss, nk)], caughtbefore[k]);
                }
	    }
	}

    }   /* loop over s */

    if ((*detect==3) || (*detect==4) || (*detect==5) || (*detect==6) || (*detect==7)) {
        for (i=0; i<nd; i++) sortorder[i] = i;
        if (nd>0) rsort_with_index (sortkey, sortorder, nd);
        if (*detect==5) {
            for (i=0; i<nd; i++) signal[i] = work[sortorder[i]];
	    if ((*fn == 12) || (*fn == 13)) {
		for (i=0; i<nd; i++) signal[i+nd] = noise[sortorder[i]];
	    }
	}
        else {
            for (i=0; i<nd; i++) {
                detectedXY[i]    = work[sortorder[i]*2];
                detectedXY[i+nd] = work[sortorder[i]*2+1];
            }
        }
    }
    *n = nc;
    PutRNGstate();
    *resultcode = 0;
}
Beispiel #6
0
double rhyper(double nn1in, double nn2in, double kkin)
{
    const static double deltal = 0.0078;
    const static double deltau = 0.0034;

    /* extern double afc(int); */

    int nn1, nn2, kk;
    int i, ix;
    Rboolean reject, setup1, setup2;

    double e, f, g, r, t, y;

    /* These should become 'thread_local globals' : */
    static int ks = -1, n1s = -1, n2s = -1;
    static int k, m, minjx, maxjx, n1, n2;
    static double tn;
    // II :
    static double w;
    // III:
    static double a, d, s, xl, xr, kl, kr, lamdl, lamdr, p1, p2, p3;

    /* check parameter validity */

    if(!R_FINITE(nn1in) || !R_FINITE(nn2in) || !R_FINITE(kkin))
	ML_ERR_return_NAN;

    // Disabling large (nn1, nn2, kk) { =^= rhyper (m,n,k) }:
    nn1 = (int) R_forceint(nn1in);
    nn2 = (int) R_forceint(nn2in);
    kk	= (int) R_forceint(kkin);

    if (nn1 < 0 || nn2 < 0 || kk < 0 || kk > nn1 + nn2)
	ML_ERR_return_NAN;

    /* if new parameter values, initialize */
    reject = TRUE;
    if (nn1 != n1s || nn2 != n2s) {
	setup1 = TRUE;	setup2 = TRUE;
    } else if (kk != ks) {
	setup1 = FALSE;	setup2 = TRUE;
    } else {
	setup1 = FALSE;	setup2 = FALSE;
    }
    if (setup1) {
	n1s = nn1;
	n2s = nn2;
	tn = nn1 + nn2;
	if (nn1 <= nn2) {
	    n1 = nn1;
	    n2 = nn2;
	} else {
	    n1 = nn2;
	    n2 = nn1;
	}
    }
    if (setup2) {
	ks = kk;
	if (kk + kk >= tn) {
	    k = (int)(tn - kk);
	} else {
	    k = kk;
	}
    }
    if (setup1 || setup2) {
	m = (int) ((k + 1.0) * (n1 + 1.0) / (tn + 2.0));
	minjx = imax2(0, k - n2);
	maxjx = imin2(n1, k);
    }
    /* generate random variate --- Three basic cases */

    if (minjx == maxjx) { /* I: degenerate distribution ---------------- */
	ix = maxjx;
	/* return ix;
	   No, need to unmangle <TSL>*/
	/* return appropriate variate */

	if (kk + kk >= tn) {
	  if (nn1 > nn2) {
	    ix = kk - nn2 + ix;
	  } else {
	    ix = nn1 - ix;
	  }
	} else {
	  if (nn1 > nn2)
	    ix = kk - ix;
	}
	return ix;

    } else if (m - minjx < 10) { // II: (Scaled) algorithm HIN (inverse transformation) ----
	const static double scale = 1e25; // scaling factor against (early) underflow
	const static double con = 57.5646273248511421;
                                          // 25*log(10) = log(scale) { <==> exp(con) == scale }
	if (setup1 || setup2) {
	    double lw; // log(w);  w = exp(lw) * scale = exp(lw + log(scale)) = exp(lw + con)
	    if (k < n2) {
		lw = afc(n2) + afc(n1 + n2 - k) - afc(n2 - k) - afc(n1 + n2);
	    } else {
		lw = afc(n1) + afc(     k     ) - afc(k - n2) - afc(n1 + n2);
	    }
	    w = exp(lw + con);
	}
	double p, u;
      L10:
	p = w;
	ix = minjx;
	u = unif_rand() * scale;
	while (u > p) {
	    u -= p;
	    p *= ((double) n1 - ix) * (k - ix);
	    ix++;
	    p = p / ix / (n2 - k + ix);
	    if (ix > maxjx)
		goto L10;
	}
    } else { /* III : H2PE Algorithm --------------------------------------- */

	double u,v;

	if (setup1 || setup2) {
	    s = sqrt((tn - k) * k * n1 * n2 / (tn - 1) / tn / tn);

	    /* remark: d is defined in reference without int. */
	    /* the truncation centers the cell boundaries at 0.5 */

	    d = (int) (1.5 * s) + .5;
	    xl = m - d + .5;
	    xr = m + d + .5;
	    a = afc(m) + afc(n1 - m) + afc(k - m) + afc(n2 - k + m);
	    kl = exp(a - afc((int) (xl)) - afc((int) (n1 - xl))
		     - afc((int) (k - xl))
		     - afc((int) (n2 - k + xl)));
	    kr = exp(a - afc((int) (xr - 1))
		     - afc((int) (n1 - xr + 1))
		     - afc((int) (k - xr + 1))
		     - afc((int) (n2 - k + xr - 1)));
	    lamdl = -log(xl * (n2 - k + xl) / (n1 - xl + 1) / (k - xl + 1));
	    lamdr = -log((n1 - xr + 1) * (k - xr + 1) / xr / (n2 - k + xr));
	    p1 = d + d;
	    p2 = p1 + kl / lamdl;
	    p3 = p2 + kr / lamdr;
	}
      L30:
	u = unif_rand() * p3;
	v = unif_rand();
	if (u < p1) {		/* rectangular region */
	    ix = (int) (xl + u);
	} else if (u <= p2) {	/* left tail */
	    ix = (int) (xl + log(v) / lamdl);
	    if (ix < minjx)
		goto L30;
	    v = v * (u - p1) * lamdl;
	} else {		/* right tail */
	    ix = (int) (xr - log(v) / lamdr);
	    if (ix > maxjx)
		goto L30;
	    v = v * (u - p2) * lamdr;
	}

	/* acceptance/rejection test */

	if (m < 100 || ix <= 50) {
	    /* explicit evaluation */
	    /* The original algorithm (and TOMS 668) have
		   f = f * i * (n2 - k + i) / (n1 - i) / (k - i);
	       in the (m > ix) case, but the definition of the
	       recurrence relation on p134 shows that the +1 is
	       needed. */
	    f = 1.0;
	    if (m < ix) {
		for (i = m + 1; i <= ix; i++)
		    f = f * (n1 - i + 1) * (k - i + 1) / (n2 - k + i) / i;
	    } else if (m > ix) {
		for (i = ix + 1; i <= m; i++)
		    f = f * i * (n2 - k + i) / (n1 - i + 1) / (k - i + 1);
	    }
	    if (v <= f) {
		reject = FALSE;
	    }
	} else {
	    double de, dg, dr, ds, dt, gl, gu, nk, nm, ub;
	    double xk, xm, xn, y1, ym, yn, yk, alv;
	    /* squeeze using upper and lower bounds */
	    y = ix;
	    y1 = y + 1.0;
	    ym = y - m;
	    yn = n1 - y + 1.0;
	    yk = k - y + 1.0;
	    nk = n2 - k + y1;
	    r = -ym / y1;
	    s = ym / yn;
	    t = ym / yk;
	    e = -ym / nk;
	    g = yn * yk / (y1 * nk) - 1.0;
	    dg = 1.0;
	    if (g < 0.0)
		dg = 1.0 + g;
	    gu = g * (1.0 + g * (-0.5 + g / 3.0));
	    gl = gu - .25 * (g * g * g * g) / dg;
	    xm = m + 0.5;
	    xn = n1 - m + 0.5;
	    xk = k - m + 0.5;
	    nm = n2 - k + xm;
	    ub = y * gu - m * gl + deltau
		+ xm * r * (1. + r * (-0.5 + r / 3.0))
		+ xn * s * (1. + s * (-0.5 + s / 3.0))
		+ xk * t * (1. + t * (-0.5 + t / 3.0))
		+ nm * e * (1. + e * (-0.5 + e / 3.0));
	    /* test against upper bound */
	    alv = log(v);
	    if (alv > ub) {
		reject = TRUE;
	    } else {
				/* test against lower bound */
		dr = xm * (r * r * r * r);
		if (r < 0.0)
		    dr /= (1.0 + r);
		ds = xn * (s * s * s * s);
		if (s < 0.0)
		    ds /= (1.0 + s);
		dt = xk * (t * t * t * t);
		if (t < 0.0)
		    dt /= (1.0 + t);
		de = nm * (e * e * e * e);
		if (e < 0.0)
		    de /= (1.0 + e);
		if (alv < ub - 0.25 * (dr + ds + dt + de)
		    + (y + m) * (gl - gu) - deltal) {
		    reject = FALSE;
		}
		else {
		    /* * Stirling's formula to machine accuracy
		     */
		    if (alv <= (a - afc(ix) - afc(n1 - ix)
				- afc(k - ix) - afc(n2 - k + ix))) {
			reject = FALSE;
		    } else {
			reject = TRUE;
		    }
		}
	    }
	} // else
	if (reject)
	    goto L30;
    }

    /* return appropriate variate */

    if (kk + kk >= tn) {
	if (nn1 > nn2) {
	    ix = kk - nn2 + ix;
	} else {
	    ix = nn1 - ix;
	}
    } else {
	if (nn1 > nn2)
	    ix = kk - ix;
    }
    return ix;
}
Beispiel #7
0
nlopt_result isres_minimize(int n, nlopt_func f, void *f_data,
			    int m, nlopt_constraint *fc, /* fc <= 0 */
			    int p, nlopt_constraint *h, /* h == 0 */
			    const double *lb, const double *ub, /* bounds */
			    double *x, /* in: initial guess, out: minimizer */
			    double *minf,
			    nlopt_stopping *stop,
			    int population) /* pop. size (= 0 for default) */
{
     const double ALPHA = 0.2; /* smoothing factor from paper */
     const double GAMMA = 0.85; /* step-reduction factor from paper */
     const double PHI = 1.0; /* expected rate of convergence, from paper */
     const double PF = 0.45; /* fitness probability, from paper */
     const double SURVIVOR = 1.0/7.0; /* survivor fraction, from paper */
     int survivors;
     nlopt_result ret = NLOPT_SUCCESS;
     double *sigmas = 0, *xs; /* population-by-n arrays (row-major) */
     double *fval; /* population array of function vals */
     double *penalty; /* population array of penalty vals */
     double *x0;
     int *irank = 0;
     int k, i, j, c;
     int mp = m + p;
     double minf_penalty = HUGE_VAL, minf_gpenalty = HUGE_VAL;
     double taup, tau;
     double *results = 0; /* scratch space for mconstraint results */
     unsigned ires;

     *minf = HUGE_VAL;

     if (!population) population = 20 * (n + 1);
     if (population < 1) {
         nlopt_stop_msg(stop, "population %d is too small", population);
         return NLOPT_INVALID_ARGS;
     }
     survivors = (int) ceil(population * SURVIVOR);

     taup = PHI / sqrt(2*n);
     tau = PHI / sqrt(2*sqrt(n));

     /* we don't handle unbounded search regions */
     for (j = 0; j < n; ++j) if (nlopt_isinf(lb[j]) || nlopt_isinf(ub[j])) {
             nlopt_stop_msg(stop, "isres requires a finite search region");
             return NLOPT_INVALID_ARGS;
         }

     ires = imax2(nlopt_max_constraint_dim(m, fc),
		  nlopt_max_constraint_dim(p, h));
     results = (double *) malloc(ires * sizeof(double));
     if (ires > 0 && !results) return NLOPT_OUT_OF_MEMORY;

     sigmas = (double*) malloc(sizeof(double) * (population*n*2
						 + population
						 + population
						 + n));
     if (!sigmas) { free(results); return NLOPT_OUT_OF_MEMORY; }
     xs = sigmas + population*n;
     fval = xs + population*n;
     penalty = fval + population;
     x0 = penalty + population;

     irank = (int*) malloc(sizeof(int) * population);
     if (!irank) { ret = NLOPT_OUT_OF_MEMORY; goto done; }

     for (k = 0; k < population; ++k) {
	  for (j = 0; j < n; ++j) {
	       sigmas[k*n+j] = (ub[j] - lb[j]) / sqrt(n);
	       xs[k*n+j] = nlopt_urand(lb[j], ub[j]);
	  }
     }
     memcpy(xs, x, sizeof(double) * n); /* use input x for xs_0 */

     while (1) { /* each loop body = one generation */
	  int all_feasible = 1;

	  /* evaluate f and constraint violations for whole population */
	  for (k = 0; k < population; ++k) {
	       int feasible = 1;
	       double gpenalty;
	       ++ *(stop->nevals_p);
	       fval[k] = f(n, xs + k*n, NULL, f_data);
	       if (nlopt_stop_forced(stop)) { 
		    ret = NLOPT_FORCED_STOP; goto done; }
	       penalty[k] = 0;
	       for (c = 0; c < m; ++c) { /* inequality constraints */
		    nlopt_eval_constraint(results, NULL,
					  fc + c, n, xs + k*n);
		    if (nlopt_stop_forced(stop)) { 
			 ret = NLOPT_FORCED_STOP; goto done; }
		    for (ires = 0; ires < fc[c].m; ++ires) {
			 double gval = results[ires];
			 if (gval > fc[c].tol[ires]) feasible = 0;
			 if (gval < 0) gval = 0;
			 penalty[k] += gval*gval;
		    }
	       }
	       gpenalty = penalty[k];
	       for (c = m; c < mp; ++c) { /* equality constraints */
		    nlopt_eval_constraint(results, NULL,
					  h + (c-m), n, xs + k*n);
		    if (nlopt_stop_forced(stop)) { 
			 ret = NLOPT_FORCED_STOP; goto done; }
		    for (ires = 0; ires < h[c-m].m; ++ires) {
			 double hval = results[ires];
			 if (fabs(hval) > h[c-m].tol[ires]) feasible = 0;
			 penalty[k] += hval*hval;
		    }
	       }
	       if (penalty[k] > 0) all_feasible = 0;

	       /* convergence criteria (FIXME: improve?) */

	       /* FIXME: with equality constraints, how do
		  we decide which solution is the "best" so far?
		  ... need some total order on the solutions? */

	       if ((penalty[k] <= minf_penalty || feasible)
		   && (fval[k] <= *minf || minf_gpenalty > 0)
		   && ((feasible ? 0 : penalty[k]) != minf_penalty
		       || fval[k] != *minf)) {
		    if (fval[k] < stop->minf_max && feasible) 
			 ret = NLOPT_MINF_MAX_REACHED;
		    else if (!nlopt_isinf(*minf)) {
			 if (nlopt_stop_f(stop, fval[k], *minf)
			     && nlopt_stop_f(stop, feasible ? 0 : penalty[k], 
					     minf_penalty))
			      ret = NLOPT_FTOL_REACHED;
			 else if (nlopt_stop_x(stop, xs+k*n, x))
			      ret = NLOPT_XTOL_REACHED;
		    }
		    memcpy(x, xs+k*n, sizeof(double)*n);
		    *minf = fval[k];
		    minf_penalty = feasible ? 0 : penalty[k];
		    minf_gpenalty = feasible ? 0 : gpenalty;
		    if (ret != NLOPT_SUCCESS) goto done;
	       }

	       if (nlopt_stop_forced(stop)) ret = NLOPT_FORCED_STOP;
	       else if (nlopt_stop_evals(stop)) ret = NLOPT_MAXEVAL_REACHED;
	       else if (nlopt_stop_time(stop)) ret = NLOPT_MAXTIME_REACHED;
	       if (ret != NLOPT_SUCCESS) goto done;
	  }

	  /* "selection" step: rank the population */
	  for (k = 0; k < population; ++k) irank[k] = k;
	  if (all_feasible) /* special case: rank by objective function */
	       nlopt_qsort_r(irank, population, sizeof(int), fval,key_compare);
	  else {
	       /* Runarsson & Yao's stochastic ranking of the population */
	       for (i = 0; i < population; ++i) {
		    int swapped = 0;
		    for (j = 0; j < population-1; ++j) {
			 double u = nlopt_urand(0,1);
			 if (u < PF || (penalty[irank[j]] == 0
					&& penalty[irank[j+1]] == 0)) {
			      if (fval[irank[j]] > fval[irank[j+1]]) {
				   int irankj = irank[j];
				   irank[j] = irank[j+1];
				   irank[j+1] = irankj;
				   swapped = 1;
			      }
			 }
			 else if (penalty[irank[j]] > penalty[irank[j+1]]) {
			      int irankj = irank[j];
			      irank[j] = irank[j+1];
			      irank[j+1] = irankj;
			      swapped = 1;
			 }
		    }
		    if (!swapped) break;
	       }
	  }

	  /* evolve the population:
	     differential evolution for the best survivors,
	     and standard mutation of the best survivors for the rest: */
	  for (k = survivors; k < population; ++k) { /* standard mutation */
	       double taup_rand = taup * nlopt_nrand(0,1);
	       int rk = irank[k], ri;
	       i = k % survivors;
	       ri = irank[i];
	       for (j = 0; j < n; ++j) {
		    double sigmamax = (ub[j] - lb[j]) / sqrt(n);
		    sigmas[rk*n+j] = sigmas[ri*n+j] 
			 * exp(taup_rand + tau*nlopt_nrand(0,1));
		    if (sigmas[rk*n+j] > sigmamax)
			 sigmas[rk*n+j] = sigmamax;
		    do {
			 xs[rk*n+j] = xs[ri*n+j] 
			      + sigmas[rk*n+j] * nlopt_nrand(0,1);
		    } while (xs[rk*n+j] < lb[j] || xs[rk*n+j] > ub[j]);
		    sigmas[rk*n+j] = sigmas[ri*n+j] + ALPHA*(sigmas[rk*n+j]
							   - sigmas[ri*n+j]);
	       }
	  }
	  memcpy(x0, xs, n * sizeof(double));
	  for (k = 0; k < survivors; ++k) { /* differential variation */
	       double taup_rand = taup * nlopt_nrand(0,1);
	       int rk = irank[k];
	       for (j = 0; j < n; ++j) {
		    double xi = xs[rk*n+j];
		    if (k+1 < survivors)
			 xs[rk*n+j] += GAMMA * (x0[j] - xs[(k+1)*n+j]);
		    if (k+1 == survivors
			|| xs[rk*n+j] < lb[j] || xs[rk*n+j] > ub[j]) {
			 /* standard mutation for last survivor and
			    for any survivor components that are now
			    outside the bounds */
			 double sigmamax = (ub[j] - lb[j]) / sqrt(n);
			 double sigi = sigmas[rk*n+j];
			 sigmas[rk*n+j] *= exp(taup_rand 
					       + tau*nlopt_nrand(0,1));
			 if (sigmas[rk*n+j] > sigmamax)
			      sigmas[rk*n+j] = sigmamax;
			 do {
			      xs[rk*n+j] = xi 
				   + sigmas[rk*n+j] * nlopt_nrand(0,1);
			 } while (xs[rk*n+j] < lb[j] || xs[rk*n+j] > ub[j]);
			 sigmas[rk*n+j] = sigi 
			      + ALPHA * (sigmas[rk*n+j] - sigi);
		    }
	       }
	  }
     }

done:
     if (irank) free(irank);
     if (sigmas) free(sigmas);
     if (results) free(results);
     return ret;
}
Beispiel #8
0
extern "C" SEXP covOPW(SEXP SX, SEXP Siter, SEXP SscaleFun, SEXP SrcovFun)
{
  std::cout << "calling covOPW" << std::endl;
  char CHARA = 'A', CHARL = 'L', CHARN = 'N', CHART = 'T', CHARV = 'V';
  double *X = NULL, *Z = NULL, *ZCOPY = NULL, *U = NULL, **A = NULL, *d = NULL;
  double *dwork2 = NULL, *dwork3 = NULL, *diagT = NULL, *offdiagT = NULL;
  double *tau = NULL, *gamma = NULL, *cov = NULL, *covcopy = NULL, *center = NULL, *dist = NULL;
  double mu = 0.0, alpha = 0.0, DZERO = 0.0, DONE = 1.0;
  int n = 0, p = 0, np = 0, pp = 0, iter = -1, i = 0, j = 0, info = 0, lwork = 0;
  int liwork = 0, IONE = 1;
  int *isuppz = NULL, *iwork = NULL;
	SEXP Sans = R_NilValue, Scov = R_NilValue, Scenter = R_NilValue;
	SEXP Sdist = R_NilValue, Sdim = R_NilValue, Snames = R_NilValue;
  scaleFnPtr *scalefn = NULL;
  rcovFnPtr *rcovfn = NULL;

  if(strncmp(CHAR(asChar(SscaleFun)), "s_mad", 5) == 0)
    scalefn = &my_mad;
  else if(strncmp(CHAR(asChar(SscaleFun)), "scaleTau2", 9) == 0)
    scalefn = &scaleTau2;
  else
    error("unable to set scale function pointer in C function covOPW");

  if(strncmp(CHAR(asChar(SrcovFun)), "gk", 2) == 0) 
    rcovfn = &gk;
  else if(strncmp(CHAR(asChar(SrcovFun)), "qc", 2) == 0) 
    rcovfn = &qc;
  else
    error("unable to set rcov function pointer in C function covOPW");

  if(!isMatrix(SX))
    error("first argument to C function covOPW is not a matrix");

  PROTECT(Sdim = getAttrib(SX, R_DimSymbol));
  n = INTEGER(Sdim)[0];
  p = INTEGER(Sdim)[1];
  Sdim = R_NilValue;
  UNPROTECT(1);

  np = n*p;
  pp = p*p;
  lwork = 18*p;
  liwork = 10*p;

  iter = INTEGER(Siter)[0];

  X = REAL(SX);
  Z = (double*) R_alloc((size_t) np, sizeof(double));
  arma::mat ZZ(X,n,p,false,true);
  F77_CALL(dcopy)(&np, X, &IONE, Z, &IONE);

  ZCOPY = (double*) R_alloc((size_t) np, sizeof(double));
  U = (double*) R_alloc((size_t) (p*(p+1))/2, sizeof(double));
  covcopy = (double*) R_alloc((size_t) pp, sizeof(double));

  A = (double**) R_alloc((size_t) iter, sizeof(double*));
  for(int k = 0; k < iter; k++)
    A[k] = (double*) R_alloc((size_t) pp, sizeof(double));

  d = (double*) R_alloc((size_t) p, sizeof(double));
  dwork2 = (double*) R_alloc((size_t) n, sizeof(double));
  dwork3 = (double*) R_alloc((size_t) imax2(n, lwork), sizeof(double));
  diagT = (double*) R_alloc((size_t) p, sizeof(double));
  offdiagT = (double*) R_alloc((size_t) (p-1), sizeof(double));
  tau = (double*) R_alloc((size_t) (p-1), sizeof(double));
  gamma = (double*) R_alloc((size_t) p, sizeof(double));
  isuppz = (int*) R_alloc((size_t) (2*p), sizeof(int));
  iwork = (int*) R_alloc((size_t) liwork, sizeof(int));

  for(int k = 0; k < iter; k++) {

    for(j = 0; j < p; j++) {
      d[j] = scalefn(n, ZZ.colptr(j), &mu);
      //this can be handled better
      if(fabs(d[j]) < 1e-12) error("column with zero scale encountered in C function covOPW");
      alpha = 1.0 / d[j];
      ZZ.col(j) *= alpha;
    }

    for(i = 0; i < p; i++) U[i+((2*p-i-1)*i)/2] = 1.0;
    calcCovs(U, ZZ, rcovfn, scalefn);

    F77_CALL(dsptrd)(&CHARL, &p, U, diagT, offdiagT, tau, &info);
    F77_CALL(dstegr)(&CHARV, &CHARA, &p, diagT, offdiagT, &mu, &mu, &i,
                     &i, &DZERO, &j, gamma, A[k], &p, isuppz, dwork3,
                     &lwork, iwork, &liwork, &info);
    F77_CALL(dopmtr)(&CHARL, &CHARL, &CHARN, &p, &p, U, tau, A[k], &p,
                     dwork2, &info);

    for(j = 0; j < p/2; j++) {
      F77_CALL(dswap)(&p, A[k]+j*p, &IONE, A[k]+p*(p-j-1), &IONE);
    }

    F77_CALL(dcopy)(&np, Z, &IONE, ZCOPY, &IONE);
    F77_CALL(dgemm)(&CHARN, &CHARN, &n, &p, &p, &DONE, ZCOPY, &n, A[k],
                    &p, &DZERO, Z, &n);

    for(i = 0; i < p; i++)
      for(j = 0; j < p; j++)
        A[k][i+j*p] = d[i] * A[k][i+j*p];
  }

  PROTECT(Scov = allocMatrix(REALSXP, p, p));
  PROTECT(Scenter = allocVector(REALSXP, p));
  PROTECT(Sdist = allocVector(REALSXP, n));
  cov = REAL(Scov);
  center = REAL(Scenter);
  dist = REAL(Sdist);

  for(j = 0; j < p; j++) {
    gamma[j] = scalefn(n, Z+j*n, &mu);
    for(i = 0; i < p; i++)
      cov[i+j*p] = i == j ? gamma[j] * gamma[j] : 0.0;
    center[j] = mu;
  }

  for(i = 0; i < n; i++) {
    for(j = 0; j < p; j++)
      Z[i+j*n] = R_pow_di(((Z[i+j*n] - center[j]) / gamma[j]), 2);
    dist[i] = F77_CALL(dasum)(&p, Z+i, &n);
  }

  for(int k = iter-1; k >= 0; k--) {
    F77_CALL(dcopy)(&pp, cov, &IONE, covcopy, &IONE);
    F77_CALL(dgemm)(&CHARN, &CHARN, &p, &p, &p, &DONE, A[k], &p, covcopy,
                    &p, &DZERO, cov, &p);
    F77_CALL(dcopy)(&pp, cov, &IONE, covcopy, &IONE);
    F77_CALL(dgemm)(&CHARN, &CHART, &p, &p, &p, &DONE, covcopy, &p, A[k],
                    &p, &DZERO, cov, &p);
    F77_CALL(dcopy)(&p, center, &IONE, gamma, &IONE);
    F77_CALL(dgemv)(&CHARN, &p, &p, &DONE, A[k], &p, gamma, &IONE,
                    &DZERO, center, &IONE);
  }

  PROTECT(Sans = allocVector(VECSXP, 3));
  SET_VECTOR_ELT(Sans, 0, Scenter);
  SET_VECTOR_ELT(Sans, 1, Scov);
  SET_VECTOR_ELT(Sans, 2, Sdist);
	PROTECT(Snames = allocVector(STRSXP, 3));
	SET_STRING_ELT(Snames, 0, mkChar("center"));
	SET_STRING_ELT(Snames, 1, mkChar("cov"));
	SET_STRING_ELT(Snames, 2, mkChar("distances"));
	setAttrib(Sans, R_NamesSymbol, Snames);
  UNPROTECT(5);

  return Sans;
}
Beispiel #9
0
/* used in graphics and grid */
SEXP CreateAtVector(double *axp, double *usr, int nint, Rboolean logflag)
{
/*	Create an  'at = ...' vector for  axis(.)
 *	i.e., the vector of tick mark locations,
 *	when none has been specified (= default).
 *
 *	axp[0:2] = (x1, x2, nInt), where x1..x2 are the extreme tick marks
 *		   {unless in log case, where nInt \in {1,2,3 ; -1,-2,....}
 *		    and the `nint' argument is used *instead*.}

 *	The resulting REAL vector must have length >= 1, ideally >= 2
 */
    SEXP at = R_NilValue;/* -Wall*/
    double umin, umax, dn, rng, small;
    int i, n, ne;
    if (!logflag || axp[2] < 0) { /* --- linear axis --- Only use axp[] arg. */
	n = (int)(fabs(axp[2]) + 0.25);/* >= 0 */
	dn = imax2(1, n);
	rng = axp[1] - axp[0];
	small = fabs(rng)/(100.*dn);
	at = allocVector(REALSXP, n + 1);
	for (i = 0; i <= n; i++) {
	    REAL(at)[i] = axp[0] + (i / dn) * rng;
	    if (fabs(REAL(at)[i]) < small)
		REAL(at)[i] = 0;
	}
    }
    else { /* ------ log axis ----- */
	Rboolean reversed = FALSE;

	n = (int)(axp[2] + 0.5);
	/* {xy}axp[2] for 'log': GLpretty() [./graphics.c] sets
	   n < 0: very small scale ==> linear axis, above, or
	   n = 1,2,3.  see switch() below */
	umin = usr[0];
	umax = usr[1];
	if (umin > umax) {
	    reversed = (axp[0] > axp[1]);
	    if (reversed) {
		/* have *reversed* log axis -- whereas
		 * the switch(n) { .. } below assumes *increasing* values
		 * --> reverse axis direction here, and reverse back at end */
		umin = usr[1];
		umax = usr[0];
		dn = axp[0]; axp[0] = axp[1]; axp[1] = dn;
	    }
	    else {
		/* can the following still happen... ? */
		warning("CreateAtVector \"log\"(from axis()): "
			"usr[0] = %g > %g = usr[1] !", umin, umax);
	    }
	}
	/* allow a fuzz since we will do things like 0.2*dn >= umin */
	umin *= 1 - 1e-12;
	umax *= 1 + 1e-12;

	dn = axp[0];
	if (dn < DBL_MIN) {/* was 1e-300; now seems too cautious */
	    warning("CreateAtVector \"log\"(from axis()): axp[0] = %g !", dn);
	    if (dn <= 0) /* real trouble (once for Solaris) later on */
		error("CreateAtVector [log-axis()]: axp[0] = %g < 0!", dn);
	}

	/* You get the 3 cases below by
	 *  for (y in 1e-5*c(1,2,8))  plot(y, log = "y")
	 */
	switch(n) {
	case 1: /* large range:	1	 * 10^k */
	    i = (int)(floor(log10(axp[1])) - ceil(log10(axp[0])) + 0.25);
	    ne = i / nint + 1;
#ifdef DEBUG_axis
	    REprintf("CreateAtVector [log-axis(), case 1]: (nint, ne) = (%d,%d)\n",
		     nint, ne);
#endif
	    if (ne < 1)
		error("log - axis(), 'at' creation, _LARGE_ range: "
		      "ne = %d <= 0 !!\n"
		      "\t axp[0:1]=(%g,%g) ==> i = %d;	nint = %d",
		      ne, axp[0],axp[1], i, nint);
	    rng = Rexp10((double)ne); /* >= 10 */
	    n = 0;
	    while (dn < umax) {
		n++;
		dn *= rng;
	    }
	    if (!n)
		error("log - axis(), 'at' creation, _LARGE_ range: "
		      "invalid {xy}axp or par; nint=%d\n"
		      "	 axp[0:1]=(%g,%g), usr[0:1]=(%g,%g); i=%d, ni=%d",
		      nint, axp[0],axp[1], umin,umax, i,ne);
	    at = allocVector(REALSXP, n);
	    dn = axp[0];
	    n = 0;
	    while (dn < umax) {
		REAL(at)[n++] = dn;
		dn *= rng;
	    }
	    break;

	case 2: /* medium range:  1, 5	  * 10^k */
	    n = 0;
	    if (0.5 * dn >= umin) n++;
	    for (;;) {
		if (dn > umax) break;		n++;
		if (5 * dn > umax) break;	n++;
		dn *= 10;
	    }
	    if (!n)
		error("log - axis(), 'at' creation, _MEDIUM_ range: "
		      "invalid {xy}axp or par;\n"
		      "	 axp[0]= %g, usr[0:1]=(%g,%g)",
		      axp[0], umin,umax);

	    at = allocVector(REALSXP, n);
	    dn = axp[0];
	    n = 0;
	    if (0.5 * dn >= umin) REAL(at)[n++] = 0.5 * dn;
	    for (;;) {
		if (dn > umax) break;		REAL(at)[n++] = dn;
		if (5 * dn > umax) break;	REAL(at)[n++] = 5 * dn;
		dn *= 10;
	    }
	    break;

	case 3: /* small range:	 1,2,5,10 * 10^k */
	    n = 0;
	    if (0.2 * dn >= umin) n++;
	    if (0.5 * dn >= umin) n++;
	    for (;;) {
		if (dn > umax) break;		n++;
		if (2 * dn > umax) break;	n++;
		if (5 * dn > umax) break;	n++;
		dn *= 10;
	    }
	    if (!n)
		error("log - axis(), 'at' creation, _SMALL_ range: "
		      "invalid {xy}axp or par;\n"
		      "	 axp[0]= %g, usr[0:1]=(%g,%g)",
		      axp[0], umin,umax);
	    at = allocVector(REALSXP, n);
	    dn = axp[0];
	    n = 0;
	    if (0.2 * dn >= umin) REAL(at)[n++] = 0.2 * dn;
	    if (0.5 * dn >= umin) REAL(at)[n++] = 0.5 * dn;
	    for (;;) {
		if (dn > umax) break;		REAL(at)[n++] = dn;
		if (2 * dn > umax) break;	REAL(at)[n++] = 2 * dn;
		if (5 * dn > umax) break;	REAL(at)[n++] = 5 * dn;
		dn *= 10;
	    }
	    break;
	default:
	    error("log - axis(), 'at' creation: INVALID {xy}axp[3] = %g",
		  axp[2]);
	}

	if (reversed) {/* reverse back again - last assignment was at[n++]= . */
	    for (i = 0; i < n/2; i++) { /* swap( at[i], at[n-i-1] ) : */
		dn = REAL(at)[i];
		REAL(at)[i] = REAL(at)[n-i-1];
		REAL(at)[n-i-1] = dn;
	    }
	}
    } /* linear / log */
    return at;
}
Beispiel #10
0
/* format.default(x, trim, digits, nsmall, width, justify, na.encode,
		  scientific) */
SEXP attribute_hidden do_format(SEXP call, SEXP op, SEXP args, SEXP env)
{
    SEXP l, x, y, swd;
    int il, digits, trim = 0, nsmall = 0, wd = 0, adj = -1, na, sci = 0;
    int w, d, e;
    int wi, di, ei, scikeep;
    const char *strp;
    R_xlen_t i, n;

    checkArity(op, args);
    PrintDefaults();
    scikeep = R_print.scipen;

    if (isEnvironment(x = CAR(args))) {
	return mkString(EncodeEnvironment(x));
    }
    else if (!isVector(x))
	error(_("first argument must be atomic"));
    args = CDR(args);

    trim = asLogical(CAR(args));
    if (trim == NA_INTEGER)
	error(_("invalid '%s' argument"), "trim");
    args = CDR(args);

    if (!isNull(CAR(args))) {
	digits = asInteger(CAR(args));
	if (digits == NA_INTEGER || digits < R_MIN_DIGITS_OPT
	    || digits > R_MAX_DIGITS_OPT)
	    error(_("invalid '%s' argument"), "digits");
	R_print.digits = digits;
    }
    args = CDR(args);

    nsmall = asInteger(CAR(args));
    if (nsmall == NA_INTEGER || nsmall < 0 || nsmall > 20)
	error(_("invalid '%s' argument"), "nsmall");
    args = CDR(args);

    if (isNull(swd = CAR(args))) wd = 0; else wd = asInteger(swd);
    if(wd == NA_INTEGER)
	error(_("invalid '%s' argument"), "width");
    args = CDR(args);

    adj = asInteger(CAR(args));
    if(adj == NA_INTEGER || adj < 0 || adj > 3)
	error(_("invalid '%s' argument"), "justify");
    args = CDR(args);

    na = asLogical(CAR(args));
    if(na == NA_LOGICAL)
	error(_("invalid '%s' argument"), "na.encode");
    args = CDR(args);
    if(LENGTH(CAR(args)) != 1)
	error(_("invalid '%s' argument"), "scientific");
    if(isLogical(CAR(args))) {
	int tmp = LOGICAL(CAR(args))[0];
	if(tmp == NA_LOGICAL) sci = NA_INTEGER;
	else sci = tmp > 0 ?-100 : 100;
    } else if (isNumeric(CAR(args))) {
	sci = asInteger(CAR(args));
    } else
	error(_("invalid '%s' argument"), "scientific");
    if(sci != NA_INTEGER) R_print.scipen = sci;

    if ((n = XLENGTH(x)) <= 0) {
	PROTECT(y = allocVector(STRSXP, 0));
    } else {
	switch (TYPEOF(x)) {

	case LGLSXP:
	    PROTECT(y = allocVector(STRSXP, n));
	    if (trim) w = 0; else formatLogical(LOGICAL(x), n, &w);
	    w = imax2(w, wd);
	    for (i = 0; i < n; i++) {
		strp = EncodeLogical(LOGICAL(x)[i], w);
		SET_STRING_ELT(y, i, mkChar(strp));
	    }
	    break;

	case INTSXP:
	    PROTECT(y = allocVector(STRSXP, n));
	    if (trim) w = 0;
	    else formatInteger(INTEGER(x), n, &w);
	    w = imax2(w, wd);
	    for (i = 0; i < n; i++) {
		strp = EncodeInteger(INTEGER(x)[i], w);
		SET_STRING_ELT(y, i, mkChar(strp));
	    }
	    break;

	case REALSXP:
	    formatReal(REAL(x), n, &w, &d, &e, nsmall);
	    if (trim) w = 0;
	    w = imax2(w, wd);
	    PROTECT(y = allocVector(STRSXP, n));
	    for (i = 0; i < n; i++) {
		strp = EncodeReal0(REAL(x)[i], w, d, e, OutDec);
		SET_STRING_ELT(y, i, mkChar(strp));
	    }
	    break;

	case CPLXSXP:
	    formatComplex(COMPLEX(x), n, &w, &d, &e, &wi, &di, &ei, nsmall);
	    if (trim) wi = w = 0;
	    w = imax2(w, wd); wi = imax2(wi, wd);
	    PROTECT(y = allocVector(STRSXP, n));
	    for (i = 0; i < n; i++) {
		strp = EncodeComplex(COMPLEX(x)[i], w, d, e, wi, di, ei, OutDec);
		SET_STRING_ELT(y, i, mkChar(strp));
	    }
	    break;

	case STRSXP:
	{
	    /* this has to be different from formatString/EncodeString as
	       we don't actually want to encode here */
	    const char *s;
	    char *q;
	    int b, b0, cnt = 0, j;
	    SEXP s0, xx;

	    /* This is clumsy, but it saves rewriting and re-testing
	       this complex code */
	    PROTECT(xx = duplicate(x));
	    for (i = 0; i < n; i++) {
		SEXP tmp =  STRING_ELT(xx, i);
		if(IS_BYTES(tmp)) {
		    const char *p = CHAR(tmp), *q;
		    char *pp = R_alloc(4*strlen(p)+1, 1), *qq = pp, buf[5];
		    for (q = p; *q; q++) {
			unsigned char k = (unsigned char) *q;
			if (k >= 0x20 && k < 0x80) {
			    *qq++ = *q;
			} else {
			    snprintf(buf, 5, "\\x%02x", k);
			    for(int j = 0; j < 4; j++) *qq++ = buf[j];
			}
		    }
		    *qq = '\0';
		    s = pp;
		} else s = translateChar(tmp);
		if(s != CHAR(tmp)) SET_STRING_ELT(xx, i, mkChar(s));
	    }

	    w = wd;
	    if (adj != Rprt_adj_none) {
		for (i = 0; i < n; i++)
		    if (STRING_ELT(xx, i) != NA_STRING)
			w = imax2(w, Rstrlen(STRING_ELT(xx, i), 0));
		    else if (na) w = imax2(w, R_print.na_width);
	    } else w = 0;
	    /* now calculate the buffer size needed, in bytes */
	    for (i = 0; i < n; i++)
		if (STRING_ELT(xx, i) != NA_STRING) {
		    il = Rstrlen(STRING_ELT(xx, i), 0);
		    cnt = imax2(cnt, LENGTH(STRING_ELT(xx, i)) + imax2(0, w-il));
		} else if (na) cnt  = imax2(cnt, R_print.na_width + imax2(0, w-R_print.na_width));
	    R_CheckStack2(cnt+1);
	    char buff[cnt+1];
	    PROTECT(y = allocVector(STRSXP, n));
	    for (i = 0; i < n; i++) {
		if(!na && STRING_ELT(xx, i) == NA_STRING) {
		    SET_STRING_ELT(y, i, NA_STRING);
		} else {
		    q = buff;
		    if(STRING_ELT(xx, i) == NA_STRING) s0 = R_print.na_string;
		    else s0 = STRING_ELT(xx, i) ;
		    s = CHAR(s0);
		    il = Rstrlen(s0, 0);
		    b = w - il;
		    if(b > 0 && adj != Rprt_adj_left) {
			b0 = (adj == Rprt_adj_centre) ? b/2 : b;
			for(j = 0 ; j < b0 ; j++) *q++ = ' ';
			b -= b0;
		    }
		    for(j = 0; j < LENGTH(s0); j++) *q++ = *s++;
		    if(b > 0 && adj != Rprt_adj_right)
			for(j = 0 ; j < b ; j++) *q++ = ' ';
		    *q = '\0';
		    SET_STRING_ELT(y, i, mkChar(buff));
		}
	    }
	}
	UNPROTECT(2); /* xx , y */
	PROTECT(y);
	break;
	default:
	    error(_("Impossible mode ( x )")); y = R_NilValue;/* -Wall */
	}
    }
    if((l = getAttrib(x, R_DimSymbol)) != R_NilValue) {
	setAttrib(y, R_DimSymbol, l);
	if((l = getAttrib(x, R_DimNamesSymbol)) != R_NilValue)
	    setAttrib(y, R_DimNamesSymbol, l);
    } else if((l = getAttrib(x, R_NamesSymbol)) != R_NilValue)
	setAttrib(y, R_NamesSymbol, l);

    /* In case something else forgets to set PrintDefaults(), PR#14477 */
    R_print.scipen = scikeep;

    UNPROTECT(1); /* y */
    return y;
}
Beispiel #11
0
static void measurement_loop(struct term *t)
{
  struct variable spent_time;
  int i, p;
  int result_index, start_not_yet_gathered_results;
  int  source, dest;
  double *local_results;     /* local_results[max_rep_hard_limit] */
  double previous_interval;
  int previous_max_counter;
  bool stop;
  double *quantiles;
  
  int *recv_counts = NULL;
  int *recv_displs = NULL;

  logging(DBG_MEAS, "starting measurement with min_repetitions = %d\n", 
	  min_repetitions);
  logging(DBG_MEAS, "                          max_repetitions = %d\n", 
	  max_repetitions);
  logging(DBG_MEAS, "                          max_relative_standard_error = %f\n",
	  max_relative_standard_error);

  assert( min_repetitions <= max_repetitions );

  max_rep_hard_limit = imax2(First_max_counter,
			     max_repetitions*1.5+0.5); /* @@ pretty arbitrary */ 

  local_results = skampi_malloc_doubles(max_rep_hard_limit);
  invalid = skampi_malloc_ints(max_rep_hard_limit);
  if( lrootproc() ) {
    all_results = skampi_malloc_doubles(get_measurement_size()*max_rep_hard_limit);
    global_invalid = skampi_malloc_ints(get_measurement_size()*max_rep_hard_limit);

    recv_counts = skampi_malloc_ints(get_measurement_size());
    recv_displs = skampi_malloc_ints(get_measurement_size());

    max_results = skampi_malloc_doubles(max_rep_hard_limit); /* @@ max_repetitions? */
    final_results = skampi_malloc_doubles(get_measurement_size());
  }
  sum_of_results = 0.0;
  sum_of_squares = 0.0;
  result_index = 0;
  start_not_yet_gathered_results = 0;

  init_buffer();
  init_struct_variable(&spent_time, TYPE_VOID, NULL, NULL);
  stop = False; 
  do { /* measurement loop */
    
    
    logging(DBG_MEAS, "max_counter = %d\n", max_counter);
    /*    assert( result_index + max_counter <= max_rep_hard_limit); */
    max_counter = imin2(max_rep_hard_limit - result_index, max_counter);
    for( counter = 0; counter < max_counter; counter++ ) {  /* doing the actual measurements */
      check_buffer();
      t->call_fp(&spent_time, meas_params);
      assert( spent_time.type == TYPE_DOUBLE );
      logging(DBG_MEAS, "spent_time = %9.1f\n", spent_time.u.doublev*1.0e6);
      local_results[result_index] = spent_time.u.doublev;
      result_index++;
    }
    logging(DBG_MEAS, "result_index = %d\n", result_index);

    DEBUG(DBG_MEAS, 
    {
      for( i = start_not_yet_gathered_results; i < result_index; i++) 
	logging(DBG_MEAS, "local_results[%d] = %9.1f\n", i, local_results[i]*1.0e6);
    });  

    if( lrootproc() ) {
      for( p = 0; p < get_measurement_size(); p++) {
	recv_counts[p] = result_index - start_not_yet_gathered_results;
	recv_displs[p] = p*max_rep_hard_limit + start_not_yet_gathered_results;
      }
    }

    MPI_Gatherv(&(local_results[start_not_yet_gathered_results]), 
		result_index - start_not_yet_gathered_results, MPI_DOUBLE,
		all_results, recv_counts, recv_displs, MPI_DOUBLE, 0, get_measurement_comm());

    if( current_synchronization == SYNC_REAL ) {
      MPI_Gather(invalid, max_counter, MPI_INT, 
		 global_invalid, max_counter, MPI_INT, 0, get_measurement_comm());
      
      stop_batch += tds[get_global_rank(0)];
      
      MPI_Reduce(&stop_batch, &global_stop_batch, 1, MPI_DOUBLE, MPI_MAX, 0, get_measurement_comm());
    }

    if( lrootproc() ) { /* overwrite invalid results */ 

      for( i = start_not_yet_gathered_results; i < result_index; i++ ) {
	logging(DBG_MEAS, "all_results[%d] = [%9.1f", i, all_results[0*max_rep_hard_limit + i]*1.0e6);
	for( p = 1; p < get_measurement_size(); p++)
	  logging(DBG_MEAS, " %9.1f", all_results[p*max_rep_hard_limit + i]*1.0e6);
	logging(DBG_MEAS, "]\n"); 
      }

      previous_interval = interval;
      previous_max_counter = max_counter;
      update_batch_params(); /* adapt max_counter for next batch of measurements */

      logging(DBG_MEAS, "start overwrite invalid results\n");
      logging(DBG_MEAS, "start_not_yet_gathered_results = %d  result_index = %d\n", 
	      start_not_yet_gathered_results, result_index);

      /* move up valid results in all_results[] and global_invalid[], overwriting invalid ones */
      if( current_synchronization == SYNC_REAL ) {
	source = start_not_yet_gathered_results;
	dest = start_not_yet_gathered_results;
	while( source < result_index ) {
	  while( source < result_index && 
		 global_invalid[source-start_not_yet_gathered_results] ) { 
	    if( global_invalid[source-start_not_yet_gathered_results] == INVALID_TOOK_TOO_LONG ) {
	      /*	      double m = 0.0; */
	      /* for(p = 0; p < get_measurement_size(); p++ )  */
		/* m = fmax2(m, all_results[p * max_rep_hard_limit + source]); */
		/* add_to_over_time(m); */
		add_to_over_time(previous_interval);
	    }
	    source++;	
	  }
	  if( source >= result_index ) break;
	  {
	    double m = 0.0;
	      for(p = 0; p < get_measurement_size(); p++ ) 
		m = fmax2(m, all_results[p * max_rep_hard_limit + source]);
	      add_to_comm_time(m);  /* @@ actually that's wrong, we should add stop_sync - start_sync  */
	      add_to_wait_time(previous_interval - m);
	  }

	  if( source != dest ) {
	    for( p = 0; p < get_measurement_size(); p++ ) 
	      all_results[p*max_rep_hard_limit + dest] = 
		all_results[p*max_rep_hard_limit + source];
	  }
	  source++;
	  dest++;
        }
	logging(DBG_MEAS, "%d results thrown away\n", source - dest);
	
	result_index = dest;
	logging(DBG_MEAS, "result_index = %d start_not_yet_gathered_results = %d\n",
		result_index, start_not_yet_gathered_results);

	add_to_over_time(global_stop_batch - start_batch - previous_max_counter*previous_interval);
      }
      DEBUG(DBG_MEAS,
      {
        for( i = start_not_yet_gathered_results; i < result_index; i++ ) {
          logging(DBG_MEAS, "all_results[%d] = [%9.1f", i, all_results[0*max_rep_hard_limit +i]*1.0e6);
          for( p = 1; p < get_measurement_size(); p++)
            logging(DBG_MEAS, " %9.1f", all_results[p*max_rep_hard_limit + i]*1.0e6);
          logging(DBG_MEAS, "]\n");
        }
      });


      update_std_error(start_not_yet_gathered_results, result_index);
      /* eigentlich update_std_error(start_not_yet_gathered_results, 
	 min(result_index, max_results)); ???!!! @@@@ */

      stop = result_index >= max_repetitions ||
	     (result_index >= min_repetitions &&
	      std_error <= max_relative_standard_error*mean_value);
    } 
Beispiel #12
0
//     rhyper(NR, NB, n) -- NR 'red', NB 'blue', n drawn, how many are 'red'
double rhyper(rng_t unif_rand, double nn1in, double nn2in, double kkin)
{
    /* extern double afc(int); */

    int nn1, nn2, kk;
    int ix; // return value (coerced to double at the very end)
    Rboolean setup1, setup2;

    /* These should become 'thread_local globals' : */
    static int ks = -1, n1s = -1, n2s = -1;
    static int m, minjx, maxjx;
    static int k, n1, n2; // <- not allowing larger integer par
    static double tn;

    // II :
    static double w;
    // III:
    static double a, d, s, xl, xr, kl, kr, lamdl, lamdr, p1, p2, p3;

    /* check parameter validity */

    if(!R_FINITE(nn1in) || !R_FINITE(nn2in) || !R_FINITE(kkin))
	ML_ERR_return_NAN;

    nn1in = R_forceint(nn1in);
    nn2in = R_forceint(nn2in);
    kkin  = R_forceint(kkin);

    if (nn1in < 0 || nn2in < 0 || kkin < 0 || kkin > nn1in + nn2in)
	ML_ERR_return_NAN;
    if (nn1in >= INT_MAX || nn2in >= INT_MAX || kkin >= INT_MAX) {
	/* large n -- evade integer overflow (and inappropriate algorithms)
	   -------- */
        // FIXME: Much faster to give rbinom() approx when appropriate; -> see Kuensch(1989)
	// Johnson, Kotz,.. p.258 (top) mention the *four* different binomial approximations
	if(kkin == 1.) { // Bernoulli
	    return rbinom(unif_rand, kkin, nn1in / (nn1in + nn2in));
	}
	// Slow, but safe: return  F^{-1}(U)  where F(.) = phyper(.) and  U ~ U[0,1]
	return qhyper(unif_rand(), nn1in, nn2in, kkin, FALSE, FALSE);
    }
    nn1 = (int)nn1in;
    nn2 = (int)nn2in;
    kk  = (int)kkin;

    /* if new parameter values, initialize */
    if (nn1 != n1s || nn2 != n2s) {
	setup1 = TRUE;	setup2 = TRUE;
    } else if (kk != ks) {
	setup1 = FALSE;	setup2 = TRUE;
    } else {
	setup1 = FALSE;	setup2 = FALSE;
    }
    if (setup1) {
	n1s = nn1;
	n2s = nn2;
	tn = nn1 + nn2;
	if (nn1 <= nn2) {
	    n1 = nn1;
	    n2 = nn2;
	} else {
	    n1 = nn2;
	    n2 = nn1;
	}
    }
    if (setup2) {
	ks = kk;
	if (kk + kk >= tn) {
	    k = (int)(tn - kk);
	} else {
	    k = kk;
	}
    }
    if (setup1 || setup2) {
	m = (int) ((k + 1.) * (n1 + 1.) / (tn + 2.));
	minjx = imax2(0, k - n2);
	maxjx = imin2(n1, k);
#ifdef DEBUG_rhyper
	REprintf("rhyper(nn1=%d, nn2=%d, kk=%d), setup: floor(mean)= m=%d, jx in (%d..%d)\n",
		 nn1, nn2, kk, m, minjx, maxjx);
#endif
    }
    /* generate random variate --- Three basic cases */

    if (minjx == maxjx) { /* I: degenerate distribution ---------------- */
#ifdef DEBUG_rhyper
	REprintf("rhyper(), branch I (degenerate)\n");
#endif
	ix = maxjx;
	goto L_finis; // return appropriate variate

    } else if (m - minjx < 10) { // II: (Scaled) algorithm HIN (inverse transformation) ----
	const static double scale = 1e25; // scaling factor against (early) underflow
	const static double con = 57.5646273248511421;
                                          // 25*log(10) = log(scale) { <==> exp(con) == scale }
	if (setup1 || setup2) {
	    double lw; // log(w);  w = exp(lw) * scale = exp(lw + log(scale)) = exp(lw + con)
	    if (k < n2) {
		lw = afc(n2) + afc(n1 + n2 - k) - afc(n2 - k) - afc(n1 + n2);
	    } else {
		lw = afc(n1) + afc(     k     ) - afc(k - n2) - afc(n1 + n2);
	    }
	    w = exp(lw + con);
	}
	double p, u;
#ifdef DEBUG_rhyper
	REprintf("rhyper(), branch II; w = %g > 0\n", w);
#endif
      L10:
	p = w;
	ix = minjx;
	u = unif_rand() * scale;
#ifdef DEBUG_rhyper
	REprintf("  _new_ u = %g\n", u);
#endif
	while (u > p) {
	    u -= p;
	    p *= ((double) n1 - ix) * (k - ix);
	    ix++;
	    p = p / ix / (n2 - k + ix);
#ifdef DEBUG_rhyper
	    REprintf("       ix=%3d, u=%11g, p=%20.14g (u-p=%g)\n", ix, u, p, u-p);
#endif
	    if (ix > maxjx)
		goto L10;
	    // FIXME  if(p == 0.)  we also "have lost"  => goto L10
	}
    } else { /* III : H2PE Algorithm --------------------------------------- */

	double u,v;

	if (setup1 || setup2) {
	    s = sqrt((tn - k) * k * n1 * n2 / (tn - 1) / tn / tn);

	    /* remark: d is defined in reference without int. */
	    /* the truncation centers the cell boundaries at 0.5 */

	    d = (int) (1.5 * s) + .5;
	    xl = m - d + .5;
	    xr = m + d + .5;
	    a = afc(m) + afc(n1 - m) + afc(k - m) + afc(n2 - k + m);
	    kl = exp(a - afc((int) (xl)) - afc((int) (n1 - xl))
		     - afc((int) (k - xl))
		     - afc((int) (n2 - k + xl)));
	    kr = exp(a - afc((int) (xr - 1))
		     - afc((int) (n1 - xr + 1))
		     - afc((int) (k - xr + 1))
		     - afc((int) (n2 - k + xr - 1)));
	    lamdl = -log(xl * (n2 - k + xl) / (n1 - xl + 1) / (k - xl + 1));
	    lamdr = -log((n1 - xr + 1) * (k - xr + 1) / xr / (n2 - k + xr));
	    p1 = d + d;
	    p2 = p1 + kl / lamdl;
	    p3 = p2 + kr / lamdr;
	}
#ifdef DEBUG_rhyper
	REprintf("rhyper(), branch III {accept/reject}: (xl,xr)= (%g,%g); (lamdl,lamdr)= (%g,%g)\n",
		 xl, xr, lamdl,lamdr);
	REprintf("-------- p123= c(%g,%g,%g)\n", p1,p2, p3);
#endif
	int n_uv = 0;
      L30:
	u = unif_rand() * p3;
	v = unif_rand();
	n_uv++;
	if(n_uv >= 10000) {
	    REprintf("rhyper() branch III: giving up after %d rejections", n_uv);
	    ML_ERR_return_NAN;
        }
#ifdef DEBUG_rhyper
	REprintf(" ... L30: new (u=%g, v ~ U[0,1])[%d]\n", u, n_uv);
#endif

	if (u < p1) {		/* rectangular region */
	    ix = (int) (xl + u);
	} else if (u <= p2) {	/* left tail */
	    ix = (int) (xl + log(v) / lamdl);
	    if (ix < minjx)
		goto L30;
	    v = v * (u - p1) * lamdl;
	} else {		/* right tail */
	    ix = (int) (xr - log(v) / lamdr);
	    if (ix > maxjx)
		goto L30;
	    v = v * (u - p2) * lamdr;
	}

	/* acceptance/rejection test */
	Rboolean reject = TRUE;

	if (m < 100 || ix <= 50) {
	    /* explicit evaluation */
	    /* The original algorithm (and TOMS 668) have
		   f = f * i * (n2 - k + i) / (n1 - i) / (k - i);
	       in the (m > ix) case, but the definition of the
	       recurrence relation on p134 shows that the +1 is
	       needed. */
	    int i;
	    double f = 1.0;
	    if (m < ix) {
		for (i = m + 1; i <= ix; i++)
		    f = f * (n1 - i + 1) * (k - i + 1) / (n2 - k + i) / i;
	    } else if (m > ix) {
		for (i = ix + 1; i <= m; i++)
		    f = f * i * (n2 - k + i) / (n1 - i + 1) / (k - i + 1);
	    }
	    if (v <= f) {
		reject = FALSE;
	    }
	} else {

	    const static double deltal = 0.0078;
	    const static double deltau = 0.0034;

	    double e, g, r, t, y;
	    double de, dg, dr, ds, dt, gl, gu, nk, nm, ub;
	    double xk, xm, xn, y1, ym, yn, yk, alv;

#ifdef DEBUG_rhyper
	    REprintf(" ... accept/reject 'large' case v=%g\n", v);
#endif
	    /* squeeze using upper and lower bounds */
	    y = ix;
	    y1 = y + 1.0;
	    ym = y - m;
	    yn = n1 - y + 1.0;
	    yk = k - y + 1.0;
	    nk = n2 - k + y1;
	    r = -ym / y1;
	    s = ym / yn;
	    t = ym / yk;
	    e = -ym / nk;
	    g = yn * yk / (y1 * nk) - 1.0;
	    dg = 1.0;
	    if (g < 0.0)
		dg = 1.0 + g;
	    gu = g * (1.0 + g * (-0.5 + g / 3.0));
	    gl = gu - .25 * (g * g * g * g) / dg;
	    xm = m + 0.5;
	    xn = n1 - m + 0.5;
	    xk = k - m + 0.5;
	    nm = n2 - k + xm;
	    ub = y * gu - m * gl + deltau
		+ xm * r * (1. + r * (-0.5 + r / 3.0))
		+ xn * s * (1. + s * (-0.5 + s / 3.0))
		+ xk * t * (1. + t * (-0.5 + t / 3.0))
		+ nm * e * (1. + e * (-0.5 + e / 3.0));
	    /* test against upper bound */
	    alv = log(v);
	    if (alv > ub) {
		reject = TRUE;
	    } else {
				/* test against lower bound */
		dr = xm * (r * r * r * r);
		if (r < 0.0)
		    dr /= (1.0 + r);
		ds = xn * (s * s * s * s);
		if (s < 0.0)
		    ds /= (1.0 + s);
		dt = xk * (t * t * t * t);
		if (t < 0.0)
		    dt /= (1.0 + t);
		de = nm * (e * e * e * e);
		if (e < 0.0)
		    de /= (1.0 + e);
		if (alv < ub - 0.25 * (dr + ds + dt + de)
		    + (y + m) * (gl - gu) - deltal) {
		    reject = FALSE;
		}
		else {
		    /* * Stirling's formula to machine accuracy
		     */
		    if (alv <= (a - afc(ix) - afc(n1 - ix)
				- afc(k - ix) - afc(n2 - k + ix))) {
			reject = FALSE;
		    } else {
			reject = TRUE;
		    }
		}
	    }
	} // else
	if (reject)
	    goto L30;
    }


L_finis:
    /* return appropriate variate */

    if (kk + kk >= tn) {
	if (nn1 > nn2) {
	    ix = kk - nn2 + ix;
	} else {
	    ix = nn1 - ix;
	}
    } else {
	if (nn1 > nn2)
	    ix = kk - ix;
    }
    return ix;
}
Beispiel #13
0
double rpois(double mu)
{
    /* Factorial Table (0:9)! */
    const static double fact[10] =
    {
	1., 1., 2., 6., 24., 120., 720., 5040., 40320., 362880.
    };

    /* These are static --- persistent between calls for same mu : */
    static int l, m;

    static double b1, b2, c, c0, c1, c2, c3;
    static double pp[36], p0, p, q, s, d, omega;
    static double big_l;/* integer "w/o overflow" */
    static double muprev = 0., muprev2 = 0.;/*, muold	 = 0.*/

    /* Local Vars  [initialize some for -Wall]: */
    double del, difmuk= 0., E= 0., fk= 0., fx, fy, g, px, py, t, u= 0., v, x;
    double pois = -1.;
    int k, kflag, big_mu, new_big_mu = FALSE;

    if (!R_FINITE(mu) || mu < 0)
	ML_ERR_return_NAN;

    if (mu <= 0.)
	return 0.;

    big_mu = mu >= 10.;
    if(big_mu)
	new_big_mu = FALSE;

    if (!(big_mu && mu == muprev)) {/* maybe compute new persistent par.s */

	if (big_mu) {
	    new_big_mu = TRUE;
	    /* Case A. (recalculation of s,d,l	because mu has changed):
	     * The poisson probabilities pk exceed the discrete normal
	     * probabilities fk whenever k >= m(mu).
	     */
	    muprev = mu;
	    s = sqrt(mu);
	    d = 6. * mu * mu;
	    big_l = floor(mu - 1.1484);
	    /* = an upper bound to m(mu) for all mu >= 10.*/
	}
	else { /* Small mu ( < 10) -- not using normal approx. */

	    /* Case B. (start new table and calculate p0 if necessary) */

	    /*muprev = 0.;-* such that next time, mu != muprev ..*/
	    if (mu != muprev) {
		muprev = mu;
		m = imax2(1, (int) mu);
		l = 0; /* pp[] is already ok up to pp[l] */
		q = p0 = p = exp(-mu);
	    }

	    repeat {
		/* Step U. uniform sample for inversion method */
		u = unif_rand();
		if (u <= p0)
		    return 0.;

		/* Step T. table comparison until the end pp[l] of the
		   pp-table of cumulative poisson probabilities
		   (0.458 > ~= pp[9](= 0.45792971447) for mu=10 ) */
		if (l != 0) {
		    for (k = (u <= 0.458) ? 1 : imin2(l, m);  k <= l; k++)
			if (u <= pp[k])
			    return (double)k;
		    if (l == 35) /* u > pp[35] */
			continue;
		}
		/* Step C. creation of new poisson
		   probabilities p[l..] and their cumulatives q =: pp[k] */
		l++;
		for (k = l; k <= 35; k++) {
		    p *= mu / k;
		    q += p;
		    pp[k] = q;
		    if (u <= q) {
			l = k;
			return (double)k;
		    }
		}
		l = 35;
	    } /* end(repeat) */
	}/* mu < 10 */

    } /* end {initialize persistent vars} */

/* Only if mu >= 10 : ----------------------- */

    /* Step N. normal sample */
    g = mu + s * norm_rand();/* norm_rand() ~ N(0,1), standard normal */

    if (g >= 0.) {
	pois = floor(g);
	/* Step I. immediate acceptance if pois is large enough */
	if (pois >= big_l)
	    return pois;
	/* Step S. squeeze acceptance */
	fk = pois;
	difmuk = mu - fk;
	u = unif_rand(); /* ~ U(0,1) - sample */
	if (d * u >= difmuk * difmuk * difmuk)
	    return pois;
    }

    /* Step P. preparations for steps Q and H.
       (recalculations of parameters if necessary) */

    if (new_big_mu || mu != muprev2) {
        /* Careful! muprev2 is not always == muprev
	   because one might have exited in step I or S
	   */
        muprev2 = mu;
	omega = M_1_SQRT_2PI / s;
	/* The quantities b1, b2, c3, c2, c1, c0 are for the Hermite
	 * approximations to the discrete normal probabilities fk. */

	b1 = one_24 / mu;
	b2 = 0.3 * b1 * b1;
	c3 = one_7 * b1 * b2;
	c2 = b2 - 15. * c3;
	c1 = b1 - 6. * b2 + 45. * c3;
	c0 = 1. - b1 + 3. * b2 - 15. * c3;
	c = 0.1069 / mu; /* guarantees majorization by the 'hat'-function. */
    }

    if (g >= 0.) {
	/* 'Subroutine' F is called (kflag=0 for correct return) */
	kflag = 0;
	goto Step_F;
    }


    repeat {
	/* Step E. Exponential Sample */

	E = exp_rand();	/* ~ Exp(1) (standard exponential) */

	/*  sample t from the laplace 'hat'
	    (if t <= -0.6744 then pk < fk for all mu >= 10.) */
	u = 2 * unif_rand() - 1.;
	t = 1.8 + fsign(E, u);
	if (t > -0.6744) {
	    pois = floor(mu + s * t);
	    fk = pois;
	    difmuk = mu - fk;

	    /* 'subroutine' F is called (kflag=1 for correct return) */
	    kflag = 1;

	  Step_F: /* 'subroutine' F : calculation of px,py,fx,fy. */

	    if (pois < 10) { /* use factorials from table fact[] */
		px = -mu;
		py = pow(mu, pois) / fact[(int)pois];
	    }
	    else {
		/* Case pois >= 10 uses polynomial approximation
		   a0-a7 for accuracy when advisable */
		del = one_12 / fk;
		del = del * (1. - 4.8 * del * del);
		v = difmuk / fk;
		if (fabs(v) <= 0.25)
		    px = fk * v * v * (((((((a7 * v + a6) * v + a5) * v + a4) *
					  v + a3) * v + a2) * v + a1) * v + a0)
			- del;
		else /* |v| > 1/4 */
		    px = fk * log(1. + v) - difmuk - del;
		py = M_1_SQRT_2PI / sqrt(fk);
	    }
	    x = (0.5 - difmuk) / s;
	    x *= x;/* x^2 */
	    fx = -0.5 * x;
	    fy = omega * (((c3 * x + c2) * x + c1) * x + c0);
	    if (kflag > 0) {
		/* Step H. Hat acceptance (E is repeated on rejection) */
		if (c * fabs(u) <= py * exp(px + E) - fy * exp(fx + E))
		    break;
	    } else
		/* Step Q. Quotient acceptance (rare case) */
		if (fy - u * fy <= py * exp(px - fx))
		    break;
	}/* t > -.67.. */
    }
    return pois;
}
Beispiel #14
0
Datei: trlan.c Projekt: eodus/svd
void trl_clear_counter(trl_info * info, int nrow, int mev, int lde) {
  int ntmp;

  info->stat = 0;
  if (nrow != info->nloc || nrow > info->ntot)
    error("TRLAN: info not setup for this problem.\n       Please reset info before calling TRLAN.\n");

  if (info->nec < 0)
    info->nec = 0;

  if (lde < nrow)
    error("TRLAN: leading dimension of EVEC to small.\n");

  if (info->tol >= 1.0) {
    info->tol = sqrt(DBL_EPSILON);
  } else if (info->tol <= DBL_MIN) {
    info->tol = DBL_EPSILON;
  }

  if (info->ned + info->ned >= info->ntot) {
    warning("TRLAN: info->ned (%d) is large relative to the matrix dimension (%d)\n",
            info->ned, info->ntot);
    warning(" **    It is more appropriate to use LAPACK dsyev/ssyev.\n");
    if (info->ned > info->ntot) {
      info->ned = imin2(info->ntot - 1, info->maxlan - 3);
      warning("TRLAN: ** reduced ned to %d **\n", info->ned);
    }
  }
  if (mev < info->ned)
    error("TRLAN: array EVAL and EVEC can not hold wanted number of eigenpairs.\n");

  if (info->ntot < 10)
    error("TRLAN is not designed to work with such a small matrix(%dx%d).  Please use LAPACK or EISPACK instead.\n",
          info->ntot, info->ntot);

  info->nrand = info->stat;
  info->stat = trl_sync_flag(info->mpicom, info->nrand);

  /* decide what is a good maximum basis size to use */
  if (info->maxlan < info->ned + 3) {
    info->maxlan = info->ned + imin2(info->ned, 20) +
      (int)(log((double)info->ntot));
    info->maxlan = imin2(info->maxlan, info->ntot);
    warning("TRLAN: ** reset maxlan to %d! **\n", info->maxlan);
  }

  if (info->maxlan < mev) {
    ntmp = imin2(info->ntot, imax2(100 + info->ned, 10 * info->ned));
    if (mev < ntmp) {
      info->maxlan = mev;
    } else {
      info->maxlan = ntmp;
    }
  }
  if (info->maxlan < 5)
    error("TRLAN must have at least 5 basis vectors, it is currently %d.\n",
          info->maxlan);

  /* clear regular counters */
  info->tmv = -1;
  info->klan = imin2(info->maxlan, info->ntot);
  if (info->restart >= 7) {
    info->klan = imin2(info->maxlan,
                       imax2(100,
                             imin2(info->klan, 2 * (info->ned))));
  }
  info->locked = info->nec;
  info->matvec = 0;
  info->nloop = 0;
  info->north = 0;
  info->nrand = 0;
  info->tick_t = 0.0;
  info->clk_op = 0;
  info->tick_o = 0.0;
  info->clk_orth = 0;
  info->tick_h = 0.0;
  info->clk_res = 0;
  info->tick_r = 0.0;
  info->clk_in = 0;
  info->clk_out = 0;
  info->wrds_in = 0;
  info->wrds_out = 0;
  info->avgm = 0.0;
  return;
}
Beispiel #15
0
static
void clowess(double *x, double *y, int n,
	     double f, int nsteps, double delta,
	     double *ys, double *rw, double *res)
{
    int i, iter, j, last, m1, m2, nleft, nright, ns;
    Rboolean ok;
    double alpha, c1, c9, cmad, cut, d1, d2, denom, r, sc;

    if (n < 2) {
	ys[0] = y[0]; return;
    }

    /* nleft, nright, last, etc. must all be shifted to get rid of these: */
    x--;
    y--;
    ys--;


    /* at least two, at most n points */
    ns = imax2(2, imin2(n, (int)(f*n + 1e-7)));
#ifdef DEBUG_lowess
    REprintf("lowess(): ns = %d\n", ns);
#endif

    /* robustness iterations */

    iter = 1;
    while (iter <= nsteps+1) {
	nleft = 1;
	nright = ns;
	last = 0;	/* index of prev estimated point */
	i = 1;		/* index of current point */

	for(;;) {
	    if (nright < n) {

		/* move nleft,  nright to right */
		/* if radius decreases */

		d1 = x[i] - x[nleft];
		d2 = x[nright+1] - x[i];

		/* if d1 <= d2 with */
		/* x[nright+1] == x[nright], */
		/* lowest fixes */

		if (d1 > d2) {

		    /* radius will not */
		    /* decrease by */
		    /* move right */

		    nleft++;
		    nright++;
		    continue;
		}
	    }

	    /* fitted value at x[i] */

	    lowest(&x[1], &y[1], n, &x[i], &ys[i],
		   nleft, nright, res, iter>1, rw, &ok);
	    if (!ok) ys[i] = y[i];

	    /* all weights zero */
	    /* copy over value (all rw==0) */

	    if (last < i-1) {
		denom = x[i]-x[last];

		/* skipped points -- interpolate */
		/* non-zero - proof? */

		for(j = last+1; j < i; j++) {
		    alpha = (x[j]-x[last])/denom;
		    ys[j] = alpha*ys[i] + (1.-alpha)*ys[last];
		}
	    }

	    /* last point actually estimated */
	    last = i;

	    /* x coord of close points */
	    cut = x[last]+delta;
	    for (i = last+1; i <= n; i++) {
		if (x[i] > cut)
		    break;
		if (x[i] == x[last]) {
		    ys[i] = ys[last];
		    last = i;
		}
	    }
	    i = imax2(last+1, i-1);
	    if (last >= n)
		break;
	}
	/* residuals */
	for(i = 0; i < n; i++)
	    res[i] = y[i+1] - ys[i+1];

	/* overall scale estimate */
	sc = 0.;
	for(i = 0; i < n; i++) sc += fabs(res[i]);
	sc /= n;

	/* compute robustness weights */
	/* except last time */

	if (iter > nsteps)
	    break;
	/* Note: The following code, biweight_{6 MAD|Ri|}
	   is also used in stl(), loess and several other places.
	   --> should provide API here (MM) */
	for(i = 0 ; i < n ; i++)
	    rw[i] = fabs(res[i]);

	/* Compute   cmad := 6 * median(rw[], n)  ---- */
	/* FIXME: We need C API in R for Median ! */
	m1 = n/2;
	/* partial sort, for m1 & m2 */
	rPsort(rw, n, m1);
	if(n % 2 == 0) {
	    m2 = n-m1-1;
	    rPsort(rw, n, m2);
	    cmad = 3.*(rw[m1]+rw[m2]);
	}
	else { /* n odd */
	    cmad = 6.*rw[m1];
	}
#ifdef DEBUG_lowess
	REprintf("   cmad = %12g\n", cmad);
#endif
	if(cmad < 1e-7 * sc) /* effectively zero */
	    break;
	c9 = 0.999*cmad;
	c1 = 0.001*cmad;
	for(i = 0 ; i < n ; i++) {
	    r = fabs(res[i]);
	    if (r <= c1)
		rw[i] = 1.;
	    else if (r <= c9)
		rw[i] = fsquare(1.-fsquare(r/cmad));
	    else
		rw[i] = 0.;
	}
	iter++;
    }
}
Beispiel #16
0
double R_pretty0(double *lo, double *up, int *ndiv, int min_n,
	       double shrink_sml, double high_u_fact[],
	       int eps_correction, int return_bounds)
{
/* From version 0.65 on, we had rounding_eps := 1e-5, before, r..eps = 0
 * 1e-7 is consistent with seq.default() */
#define rounding_eps 1e-7

#define h  high_u_fact[0]
#define h5 high_u_fact[1]

    double dx, cell, unit, base, U;
    double ns, nu;
    int k;
    Rboolean i_small;

    dx = *up - *lo;
    /* cell := "scale"	here */
    if(dx == 0 && *up == 0) { /*  up == lo == 0	 */
	cell = 1;
	i_small = TRUE;
    } else {
	cell = fmax2(fabs(*lo),fabs(*up));
	/* U = upper bound on cell/unit */
	U = (1 + (h5 >= 1.5*h+.5)) ? 1/(1+h) : 1.5/(1+h5);
	/* added times 3, as several calculations here */
	i_small = dx < cell * U * imax2(1,*ndiv) * DBL_EPSILON *3;
    }

    /*OLD: cell = FLT_EPSILON+ dx / *ndiv; FLT_EPSILON = 1.192e-07 */
    if(i_small) {
        if(cell > 10)
	    cell = 9 + cell/10;
	cell *= shrink_sml;
	if(min_n > 1) cell /= min_n;
    } else {
	cell = dx;
	if(*ndiv > 1) cell /= *ndiv;
    }

    if(cell < 20*DBL_MIN) {
      warning(_("Internal(pretty()): very small range.. corrected"));
      cell = 20*DBL_MIN;
    } else if(cell * 10 > DBL_MAX) {
      warning(_("Internal(pretty()): very large range.. corrected"));
      cell = .1*DBL_MAX;
    }
    base = pow(10., floor(log10(cell))); /* base <= cell < 10*base */

    /* unit : from { 1,2,5,10 } * base
     *	 such that |u - cell| is small,
     * favoring larger (if h > 1, else smaller)  u  values;
     * favor '5' more than '2'  if h5 > h  (default h5 = .5 + 1.5 h) */
    unit = base;
    if((U = 2*base)-cell <  h*(cell-unit)) { unit = U;
    if((U = 5*base)-cell < h5*(cell-unit)) { unit = U;
    if((U =10*base)-cell <  h*(cell-unit)) unit = U; }}
    /* Result: c := cell,  u := unit,  b := base
     *	c in [	1,	      (2+ h) /(1+h) ] b ==> u=  b
     *	c in ( (2+ h)/(1+h),  (5+2h5)/(1+h5)] b ==> u= 2b
     *	c in ( (5+2h)/(1+h), (10+5h) /(1+h) ] b ==> u= 5b
     *	c in ((10+5h)/(1+h),	         10 ) b ==> u=10b
     *
     *	===>	2/5 *(2+h)/(1+h)  <=  c/u  <=  (2+h)/(1+h)	*/

    ns = floor(*lo/unit+rounding_eps);
    nu = ceil (*up/unit-rounding_eps);
#ifdef DEBUGpr
    REprintf("pretty(lo=%g,up=%g,ndiv=%d,min_n=%d,shrink=%g,high_u=(%g,%g),"
	     "eps=%d)\n\t dx=%g; is.small:%d. ==> cell=%g; unit=%g\n",
	     *lo, *up, *ndiv, min_n, shrink_sml, h, h5,
	      eps_correction,	dx, (int)i_small, cell, unit);
#endif
    if(eps_correction && (eps_correction > 1 || !i_small)) {
        if(*lo) *lo *= (1- DBL_EPSILON); else *lo = -DBL_MIN;
        if(*up) *up *= (1+ DBL_EPSILON); else *up = +DBL_MIN;
    }

#ifdef DEBUGpr
    if(ns*unit > *lo)
	REprintf("\t ns= %.0f -- while(ns*unit > *lo) ns--;\n", ns);
#endif
    while(ns*unit > *lo + rounding_eps*unit) ns--;

#ifdef DEBUGpr
    if(nu*unit < *up)
	REprintf("\t nu= %.0f -- while(nu*unit < *up) nu++;\n", nu);
#endif
    while(nu*unit < *up - rounding_eps*unit) nu++;

    k = .5 + nu - ns;
    if(k < min_n) {
	/* ensure that	nu - ns	 == min_n */
#ifdef DEBUGpr
	REprintf("\tnu-ns=%.0f-%.0f=%d SMALL -> ensure nu-ns= min_n=%d\n",
		 nu,ns, k, min_n);
#endif
	k = min_n - k;
	if(ns >= 0.) {
	    nu += k/2;
	    ns -= k/2 + k%2;/* ==> nu-ns = old(nu-ns) + min_n -k = min_n */
	} else {
	    ns -= k/2;
	    nu += k/2 + k%2;
	}
	*ndiv = min_n;
    }
    else {
	*ndiv = k;
    }
    if(return_bounds) { /* if()'s to ensure that result covers original range */
        if(ns * unit < *lo) *lo = ns * unit;
        if(nu * unit > *up) *up = nu * unit;
    } else {
        *lo = ns;
	*up = nu;
    }
#ifdef DEBUGpr
    REprintf("\t ns=%.0f ==> lo=%g\n", ns, *lo);
    REprintf("\t nu=%.0f ==> up=%g  ==> ndiv = %d\n", nu, *up, *ndiv);
#endif
    return unit;
#undef h
#undef h5
}
Beispiel #17
0
/* Matrix exponential exp(x), where x is an (n x n) matrix. Result z
 * is an (n x n) matrix. Mostly lifted from the core of fonction
 * expm() of package Matrix, which is itself based on the function of
 * the same name in Octave.
 */
void expm(double *x, int n, double *z, precond_type precond_kind)
{
    if (n == 1)
	z[0] = exp(x[0]);		/* scalar exponential */
    else
    {
	/* Constants */
	const double one = 1.0, zero = 0.0;
	const int i1 = 1, nsqr = n * n, np1 = n + 1;
	/* Variables */
	int i, j, is_uppertri = TRUE;;
	int ilo, ihi, iloscal, ihiscal, info, sqrpowscal;
	double infnorm, trshift, m1pj = -1;

	/* Arrays */
	int *pivot    = (int *) R_alloc(n, sizeof(int)); /* pivot vector */
	double *scale; /* scale array */
	double *perm  = (double *) R_alloc(n, sizeof(double));/* permutation/sc array */

	double *work  = (double *) R_alloc(nsqr, sizeof(double)); /* workspace array */
	double *npp   = (double *) R_alloc(nsqr, sizeof(double)); /* num. power Pade */
	double *dpp   = (double *) R_alloc(nsqr, sizeof(double)); /* denom. power Pade */

	Memcpy(z, x, nsqr);

	/* Check if matrix x is upper triangular; stop checking as
	 * soon as a non-zero value is found below the diagonal. */
	for (i = 0; i < n - 1 && is_uppertri; i++)
	    for (j = i + 1; j < n; j++)
		if (!(is_uppertri = x[i * n + j] == 0.0))
		    break;


	/* Step 1 of preconditioning: shift diagonal by average diagonal. */
	trshift = 0.0;
	for (i = 0; i < n; i++)
	    trshift += x[i * np1];
	trshift /= n;		/* average diagonal element */
	if (trshift > 0.0)
	    for (i = 0; i < n; i++)
		z[i * np1] -= trshift;

	/* Step 2 of preconditioning: balancing with dgebal. */
	if(precond_kind == Ward_2 || precond_kind == Ward_buggy_octave) {
	    if (is_uppertri) {
		/* no need to permute if x is upper triangular */
		ilo = 1;
		ihi = n;
	    }
	    else {
		F77_CALL(dgebal)("P", &n, z, &n, &ilo, &ihi, perm, &info);
		if (info)
		    error(_("LAPACK routine dgebal returned info code %d when permuting"), info);
	    }
	    scale = (double *) R_alloc(n, sizeof(double));
	    F77_CALL(dgebal)("S", &n, z, &n, &iloscal, &ihiscal, scale, &info);
	    if (info)
		error(_("LAPACK routine dgebal returned info code %d when scaling"), info);
	}
	else if(precond_kind == Ward_1) {

	    F77_CALL(dgebal)("B", &n, z, &n, &ilo, &ihi, perm, &info);
	    if (info)
		error(_("LAPACK' dgebal(\"B\",.) returned info code %d"), info);

	}
	else {
	    error(_("invalid 'precond_kind: %d"), precond_kind);
	}


	/* Step 3 of preconditioning: Scaling according to infinity
	 * norm (a priori always needed). */
	infnorm = F77_CALL(dlange)("I", &n, &n, z, &n, work);
	sqrpowscal = (infnorm > 0) ? imax2((int) 1 + log(infnorm)/M_LN2, 0) : 0;
	if (sqrpowscal > 0) {
	    double scalefactor = R_pow_di(2, sqrpowscal);
	    for (i = 0; i < nsqr; i++)
		z[i] /= scalefactor;
	}

	/* Pade approximation (p = q = 8): compute x^8, x^7, x^6,
	 * ..., x^1 */
	for (i = 0; i < nsqr; i++)
	{
	    npp[i] = 0.0;
	    dpp[i] = 0.0;
	}
	for (j = 7; j >= 0; j--)
	{
	    /* npp = z * npp + padec88[j] * z */
	    F77_CALL(dgemm) ("N", "N", &n, &n, &n, &one, z, &n, npp,
			     &n, &zero, work, &n);
	    /* npp <- work + padec88[j] * z */
	    for (i = 0; i < nsqr; i++)
		npp[i] = work[i] + padec88[j] * z[i];
	    /* dpp = z * dpp + (-1)^j * padec88[j] * z */
	    F77_CALL(dgemm) ("N", "N", &n, &n, &n, &one, z, &n, dpp,
			     &n, &zero, work, &n);
	    for (i = 0; i < nsqr; i++)
		dpp[i] = work[i] + m1pj * padec88[j] * z[i];
	    m1pj *= -1; /* (-1)^j */
	}
	/* power 0 */
	for (i = 0; i < nsqr; i++)
	    dpp[i] *= -1.0;
	for (j = 0; j < n; j++)
	{
	    npp[j * np1] += 1.0;
	    dpp[j * np1] += 1.0;
	}

	/* Pade approximation is (dpp)^-1 * npp. */
	F77_CALL(dgetrf) (&n, &n, dpp, &n, pivot, &info);
	if (info)
	    error(_("LAPACK routine dgetrf returned info code %d"), info);
	F77_CALL(dgetrs) ("N", &n, &n, dpp, &n, pivot, npp, &n, &info);
	if (info)
	    error(_("LAPACK routine dgetrs returned info code %d"), info);

	Memcpy(z, npp, nsqr);

	/* Now undo all of the preconditioning */
	/* Preconditioning 3: square the result for every power of 2 */
	while (sqrpowscal--)
	{
	    F77_CALL(dgemm)("N", "N", &n, &n, &n, &one, z, &n,
			    z, &n, &zero, work, &n);
	    Memcpy(z, work, nsqr);
	}


	/* Preconditioning 2: Inversion of 'dgebal()' :
	 * ------------------ Note that dgebak() seems *not* applicable */

	/* Step 2 a)  apply inverse scaling */
	if(precond_kind == Ward_2 || precond_kind == Ward_buggy_octave) {
	    for (j = 0; j < n; j++)
		for (i = 0; i < n; i++)
		    z[i + j * n] *= scale[i]/scale[j];
	}
	else if(precond_kind == Ward_1) { /* here, perm[ilo:ihi] contains scale[] */
	    for (j = 0; j < n; j++) {
		double sj = ((ilo-1 <= j && j < ihi)? perm[j] : 1.);
		for (i = 0; i < ilo-1; i++)	z[i + j * n] /= sj;
		for (i = ilo-1; i < ihi; i++)	z[i + j * n] *= perm[i]/sj;
		for (i = ihi+1; i < n; i++)	z[i + j * n] /= sj;
	    }
	}

	/* 2 b) Inverse permutation  (if not the identity permutation) */

	if (ilo != 1 || ihi != n) {

	    if(precond_kind == Ward_buggy_octave) {

		/* inverse permutation vector */
		int *invP  = (int *) R_alloc(n, sizeof(int));

		/* balancing permutation vector */
		for (i = 0; i < n; i++)
		    invP[i] = i;	/* identity permutation */

		/* leading permutations applied in forward order */
		for (i = 0; i < (ilo - 1); i++)
		{
		    int p_i = (int) (perm[i]) - 1;
		    int tmp = invP[i]; invP[i] = invP[p_i]; invP[p_i] = tmp;
		}

		/* trailing permutations applied in reverse order */
		for (i = n - 1; i >= ihi; i--)
		{
		    int p_i = (int) (perm[i]) - 1;
		    int tmp = invP[i]; invP[i] = invP[p_i]; invP[p_i] = tmp;
		}

		/* construct inverse balancing permutation vector */
		Memcpy(pivot, invP, n);
		for (i = 0; i < n; i++)
		    invP[pivot[i]] = i;

		/* apply inverse permutation */
		Memcpy(work, z, nsqr);
		for (j = 0; j < n; j++)
		    for (i = 0; i < n; i++)
			z[i + j * n] = work[invP[i] + invP[j] * n];

	    }
	    else if(precond_kind == Ward_2 || precond_kind == Ward_1) {

		/* ---- new code by Martin Maechler ----- */

#define SWAP_ROW(I,J) F77_CALL(dswap)(&n, &z[(I)], &n, &z[(J)], &n)

#define SWAP_COL(I,J) F77_CALL(dswap)(&n, &z[(I)*n], &i1, &z[(J)*n], &i1)

#define RE_PERMUTE(I)				\
		int p_I = (int) (perm[I]) - 1;	\
		SWAP_COL(I, p_I);		\
		SWAP_ROW(I, p_I)

		/* reversion of "leading permutations" : in reverse order */
		for (i = (ilo - 1) - 1; i >= 0; i--) {
		    RE_PERMUTE(i);
		}

		/* reversion of "trailing permutations" : applied in forward order */
		for (i = (ihi + 1) - 1; i < n; i++) {
		    RE_PERMUTE(i);
		}

	    }
/* 	    else if(precond_kind == Ward_1) { */

/* 	    } */

	}
	/* Preconditioning 1: Trace normalization */
	if (trshift > 0)
	{
	    double mult = exp(trshift);
	    for (i = 0; i < nsqr; i++)
		z[i] *= mult;
	}

    }
}
Beispiel #18
0
/* Written by Mikko Korpela */
SEXP readloop(SEXP series_index, SEXP decade, SEXP x) {
    SEXP ans, dims, rw_mat, prec_rproc;
    size_t i, x_nrow, rw_nrow, rw_ncol, x_idx;
    int j, x_ncol, yr_idx, rw_idx, this_series, this_val, min_year, max_year;
    int span, this_decade, last_valid, nseries;
    int *series_index_p, *decade_p, *x_p, *prec_rproc_p, *last_yr;
    double stop_marker;
    double *dims_p, *rw_vec;

    /* Safety checks */
    if (!(isInteger(series_index) && isInteger(decade) && isInteger(x))) {
	error(_("all arguments must be integers"));
    }

    /* Dimensions of x */
    dims = PROTECT(coerceVector(getAttrib(x, R_DimSymbol), REALSXP));
    if (length(dims) != 2) {
	UNPROTECT(1);
	error(_("'x' must be a matrix"));
    }
    dims_p = REAL(dims);
    /* Nominally max 10 years per row, allow a few more */
    if (dims_p[1] > 100) {
	UNPROTECT(1);
	error(_("too many columns in 'x'"));
    }
    x_nrow = (size_t) dims_p[0];
    x_ncol = (int) dims_p[1];
    UNPROTECT(1);

    /* More safety checks */
    if (!(dplRlength(series_index) == x_nrow &&
	  dplRlength(decade) == x_nrow)) {
	error(_("dimensions of 'x', 'series_index' and 'decade' must match"));
    }

    series_index_p = INTEGER(series_index);
    decade_p = INTEGER(decade);
    x_p = INTEGER(x);

    /* Calculate dimensions of result matrix */
    nseries = 0;
    min_year = INT_MAX;
    max_year = INT_MIN;
    for (i = 0; i < x_nrow; i++) {
	if (series_index_p[i] < 1) {
	    error(_("'series_index' must be positive"));
	}
	nseries = imax2(nseries, series_index_p[i]);
	this_decade = decade_p[i];
	j = x_ncol - 1;
	x_idx = i + j * x_nrow;
	while (j >= 0 && x_p[x_idx] == NA_INTEGER) {
	    --j;
	    x_idx -= x_nrow;
	}
	if (j >= 0) {
	    min_year = imin2(min_year, this_decade);
	    max_year = imax2(max_year, this_decade + j);
	}
    }
    if (max_year >= min_year) {
	if (max_year >= 0 && min_year < max_year - R_INT_MAX + 1)
	    error(_("Number of years exceeds integer range"));
	span = max_year - min_year + 1;
    } else {
	min_year = NA_INTEGER;
	span = 0;
    }
    rw_nrow = (size_t) span;
    rw_ncol = (size_t) nseries;

    /* List for results: rw_mat, min_year, prec_rproc */
    ans = PROTECT(allocVector(VECSXP, 3));
    rw_mat = SET_VECTOR_ELT(ans, 0, allocMatrix(REALSXP, span, nseries));
    rw_vec = REAL(rw_mat);
    for (i = 0; i < rw_nrow * rw_ncol; i++) {
	rw_vec[i] = NA_REAL;
    }
    SET_VECTOR_ELT(ans, 1, ScalarInteger(min_year));
    prec_rproc = SET_VECTOR_ELT(ans, 2, allocVector(INTSXP, nseries));
    prec_rproc_p = INTEGER(prec_rproc);
    if (span == 0) {
	for(i = 0; i < rw_ncol; i++){
	    prec_rproc_p[i] = NA_INTEGER;
	}
	warning(_("no data found in 'x'"));
	UNPROTECT(1);
	return ans;
    }

    /* Allocate internal storage */
    last_yr = (int *) R_alloc(rw_ncol, sizeof(int));
    for (i = 0; i < rw_ncol; i++) {
	last_yr[i] = min_year;
    }

    /* Convert between input and output formats */
    for(i = 0; i < x_nrow; i++){
	this_decade = decade_p[i];
	yr_idx = this_decade - min_year;
	this_series = series_index_p[i] - 1;
	rw_idx = this_series * rw_nrow + yr_idx;
	x_idx = i;
	last_valid = last_yr[this_series];
	for(j = 0; j < x_ncol; j++){
	    this_val = x_p[x_idx];
	    x_idx += x_nrow;
	    if(this_val != NA_INTEGER){
		rw_vec[rw_idx] = this_val;
		last_valid = this_decade + j;
	    }
	    rw_idx++;
	}

	/* Needed for keeping track of the stop marker */
	if(last_valid > last_yr[this_series])
	    last_yr[this_series] = last_valid;
    }
    for(i = 0; i < rw_ncol; i++){
	stop_marker = rw_vec[i * rw_nrow + (last_yr[i] - min_year)];
	if(stop_marker == 999.0f){
	    prec_rproc_p[i] = 100;
	} else if(stop_marker == -9999.0f){
	    prec_rproc_p[i] = 1000;
	} else {
	    prec_rproc_p[i] = 1;
	}
    }

    UNPROTECT(1);
    return ans;
}
Beispiel #19
0
int main(int argc, char *argv[])
{
  static char *Spec[] = {"[-root_id <int>] [<input:string>]",
    "[-a <string>] [-b <string>]", 
    "[-stitch_script] [-exclude <string>] [-tile_number <int>]",
    NULL};
  Process_Arguments(argc, argv, Spec, 1);

  int *excluded = NULL;
  int nexc = 0;
  int *excluded_pair = NULL;
  int nexcpair = 0;
  if (Is_Arg_Matched("-exclude")) {
    String_Workspace *sw = New_String_Workspace();
    FILE *fp = fopen(Get_String_Arg("-exclude"), "r");
    char *line = Read_Line(fp, sw);
    excluded = String_To_Integer_Array(line, NULL, &nexc);
    line = Read_Line(fp, sw);
    if (line != NULL) {
      excluded_pair = String_To_Integer_Array(line, NULL, &nexcpair);
      nexcpair /= 2;
    }
    Kill_String_Workspace(sw);
    fclose(fp);
  }

  int n = 0;
  Graph *graph = Make_Graph(n + 1, n, TRUE);
  char filepath1[100];
  char filepath2[100];
  int i, j;
  Stack *stack1 = NULL;
  FILE *fp = NULL;
  if (Is_Arg_Matched("-stitch_script")) {
    Cuboid_I *boxes = read_tile_array(Get_String_Arg("-a"), &n);
    for (i = 0; i < n; i++) {
      for (j = i + 1; j < n; j++) {      
	BOOL is_excluded = FALSE;
	int k;
	for (k = 0; k < nexc; k++) {
	  if ((i == excluded[k] - 1) || (j == excluded[k] - 1)) {
	    is_excluded = TRUE;
	    break;
	  }
	}
	for (k = 0; k < nexcpair; k++) {
	  if (((i == excluded_pair[k*2]) && (j == excluded_pair[k*2+1])) ||
	      ((j == excluded_pair[k*2]) && (i == excluded_pair[k*2+1]))) {
	    is_excluded = TRUE;
	    break;
	  }
	}
	/*
	if ((i != 103) && (j != 103) && (i != 115) && (j != 115) && (i != 59) &&
	    (j != 59) && !(i == 116 && j == 116)) {
	    */
	if (is_excluded == FALSE) {
	  Cuboid_I_Overlap_Volume(boxes + i, boxes + j);
	  Cuboid_I ibox;
	  Cuboid_I_Intersect(boxes + i, boxes + j, &ibox);
	  int width, height, depth;
	  Cuboid_I_Size(&ibox, &width, &height, &depth);

	  if ((imax2(width, height) > 1024 / 3) && (imin2(width, height) > 0)) {
	    sprintf(filepath1, "%s/stack/%03d.xml", 
		Get_String_Arg("input"), i + 1);
	    sprintf(filepath2, "%s/stack/%03d.xml", 
		Get_String_Arg("input"), j + 1);
	    if (stack1 == NULL) {
	      stack1 = Read_Stack_U(filepath1);
	    }
	    Stack *stack2 = Read_Stack_U(filepath2);

	    Stack *substack1= Crop_Stack(stack1, ibox.cb[0] - boxes[i].cb[0], 
		ibox.cb[1] - boxes[i].cb[1], 0,
		width, height, stack1->depth, NULL);
	    Stack *substack2 = Crop_Stack(stack2, ibox.cb[0] - boxes[j].cb[0], 
		ibox.cb[1] - boxes[j].cb[1], 0,
		width, height, stack2->depth, NULL);

	    Image *img1 = Proj_Stack_Zmax(substack1);	
	    Image *img2 = Proj_Stack_Zmax(substack2);
	    double w = u16array_corrcoef((uint16_t*) img1->array, 
		(uint16_t*) img2->array, 
		img1->width * img1->height);

	    Kill_Stack(stack2);
	    Kill_Stack(substack1);
	    Kill_Stack(substack2);
	    Kill_Image(img1);
	    Kill_Image(img2);
	    printf("%d, %d : %g\n", i + 1, j + 1, w);
	    Graph_Add_Weighted_Edge(graph, i + 1, j + 1, 1000.0 / (w + 1.0));
	  }
	}
	if (stack1 != NULL) {
	  Kill_Stack(stack1);
	  stack1 = NULL;
	}
      }
    }

    Graph_Workspace *gw = New_Graph_Workspace();
    Graph_To_Mst2(graph, gw);

    Arrayqueue q = Graph_Traverse_B(graph, Get_Int_Arg("-root_id"), gw);

    Print_Arrayqueue(&q);

    int *grown = iarray_malloc(graph->nvertex);
    for (i = 0; i < graph->nvertex; i++) {
      grown[i] = 0;
    }

    int index  = Arrayqueue_Dequeue(&q);
    grown[index] = 1;

    char stitch_p_file[5][500];
    FILE *pfp[5];
    for (i = 0; i < 5; i++) {
      sprintf(stitch_p_file[i], "%s/stitch/stitch_%d.sh", Get_String_Arg("input"), i);
      pfp[i] = fopen(stitch_p_file[i], "w");
    }

    sprintf(filepath1, "%s/stitch/stitch_all.sh", Get_String_Arg("input"));

    fp = GUARDED_FOPEN(filepath1, "w");
    fprintf(fp, "#!/bin/bash\n");

    int count = 0;
    while ((index = Arrayqueue_Dequeue(&q)) > 0) {
      for (i = 0; i < graph->nedge; i++) {
	int index2 = -1;
	if (index == graph->edges[i][0]) {
	  index2 = graph->edges[i][1];
	} else if (index == graph->edges[i][1]) {
	  index2 = graph->edges[i][0];
	}

	if (index2 > 0) {
	  if (grown[index2] == 1) {
	    char cmd[500];
	    sprintf(filepath2, "%s/stitch/%03d_%03d_pos.txt",
		Get_String_Arg("input"), index2, index);
	    sprintf(cmd, 
		"%s/stitchstack %s/stack/%03d.xml %s/stack/%03d.xml -o %s", 
		Get_String_Arg("-b"), Get_String_Arg("input"),
		index2, Get_String_Arg("input"), index, filepath2);
	    fprintf(fp, "%s\n", cmd);
	    count++;
	    fprintf(pfp[count%5], "%s\n", cmd);
	    /*
	    if (!fexist(filepath2)) {
	      system(cmd);
	    }
	    */
	    grown[index] = 1;
	    break;
	  }
	}
      }
    }

    fclose(fp);  
    for (i = 0; i < 5; i++) {
      fprintf(pfp[i], "touch %s/stitch/stitch_%d_done\n", 
	  Get_String_Arg("input"), i);
      fclose(pfp[i]);
    }
    return 0;
  }
  
  sprintf(filepath1, "%s/stitch/stitch_all.sh", Get_String_Arg("input"));
  fp = GUARDED_FOPEN(filepath1, "r");

//#define MAX_TILE_INDEX 153
  int tile_number = Get_Int_Arg("-tile_number");
  int max_tile_index = tile_number + 1;

  char *line = NULL;
  String_Workspace *sw = New_String_Workspace();
  int id[2];
  char filepath[100];
  int offset[max_tile_index][3];
  int relative_offset[max_tile_index][3];
  int array[max_tile_index];

  for (i = 0; i < max_tile_index; i++) {
    array[i] = -1;
    offset[i][0] = 0;
    offset[i][1] = 0;
    offset[i][2] = 0;
    relative_offset[i][0] = 0;
    relative_offset[i][1] = 0;
    relative_offset[i][2] = 0;
  }

  while ((line = Read_Line(fp, sw)) != NULL) {
    char *remain = strsplit(line, ' ', 1);
    if (String_Ends_With(line, "stitchstack")) {
      String_To_Integer_Array(remain, id, &n);
      id[0] = id[1];
      id[1] = id[3];
      array[id[1]] = id[0];

      sprintf(filepath, "%s/stitch/%03d_%03d_pos.txt", Get_String_Arg("input"),
	      id[0], id[1]);
      if (!fexist(filepath)) {
	fprintf(stderr, "file %s does not exist\n", filepath);
	return 1;
      }
      FILE *fp2 = GUARDED_FOPEN(filepath, "r");
      line = Read_Line(fp2, sw);
      line = Read_Line(fp2, sw);
      int tmpoffset[8];
      String_To_Integer_Array(line, tmpoffset, &n);
      relative_offset[id[1]][0] = tmpoffset[2];
      relative_offset[id[1]][1] = tmpoffset[3];
      relative_offset[id[1]][2] = tmpoffset[4];

      fclose(fp2);
    }
  }
  
  for (i = 1; i < max_tile_index; i++) {
    BOOL is_excluded = FALSE;
    int k;
    for (k = 0; k < nexc; k++) {
      if (i == excluded[k]) {
	is_excluded = TRUE;
	break;
      }
    }
    /*if ((i == 104) || (i == 116) || (i == 60) || (i == 152)) {*/
    if (is_excluded) {
      printf("%d: (0, 0, 10000)\n", i);
    } else {
      int index = i;
      while (index >= 0) {
	offset[i][0] += relative_offset[index][0];
	offset[i][1] += relative_offset[index][1];
	offset[i][2] += relative_offset[index][2];
	index = array[index];
      }
      printf("%d: (%d, %d, %d)\n", i, offset[i][0], offset[i][1], offset[i][2]);
    }
  }

  fclose(fp);

  return 0;
}