예제 #1
0
/* Breadth first seach algorithm to find & mark connected components. */
int find_comps(struct vtx_data **graph,  /* graph data structure */
               int               nvtxs,  /* number of vertices in graph */
               int *             mark,   /* space for nvtxs+1 ints */
               int *             vtxlist /* space for nvtxs ints */
               )
{
  int    root;   /* vertex to start the dfs */
  int    count;  /* number of vertices seen so far */
  int    ncomps; /* number of components found */
  int    i;      /* loop counter */
  double drandom();

  for (i    = 1; i <= nvtxs; i++)
    mark[i] = -1;
  count     = 0;
  ncomps    = 0;
  root      = nvtxs * drandom() + 1;

  bfsearch(graph, root, &count, mark, vtxlist, ncomps);

  while (count != nvtxs) { /* Are there any remaining vertices? */
    /* Find starting vtx for next BFS. */
    root = nvtxs * drandom() + 1;
    while (mark[root] >= 0) {
      root++;
      if (root > nvtxs)
        root = 1;
    }
    /* Add new edge to list needed for connectivity. */
    ncomps++;
    bfsearch(graph, root, &count, mark, vtxlist, ncomps);
  }
  return (ncomps + 1);
}
예제 #2
0
/* Inititialize the perturbation */
void 
perturb_init (
    int n			/* graph size at this level */
)
{
    extern int NPERTURB;	/* number of edges to perturb */
    extern double PERTURB_MAX;	/* maximum perturbation */
    int       i, j;		/* loop counter */
    double    drandom();

    /* Initialize the diagonal perturbation weights */
    pedges = smalloc(NPERTURB * sizeof(struct ipairs));
    pvals = smalloc(NPERTURB * sizeof(double));

    if (n <= 1) {
	for (i = 0; i < NPERTURB; i++) {
	    pedges[i].val1 = pedges[i].val2 = 0;
	    pvals[i] = 0;
	}
	return;
    }

    for (i = 0; i < NPERTURB; i++) {
	pedges[i].val1 = 1 + (n * drandom());

	/* Find another vertex to define an edge. */
	j = 1 + (n * drandom());
	while (j == i)
	    j = 1 + (n * drandom());
	pedges[i].val2 = 1 + (n * drandom());

	pvals[i] = PERTURB_MAX * drandom();
    }
}
예제 #3
0
파일: maze.c 프로젝트: akiyks/perfbook
/*
 * Find a boundary between the created and inchoate portions of the maze.
 * Return 0 if the maze is now fully created.
 */
int maze_find_boundary(struct maze *mp, int *prevrow, int *prevcol,
		       int *currow, int *curcol)
{
	int d;
	int cr;
	int cc;
	int pr;
	int pc;
	int vi;
	int vi_lim;
	int vi_start;

	if (mp->lastvi == -1 || drandom() > mp->revisit)
		vi = drandom() * mp->vi;
	else
		vi = mp->lastvi;
	vi_lim = mp->vi;
	vi_start = vi;
	do {
		pr = mp->visited[vi].row;
		pc = mp->visited[vi].col;
		cr = -1;
		if (!maze_cell_visited(mp, pr - 1, pc)) {
			cr = pr - 1;
			cc = pc;
		}
		if (!maze_cell_visited(mp, pr + 1, pc) &&
		    (cr == -1 || drandom() < 0.5)) {
			cr = pr + 1;
			cc = pc;
		}
		if (!maze_cell_visited(mp, pr, pc - 1) &&
		    (cr == -1 || drandom() < 0.5)) {
			cr = pr;
			cc = pc - 1;
		}
		if (!maze_cell_visited(mp, pr, pc + 1) &&
		    (cr == -1 || drandom() < 0.5)) {
			cr = pr;
			cc = pc + 1;
		}
		if (cr != -1) {
			d = maze_get_cell_distance(mp, pr, pc);
			maze_remove_wall(mp, pr, pc, cr, cc);
			maze_visit_cell(mp, cr, cc, d + 1);
			*prevrow = pr;
			*prevcol = pc;
			*currow = cr;
			*curcol = cc;
			mp->lastvi = vi;
			return 1;
		}
		vi++;
		if (vi >= mp->vi)
			vi = 0;
		if (vi_lim != mp->vi)
			ABORT();
	} while (vi != vi_start);
	return 0; /* Maze is now finished. */
}
예제 #4
0
파일: maze_part.c 프로젝트: a1406/setting
/* Randomly assign any remaining thread's starting points. */
void maze_solve_start_random(struct maze *mp)
{
	int i;
	int r;
	int c;
	struct maze_child *mcp = mp->msp->mcp;

	for (i = 0; i < nthreads; i++)
		if (mcp[i].startrow == -1)
			do {
				r = (int)(drandom() * mp->nrows);
				c = (int)(drandom() * mp->ncols);
			} while (!maze_solve_start_assign(mp, i, r, c));
}
예제 #5
0
/* Returns list of edges to connect them together. */
int find_edges(struct vtx_data ** graph,   /* graph data structure */
               int                nvtxs,   /* number of vertices in graph */
               int *              mark,    /* space for nvtxs+1 ints */
               int *              vtxlist, /* space for nvtxs ints */
               struct edgeslist **edges    /* list of edges connecting graph */
               )
{
  struct edgeslist *newedge; /* space to add new edge */
  int               root;    /* vertex to start the dfs */
  int               last;    /* last vertex seen in BFS */
  int               count;   /* number of vertices seen so far */
  int               nadded;  /* number of edges needed to be added */
  int               i;       /* loop counter */
  double            drandom();

  for (i    = 1; i <= nvtxs; i++)
    mark[i] = -1;
  count     = 0;
  nadded    = 0;
  *edges    = NULL;
  root      = nvtxs * drandom() + 1;

  last = bfsearch(graph, root, &count, mark, vtxlist, nadded);

  while (count != nvtxs) { /* Are there any remaining vertices? */
    /* Find starting vtx for next BFS. */
    root = nvtxs * drandom() + 1;
    while (mark[root] >= 0) {
      root++;
      if (root > nvtxs)
        root = 1;
    }
    /* Add new edge to list needed for connectivity. */
    newedge       = smalloc(sizeof(struct edgeslist));
    newedge->next = *edges;
    newedge->vtx1 = last;
    newedge->vtx2 = root;
    *edges        = newedge;
    nadded++;
    last = bfsearch(graph, root, &count, mark, vtxlist, nadded);
  }
  return (nadded);
}
예제 #6
0
파일: dgrep.c 프로젝트: jarmoruuth/tools
/**********************************************************************
 *
 *	short_usage
 *
 * Exits with options help message and funtext.
 */
static void short_usage(void)
{
	printf("%s%s%s%s%s",
		usage_line,
		version_line,
		options1,
		options2,
		funtext[drandom() % NFUNTEXT]);
	exit(2);
}
예제 #7
0
/* Fill double vector with random numbers over a range. */
void      vecran(double *vec, int beg, int end)
{
    int       i;
    double   *pntr;
    double    ch_normalize(double *vec, int beg, int end);
    double    drandom(void);

    pntr = vec + beg;
    for (i = end - beg + 1; i; i--) {
	(*pntr++) = drandom();
    }
    ch_normalize(vec, beg, end);
}
예제 #8
0
/* Fill float vector with random numbers over a range. */
void      vecran_float(float *vec, int beg, int end)
{
    int       i;
    float    *pntr;
    double    normalize_float(float *vec, int beg, int end);
    double    drandom(void);

    pntr = vec + beg;
    for (i = end - beg + 1; i; i--) {
	(*pntr++) = drandom();
    }
    normalize_float(vec, beg, end);
}
예제 #9
0
파일: maze.c 프로젝트: akiyks/perfbook
/* Randomly choose a next cell to build the current maze segment. */
int maze_choose_next_cell(struct maze *mp, int prevrow, int prevcol,
			  int currow, int curcol, int *nextrow, int *nextcol)
{
	int d;  /* Distance. */
	int dr; /* Delta rows. */
	int dc; /* Delta columns. */
	int nr; /* Next row. */
	int nc; /* Next column. */
	struct segment_weights *swp = &mp->weights[prevrow != currow];
	double w = drandom();

	d = maze_get_cell_distance(mp, currow, curcol);
	if (w > swp->randweight) {
		/* Time to stop. */
		return MAZE_END_SEGMENT;
	}
	if (w > swp->contweight && (prevrow != currow || prevcol != curcol)) {
		/* Erect a perpendicular vector. */
		dr = -(curcol - prevcol);
		dc = currow - prevrow;
		/* Flip the vector if randomly required. */
		if (pmrandom()) {
			dr = -dr;
			dc = -dc;
		}
		/* Try out the corresponding cell. */
		nr = currow + dr;
		nc = curcol + dc;
		if (!maze_try_visit_cell(mp, currow, curcol, nr, nc,
					nextrow, nextcol, d + 1))
			return MAZE_CONTINUE_SEGMENT;
		/* No go, try turning the opposite direction. */
		nr = currow - dr;
		nc = curcol - dc;
		if (!maze_try_visit_cell(mp, currow, curcol, nr, nc,
					nextrow, nextcol, d + 1))
			return MAZE_CONTINUE_SEGMENT;
		/* Neither worked, drop through and try straight. */
	}
	nr = currow + (currow - prevrow);
	nc = curcol + (curcol - prevcol);
	if (!maze_try_visit_cell(mp, currow, curcol, nr, nc,
				nextrow, nextcol, d + 1))
		return MAZE_CONTINUE_SEGMENT;
	/* No go, check all possibilities.  Done being picky! */
	if (maze_find_any_next_cell(mp, currow, curcol, nextrow, nextcol))
		return MAZE_CONTINUE_SEGMENT;
	/* Nowhere left to go. */
	return MAZE_STUCK_SEGMENT;
}
예제 #10
0
/* Randomly permute elements of an array. */
void randomize(int *array, int n)
/* array of integer values */
/* number of values */
{
  double value; /* random value */
  int    index; /* array index to swap with */
  int    temp;  /* holds value being swapped */
  int    i;     /* loop counter */
  double drandom(void);

  for (i = 1; i <= n; i++) {
    value        = drandom();
    index        = n * value + 1;
    temp         = array[i];
    array[i]     = array[index];
    array[index] = temp;
  }
}
예제 #11
0
/*! \fn int addSaltPepperNoisePGM(Pgm* pgmIn, Pgm* pgmOut, double density)
 * \brief Add Salt & Pepper noise to the image \a pgmIn. The final result is stored in \a pgmOut.
 *
 * Superimpose a percentage 'density' of white or black pixels onto the image.
 * \param pgmIn Pointer to the input PGM image structure.
 * \param pgmOut Pointer to the output PGM image structure.
 * \param density The percentage of pixels that will become black or white with equal probability.
 * \return 0 on success, -1 if either pgmIn or pgmOut are NULL.
 */
int addSaltPepperNoisePGM(Pgm* pgmIn, Pgm* pgmOut, double density)
{
    int i;
    
    if(!pgmIn)
    {
        fprintf(stderr, "Error! No input data. Please Check.\n");
        return -1;
    }
    
    if(!pgmOut)
    {
        fprintf(stderr, "Error! No space to store the result. Please Check.\n");
        return -1;
    }
    
    int width = pgmIn->width;
    int height = pgmIn->height;
    
    // Iterate over all pixels
    for (i = 0; i < width*height; i++) {
        if (drandom()>density) {
            pgmOut->pixels[i] = pgmIn->pixels[i];
        } else {
            // A density percentage of pixels will randomly
            // be transformed to black or white
            if (random()&01) {
                pgmOut->pixels[i] = 0;
            } else {
                pgmOut->pixels[i] = 255;
            }
        }
    }
    
    pgmOut->max_val = 255;
    
    return 0;
}
예제 #12
0
void gen_comm_data(
struct Params *params,
struct Data *data,
int nprocs)
{
    int       sizes_max = 4;	/* maximum size of variable sized data */
    int       index;		/* pointer into vals array */
    int       i, j;		/* loop counters */

    data->proc_owner = (int *) ZOLTAN_MALLOC(params->nvals * sizeof(int));
    data->proc_dest = (int *) ZOLTAN_MALLOC(params->nvals * sizeof(int));
    if (params->variable_sizes) {
	data->sizes = (int *) ZOLTAN_MALLOC((params->nvals + 1) * sizeof(int));
	data->vals = (float *)
	   ZOLTAN_MALLOC(params->nvals * sizes_max * sizeof(float));
    }
    else {
	data->sizes = NULL;
	data->same_size = params->same_size;
	data->vals = (float *)
	   ZOLTAN_MALLOC(params->nvals * data->same_size * sizeof(float));
    }

    data->nvals = params->nvals;

    srand(params->seed);
    index = 0;
    for (i = 0; i < params->nvals; i++) {
	data->proc_owner[i] = drandom() * nprocs;
	data->proc_dest[i] = drandom() * nprocs;
	if (drandom() < params->drop_freq)
	    data->proc_dest[i] = -1;
	if (params->variable_sizes) {
	    data->sizes[i] = 1 + drandom() * (sizes_max - 1);
	    for (j = 0; j < data->sizes[i]; j++) {
		data->vals[index++] = drandom();
	    }
	}
	else {
	    for (j = 0; j < params->same_size; j++) {
		data->vals[index++] = drandom();
	    }
	}
    }
}
예제 #13
0
void randomVector(Vector *v, double xR, double yR, double zR)
{
    v->x = drandom(xR);
    v->y = drandom(yR);
    v->z = drandom(zR);
}
예제 #14
0
파일: opt3d.c 프로젝트: 00liujj/trilinos
void 
opt3d (
    struct vtx_data **graph,	/* data structure containing vertex weights */
    double **yvecs,		/* eigenvectors */
    int nvtxs,		/* total number of vertices */
    int nmyvtxs,		/* number of vertices I own */
    double *vwsqrt,		/* square root of vertex weights */
    double *ptheta,
    double *pphi,
    double *pgamma,	/* return optimal angles */
    int using_vwgts		/* are vertex weights being used? */
)

/* Compute rotation angle to minimize distance to discrete points. */
{
    extern int DEBUG_OPTIMIZE;	/* debug flag for optimization */
    extern int OPT3D_NTRIES;	/* number of local opts to find global min */
    double   *aptr, *bptr, *cptr;	/* loop through yvecs */
    double   *wsptr;		/* loops through vwsqrt */
    double    coeffs[25];	/* various products of yvecs */
    double    vars[3];		/* angular variables */
    double    best[3];		/* best minimizer found so far */
    double    grad[3];		/* gradiant of the function */
    double    gradc[3];		/* gradiant of the constraint */
    double    hess[3][3];	/* hessian of the function */
    double    hessc[3][3];	/* hessian of the constraint */
    double    step[3];		/* Newton step in optimization */
    double    grad_norm;	/* norm of the gradient */
    double    grad_min;		/* acceptable gradient for convergence */
    double    a, b, c;		/* temporary values */
    double    funcf=0.0, funcc;	/* values of function to be minimized */
    double    step_size;	/* norm of step */
    double    step_max;		/* maximum allowed step */
    double    step_min;		/* minimum step => convergence */
    double    early_step_min;	/* min step for early convergence stages */
    double    final_step_min;	/* min step for final convergence */
    double    hess_min;		/* value for hessian if < 0 */
    double    hess_tol;		/* smallest possible positive hess_min */
    double    hfact;		/* scales minimum tolerated hessian */
    double    w, ws=0;		/* vertex weight squared or to the 1.5 */
    double    mult;		/* multiplier for constraint violation */
    double    max_constraint;	/* maximum allowed value for constraint */
    double    eval;		/* smallest eigenvalue of Hessian */
    double    pdtol;		/* eval < tol considered to be 0 */
    double    mfactor;		/* scaling for constraint growth */
    double    mstart;		/* starting value for constraint scaling */
    double    bestf;		/* value of best minimizer so far */
    double    res;		/* returned eigen-residual */
    int       pdflag;		/* converging to non-minimum? */
    int       inner;		/* number of iterations at each stage */
    int       inner1;
    int       total;		/* total number of iterations */
    int       ntries, maxtries;	/* number of local minimizations */
    int       i, j;		/* loop counter */
int kk;
    double    func3d(), constraint();
    double    drandom();
    void      grad3d(), hess3d(), gradcon(), hesscon(), kramer3(), ch_eigenvec3();
    void      ch_evals3();

    /* Set parameters. */
    best[0]=best[1]=best[2]=0.0;
    a = sqrt((double) nvtxs);
    step_max = PI / 4;
    early_step_min = 2.0e-4;
    final_step_min = early_step_min / 10;
    grad_min = 1.0e-7;
    hfact = 2;
    hess_tol = 1.0e-6;
    pdtol = 1.0e-7;
    max_constraint = 1.0e-12 * a;
    mfactor = 20.0;
    mstart = 5.0 * a;

    for (i = 0; i < 25; i++)
	coeffs[i] = 0;

    aptr = yvecs[1] + 1;
    bptr = yvecs[2] + 1;
    cptr = yvecs[3] + 1;
    wsptr = vwsqrt + 1;
    for (i = 1; i <= nmyvtxs; i++) {
	a = *aptr++;
	b = *bptr++;
	c = *cptr++;
	w = graph[i]->vwgt;
	if (using_vwgts)
	    ws = *wsptr++;
	if (w == 1) {
	    coeffs[0] += a * a * a * a;
	    coeffs[1] += b * b * b * b;
	    coeffs[2] += c * c * c * c;
	    coeffs[3] += a * a * a * b;
	    coeffs[4] += a * a * b * b;
	    coeffs[5] += a * b * b * b;
	    coeffs[6] += a * a * a * c;
	    coeffs[7] += a * a * c * c;
	    coeffs[8] += a * c * c * c;
	    coeffs[9] += b * b * b * c;
	    coeffs[10] += b * b * c * c;
	    coeffs[11] += b * c * c * c;
	    coeffs[12] += a * a * b * c;
	    coeffs[13] += a * b * b * c;
	    coeffs[14] += a * b * c * c;

	    coeffs[15] += a * a * a;
	    coeffs[16] += b * b * b;
	    coeffs[17] += c * c * c;
	    coeffs[18] += a * a * b;
	    coeffs[19] += a * a * c;
	    coeffs[20] += a * b * b;
	    coeffs[21] += b * b * c;
	    coeffs[22] += a * c * c;
	    coeffs[23] += b * c * c;
	    coeffs[24] += a * b * c;
	}
	else {
	    w = 1 / (w * w);
	    ws = 1 / ws;
	    coeffs[0] += a * a * a * a * w;
	    coeffs[1] += b * b * b * b * w;
	    coeffs[2] += c * c * c * c * w;
	    coeffs[3] += a * a * a * b * w;
	    coeffs[4] += a * a * b * b * w;
	    coeffs[5] += a * b * b * b * w;
	    coeffs[6] += a * a * a * c * w;
	    coeffs[7] += a * a * c * c * w;
	    coeffs[8] += a * c * c * c * w;
	    coeffs[9] += b * b * b * c * w;
	    coeffs[10] += b * b * c * c * w;
	    coeffs[11] += b * c * c * c * w;
	    coeffs[12] += a * a * b * c * w;
	    coeffs[13] += a * b * b * c * w;
	    coeffs[14] += a * b * c * c * w;

	    coeffs[15] += a * a * a * ws;
	    coeffs[16] += b * b * b * ws;
	    coeffs[17] += c * c * c * ws;
	    coeffs[18] += a * a * b * ws;
	    coeffs[19] += a * a * c * ws;
	    coeffs[20] += a * b * b * ws;
	    coeffs[21] += b * b * c * ws;
	    coeffs[22] += a * c * c * ws;
	    coeffs[23] += b * c * c * ws;
	    coeffs[24] += a * b * c * ws;
	}
    }

    /* Adjust for normalization of eigenvectors. */
    /* This should make convergence criteria insensitive to problem size. */
    /* Note that the relative sizes of funcf and funcc depend on normalization of
       eigenvectors, and I'm assuming them normalized to 1. */
    for (i = 0; i < 15; i++)
	coeffs[i] *= nvtxs;
    a = sqrt((double) nvtxs);
    for (i = 15; i < 25; i++)
	coeffs[i] *= a;

    bestf = 0;
    maxtries = OPT3D_NTRIES;
    for (ntries = 1; ntries <= maxtries; ntries++) {
	/* Initialize the starting guess randomly. */
	vars[0] = TWOPI * (drandom() - .5);
	vars[1] = acos(2.0 * drandom() - 1.0) - HALFPI;
	vars[2] = TWOPI * (drandom() - .5);

	inner1 = 0;
	total = 0;
	mult = mstart;
	step_min = early_step_min;
	funcc = max_constraint;
	while (funcc >= max_constraint && total < 70) {
	    inner = 0;
	    step_size = step_min;
	    pdflag = FALSE;
	    grad_norm = 0;
	    while (step_size >= step_min && (!pdflag || grad_norm > grad_min)
		   && inner < 15) {
		funcf = func3d(coeffs, vars[0], vars[1], vars[2]);
		grad3d(coeffs, grad, vars[0], vars[1], vars[2]);
		hess3d(coeffs, hess);

		/* Compute contribution of constraint term. */
		funcc = constraint(&coeffs[15]);
		/* func = funcf + mult*funcc; */
		gradcon(&coeffs[15], gradc);
		hesscon(&coeffs[15], hessc);

		/* If in final pass, tighten convergence criterion. */
		if (funcc < max_constraint)
		    step_min = final_step_min;

kk = 0;
if (kk) {
  ch_evals3(hessc, &eval, &res, &res);
}
   

		for (i = 0; i < 3; i++) {
		    /* Note: I'm taking negative of gradient here. */
		    grad[i] = -grad[i] - mult * gradc[i];
		    for (j = 0; j < 3; j++)
			hess[i][j] += mult * hessc[i][j];
		}

		grad_norm = fabs(grad[0]) + fabs(grad[1]) + fabs(grad[2]);
		hess_min = hfact * grad_norm / step_max;
		if (hess_min < hess_tol)
		    hess_min = hess_tol;

		/* Find smallest eigenvalue of hess. */
		ch_evals3(hess, &eval, &res, &res);

		/* If eval < 0, add to diagonal to make pos def. */
		if (eval < -pdtol)
		    pdflag = FALSE;
		else
		    pdflag = TRUE;

		if (eval < hess_min) {
		    for (i = 0; i < 3; i++)
			hess[i][i] += hess_min - eval;
		}

		/* Now solve linear system for step sizes. */
		kramer3(hess, grad, step);

		/* Scale step down if too big. */
		step_size = fabs(step[0]) + fabs(step[1]) + fabs(step[2]);
		if (step_size > step_max) {
		    a = step_max / step_size;
		    for (i = 0; i < 3; i++)
			step[i] *= a;
		}

		if ((step_size < step_min || grad_norm < grad_min) && !pdflag) {
		    /* Convergence to non-min. */
		    for (i = 0; i < 3; i++)
			hess[i][i] -= hess_min - eval;
		    ch_eigenvec3(hess, eval, step, &res);
		    step_size = fabs(step[0]) + fabs(step[1]) + fabs(step[2]);
		    a = step_min / step_size;
		    for (i = 0; i < 3; i++)
			step[i] *= a;
		    step_size = step_min;
		}
		for (i = 0; i < 3; i++)
		    vars[i] += step[i];
		inner++;
	    }
	    if (inner1 == 0)
		inner1 = inner;
	    total += inner;
	    mult *= mfactor;
	}

	if (DEBUG_OPTIMIZE > 0) {
	    printf("On try %d, After %d (%d) passes, funcf=%e, funcc=%e (%f, %f, %f)\n",
		   ntries, total, inner1, funcf, funcc, vars[0], vars[1], vars[2]);
	}

	if (ntries == 1 || funcf < bestf) {
	    bestf = funcf;
	    for (i = 0; i < 3; i++)
		best[i] = vars[i];
	}
    }
    *ptheta = best[0];
    *pphi = best[1];
    *pgamma = best[2];
}
예제 #15
0
int 
nway_kl (
    struct vtx_data **graph,	/* data structure for graph */
    int nvtxs,		/* number of vtxs in graph */
    struct bilist ****buckets,	/* array of lists for bucket sort */
    struct bilist **listspace,	/* list data structure for each vertex */
    int **tops,			/* 2-D array of top of each set of buckets */
    int **dvals,		/* d-values for each transition */
    int *sets,			/* processor each vertex is assigned to */
    int maxdval,		/* maximum d-value for a vertex */
    int nsets,		/* number of sets divided into */
    double *goal,			/* desired set sizes */
    float *term_wgts[],		/* weights for terminal propogation */
    int (*hops)[MAXSETS],	/* cost of set transitions */
    int max_dev,		/* largest allowed deviation from balance */
    int using_ewgts,		/* are edge weights being used? */
    int **bndy_list,		/* list of vertices on boundary (0 ends) */
    double *startweight		/* sum of vweights in each set (in and out) */
)

/* Suaris and Kedem algorithm for quadrisection, generalized to an */
/* arbitrary number of sets, with intra-set cost function specified by hops. */
/* Note: this is for a single divide step. */
/* Also, sets contains an intial (possibly crummy) partitioning. */

{
    extern double kl_bucket_time;	/* time spent in KL bucketsort */
    extern int KL_BAD_MOVES;	/* # bad moves in a row to stop KL */
    extern int DEBUG_KL;	/* debug flag for KL */
    extern int KL_RANDOM;	/* use randomness in KL? */
    extern int KL_NTRIES_BAD;	/* number of unhelpful passes before quitting */
    extern int KL_UNDO_LIST;	/* should I back out of changes or start over? */
    extern int KL_MAX_PASS;	/* maximum number of outer KL loops */
    extern double CUT_TO_HOP_COST;	/* if term_prop; cut/hop importance */
    struct bilist *movelist;	/* list of vtxs to be moved */
    struct bilist **endlist;	/* end of movelists */
    struct bilist *bestptr;	/* best vertex in linked list */
    struct bilist *bptr;	/* loops through bucket list */
    float    *ewptr=NULL;		/* loops through edge weights */
    double   *locked=NULL;		/* weight of vertices locked in a set */
    double   *loose=NULL;		/* weight of vtxs that can move from a set */
    int      *bspace=NULL;		/* list of active vertices for bucketsort */
    double   *weightsum=NULL;	/* sum of vweights for each partition */
    int      *edges=NULL;		/* edge list for a vertex */
    int      *bdy_ptr=NULL;	 	/* loops through bndy_list */
    double    time;		/* timing parameter */
    double    delta;		/* desire of sets to change size */
    double    bestdelta=-1;	/* strongest delta value */
    double    deltaplus;	/* largest negative deviation from goal size */
    double    deltaminus;	/* largest negative deviation from goal size */
    int       list_length;	/* how long is list of vertices to bucketsort? */
    int       balanced;		/* is partition balanced? */
    int       temp_balanced;	/* is intermediate partition balanced? */
    int       ever_balanced;	/* has any partition been balanced? */
    int       bestvtx=-1;		/* best vertex to move */
    int       bestval=-1;		/* best change in value for a vtx move */
    int       bestfrom=-1, bestto=-1;	/* sets best vertex moves between */
    int       vweight;		/* weight of best vertex */
    int       gtotal;		/* sum of changes from moving */
    int       improved;		/* total improvement from KL */
    double    balance_val=0.0;	/* how imbalanced is it */
    double    balance_best;	/* best balance yet if trying hard */
    double    bestg;		/* maximum gtotal found in KL loop */
    double    bestg_min;	/* smaller than any possible bestg */
    int       beststep;		/* step where maximum value occurred */
    int       neighbor;		/* neighbor of a vertex */
    int       step_cutoff;	/* number of negative steps in a row allowed */
    int       cost_cutoff;	/* amount of negative d-values allowed */
    int       neg_steps;	/* number of negative steps in a row */
    int       neg_cost;		/* decrease in sum of d-values */
    int       vtx;		/* vertex number */
    int       dval;		/* dval of a vertex */
    int       group;		/* set that a vertex is assigned to */
    double    cut_cost;		/* if term_prop; relative cut/hop importance */
    int       diff;		/* change in a d-value */
    int       stuck1st, stuck2nd;	/* how soon will moves be disallowed? */
    int       beststuck1=-1, beststuck2=-1;	/* best stuck values for tie-breaking */
    int       eweight;		/* a particular edge weight */
    int       worth_undoing;	/* is it worth undoing list? */
    float     undo_frac;	/* fraction of vtxs indicating worth of undoing */
    int       step;		/* loops through movements of vertices */
    int       parity;		/* sort forwards or backwards? */
    int       done;		/* has termination criteria been achieved? */
    int       nbad;		/* number of unhelpful passes in a row */
    int       npass;		/* total number of passes */
    int       nbadtries;	/* number of unhelpful passes before quitting */
    int       enforce_balance;	/* force a balanced partition? */
    int       enforce_balance_hard;	/* really force a balanced partition? */
    int       balance_trouble;	/* even balance_hard isn't working */
    int       size;		/* array spacing */
    int       i, j, k, l;	/* loop counters */

    double    drandom(), seconds();
    int       make_kl_list();
    void      bucketsorts(), bucketsorts_bi(), bucketsort1();
    void      pbuckets(), removebilist(), movebilist(), make_bndy_list();

    nbadtries = KL_NTRIES_BAD;

    enforce_balance = FALSE;
    temp_balanced = FALSE;
    enforce_balance_hard = FALSE;
    balance_trouble = FALSE;

    size = (int) (&(listspace[0][1]) - &(listspace[0][0]));

    undo_frac = .3;

    cut_cost = 1;
    if (term_wgts[1] != NULL) {
	if (CUT_TO_HOP_COST > 1) {
	    cut_cost = CUT_TO_HOP_COST;
	}
    }

    bspace = smalloc_ret(nvtxs * sizeof(int));
    weightsum = smalloc_ret(nsets * sizeof(double));
    locked = smalloc_ret(nsets * sizeof(double));
    loose = smalloc_ret(nsets * sizeof(double));

    if (bspace == NULL || weightsum == NULL || locked == NULL || loose == NULL) {
        sfree(loose);
        sfree(locked);
        sfree(weightsum);
        sfree(bspace);
	return(1);
    }

    if (*bndy_list != NULL) {
	bdy_ptr = *bndy_list;
	list_length = 0;
	while (*bdy_ptr != 0) {
	    bspace[list_length++] = *bdy_ptr++;
	}
	sfree(*bndy_list);

	if (list_length == 0) {		/* No boundary -> make everybody bndy. */
	    for (i = 0; i < nvtxs; i++) {
		bspace[i] = i + 1;
	    }
	    list_length = nvtxs;
	}
	/* Set dvals to flag uninitialized vertices. */
	for (i = 1; i <= nvtxs; i++) {
	    dvals[i][0] = 3 * maxdval;
	}
    }
    else {
        list_length = nvtxs;
    }

    step_cutoff = KL_BAD_MOVES;
    cost_cutoff = maxdval * step_cutoff / 7;
    if (cost_cutoff < step_cutoff)
	cost_cutoff = step_cutoff;

    deltaminus = deltaplus = 0;
    for (i = 0; i < nsets; i++) {
	if (startweight[i] - goal[i] > deltaplus) {
	    deltaplus = startweight[i] - goal[i];
	}
	else if (goal[i] - startweight[i] > deltaminus) {
	    deltaminus = goal[i] - startweight[i];
	}
    }
    balanced = (deltaplus + deltaminus <= max_dev);

    bestg_min = -2.0 * nvtxs * maxdval;
    parity = FALSE;
    eweight = cut_cost + .5;
    nbad = 0;
    npass = 0;
    improved = 0;
    done = FALSE;
    while (!done) {
	npass++;
	ever_balanced = FALSE;

	/* Initialize various quantities. */
	balance_best = 0;
	for (i = 0; i < nsets; i++) {
	    for (j = 0; j < nsets; j++)
		tops[i][j] = 2 * maxdval;
	    weightsum[i] = startweight[i];
	    loose[i] = weightsum[i];
	    locked[i] = 0;
	    balance_best += goal[i];
	}

	gtotal = 0;
	bestg = bestg_min;
	beststep = -1;

	movelist = NULL;
	endlist = &movelist;

	neg_steps = 0;

	/* Compute the initial d-values, and bucket-sort them. */
	time = seconds();
	if (nsets == 2) {
	    bucketsorts_bi(graph, nvtxs, buckets, listspace, dvals, sets, term_wgts,
			   maxdval, nsets, parity, hops, bspace, list_length, npass,
			   using_ewgts);
	}
	else {
	    bucketsorts(graph, nvtxs, buckets, listspace, dvals, sets, term_wgts,
			maxdval, nsets, parity, hops, bspace, list_length, npass,
			using_ewgts);
	}
	parity = !parity;
	kl_bucket_time += seconds() - time;

	if (DEBUG_KL > 2) {
	    pbuckets(buckets, listspace, maxdval, nsets);
	}

	/* Now determine the set of K-L moves. */

	for (step = 1;; step++) {

	    /* Find the highest d-value in each set. */
	    /* But only consider moves from large to small sets, or moves */
	    /* in which balance is preserved. */
	    /* Break ties in some nonarbitrary manner. */
	    bestval = -maxdval - 1;
	    for (i = 0; i < nsets; i++)
		for (j = 0; j < nsets; j++)
		    /* Only allow moves from large sets to small sets, or */
		    /* moves which preserve balance. */
		    if (i != j) {
			/* Find the best move from i to j. */
			for (k = tops[i][j]; k >= 0 && buckets[i][j][k] == NULL;
			     k--) ;
			tops[i][j] = k;

			if (k >= 0) {
			    l = (j > i) ? j - 1 : j;
			    vtx = ((int) (buckets[i][j][k] - listspace[l])) / size;
			    vweight = graph[vtx]->vwgt;

			    if ((enforce_balance_hard && 
				  weightsum[i] >= goal[i] && weightsum[j] <= goal[j] &&
				  weightsum[i] - goal[i] - (weightsum[j] - goal[j]) >
				   max_dev) ||
				(!enforce_balance_hard &&
				  weightsum[i] >= goal[i] && weightsum[j] <= goal[j]) ||
				(!enforce_balance_hard &&
				 weightsum[i] - vweight - goal[i] > -(double)((max_dev + 1) / 2) &&
				 weightsum[j] + vweight - goal[j] <  (double)((max_dev + 1) / 2))) {

				/* Is it the best move seen so far? */
				if (k - maxdval > bestval) {
				    bestval = k - maxdval;
				    bestvtx = vtx;
				    bestto = j;
				    /* DO I NEED ALL THIS DATA?  Just to break ties. */
				    bestdelta = fabs(weightsum[i] - vweight - goal[i]) +
				                fabs(weightsum[j] + vweight - goal[j]);
				    beststuck1 = min(loose[i], goal[j] - locked[j]);
				    beststuck2 = max(loose[i], goal[j] - locked[j]);
				}

				else if (k - maxdval == bestval) {
				    /* Tied.  Is better balanced than current best? */
				    /* If tied, move among sets with most freedom. */
				    stuck1st = min(loose[i], goal[j] - locked[j]);
				    stuck2nd = max(loose[i], goal[j] - locked[j]);
				    delta = fabs(weightsum[i] - vweight - goal[i]) +
				            fabs(weightsum[j] + vweight - goal[j]);

				    /* NOTE: Randomization in this check isn't ideal */
				    /* if more than two guys are tied. */
				    if (delta < bestdelta ||
				    (delta == bestdelta && (stuck1st > beststuck1 ||
							 (stuck1st == beststuck1 &&
							  (stuck2nd > beststuck2 ||
							 (stuck2nd == beststuck2 &&
					      (KL_RANDOM && drandom() < .5))))))) {
					bestval = k - maxdval;
					bestvtx = vtx;
					bestto = j;
					bestdelta = delta;
					beststuck1 = stuck1st;
					beststuck2 = stuck2nd;
				    }
				}
			    }
			}
		    }

	    if (bestval == -maxdval - 1) {	/* No allowed moves */
		if (DEBUG_KL > 0) {
		    printf("No KL moves at step %d.  bestg = %g at step %d.\n",
			   step, bestg, beststep);
		}
		break;
	    }

	    bestptr = &(listspace[0][bestvtx]);
	    bestfrom = sets[bestvtx];

	    vweight = graph[bestvtx]->vwgt;
	    weightsum[bestto] += vweight;
	    weightsum[bestfrom] -= vweight;
	    loose[bestfrom] -= vweight;
	    locked[bestto] += vweight;

	    if (enforce_balance) {	/* Check if this partition is balanced. */
		deltaminus = deltaplus = 0;
		for (i = 0; i < nsets; i++) {
		    if (weightsum[i] - goal[i] > deltaplus) {
			deltaplus = weightsum[i] - goal[i];
		    }
		    else if (goal[i] - weightsum[i] > deltaminus) {
			deltaminus = goal[i] - weightsum[i];
		    }
		}
		balance_val = deltaminus + deltaplus;
		temp_balanced = (balance_val <= max_dev);
		ever_balanced = (ever_balanced || temp_balanced);
	    }

	    gtotal += bestval;
	    if (((gtotal > bestg && (!enforce_balance || temp_balanced)) ||
		 (enforce_balance_hard && balance_val < balance_best)) &&
		 step != nvtxs) {
		bestg = gtotal;
		beststep = step;
		if (enforce_balance_hard) {
		    balance_best = balance_val;
		}
		if (temp_balanced) {
		    enforce_balance_hard = FALSE;
		}
	    }

	    if (DEBUG_KL > 1) {
		printf("At KL step %d, bestvtx=%d, bestval=%d (%d-> %d)\n",
		       step, bestvtx, bestval, bestfrom, bestto);
	    }

	    /* Monitor the stopping criteria. */
	    if (bestval < 0) {
		if (!enforce_balance || ever_balanced)
		    neg_steps++;
		if (bestg != bestg_min)
		    neg_cost = bestg - gtotal;
		else
		    neg_cost = -maxdval - 1;
		if ((neg_steps > step_cutoff || neg_cost > cost_cutoff) &&
			!(enforce_balance && bestg == bestg_min) &&
			(beststep != step)) {
		    if (DEBUG_KL > 0) {
			if (neg_steps > step_cutoff) {
			    printf("KL step cutoff at step %d.  bestg = %g at step %d.\n",
				   step, bestg, beststep);
			}
			else if (neg_cost > cost_cutoff) {
			    printf("KL cost cutoff at step %d.  bestg = %g at step %d.\n",
				   step, bestg, beststep);
			}
		    }
		    break;
		}
	    }
	    else if (bestval > 0) {
		neg_steps = 0;
	    }

	    /* Remove vertex from its buckets, and flag it as finished. */
	    l = 0;
	    for (k = 0; k < nsets; k++) {
		if (k != bestfrom) {
		    dval = dvals[bestvtx][l] + maxdval;
		    removebilist(&listspace[l][bestvtx],
				 &buckets[bestfrom][k][dval]);
		    l++;
		}
	    }


	    /* Is there a better way to do this? */
	    sets[bestvtx] = -sets[bestvtx] - 1;

	    /* Set up the linked list of moved vertices. */
	    bestptr->next = NULL;
	    bestptr->prev = (struct bilist *) (unsigned long) bestto;
	    *endlist = bestptr;
	    endlist = &(bestptr->next);

	    /* Now update the d-values of all the neighbors */
	    edges = graph[bestvtx]->edges;
	    if (using_ewgts)
		ewptr = graph[bestvtx]->ewgts;
	    for (j = graph[bestvtx]->nedges - 1; j; j--) {
		neighbor = *(++edges);
		if (using_ewgts)
		    eweight = *(++ewptr) * cut_cost + .5;

		/* First make sure neighbor is alive. */
		if (sets[neighbor] >= 0) {
		    group = sets[neighbor];

                    if (dvals[neighbor][0] >= 3 * maxdval) {
		        /* New vertex, not yet in buckets. */
		        /* Can't be neighbor of moved vtx, so compute */
		        /* inital dvals and buckets, then update. */
			bucketsort1(graph, neighbor, buckets, listspace, dvals, sets,
			    term_wgts, maxdval, nsets, hops, using_ewgts);
		    }

		    l = 0;
		    for (k = 0; k < nsets; k++) {
			if (k != group) {
			    diff = eweight * (
					hops[k][bestfrom] - hops[group][bestfrom] +
					    hops[group][bestto] - hops[k][bestto]);
			    dval = dvals[neighbor][l] + maxdval;
			    movebilist(&listspace[l][neighbor],
				       &buckets[group][k][dval],
				       &buckets[group][k][dval + diff]);
			    dvals[neighbor][l] += diff;
			    dval += diff;
			    if (dval > tops[group][k])
				tops[group][k] = dval;
			    l++;
			}
		    }
		}
	    }
	    if (DEBUG_KL > 2) {
		pbuckets(buckets, listspace, maxdval, nsets);
	    }
	}

	/* Done with a pass; should we actually perform any swaps? */
	bptr = movelist;
	if (bestg > 0 || (bestg != bestg_min && !balanced && enforce_balance) ||
	    (bestg != bestg_min && balance_trouble)) {
	    improved += bestg;
	    for (i = 1; i <= beststep; i++) {
		vtx = ((int) (bptr - listspace[0])) / size;
		bestto = (int) (unsigned long) bptr->prev;
		startweight[bestto] += graph[vtx]->vwgt;
		startweight[-sets[vtx] - 1] -= graph[vtx]->vwgt;
		sets[vtx] = (int) bestto;
		bptr = bptr->next;
	    }

	    deltaminus = deltaplus = 0;
	    for (i = 0; i < nsets; i++) {
		if (startweight[i] - goal[i] > deltaplus) {
		    deltaplus = startweight[i] - goal[i];
		}
		else if (goal[i] - startweight[i] > deltaminus) {
		    deltaminus = goal[i] - startweight[i];
		}
	    }
/*
printf(" deltaplus = %f, deltaminus = %f, max_dev = %d\n", deltaplus, deltaminus, max_dev);
*/
	    balanced = (deltaplus + deltaminus <= max_dev);
	}
	else {
	    nbad++;
	}

	if (!balanced || bptr == movelist) {
	    if (enforce_balance) {
	        if (enforce_balance_hard) {
		     balance_trouble = TRUE;
		}
		enforce_balance_hard = TRUE;
	    }
	    enforce_balance = TRUE;
	    nbad++;
	}

	worth_undoing = (step < undo_frac * nvtxs);
	done = (nbad >= nbadtries && balanced);
	if (KL_MAX_PASS > 0) {
	    done = done || (npass == KL_MAX_PASS && balanced);
	}
	if (!done) {		/* Prepare for next pass. */
	    if (KL_UNDO_LIST && worth_undoing && !balance_trouble) {
		/* Make a list of modified vertices for next bucketsort. */
		/* Also, ensure these vertices are removed from their buckets. */
		list_length = make_kl_list(graph, movelist, buckets, listspace,
					   sets, nsets, bspace, dvals, maxdval);
	    }
	}
	if (done || !(KL_UNDO_LIST && worth_undoing && !balance_trouble)) {
	    /* Restore set numbers of remaining, altered vertices. */
	    while (bptr != NULL) {
		vtx = ((int) (bptr - listspace[0])) / size;
		sets[vtx] = -sets[vtx] - 1;
		bptr = bptr->next;
	    }
	    list_length = nvtxs;
	}

	if (done && *bndy_list != NULL) {
	    make_bndy_list(graph, movelist, buckets, listspace, sets, nsets,
			   bspace, tops, bndy_list);
	}
    }

    if (DEBUG_KL > 0) {
	printf("   KL required %d passes to improve by %d.\n", npass, improved);
    }

    sfree(loose);
    sfree(locked);
    sfree(weightsum);
    sfree(bspace);
    return(0);
}
예제 #16
0
int 
maxmatch5 (
    struct vtx_data **graph,	/* array of vtx data for graph */
    int nvtxs,		/* number of vertices in graph */
    int *mflag,		/* flag indicating vtx selected or not */
    int igeom,		/* geometric dimensionality */
    float **coords		/* coordinates of each vertex */
)
{
    extern double DOUBLE_MAX;	/* largest floating point value */
    double    dist;		/* distance to free neighbor */
    double    min_dist;		/* smallest distance to free neighbor */
    int      *jptr;		/* loops through integer arrays */
    int       vtx;		/* vertex to process next */
    int       neighbor;		/* neighbor of a vertex */
    int       nmerged;		/* number of edges in matching */
    int       jsave;		/* best edge so far */
    int       i, j;		/* loop counters */
    double    drandom();

    /* Initialize mflag array. */
    jptr = mflag;
    for (i = 1; i <= nvtxs; i++) {
	*(++jptr) = 0;
    }

    nmerged = 0;

    /* Select random starting point in list of vertices. */
    vtx = 1 + drandom() * nvtxs;

    if (igeom == 1) {
	for (i = nvtxs; i; i--) {	/* Choose geometrically nearest neighbor */
	    if (mflag[vtx] == 0) {	/* Not already matched. */
		/* Select nearest free edge. */
		jsave = 0;
		min_dist = DOUBLE_MAX;
		for (j = 1; j < graph[vtx]->nedges; j++) {
		    neighbor = graph[vtx]->edges[j];
		    if (mflag[neighbor] == 0) {
			dist = (coords[0][vtx] - coords[0][neighbor]) *
			   (coords[0][vtx] - coords[0][neighbor]);
			if (dist < min_dist) {
			    jsave = j;
			    min_dist = dist;
			}
		    }
		}
		if (jsave > 0) {
		    neighbor = graph[vtx]->edges[jsave];
		    mflag[vtx] = neighbor;
		    mflag[neighbor] = vtx;
		    nmerged++;
		}
	    }
	    if (++vtx > nvtxs)
		vtx = 1;
	}
    }

    else if (igeom == 2) {
	for (i = nvtxs; i; i--) {	/* Choose geometrically nearest neighbor */
	    if (mflag[vtx] == 0) {	/* Not already matched. */
		/* Select nearest free edge. */
		jsave = 0;
		min_dist = DOUBLE_MAX;
		for (j = 1; j < graph[vtx]->nedges; j++) {
		    neighbor = graph[vtx]->edges[j];
		    if (mflag[neighbor] == 0) {
			dist = (coords[0][vtx] - coords[0][neighbor]) *
			   (coords[0][vtx] - coords[0][neighbor]);
			if (dist < min_dist) {
			    dist += (coords[1][vtx] - coords[1][neighbor]) *
			       (coords[1][vtx] - coords[1][neighbor]);
			    if (dist < min_dist) {
				jsave = j;
				min_dist = dist;
			    }
			}
		    }
		}
		if (jsave > 0) {
		    neighbor = graph[vtx]->edges[jsave];
		    mflag[vtx] = neighbor;
		    mflag[neighbor] = vtx;
		    nmerged++;
		}
	    }
	    if (++vtx > nvtxs)
		vtx = 1;
	}
    }

    else if (igeom >= 2) {
	for (i = nvtxs; i; i--) {	/* Choose geometrically nearest neighbor */
	    if (mflag[vtx] == 0) {	/* Not already matched. */
		/* Select nearest free edge. */
		jsave = 0;
		min_dist = DOUBLE_MAX;
		for (j = 1; j < graph[vtx]->nedges; j++) {
		    neighbor = graph[vtx]->edges[j];
		    if (mflag[neighbor] == 0) {
			dist = (coords[0][vtx] - coords[0][neighbor]) *
			   (coords[0][vtx] - coords[0][neighbor]);
			if (dist < min_dist) {
			    dist += (coords[1][vtx] - coords[1][neighbor]) *
			       (coords[1][vtx] - coords[1][neighbor]);
			    if (dist < min_dist) {
				dist += (coords[2][vtx] - coords[2][neighbor]) *
				   (coords[2][vtx] - coords[2][neighbor]);
				if (dist < min_dist) {
				    jsave = j;
				    min_dist = dist;
				}
			    }
			}
		    }
		}
		if (jsave > 0) {
		    neighbor = graph[vtx]->edges[jsave];
		    mflag[vtx] = neighbor;
		    mflag[neighbor] = vtx;
		    nmerged++;
		}
	    }
	    if (++vtx > nvtxs)
		vtx = 1;
	}
    }

    return (nmerged);
}
예제 #17
0
파일: ransack.c 프로젝트: bareid/mangle
/*------------------------------------------------------------------------------
  Generate random az, el positions within mask defined by poly.
  The results are written to out_filename.

   Input: out_filename = name of file to write to;
			"" or "-" means write to standard output.
	  fmt = pointer to format structure.
	  npoly = number of polygons in poly array.
	  npolysmax = maximum number of polygons in poly array.
	  poly = array of pointers to polygons.
	  mtol = initial tolerance angle for multiple intersections.
  Return value: number of random points generated,
		or -1 if error occurred.
*/
int ransack(char *out_filename, format *fmt, int npoly, int npolysmax, polygon *poly[/*npolysmax*/])
{
/* number of extra caps to allocate to polygon, to allow for expansion */
#define DNP			4
/* length of state vector for random number generator */
#define STATELEN		256
    static char state[STATELEN], stateo[STATELEN];
#define AZEL_STR_LEN		32
    char output[] = "output";
    char az_str[AZEL_STR_LEN], el_str[AZEL_STR_LEN];
    int dnp, dnwl, i, idwidth, ier, in, inull, ip, ipmin, ipoly, iprune, irandom, lassoed, np, nwl, tries, verb, width, k;
    long long idmin,idmax;
    int *dlasso=0x0, *lasso=0x0;
    long double area, cmmin, cmi, phi, rpoly, si, tol, w, wcum, x, y, z;
    long double *wpoly;
    vec rp, xi, yi;
    azel v;
    char *out_fn;
    FILE *outfile;

    /* open out_filename for writing */
    if (!out_filename || strcmp(out_filename, "-") == 0) {
	outfile = stdout;
	out_fn = output;
    } else {
	outfile = fopen(out_filename, "w");
	if (!outfile) {
	    fprintf(stderr, "ransack: cannot open %s for writing\n", out_filename);
	    goto error;
	}
	out_fn = out_filename;
    }

    /* advise angular units */
    if (fmt->outunit != fmt->inunit) {
	msg("units of output az, el angles will be ");
	switch (fmt->outunit) {
#include "angunit.h"
	}
	msg("\n");
    }

    /* initialize random number generator used by ransack() */
    initstate(seed, state, STATELEN);
    /* initialize random number generator used by ikrand() */
    initstate(seed, stateo, STATELEN);

    /* prune polygons, discarding those with zero weight * area */
    msg("pruning %d polygons ...\n", npoly);
    ier = 0;
    inull = 0;
    np = 0;
    for (ipoly = 0; ipoly < npoly; ipoly++) {
	/* zero weight polygon */
	if (poly[ipoly]->weight == 0.) {
            inull++;
	    free_poly(poly[ipoly]);
	    poly[ipoly] = 0x0;
	} else {
	/* prune polygon */
	    iprune = prune_poly(poly[ipoly], mtol);
	    /* error */
	    if (iprune == -1) {
		ier++;
		free_poly(poly[ipoly]);
		poly[ipoly] = 0x0;
		fprintf(stderr, "ransack: failed to prune polygon %d; discard it\n", ipoly);
		/* goto error; */
	    /* zero area polygon */
	    } else if (iprune >= 2) {
		inull++;
		free_poly(poly[ipoly]);
		poly[ipoly] = 0x0;
	    } else {
		np++;
	    }
	}
    }
   /*copy down non-null polygons*/
    k=0;
    for(ipoly = 0; ipoly < npoly; ipoly++){
      if(poly[ipoly]){
	poly[k++]=poly[ipoly];
      }
    }
    /*after copying non-null polygons, k should be equal to np */
    if(k!=np){
      fprintf(stderr, "ransack: should be left with %d non-null polygons, but actually have %d\n",np,k);
    }

    /*nullify the rest of the array, but don't free, since pointers have been copied above*/
    for(ipoly=np; ipoly < npoly; ipoly++){
      poly[ipoly]=0x0;
    }

    if (ier > 0) {
	msg("discarding %d unprunable polygons\n", ier);
    }
    if (inull > 0) {
	msg("discarding %d polygons with zero weight * area\n", inull);
    }
    /* number of polygons with finite weight * area */
    npoly = np;

    /* no polygons */
    if (npoly == 0) {
	fprintf(stderr, "ransack: no polygons to generate random points inside!\n");
	goto error;
    }

    /* pre-lasso polygons if there are many random points */
    if (nrandom >= npoly) {
	msg("lassoing %d polygons ...\n", npoly);

	/* lasso each polygon */
	np = npoly;
	for (ipoly = 0; ipoly < npoly; ipoly++) {
	    ier = lasso_poly(&poly[ipoly], npolysmax - np, &poly[np], mtol, &dnp);
	    if (ier == -1) {
		fprintf(stderr, "ransack: UHOH at polygon %lld; continuing ...\n", poly[ipoly]->id);
	    }

	    /* lassoed polygons are an improvement over original polygon */
	    if (dnp > 0) {
		/* check whether exceeded maximum number of polygons */
		if (np + dnp > npolysmax) {
		    fprintf(stderr, "ransack: total number of polygons exceeded maximum %d\n", npolysmax);
		    fprintf(stderr, "if you need more space, enlarge NPOLYSMAX in defines.h, and recompile\n");
		    goto error;
		}

		/* decrement dnp by 1 */
		dnp--;

		/* increment number of polygons */
		np += dnp;

		/* move last polygon part into poly[ipoly] */
		free_poly(poly[ipoly]);
		poly[ipoly] = poly[np];
		poly[np] = 0x0;
	    }
	}

	/* revised number of polygons */
	npoly = np;

	/* flag that all polygons have been lassoed */
	lassoed = 1;

    /* two few random points to make it worth pre-lassoing */
    } else {
	/* flag that all polygons have not been lassoed */
	lassoed = 0;

    }

    /* allocate memory for wpoly array */
    nwl = npoly;
    wpoly = (long double *) malloc(sizeof(long double) * nwl);
    if (!wpoly) {
        fprintf(stderr, "ransack: failed to allocate memory for %d long doubles\n", nwl);
        goto error;
    }
    if (!lassoed) {
	/* allocate memory for lasso and dlasso arrays */
	lasso = (int *) malloc(sizeof(int) * nwl);
	if (!lasso) {
	    fprintf(stderr, "ransack: failed to allocate memory for %d ints\n", nwl);
	    goto error;
	}
	dlasso = (int *) malloc(sizeof(int) * nwl);
	if (!dlasso) {
	    fprintf(stderr, "ransack: failed to allocate memory for %d ints\n", nwl);
	    goto error;
	}

	/* initialize dlasso array to zero */
	for (ipoly = 0; ipoly < nwl; ipoly++) dlasso[ipoly] = 0;
    }

    /* largest width of polygon id number */
    idmin = 0;
    idmax = 0;
    for (ipoly = 0; ipoly < npoly; ipoly++) {
	if (poly[ipoly]->id < idmin) idmin = poly[ipoly]->id;
	if (poly[ipoly]->id > idmax) idmax = poly[ipoly]->id;
    }
    idmin = ((idmin < 0)? floorl(log10l((long double)-idmin)) + 2 : 1);
    idmax = ((idmax > 0)? floorl(log10l((long double)idmax)) + 1 : 1);
    idwidth = ((idmin > idmax)? idmin : idmax);

    /* write header */
    wrangle(0., fmt->outunit, fmt->outprecision, AZEL_STR_LEN, az_str);
    width = strlen(az_str);
    if (fmt->outunit == 'h') {
	sprintf(az_str, "az(hms)");
	sprintf(el_str, "el(dms)");
    } else {
	sprintf(az_str, "az(%c)", fmt->outunit);
	sprintf(el_str, "el(%c)", fmt->outunit);
    }
    fprintf(outfile, "%*s\t%*s\t%*s\n", width, az_str, width, el_str, idwidth, "id");

    /* accept error messages from garea */
    /* unprunable polygons were already discarded, so garea should give no errors */
    verb = 1;

    /* cumulative area times weight of polygons */
    w = 0.;
    for (ipoly = 0; ipoly < npoly; ipoly++) {
	/* skip null polygons */
	if (poly[ipoly]) {
	    /* area of polygon */
	    tol = mtol;
	    ier = garea(poly[ipoly], &tol, verb, &area);
	    if (ier) goto error;
	    /* accumulate weight times area */
	    w += poly[ipoly]->weight * area;
	}
	wpoly[ipoly] = w;
    }
    wcum = w;

    /* random points */
    if (strcmp(out_fn, output) != 0) {
	msg("generating %d random points from seed %u in %d polygons ...\n", nrandom, seed, npoly);
    }
    for (irandom = 0; irandom < nrandom; irandom++) {

	/* random number in interval [0, 1) wcum */
	setstate(state);
	rpoly = drandom() * wcum;
	setstate(stateo);

	/* which polygon to put random point in */
	ipoly = search(npoly, wpoly, rpoly);

	/* guard against roundoff */
	if (ipoly >= npoly) {
	    fprintf(stderr, "ransack: %d should be < %d (i.e. %.15Lg < %.15Lg)\n", ipoly, npoly, rpoly, wpoly[npoly - 1]);
	    ipoly = npoly - 1;
	}

	/* all polygons have not been lassoed */
	if (!lassoed) {

	    /* polygon has not yet been lassoed */
	    if  (dlasso[ipoly] == 0) {

		/* lasso polygon */
		ier = lasso_poly(&poly[ipoly], npolysmax - np, &poly[np], mtol, &dnp);
		if (ier == -1) {
		    fprintf(stderr, "ransack: UHOH at polygon %lld; continuing ...\n", poly[ipoly]->id);
		}

		/* go with original polygon */
		if (dnp == 0) {
		    /* lasso, dlasso */
		    lasso[ipoly] = ipoly;
		    dlasso[ipoly] = 1;

		/* lassoed polygons are an improvement over original */
		} else {
		    /* check whether exceeded maximum number of polygons */
		    if (np + dnp > npolysmax) {
			fprintf(stderr, "ransack: total number of polygons exceeded maximum %d\n", npolysmax);
			fprintf(stderr, "if you need more space, enlarge NPOLYSMAX in defines.h, and recompile\n");
			goto error;
		    }

		    /* just one lassoed polygon */
		    if (dnp == 1) {
			/* move last polygon part into poly[ipoly] */
			free_poly(poly[ipoly]);
			poly[ipoly] = poly[np];
			poly[np] = 0x0;

			/* lasso, dlasso */
			lasso[ipoly] = ipoly;
			dlasso[ipoly] = 1;

		    /* more than one lassoed polygon */
		    } else {
			/* enlarge memory for wpoly, lasso, and dlasso arrays */
			if (np + dnp > nwl) {
			    dnwl = dnp + 1024;
			    wpoly = (long double *) realloc(wpoly, sizeof(long double) * (nwl + dnwl));
			    if (!wpoly) {
				fprintf(stderr, "ransack: failed to reallocate memory for %d long doubles\n", nwl + dnwl);
				goto error;
			    }
			    lasso = (int *) realloc(lasso, sizeof(int) * (nwl + dnwl));
			    if (!lasso) {
				fprintf(stderr, "ransack: failed to reallocate memory for %d ints\n", nwl + dnwl);
				goto error;
			    }
			    dlasso = (int *) realloc(dlasso, sizeof(int) * (nwl + dnwl));
			    if (!dlasso) {
				fprintf(stderr, "ransack: failed to reallocate memory for %d ints\n", nwl + dnwl);
				goto error;
			    }

			    /* initialize new part of lasso and dlasso arrays to inconsistent values */
			    for (ipoly = nwl; ipoly < nwl + dnwl; ipoly++) lasso[ipoly] = 1;
			    for (ipoly = nwl; ipoly < nwl + dnwl; ipoly++) dlasso[ipoly] = 0;

			    /* revised size of wpoly, lasso, and dlasso arrays */
			    nwl += dnwl;
			}

			/* lasso, dlasso */
			lasso[ipoly] = np;
			dlasso[ipoly] = dnp;

			/* cumulative weight times area of lassoed polygons */
			w = (ipoly == 0)? 0. : wpoly[ipoly-1];
			for (ip = np; ip < np + dnp; ip++) {
			    /* area of polygon */
			    tol = mtol;
			    ier = garea(poly[ip], &tol, verb, &area);
			    if (ier) goto error;
			    /* accumulate area times weight */
			    w += poly[ip]->weight * area;
			    wpoly[ip] = w;
			}

			/* increment number of polygons */
			np += dnp;
		    }

		}

	    }

	    /* polygon was partitioned into at least two */
	    if (dlasso[ipoly] >= 2) {
		/* which polygon to put random point in */
		ip = search(dlasso[ipoly], &wpoly[lasso[ipoly]], rpoly);

		/* guard against roundoff */
		if (ip >= lasso[ipoly] + dlasso[ipoly]) {
		    fprintf(stderr, "ransack: %d should be < %d (i.e. %.15Lg < %.15Lg)\n", ip, lasso[ipoly] + dlasso[ipoly], rpoly, wpoly[lasso[ipoly] + dlasso[ipoly] - 1]);
		    ip = lasso[ipoly] + dlasso[ipoly] - 1;
		}

		/* revised polygon number to put random point in */
		ipoly = ip;
	    }
	}

	/* smallest cap of polygon */
	cmminf(poly[ipoly], &ipmin, &cmmin);

	/* random point within polygon */
	tries = 0;
	do {
	    tries++;
	    /* random point within smallest cap */
	    setstate(state);
	    phi = TWOPI * drandom();
	    cmi = cmmin * drandom();
	    setstate(stateo);
	    /* coordinates of random point in cap frame */
	    si=sqrtl(cmi * (2. - cmi));
	    x = si * cosl(phi);
	    y = si * sinl(phi);
	    z = 1. - cmi;
	    /* polygon has caps */
	    if (poly[ipoly]->np > 0) {
		if (poly[ipoly]->cm[ipmin] < 0.) z = -z;
		/* Cartesian axes with z-axis along cap axis */
		gaxisi_(poly[ipoly]->rp[ipmin], xi, yi);
		/* coordinates of random point */
		for (i = 0; i < 3; i++) rp[i] = x * xi[i] + y * yi[i] + z * poly[ipoly]->rp[ipmin][i];
		/* whether random point is inside polygon */
		in = gptin(poly[ipoly], rp);
	    /* polygon has no caps, so is the whole sphere */
	    } else {
		rp[0] = x;
		rp[1] = y;
		rp[2] = z;
		in = 1;
	    }
	} while (!in);

	/* convert unit vector to az, el */
	rp_to_azel(rp, &v);
	v.az -= floorl(v.az / TWOPI) * TWOPI;

	/* convert az and el from radians to output units */
	scale_azel(&v, 'r', fmt->outunit);

	/* write result */
	wrangle(v.az, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, az_str);
	wrangle(v.el, fmt->outunit, fmt->outprecision, AZEL_STR_LEN, el_str);
	fprintf(outfile, "%s\t%s\t%*lld\n", az_str, el_str, idwidth, poly[ipoly]->id);
	/* fprintf(outfile, "%s %s %d %d %d %Lg %Lg %Lg %Lg %d %d\n", az_str, el_str, irandom, ipoly, tries, wcum, rpoly / wcum, area, TWOPI * cmmin / area, ipmin, poly[ipoly]->np); */

    }

    /* advise */
    if (outfile != stdout) {
	msg("ransack: %d random positions written to %s\n", nrandom, out_fn);
    }

    return(nrandom);

    /* error returns */
    error:
    return(-1);
}
예제 #18
0
int 
maxmatch3 (
    struct vtx_data **graph,	/* array of vtx data for graph */
    int nvtxs,		/* number of vertices in graph */
    int *mflag,		/* flag indicating vtx selected or not */
    int using_ewgts		/* are edge weights being used? */
)
{
    extern int HEAVY_MATCH;	/* pick heavy edges in matching? */
    int      *order;		/* random ordering of vertices */
    int      *iptr, *jptr;	/* loops through integer arrays */
    double    prob_sum;		/* sum of probabilities to select from */
    double    val;		/* random value for selecting neighbor */
    float     ewgt;		/* edge weight */
    int       save;		/* neighbor vertex if only one active */
    int       vtx;		/* vertex to process next */
    int       neighbor;		/* neighbor of a vertex */
    int       nmerged;		/* number of edges in matching */
    int       i, j;		/* loop counters */

    double    drandom();
    void      randomize();

    /* First, randomly permute the vertices. */
    iptr = order = smalloc((nvtxs + 1) * sizeof(int));
    jptr = mflag;
    for (i = 1; i <= nvtxs; i++) {
	*(++iptr) = i;
	*(++jptr) = 0;
    }
    randomize(order, nvtxs);

    nmerged = 0;
    if (!using_ewgts || !HEAVY_MATCH) {	/* All edges equal. */
	for (i = 1; i <= nvtxs; i++) {
	    vtx = order[i];
	    if (mflag[vtx] == 0) {	/* Not already matched. */
		/* Add up sum of edge weights of neighbors. */
		prob_sum = 0;
		save = 0;
		for (j = 1; j < graph[vtx]->nedges; j++) {
		    neighbor = graph[vtx]->edges[j];
		    if (mflag[neighbor] == 0) {
			/* Set flag for single possible neighbor. */
			if (prob_sum == 0)
			    save = neighbor;
			else
			    save = 0;
			prob_sum += 1.0;
		    }
		}

		if (prob_sum != 0) {	/* Does vertex have contractible edges? */
		    nmerged++;
		    if (save != 0) {	/* Only one neighbor, special case. */
			mflag[vtx] = save;
			mflag[save] = vtx;
		    }
		    else {	/* Pick randomly neighbor. */
			val = drandom() * prob_sum * .999999;
			prob_sum = 0;
			for (j = 1; !mflag[vtx]; j++) {
			    neighbor = graph[vtx]->edges[j];
			    if (mflag[neighbor] == 0) {
				prob_sum += 1.0;
				if (prob_sum >= val) {
				    mflag[vtx] = neighbor;
				    mflag[neighbor] = vtx;
				}
			    }
			}
		    }
		}
	    }
	}
    }

    else {			/* Choose heavy edges preferentially. */
	for (i = 1; i <= nvtxs; i++) {
	    vtx = order[i];
	    if (mflag[vtx] == 0) {	/* Not already matched. */
		/* Add up sum of edge weights of neighbors. */
		prob_sum = 0;
		save = 0;
		for (j = 1; j < graph[vtx]->nedges; j++) {
		    neighbor = graph[vtx]->edges[j];
		    if (mflag[neighbor] == 0) {
			/* Set flag for single possible neighbor. */
			if (prob_sum == 0)
			    save = neighbor;
			else
			    save = 0;
			ewgt = graph[vtx]->ewgts[j];
			prob_sum += ewgt;
		    }
		}

		if (prob_sum != 0) {	/* Does vertex have contractible edges? */
		    nmerged++;
		    if (save != 0) {	/* Only one neighbor, special case. */
			mflag[vtx] = save;
			mflag[save] = vtx;
		    }
		    else {	/* Pick randomly neighbor, skewed by edge weights. */
			val = drandom() * prob_sum * .999999;
			prob_sum = 0;
			for (j = 1; !mflag[vtx]; j++) {
			    neighbor = graph[vtx]->edges[j];
			    if (mflag[neighbor] == 0) {
				ewgt = graph[vtx]->ewgts[j];
				prob_sum += ewgt;
				if (prob_sum >= val) {
				    mflag[vtx] = neighbor;
				    mflag[neighbor] = vtx;
				}
			    }
			}
		    }
		}
	    }
	}
    }

    sfree(order);
    return (nmerged);
}
예제 #19
0
void
neatstuff(void)
{
	double temp;	/* for temporary calculations */
	int ch;		/* input */

	switch ((int)ROLL(0.0, 100.0)) {
	case 1:
	case 2:
		if (Player.p_poison > 0.0) {
			mvaddstr(4, 0, "You've found a medic!  How much will you offer to be cured ? ");
			temp = floor(infloat());
			if (temp < 0.0 || temp > Player.p_gold) {
				/* negative gold, or more than available */
				mvaddstr(6, 0, "He was not amused, and made you worse.\n");
				Player.p_poison += 1.0;
			} else if (drandom() / 2.0 > (temp + 1.0) / MAX(Player.p_gold, 1))
				/* medic wants 1/2 of available gold */
				mvaddstr(5, 0, "Sorry, he wasn't interested.\n");
			else {
				mvaddstr(5, 0, "He accepted.");
				Player.p_poison = MAX(0.0, Player.p_poison - 1.0);
				Player.p_gold -= temp;
			}
		}
		break;

	case 3:
		mvaddstr(4, 0, "You've been caught raping and pillaging!\n");
		Player.p_experience += 4000.0;
		Player.p_sin += 0.5;
		break;

	case 4:
		temp = ROLL(10.0, 75.0);
		mvprintw(4, 0, "You've found %.0f gold pieces, want them ? ", temp);
		ch = getanswer("NY", FALSE);

		if (ch == 'Y')
			collecttaxes(temp, 0.0);
		break;

	case 5:
		if (Player.p_sin > 1.0) {
			mvaddstr(4, 0, "You've found a Holy Orb!\n");
			Player.p_sin -= 0.25;
		}
		break;

	case 6:
		if (Player.p_poison < 1.0) {
			mvaddstr(4, 0, "You've been hit with a plague!\n");
			Player.p_poison += 1.0;
		}
		break;

	case 7:
		mvaddstr(4, 0, "You've found some holy water.\n");
		++Player.p_holywater;
		break;

	case 8:
		mvaddstr(4, 0, "You've met a Guru. . .");
		if (drandom() * Player.p_sin > 1.0)
			addstr("You disgusted him with your sins!\n");
		else if (Player.p_poison > 0.0) {
			addstr("He looked kindly upon you, and cured you.\n");
			Player.p_poison = 0.0;
		} else {
			addstr("He rewarded you for your virtue.\n");
			Player.p_mana += 50.0;
			Player.p_shield += 2.0;
		}
		break;

	case 9:
		mvaddstr(4, 0, "You've found an amulet.\n");
		++Player.p_amulets;
		break;

	case 10:
		if (Player.p_blindness) {
			mvaddstr(4, 0, "You've regained your sight!\n");
			Player.p_blindness = FALSE;
		}
		break;

	default:		/* deal with poison */
		if (Player.p_poison > 0.0) {
			temp = Player.p_poison * Statptr->c_weakness
			    * Player.p_maxenergy / 600.0;
			if (Player.p_energy > Player.p_maxenergy / 10.0
			    && temp + 5.0 < Player.p_energy)
				Player.p_energy -= temp;
		}
		break;
	}
}
예제 #20
0
void
procmain(void)
{
	int ch;			/* input */
	double x;		/* desired new x coordinate */
	double y;		/* desired new y coordinate */
	double temp;		/* for temporary calculations */
	FILE *fp;		/* for opening files */
	int loop;		/* a loop counter */
	bool hasmoved = FALSE;	/* set if player has moved */

	ch = inputoption();
	mvaddstr(4, 0, "\n\n");	/* clear status area */

	move(7, 0);
	clrtobot();		/* clear data on bottom area of screen */

	if (Player.p_specialtype == SC_VALAR && (ch == '1' || ch == '7'))
		/* valar cannot move */
		ch = ' ';

	switch (ch) {
	case 'K':		/* move up/north */
	case 'N':
		x = Player.p_x;
		y = Player.p_y + MAXMOVE();
		hasmoved = TRUE;
		break;

	case 'J':		/* move down/south */
	case 'S':
		x = Player.p_x;
		y = Player.p_y - MAXMOVE();
		hasmoved = TRUE;
		break;

	case 'L':		/* move right/east */
	case 'E':
		x = Player.p_x + MAXMOVE();
		y = Player.p_y;
		hasmoved = TRUE;
		break;

	case 'H':		/* move left/west */
	case 'W':
		x = Player.p_x - MAXMOVE();
		y = Player.p_y;
		hasmoved = TRUE;
		break;

	default:		/* rest */
		Player.p_energy += (Player.p_maxenergy + Player.p_shield) / 15.0 +
		    Player.p_level / 3.0 + 2.0;
		Player.p_energy =
		    MIN(Player.p_energy, Player.p_maxenergy + Player.p_shield);

		if (Player.p_status != S_CLOAKED) {
			/* cannot find mana if cloaked */
			Player.p_mana += (Circle + Player.p_level) / 4.0;

			if (drandom() < 0.2 && Player.p_status == S_PLAYING && !Throne)
				/* wandering monster */
				encounter(-1);
		}
		break;

	case 'X':		/* change/examine a character */
		changestats(TRUE);
		break;

	case '1':		/* move */
		for (loop = 3; loop; --loop) {
			mvaddstr(4, 0, "X Y Coordinates ? ");
			getstring(Databuf, SZ_DATABUF);

			if (sscanf(Databuf, "%lf %lf", &x, &y) != 2)
				mvaddstr(5, 0, "Try again\n");
			else if (distance(Player.p_x, x, Player.p_y, y) > MAXMOVE())
				ILLMOVE();
			else {
				hasmoved = TRUE;
				break;
			}
		}
		break;

	case '2':		/* players */
		userlist(TRUE);
		break;

	case '3':		/* message */
		mvaddstr(4, 0, "Message ? ");
		getstring(Databuf, SZ_DATABUF);
		/* we open the file for writing to erase any data which is already there */
		fp = fopen(_PATH_MESS, "w");
		if (Databuf[0] != '\0')
			fprintf(fp, "%s: %s", Player.p_name, Databuf);
		fclose(fp);
		break;

	case '4':		/* stats */
		allstatslist();
		break;

	case '5':		/* good-bye */
		leavegame();
		/* NOTREACHED */

	case '6':		/* cloak */
		if (Player.p_level < MEL_CLOAK || Player.p_magiclvl < ML_CLOAK)
			ILLCMD();
		else if (Player.p_status == S_CLOAKED)
			Player.p_status = S_PLAYING;
		else if (Player.p_mana < MM_CLOAK)
			mvaddstr(5, 0, "No mana left.\n");
		else {
			Changed = TRUE;
			Player.p_mana -= MM_CLOAK;
			Player.p_status = S_CLOAKED;
		}
		break;

	case '7':		/* teleport */

		/*
		 * conditions for teleport
		 *	- 20 per (level plus magic level)
		 *	- OR council of the wise or valar or ex-valar
		 *	- OR transport from throne
		 * transports from throne cost no mana
		 */
		if (Player.p_level < MEL_TELEPORT || Player.p_magiclvl < ML_TELEPORT)
			ILLCMD();
		else
			for (loop = 3; loop; --loop) {
				mvaddstr(4, 0, "X Y Coordinates ? ");
				getstring(Databuf, SZ_DATABUF);

				if (sscanf(Databuf, "%lf %lf", &x, &y) == 2) {
					temp = distance(Player.p_x, x, Player.p_y, y);
					if (!Throne
					/* can transport anywhere from throne */
					    && Player.p_specialtype <= SC_COUNCIL
					/* council, valar can transport anywhere */
					    && temp > (Player.p_level + Player.p_magiclvl) * 20.0)
						/* can only move 20 per exp. level + mag. level */
						ILLMOVE();
					else {
						temp = (temp / 75.0 + 1.0) * 20.0;	/* mana used */

						if (!Throne && temp > Player.p_mana)
							mvaddstr(5, 0, "Not enough power for that distance.\n");
						else {
							if (!Throne)
								Player.p_mana -= temp;
							hasmoved = TRUE;
							break;
						}
					}
				}
			}
		break;

	case 'C':
	case '9':		/* monster */
		if (Throne)
			/* no monsters while on throne */
			mvaddstr(5, 0, "No monsters in the chamber!\n");
		else if (Player.p_specialtype != SC_VALAR) {
			/* the valar cannot call monsters */
			Player.p_sin += 1e-6;
			encounter(-1);
		}
		break;

	case '0':		/* decree */
		if (Wizard || (Player.p_specialtype == SC_KING && Throne))
			/* kings must be on throne to decree */
			dotampered();
		else
			ILLCMD();
		break;

	case '8':		/* intervention */
		if (Wizard || Player.p_specialtype >= SC_COUNCIL)
			dotampered();
		else
			ILLCMD();
		break;
	}

	if (hasmoved) {
		/* player has moved -- alter coordinates, and do random monster */
		altercoordinates(x, y, A_SPECIFIC);

		if (drandom() < 0.2 && Player.p_status == S_PLAYING && !Throne)
			encounter(-1);
	}
}
double random() {
    double d = drandom(omp_get_thread_num());
    return d * (rand_high - rand_low) + rand_low;
}
예제 #22
0
int 
maxmatch4 (
    struct vtx_data **graph,	/* array of vtx data for graph */
    int nvtxs,		/* number of vertices in graph */
    int nedges,		/* number of edges in graph */
    int *mflag,		/* flag indicating vtx selected or not */
    int using_ewgts
)
{
    extern int HEAVY_MATCH;	/* try for heavy edges in matching? */
    int      *iptr;		/* loops through integer arrays */
    float    *edgevals;		/* random values for all edges */
    float    *evptr;		/* loops through edgevals */
    double    maxval;		/* largest edge value for a vertex */
    int       neighbor;		/* neighbor of a vertex */
    int       nmerged;		/* number of edges in matching */
    int       change;		/* any new edges in matching? */
    int      *start;		/* start of edgevals list for each vertex */
    int       i, j, k;		/* loop counters */

    double    drandom();

    /* Allocate and initialize space. */
    evptr = edgevals = smalloc(2 * nedges * sizeof(float));

    start = smalloc((nvtxs + 2) * sizeof(int));
    start[1] = 0;
    for (i = 1; i <= nvtxs; i++)
	start[i + 1] = start[i] + graph[i]->nedges - 1;

    /* Assign a random value to each edge. */
    if (!using_ewgts || !HEAVY_MATCH) {	/* All edges are equal. */
	for (i = 1; i <= nvtxs; i++) {
	    for (j = 1; j < graph[i]->nedges; j++) {
		neighbor = graph[i]->edges[j];
		if (neighbor > i) {
		    *evptr = (float) drandom();
		}
		else {		/* Look up already-generated value. */
		    for (k = 1; graph[neighbor]->edges[k] != i; k++);
		    *evptr = edgevals[start[neighbor] + k - 1];
		}
		evptr++;
	    }
	}
    }
    else {			/* Prefer heavy weight edges. */
	for (i = 1; i <= nvtxs; i++) {
	    for (j = 1; j < graph[i]->nedges; j++) {
		neighbor = graph[i]->edges[j];
		if (neighbor > i) {
		    *evptr = (float) graph[i]->ewgts[j] * drandom();
		}
		else {		/* Look up already-generated value. */
		    for (k = 1; graph[neighbor]->edges[k] != i; k++);
		    *evptr = edgevals[start[neighbor] + k - 1];
		}
		evptr++;
	    }
	}
    }

    for (iptr = mflag, i = nvtxs; i; i--)
	*(++iptr) = -(nvtxs + 1);
    nmerged = 0;
    change = TRUE;
    while (change) {
	change = FALSE;

	for (i = 1; i <= nvtxs; i++) {	/* Find largest valued edge of each vtx */
	    if (mflag[i] < 0) {
		maxval = 0.0;
		k = -1;
		evptr = &(edgevals[start[i]]);
		for (j = 1; j < graph[i]->nedges; j++) {
		    if (*evptr > maxval && mflag[graph[i]->edges[j]] < 0) {
			maxval = *evptr;
			k = j;
		    }
		    evptr++;
		}
		if (k == -1)
		    mflag[i] = 0;	/* No neighbors are alive. */
		else {
		    mflag[i] = -graph[i]->edges[k];
		}
	    }
	}

	/* If vtxs agree on largest valued edge, add to independent set. */
	for (i = 1; i <= nvtxs; i++) {
	    if (-mflag[i] > i) {
		if (-mflag[-mflag[i]] == i) {	/* Add edge to independent set. */
		    nmerged++;
		    mflag[i] = -mflag[i];
		    mflag[mflag[i]] = i;
		    change = TRUE;
		}
	    }
	}
    }

    /* Maximal independent set is indicated by corresponding pairs */
    /* of positive values in the mflag array. */
    for (i = 1; i <= nvtxs; i++)
	if (mflag[i] < 0)
	    mflag[i] = 0;

    sfree(start);
    sfree(edgevals);
    return (nmerged);
}
예제 #23
0
파일: nway_klv.c 프로젝트: agrippa/Trilinos
int nway_klv(struct vtx_data **graph,      /* data structure for graph */
             int               nvtxs,      /* number of vtxs in graph */
             struct bilist **  lbuckets,   /* array of lists for bucket sort */
             struct bilist **  rbuckets,   /* array of lists for bucket sort */
             struct bilist *   llistspace, /* list data structure for each vertex */
             struct bilist *   rlistspace, /* list data structure for each vertex */
             int *             ldvals,     /* d-values for each transition */
             int *             rdvals,     /* d-values for each transition */
             int *             sets,       /* processor each vertex is assigned to */
             int               maxdval,    /* maximum d-value for a vertex */
             double *          goal,       /* desired set sizes */
             int               max_dev,    /* largest allowed deviation from balance */
             int **            bndy_list,  /* list of vertices on boundary (0 ends) */
             double *          weightsum   /* sum of vweights in each set (in and out) */
             )
{
  struct bilist **to_buckets;           /* buckets I'm moving to */
  struct bilist **from_buckets;         /* buckets I'm moving from */
  struct bilist * to_listspace;         /* list structure I'm moving to */
  struct bilist * from_listspace;       /* list structure I'm moving from */
  struct bilist * out_list;             /* list of vtxs moved out of separator */
  int *           to_dvals;             /* d-values I'm moving to */
  int *           from_dvals;           /* d-values I'm moving from */
  extern double   kl_bucket_time;       /* time spent in KL bucketsort */
  extern int      KL_BAD_MOVES;         /* # bad moves in a row to stop KL */
  extern int      DEBUG_KL;             /* debug flag for KL */
  extern int      KL_NTRIES_BAD;        /* number of unhelpful passes before quitting */
  extern int      KL_MAX_PASS;          /* maximum # outer KL loops */
  int *           bspace;               /* list of active vertices for bucketsort */
  int *           edges;                /* edge list for a vertex */
  int *           edges2;               /* edge list for a vertex */
  int *           bdy_ptr;              /* loops through bndy_list */
  double          total_weight;         /* weight of all vertices */
  double          partial_weight;       /* weight of vertices not in separator */
  double          ratio;                /* fraction of weight not in separator */
  double          time;                 /* timing parameter */
  double          delta0;               /* largest negative deviation from goal size */
  double          delta1;               /* largest negative deviation from goal size */
  double          left_imbalance = 0.0; /* imbalance if I move to the left */
  double          right_imbalance;      /* imbalance if I move to the right */
  double          balance_val;          /* how imbalanced is it */
  double          balance_best;         /* best balance yet if trying hard */
  int             flag;                 /* condition indicator */
  int             to = -1, from;        /* sets moving into / out of */
  int             rtop, ltop;           /* top of each set of buckets */
  int *           to_top;               /* ptr to top of set moving to */
  int             lvtx, rvtx;           /* next vertex to move left/right */
  int             lweight, rweight;     /* weights of moving vertices */
  int             weightfrom = 0;       /* weight moving out of a set */
  int             list_length;          /* how long is list of vertices to bucketsort? */
  int             balanced;             /* is partition balanced? */
  int             temp_balanced;        /* is intermediate partition balanced? */
  int             ever_balanced;        /* has any partition been balanced? */
  int             bestvtx = -1;         /* best vertex to move */
  int             bestval = -1;         /* best change in value for a vtx move */
  int             vweight;              /* weight of best vertex */
  int             gtotal;               /* sum of changes from moving */
  int             improved;             /* total improvement from KL */
  double          bestg;                /* maximum gtotal found in KL loop */
  double          bestg_min;            /* smaller than any possible bestg */
  int             beststep;             /* step where maximum value occurred */
  int             bestlength;           /* step where maximum value occurred */
  int             neighbor;             /* neighbor of a vertex */
  int             step_cutoff;          /* number of negative steps in a row allowed */
  int             cost_cutoff;          /* amount of negative d-values allowed */
  int             neg_steps;            /* number of negative steps in a row */
  int             neg_cost;             /* decrease in sum of d-values */
  int             vtx;                  /* vertex number */
  int             dval;                 /* dval of a vertex */
  int             group, group2;        /* set that a vertex is assigned to */
  int             left_too_big;         /* is left set too large? */
  int             right_too_big;        /* is right set too large? */
  int             vwgt;                 /* weight of a vertex */
  int             gain;                 /* reduction in separator due to a move */
  int             neighbor2;            /* neighbor of a vertex */
  int             step;                 /* loops through movements of vertices */
  int             parity;               /* sort forwards or backwards? */
  int             done;                 /* has termination criteria been achieved? */
  int             nbad;                 /* number of unhelpful passes in a row */
  int             npass;                /* total number of passes */
  int             nbadtries;            /* number of unhelpful passes before quitting */
  int             enforce_balance;      /* force a balanced partition? */
  int             enforce_balance_hard; /* really force a balanced partition? */
  int             i, j, k;              /* loop counters */

  double seconds(), drandom();
  int    make_sep_list();
  void   bucketsortsv(), clear_dvals(), p1bucket();
  void   removebilist(), movebilist(), add2bilist();

  nbadtries = KL_NTRIES_BAD;

  enforce_balance      = FALSE;
  enforce_balance_hard = FALSE;

  total_weight = goal[0] + goal[1];

  bspace = smalloc_ret((nvtxs + 1) * sizeof(int));

  if (bspace == NULL) {
    return (1);
  }

  bdy_ptr     = *bndy_list;
  list_length = 0;
  while (*bdy_ptr != 0) {
    bspace[list_length++] = *bdy_ptr++;
  }

  sfree(*bndy_list);

  clear_dvals(graph, nvtxs, ldvals, rdvals, bspace, list_length);

  step_cutoff = KL_BAD_MOVES;
  cost_cutoff = maxdval * step_cutoff / 7;
  if (cost_cutoff < step_cutoff)
    cost_cutoff = step_cutoff;

  partial_weight = weightsum[0] + weightsum[1];
  ratio          = partial_weight / total_weight;
  delta0         = fabs(weightsum[0] - goal[0] * ratio);
  delta1         = fabs(weightsum[1] - goal[1] * ratio);
  balanced =
      (delta0 + delta1 <= max_dev) && weightsum[0] != total_weight && weightsum[1] != total_weight;

  bestg_min = -2.0 * nvtxs * maxdval;
  parity    = FALSE;
  nbad      = 0;
  npass     = 0;
  improved  = 0;
  done      = FALSE;
  while (!done) {
    npass++;
    ever_balanced = FALSE;
    balance_best  = delta0 + delta1;

    /* Initialize various quantities. */
    ltop = rtop = 2 * maxdval;

    gtotal     = 0;
    bestg      = bestg_min;
    beststep   = -1;
    bestlength = list_length;
    out_list   = NULL;

    neg_steps = 0;

    /* Compute the initial d-values, and bucket-sort them. */
    time = seconds();
    bucketsortsv(graph, nvtxs, lbuckets, rbuckets, llistspace, rlistspace, ldvals, rdvals, sets,
                 maxdval, parity, bspace, list_length);
    parity = !parity;
    kl_bucket_time += seconds() - time;

    if (DEBUG_KL > 2) {
      printf("After sorting, left buckets:\n");
      p1bucket(lbuckets, llistspace, maxdval);
      printf("              right buckets:\n");
      p1bucket(rbuckets, rlistspace, maxdval);
    }

    /* Now determine the set of vertex moves. */

    for (step = 1;; step++) {

      /* Find the highest d-value in each set. */
      /* But only consider moves from large to small sets, or moves */
      /* in which balance is preserved. */
      /* Break ties in some nonarbitrary manner. */
      bestval = -maxdval - 1;

      partial_weight = weightsum[0] + weightsum[1];
      ratio          = partial_weight / total_weight;
      left_too_big   = (weightsum[0] > (goal[0] + .5 * max_dev) * ratio);
      right_too_big  = (weightsum[1] > (goal[1] + .5 * max_dev) * ratio);

      while (ltop >= 0 && lbuckets[ltop] == NULL) {
        --ltop;
      }
      if (ltop >= 0 && !left_too_big) {
        lvtx           = ((long)lbuckets[ltop] - (long)llistspace) / sizeof(struct bilist);
        lweight        = graph[lvtx]->vwgt;
        rweight        = lweight - (ltop - maxdval);
        weightfrom     = rweight;
        to             = 0;
        bestvtx        = lvtx;
        bestval        = ltop - maxdval;
        partial_weight = weightsum[0] + lweight + weightsum[1] - rweight;
        ratio          = partial_weight / total_weight;
        left_imbalance = max(fabs(weightsum[0] + lweight - goal[0] * ratio),
                             fabs(weightsum[1] - rweight - goal[1] * ratio));
      }

      while (rtop >= 0 && rbuckets[rtop] == NULL) {
        --rtop;
      }
      if (rtop >= 0 && !right_too_big) {
        rvtx            = ((long)rbuckets[rtop] - (long)rlistspace) / sizeof(struct bilist);
        rweight         = graph[rvtx]->vwgt;
        lweight         = rweight - (rtop - maxdval);
        partial_weight  = weightsum[0] - lweight + weightsum[1] + rweight;
        ratio           = partial_weight / total_weight;
        right_imbalance = max(fabs(weightsum[0] - lweight - goal[0] * ratio),
                              fabs(weightsum[1] + rweight - goal[1] * ratio));
        if (rtop - maxdval > bestval || (rtop - maxdval == bestval &&
                                         (right_imbalance < left_imbalance ||
                                          (right_imbalance == left_imbalance && drandom() < .5)))) {
          to         = 1;
          weightfrom = lweight;
          bestvtx    = rvtx;
          bestval    = rtop - maxdval;
        }
      }

      if (bestval == -maxdval - 1) { /* No allowed moves */
        if (DEBUG_KL > 0) {
          printf("No KLV moves at step %d.  bestg = %g at step %d.\n", step, bestg, beststep);
        }
        break;
      }

      if (to == 0) {
        from           = 1;
        to_listspace   = llistspace;
        from_listspace = rlistspace;
        to_dvals       = ldvals;
        from_dvals     = rdvals;
        to_buckets     = lbuckets;
        from_buckets   = rbuckets;
        to_top         = &ltop;
      }
      else {
        from           = 0;
        to_listspace   = rlistspace;
        from_listspace = llistspace;
        to_dvals       = rdvals;
        from_dvals     = ldvals;
        to_buckets     = rbuckets;
        from_buckets   = lbuckets;
        to_top         = &rtop;
      }

      vweight = graph[bestvtx]->vwgt;

      weightsum[to] += vweight;
      weightsum[from] -= weightfrom;

      /* Check if this partition is balanced. */
      partial_weight = weightsum[0] + weightsum[1];
      ratio          = partial_weight / total_weight;
      delta0         = fabs(weightsum[0] - goal[0] * ratio);
      delta1         = fabs(weightsum[1] - goal[1] * ratio);
      temp_balanced  = (delta0 + delta1 <= max_dev) && weightsum[0] != total_weight &&
                      weightsum[1] != total_weight;
      ever_balanced = (ever_balanced || temp_balanced);
      balance_val   = delta0 + delta1;

      gtotal += bestval;

      if ((gtotal > bestg && temp_balanced) ||
          (enforce_balance_hard && balance_val < balance_best)) {
        bestg    = gtotal;
        beststep = step;
        if (balance_val < balance_best) {
          balance_best = balance_val;
        }
        if (temp_balanced) {
          enforce_balance_hard = FALSE;
        }
      }

      if (DEBUG_KL > 1) {
        printf("At KLV step %d, bestvtx=%d, bestval=%d (2->%d), wt0 = %g, wt1 = %g\n", step,
               bestvtx, bestval, to, weightsum[0], weightsum[1]);
      }

      /* Monitor the stopping criteria. */
      if (bestval < 0) {
        if (!enforce_balance || ever_balanced)
          neg_steps++;
        if (bestg != bestg_min)
          neg_cost = bestg - gtotal;
        else
          neg_cost = -maxdval - 1;
        if ((neg_steps > step_cutoff || neg_cost > cost_cutoff) &&
            !(enforce_balance && bestg == bestg_min)) {
          if (DEBUG_KL > 0) {
            if (neg_steps > step_cutoff) {
              printf("KLV step cutoff at step %d.  bestg = %g at step %d.\n", step, bestg,
                     beststep);
            }
            else if (neg_cost > cost_cutoff) {
              printf("KLV cost cutoff at step %d.  bestg = %g at step %d.\n", step, bestg,
                     beststep);
            }
          }
          gtotal -= bestval;
          weightsum[to] -= vweight;
          weightsum[from] += weightfrom;
          break;
        }
      }
      else if (bestval > 0) {
        neg_steps = 0;
      }

      /* Remove vertex from its buckets, and flag it as finished. */
      sets[bestvtx] = to;
      removebilist(&to_listspace[bestvtx], &to_buckets[bestval + maxdval]);
      /*
                  printf("After to removebilist\n");
                  p1bucket(to_buckets, to_listspace, maxdval);
      */

      if (from_dvals[bestvtx] != -maxdval - 1) {
        removebilist(&from_listspace[bestvtx], &from_buckets[from_dvals[bestvtx] + maxdval]);
        /*
                        printf("After from removebilist\n");
                        p1bucket(from_buckets, from_listspace, maxdval);
        */
      }
      from_dvals[bestvtx] = -maxdval - 1;

      /* Now keep track of vertices moved out of separator so */
      /* I can restore them as needed. */
      llistspace[bestvtx].next = out_list;
      out_list                 = &(llistspace[bestvtx]);

      /* Now update the d-values of all the neighbors */
      /* And neighbors of neighbors ... */

      /* If left move:
         1. Separator neighbors right gain => infinity
         2. Left neighbors unaffected.
         3. Right neighbors move into separator.
            A. Right gain = infinity.
            B. Left gain = computed.
            C. For any of their neighbors in separator increase left gain.
      */

      edges = graph[bestvtx]->edges;
      for (j = graph[bestvtx]->nedges - 1; j; j--) {
        neighbor = *(++edges);

        group = sets[neighbor];

        if (group == 2) { /* In separator. */
          gain = from_dvals[neighbor] + maxdval;
          /* Gain in the from direction => -infinity */
          if (gain >= 0) {
            removebilist(&from_listspace[neighbor], &from_buckets[gain]);
            /*
                                    printf("\n  After removing %d\n", neighbor);
                                    p1bucket(from_buckets, from_listspace, maxdval);
            */
            from_dvals[neighbor] = -maxdval - 1;
          }
        }
        else if (group == from) {
          /* Gain in the from direction => -infinity */
          sets[neighbor]       = 2;
          from_dvals[neighbor] = -maxdval - 1;

          if (to == 0) {
            bspace[list_length++] = -neighbor;
          }
          else {
            bspace[list_length++] = neighbor;
          }

          edges2 = graph[neighbor]->edges;
          vwgt   = graph[neighbor]->vwgt;
          gain   = graph[neighbor]->vwgt;
          flag   = FALSE;
          for (k = graph[neighbor]->nedges - 1; k; k--) {
            neighbor2 = *(++edges2);
            group2    = sets[neighbor2];
            if (group2 == 2) {
              dval = to_dvals[neighbor2] + maxdval;
              if (dval >= 0) {
                movebilist(&to_listspace[neighbor2], &to_buckets[dval], &to_buckets[dval + vwgt]);
                /*
                                                printf("\n  After moving %d from bucket %d to bucket
                   %d\n", neighbor2, dval, dval + vwgt);
                                                p1bucket(to_buckets, to_listspace, maxdval);
                */
                to_dvals[neighbor2] += vwgt;
                dval += vwgt;
                if (dval > *to_top) {
                  *to_top = dval;
                }
              }
            }
            else if (group2 == from) {
              gain -= graph[neighbor2]->vwgt;
              if (to_dvals[neighbor2] + maxdval < 0) {
                flag = TRUE;
              }
            }
          }

          if (flag) { /* Not allowed to move further. */
            to_dvals[neighbor] = -maxdval - 1;
          }
          else {
            to_dvals[neighbor] = gain;
            /* place in appropriate bucket */

            gain += maxdval;
            add2bilist(&to_listspace[neighbor], &to_buckets[gain]);
            /*
                                    printf("\nAfter adding %d to bucket %d\n", neighbor, gain -
               maxdval);
                                    p1bucket(to_buckets, to_listspace, maxdval);
            */

            if (gain > *to_top)
              *to_top = gain;
          }
        }
      }
      if (beststep == step) {
        bestlength = list_length;
      }
      if (DEBUG_KL > 2) {
        printf("\n-- After step, left buckets:\n");
        p1bucket(lbuckets, llistspace, maxdval);
        printf("             right buckets:\n");
        p1bucket(rbuckets, rlistspace, maxdval);
      }
    }

    /* Done with a pass; should we actually perform any swaps? */
    if (bestg > 0 || (bestg != bestg_min && !balanced && enforce_balance)) {
      improved += bestg;
    }
    else {
      if (enforce_balance_hard) {
        /* I've done the best I can, give up. */
        done = TRUE;
      }
      if (enforce_balance) {
        enforce_balance_hard = TRUE;
      }
      enforce_balance = TRUE;
      nbad++;
    }

    /* Work backwards, undoing all the undesirable moves. */

    /* First reset vertices moved out of the separator. */
    if (out_list) {
      if (beststep < 0)
        beststep = 0;
      for (i = step - 1; i > beststep; i--) {
        vtx = ((long)out_list - (long)llistspace) / sizeof(struct bilist);
        if (sets[vtx] != 2) {
          weightsum[sets[vtx]] -= graph[vtx]->vwgt;
        }
        sets[vtx] = 2;
        out_list  = out_list->next;
      }
    }

    for (i = list_length - 1; i >= bestlength; i--) {
      vtx = bspace[i];
      if (vtx < 0) {
        if (sets[-vtx] == 2) {
          weightsum[1] += graph[-vtx]->vwgt;
        }
        sets[-vtx] = 1;
      }
      else {
        if (sets[vtx] == 2) {
          weightsum[0] += graph[vtx]->vwgt;
        }
        sets[vtx] = 0;
      }
    }

    partial_weight = weightsum[0] + weightsum[1];
    ratio          = partial_weight / total_weight;
    delta0         = fabs(weightsum[0] - goal[0] * ratio);
    delta1         = fabs(weightsum[1] - goal[1] * ratio);
    balanced       = (delta0 + delta1 <= max_dev) && weightsum[0] != total_weight &&
               weightsum[1] != total_weight;

    done = done || (nbad >= nbadtries && balanced);
    if (KL_MAX_PASS > 0) {
      done = done || (npass == KL_MAX_PASS && balanced);
    }

    if (!done) { /* Rezero dval values. */
      clear_dvals(graph, nvtxs, ldvals, rdvals, bspace, list_length);
    }

    /* Construct list of separator vertices to pass to buckets or return */
    list_length = make_sep_list(bspace, list_length, sets);

    if (done) {
      bspace[list_length] = 0;
      bspace              = srealloc(bspace, (list_length + 1) * sizeof(int));
      *bndy_list          = bspace;
    }

    gain = 0;
    j = k = 0;
    for (i = 1; i <= nvtxs; i++) {
      if (sets[i] == 0)
        j += graph[i]->vwgt;
      else if (sets[i] == 1)
        k += graph[i]->vwgt;
      else if (sets[i] == 2)
        gain += graph[i]->vwgt;
    }
    /*
            printf("\nAfter pass of KLV: sets = %d/%d, sep = %d  (bestg = %g)\n\n\n",
                   j, k, gain, bestg);
    */
  }

  if (DEBUG_KL > 0) {
    printf("   KLV required %d passes to improve by %d.\n", npass, improved);
  }

  return (0);
}
예제 #24
0
파일: rescale.c 프로젝트: RTcmix/RTcmix
/* ----------------------------------------------------------------- main --- */
int
main(int argc, char *argv[])
{
   int         i, replace, result, inswap, outswap;
   int         infd, outfd, intype, outtype, inheadersize, outheadersize;
   int         inclass, outclass, nchans, informat, outformat, srate, nsamps;
   int         limiter, dither, inpeak_uptodate;
   int         nbytes, inbytes, outbytes, durbytes, readbytes, bufcount;
   float       inpeak, specified_peak, desired_peak, actual_peak;
   double      factor, inskip, outskip, dur, empty;
   long        inskipbytes, outskipbytes, len, seeds[2];
   short       outbuf[BUFSIZE];
   float       inbuf[BUFSIZE];
   short       *bufp;
   char        *insfname, *outsfname;
   SFComment   insfc, outsfc;
   struct stat statbuf;

   /* get name of this program */
   progname = strrchr(argv[0], '/');
   if (progname == NULL)
      progname = argv[0];
   else
      progname++;

   if (argc == 1)
      usage();

   insfname = outsfname = NULL;
   replace = dither = inpeak_uptodate = bufcount = 0;
   inskip = outskip = dur = empty = 0.0;
   factor = inpeak = specified_peak = desired_peak = 0.0;

   for (i = 1; i < argc; i++) {
      char *arg = argv[i];

      if (arg[0] == '-') {
         switch (arg[1]) {
            case 'P':
               if (++i >= argc)
                  usage();
               desired_peak = (float)atof(argv[i]);
               break;
            case 'p':
               if (++i >= argc)
                  usage();
               specified_peak = (float)atof(argv[i]);
               break;
            case 'f':
               if (++i >= argc)
                  usage();
               factor = atof(argv[i]);
               break;
            case 'r':
               replace = 1;
               break;
            case 't':
               dither = 1;
               break;
            case 's':
               if (++i >= argc)
                  usage();
               inskip = atof(argv[i]);
               if (inskip < 0.0) {
                  fprintf(stderr, "Input file skip must be >= 0.\n");
                  exit(1);
               }
               break;
            case 'o':
               if (++i >= argc)
                  usage();
               outskip = atof(argv[i]);
               if (outskip < 0.0) {
                  fprintf(stderr, "Output file skip must be >= 0.\n");
                  exit(1);
               }
               break;
            case 'd':
               if (++i >= argc)
                  usage();
               dur = atof(argv[i]);
               if (dur <= 0.0) {
                  fprintf(stderr, "Duration must be greater than zero.\n");
                  exit(1);
               }
               break;
            case 'e':
               if (++i >= argc)
                  usage();
               empty = atof(argv[i]);
               if (empty < 0.0) {
                  fprintf(stderr, "Silence at end must be >= 0.\n");
                  exit(1);
               }
               break;
            default:  
               usage();
         }
      }
      else {
         if (insfname == NULL)
            insfname = arg;
         else if (outsfname == NULL)
            outsfname = arg;
         else
            usage();
      }
   }

   if (insfname == NULL) {
      fprintf(stderr, "You haven't specified an input file.\n");
      exit(1);
   }

   /* Print out the specified options. */

   if (replace)
      printf("Writing over input file.\n");
   if (inskip > 0.0)
      printf("Input skip = %f\n", inskip);
   if (outskip > 0.0)
      printf("Output skip = %f\n", outskip);
   if (dur > 0.0)
      printf("Rescale duration = %f\n", dur);
   if (empty > 0.0)
      printf("Writing %g seconds of silence at end.\n", empty);
   if (factor != 0.0)
      printf("Specified rescale factor = %f\n", factor);
   if (specified_peak > 0.0)
      printf("Specified peak of input file = %f\n", specified_peak);
   if (desired_peak > 0.0) {
      if (factor > 0.0) {
         printf("You specified both a factor and a desired peak ...");
         printf(" ignoring your desired peak.\n");
      }
      else {
         if (desired_peak > 32767.0) {
            printf("Desired peak is out of range ... clamping to 32767.\n");
            desired_peak = 32767.0;
         }
         else
            printf("Desired peak = %f\n", desired_peak);
      }
   }
   else
      desired_peak = 32767.0;
   if (dither)
      printf("Dithering algorithm requested.\n");


   /************************************************************************/
   /* SET UP FILES AND PARAMETERS                                          */
   /************************************************************************/

   /*** Input File *********************************************************/

   infd = open(insfname, O_RDONLY);
   if (infd == -1) {
      perror(progname);
      exit(1);
   }
   if (fstat(infd, &statbuf) == -1) {
      perror(progname);
      exit(1);
   }
   if (!S_ISREG(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) {
      fprintf(stderr, "%s is not a regular file or a link.\n", insfname);
      exit(1);
   }

   result = sndlib_read_header(infd);
   if (result == -1) {
      fprintf(stderr, "Can't read header of %s (%s)\n",
                                                  insfname, strerror(errno));
      exit(1);
   }

   intype = mus_header_type();
   informat = mus_header_format();
   nchans = mus_header_chans();
   srate = mus_header_srate();
   inheadersize = mus_header_data_location();
   inclass = mus_header_data_format_to_bytes_per_sample();

   if (NOT_A_SOUND_FILE(intype) || INVALID_DATA_FORMAT(informat)) {
      fprintf(stderr, "\"%s\" probably not a sound file.\n", insfname);
      exit(1);
   }

   if (sndlib_get_current_header_comment(infd, &insfc) == -1) {
      fprintf(stderr, "Can't read peak stats for input file\n");
      exit(1);
   }

   printf("Input: %s\n", insfname);
   printf("%s", sndlib_print_current_header_stats(infd, &insfc, 2));

   if (!IS_FLOAT_FORMAT(informat))
      printf("NOTE: Input file is not floating point.\n");

   /* Store overall peak, in case we need it later. */
   if (SFCOMMENT_PEAKSTATS_VALID(&insfc)) {
      for (i = 0, inpeak = 0.0; i < nchans; i++) 
         if (insfc.peak[i] > inpeak)
            inpeak = insfc.peak[i];

      /* See if peak stats are up-to-date (i.e., file not modified after
         peak stats timetag).
      */
      inpeak_uptodate = sfcomment_peakstats_current(&insfc, infd);
   }
   if (!inpeak_uptodate)
      printf(BAD_PEAK_LOC_WARNING);   /* output header peak locs unreliable */

   /* Limiter turned on ... unless the rescale factor (whether computed or
      specified by user) multiplied by the input peak is not greater than
      32767, AND we're using up-to-date header peak stats or the input file
      has shorts. (See below.)  ... whew!
   */
   limiter = 1;

   /* If user doesn't give a rescale factor, we need the file (or specified)
      peak to calculate the factor.
   */
   if (factor == 0.0) {
      if (specified_peak) {                  /* use instead of header peak */
         if (inclass == SF_SHORT && specified_peak > 32767) {
            printf("Specified peak exceeds range of input file");
            printf(" ... resetting to 32767.\n");
            specified_peak = 32767.0;
         }
         inpeak = specified_peak;

         /* need sfm for calculating output peak stats at end */
         for (i = 0; i < nchans; i++)
            insfc.peak[i] = specified_peak;
      }
      else {                                 /* use peak from header */
         if (inpeak_uptodate)
            limiter = 0;
         else {
            if (inpeak == 0.0) {
               fprintf(stderr, NO_PEAK_AMP_MSG, progname);
               exit(1);
            }
            printf(STALE_PEAK_STATS_WARNING);
         }
         printf("Peak amplitude of input file is %f.\n", inpeak);
      }
      factor = ((double)desired_peak / (double)inpeak) + DBL_EPSILON;
      printf("Computed rescale factor = %f\n", factor);
   }
   else {
      if (inpeak_uptodate && factor * inpeak <= 32767.0)
         limiter = 0;
   }

   if (inclass == SF_SHORT && factor <= 1.0)
      limiter = 0;

   if (limiter)
      printf("Might get samples out of range ... turning on limiter.\n");


   /*** Output File ********************************************************/

   outclass = SF_SHORT;           /* we always rescale to shorts */

   outformat = IS_BIG_ENDIAN_FORMAT(informat) ?  MUS_BSHORT : MUS_LSHORT;

   /* If input header is a type that sndlib can't write, output to AIFF. */
   if (WRITEABLE_HEADER_TYPE(intype))
      outtype = intype;
   else {
      outtype = MUS_AIFC;
      outformat = MUS_BSHORT;
   }
   if (outtype == MUS_AIFC)
      mus_header_set_aifc(0);                    /* we want AIFF, not AIFC */

   if (replace) {                 /* will open 2 descriptors for same file */
      int      fd;
      FILE     *stream;

      /* Only way to know for sure if headersize will change is to write
         a temp file with the header that would go on the input file when
         the rescale is finished. (Note that even with the same header
         type, the input file may not have the same comment allocation
         that sndlib-savvy cmix maintains.)
      */
      stream = tmpfile();
      fd = fileno(stream);
      if (fd == -1) {
         fprintf(stderr, "Trouble preparing output header\n");
         exit(1);
      }
      if (sndlib_write_header(fd, 0, outtype, outformat, srate, nchans,
                                               NULL, &outheadersize) == -1) {
         fprintf(stderr, "Trouble preparing output header\n");
         exit(1);
      }
      close(fd);
      fclose(stream);  /* deleted automatically, since created with tmpfile */

      outsfname = insfname;
   }
   else {                         /* need to create a new short int file */
      int   fd;

      if (outsfname == NULL) {    /* no filename specified */
         long  size;
         char  suffix[] = ".rescale";

         /* Build and allocate output file name. */
         size = strlen(insfname) + strlen(suffix) + 1;
         if (size > FILENAME_MAX) {
            fprintf(stderr, "Output file name is too long!\n");
            exit(1);
         }
         outsfname = (char *)malloc(size);
         if (!outsfname) {
            perror("Can't malloc output file name");
            exit(1);
         }
         strcpy(outsfname, insfname);
         strcat(outsfname, suffix);
      }

      /* Check that file doesn't exist. */
      result = stat(outsfname, &statbuf);
      if (result == 0 || errno != ENOENT) {
         fprintf(stderr, "\"%s\" already exists.\n", outsfname);
         exit(1);
      }

      /* Create file; prepare and write header. */

      fd = open(outsfname, O_RDWR | O_CREAT | O_TRUNC, 0644);
      if (fd == -1) {
         fprintf(stderr, "Can't create file %s (%s)\n",
                                                  outsfname, strerror(errno));
         exit(1);
      }

      if (sndlib_write_header(fd, 0, outtype, outformat, srate, nchans,
                                               NULL, &outheadersize) == -1) {
         fprintf(stderr, "Trouble writing output header\n");
         exit(1);
      }
      close(fd);                                 /* will reopen just below */
   }

   /* Open a file descriptor for the output file name (which might be the
      same as the input file name).
   */
   outfd = open(outsfname, O_RDWR);
   if (outfd == -1) {
      perror(progname);
      exit(1);
   }

   printf("Writing output to \"%s\"\n", outsfname);


   /*** Seek ***************************************************************/

   inskipbytes = (long)(inskip * srate * nchans * inclass);
   outskipbytes = (long)(outskip * srate * nchans * outclass);

   if (replace) {
      long outlead = (outskipbytes - inskipbytes)
                                           + (outheadersize - inheadersize);
      if ((BUFSIZE * outclass) + outlead > BUFSIZE * inclass) {
         fprintf(stderr, DANGEROUS_OVERWRITE_MSG);
         exit(1);
      }
      if (outskip > 0.0 && inheadersize > outheadersize)
         printf(OVERWRITE_CLICK_WARNING);
   }

   /* make sure it lands on sample block */
   inskipbytes -= inskipbytes % (inclass * nchans);
   if (lseek(infd, inskipbytes + inheadersize, SEEK_SET) == -1) {
      fprintf(stderr, "Bad skip on input file!\n");
      exit(1);
   }

   /* make sure it lands on sample block */
   outskipbytes -= outskipbytes % (outclass * nchans);
   if (lseek(outfd, outskipbytes + outheadersize, SEEK_SET) == -1) {
      fprintf(stderr, "Bad skip on output file!\n");
      exit(1);
   }

#if MUS_LITTLE_ENDIAN
   inswap = IS_BIG_ENDIAN_FORMAT(informat);
   outswap = IS_BIG_ENDIAN_FORMAT(outformat);
#else
   inswap = IS_LITTLE_ENDIAN_FORMAT(informat);
   outswap = IS_LITTLE_ENDIAN_FORMAT(outformat);
#endif


   /************************************************************************/
   /* RESCALE LOOP                                                         */
   /************************************************************************/

   printf("Rescaling....\n");
   fflush(stdout);

#ifdef INPUT_PEAK_CHECK
   actual_peak = inpeak;
#endif

   readbytes = inbytes = BUFSIZE * inclass;
   durbytes = dur * inclass * nchans * srate;

   bufp = (short *)inbuf;

   seeds[0] = 17;      /* seeds for dither */
   seeds[1] = 31;

   while (1) {
      double dblsamp;

      if (dur) {
         if (durbytes <= readbytes)
            inbytes = durbytes;
         durbytes -= inbytes;
      }

      nbytes = read(infd, (char *)inbuf, inbytes);
      if (nbytes == -1) {
         fprintf(stderr, "Read on input file failed (%s)\n", strerror(errno));
         close(infd);
         close(outfd);
         exit(1);
      }
      if (nbytes == 0)                  /* reached EOF -- time to stop */
         break;

      nsamps = nbytes / inclass;
      outbytes = nsamps * outclass;

      if (inswap) {
         if (inclass == SF_FLOAT) {
            for (i = 0; i < nsamps; i++)
               byte_reverse4(&inbuf[i]);
         }
         else {
            for (i = 0; i < nsamps; i++)
               byte_reverse2(&bufp[i]);
         }
      }

      if (limiter) {
         int  samp, clipmax, numclipped;

         clipmax = numclipped = 0;

         if (inclass == SF_FLOAT) {
            for (i = 0; i < nsamps; i++) {
#ifdef INPUT_PEAK_CHECK
               float fabsamp = fabs(inbuf[i]);
               if (fabsamp > actual_peak)
                  actual_peak = fabsamp;
#endif
               /* NB: Assigning to dblsamp seems to be necessary for accuracy.
                  "samp = (int)((double)inbuf[i] * factor)" was NOT always.
               */
               dblsamp = (double)inbuf[i] * factor;
               if (dither)
                  dblsamp += (double)drandom(seeds);
               samp = (int)dblsamp;

               if (samp < -32767) {             /* not -32768 */
                  if (samp < -clipmax)
                     clipmax = -samp;
                  samp = -32767;
                  numclipped++;
               }
               else if (samp > 32767) {
                  if (samp > clipmax)
                     clipmax = samp;
                  samp = 32767;
                  numclipped++;
               }
               outbuf[i] = (short)samp;
            }
         }
         else {                                 /* SF_SHORT */
            for (i = 0; i < nsamps; i++) {
#ifdef INPUT_PEAK_CHECK
               int absamp = ABS(bufp[i]);
               if (absamp > (int)actual_peak)
                  actual_peak = (float)absamp;
#endif
               dblsamp = (double)bufp[i] * factor;
               if (dither)
                  dblsamp += (double)drandom(seeds);
               samp = (int)dblsamp;

               if (samp < -32767) {             /* not -32768 */
                  if (samp < -clipmax)
                     clipmax = -samp;
                  samp = -32767;
                  numclipped++;
               }
               else if (samp > 32767) {
                  if (samp > clipmax)
                     clipmax = samp;
                  samp = 32767;
                  numclipped++;
               }
               outbuf[i] = (short)samp;
            }
         }
         bufcount++;
         if (numclipped) {
            float loc1 = (float)(((bufcount - 1) * BUFSIZE) / nchans)
                                                                / (float)srate;
            float loc2 = (float)((bufcount * BUFSIZE) / nchans) / (float)srate;
            if (outskip > 0.0) {
               loc1 += outskip;
               loc2 += outskip;
            }
            printf("  CLIPPING: %4d samps, max: %d, output time: %f - %f\n",
                   numclipped, clipmax, loc1, loc2);
         }
      }

      else {                                   /* !limiter */
         if (inclass == SF_FLOAT) {
            for (i = 0; i < nsamps; i++) {
#ifdef INPUT_PEAK_CHECK
               float fabsamp = fabs(inbuf[i]);
               if (fabsamp > actual_peak)
                  actual_peak = fabsamp;
#endif
               dblsamp = (double)inbuf[i] * factor;
               if (dither)
                  dblsamp += (double)drandom(seeds);
               outbuf[i] = (short)dblsamp;
            }
         }
         else {                                /* SF_SHORT */
            for (i = 0; i < nsamps; i++) {
#ifdef INPUT_PEAK_CHECK
               int absamp = ABS(bufp[i]);
               if (absamp > (int)actual_peak)
                  actual_peak = (float)absamp;
#endif
               dblsamp = (double)bufp[i] * factor;
               if (dither)
                  dblsamp += (double)drandom(seeds);
               outbuf[i] = (short)dblsamp;
            }
         }
      }

      if (outswap) {
         for (i = 0; i < nsamps; i++)
            byte_reverse2(&outbuf[i]);
      }

      nbytes = write(outfd, (char *)outbuf, outbytes);
      if (nbytes != outbytes) {
         fprintf(stderr, "Write on output file failed  %s\n",
                                      (nbytes == -1) ? strerror(errno) : "");
         close(infd);
         close(outfd);
         exit(1);
      }
   }


   /************************************************************************/
   /* CLEANUP                                                              */
   /************************************************************************/

   close(infd);

   if (empty > 0.0) {                   /* write empty buffers */
      int bytesleft, bufbytes;

      for (i = 0; i < BUFSIZE; i++)
         outbuf[i] = 0;

      bufbytes = BUFSIZE * outclass;
      bytesleft = empty * srate * nchans * outclass;
      outbytes = MIN(bufbytes, bytesleft);

      for ( ; bytesleft > 0; bytesleft -= bufbytes) {
         if (bytesleft < outbytes)
            outbytes = bytesleft;
         if (write(outfd, (char *)outbuf, outbytes) != outbytes) {
            fprintf(stderr, "Bad write on output file!\n");
            close(outfd);
            exit(1);
         }
      }
   }

   if (replace) {
      long pos = lseek(outfd, 0L, SEEK_CUR);
      if (ftruncate(outfd, pos) < 0) 
         fprintf(stderr, "Bad truncation!\n");   /* but keep going */
   }

   for (i = 0; i < nchans; i++) {
      double opk = (double)insfc.peak[i];
#ifdef INPUT_PEAK_CHECK
      if (actual_peak != inpeak)
         opk += (double)(actual_peak - inpeak);
#endif
      opk *= factor;
      outsfc.peak[i] = (short)MIN(opk, 32767.0);
      outsfc.peakloc[i] = insfc.peakloc[i];
   }

   if (replace) {                             /* replace the input header */
      if (sndlib_write_header(outfd, 0, outtype, outformat, srate, nchans,
                                               NULL, &outheadersize) == -1) {
         fprintf(stderr, "Can't write header on \"%s\"\n", outsfname);
         close(outfd);
         exit(1);
      }
   }

   /* Make a text comment giving command line that wrote this file. */
   outsfc.comment[0] = '\0';
   nbytes = MAX_COMMENT_CHARS - 1;
   for (i = 0; i < argc && nbytes > 1; i++) {
      strncat(outsfc.comment, argv[i], nbytes - 1);
      strcat(outsfc.comment, " ");
      nbytes -= strlen(argv[i]);
   }
   outsfc.comment[MAX_COMMENT_CHARS - 1] = '\0';

   /* Write the peak stats and comment. */
   result = sndlib_put_header_comment(outfd, outsfc.peak, outsfc.peakloc,
                                                             outsfc.comment);
   if (result == -1) {
      fprintf(stderr, "Can't write peak stats for \"%s\"\n", outsfname);
      close(outfd);
      exit(1);
   }

   /* Update header for bytes of sound data written. */
   len = lseek(outfd, 0, SEEK_END);
   if (len == -1) {
      perror(progname);
      exit(1);
   }
   if (sndlib_set_header_data_size(outfd, outtype,
                                              len - outheadersize) == -1) {
      fprintf(stderr, "Can't update header data size for \"%s\"\n", outsfname);
      exit(1);
   }

   if (close(outfd) == -1) {
      fprintf(stderr, "Error closing output file (%s)\n", strerror(errno));
      exit(1);
   }

   printf("...done\n");

#ifdef INPUT_PEAK_CHECK
   if (actual_peak != inpeak)
      printf("Actual input peak different from expected: %f\n", actual_peak);
#endif

   return 0;
}
예제 #25
0
int 
maxmatch1 (
    struct vtx_data **graph,	/* array of vtx data for graph */
    int nvtxs,		/* number of vertices in graph */
    int *mflag,		/* flag indicating vtx selected or not */
    int using_ewgts		/* are edge weights being used? */
)
{
    extern int HEAVY_MATCH;	/* choose heavy edges in matching? */
    float     ewgt_max;		/* largest edge weight seen so far */
    int      *jptr;		/* loops through integer arrays */
    int       vtx;		/* vertex to process next */
    int       neighbor;		/* neighbor of a vertex */
    int       nmerged;		/* number of edges in matching */
    int       matched;		/* is a vertex matched yet? */
    int       jsave;		/* best matching edge found so far */
    int       i, j;		/* loop counters */
    double    drandom();

    /* Initialize mflag array. */
    jptr = mflag;
    for (i = nvtxs; i; i--) {
	*(++jptr) = 0;
    }

    nmerged = 0;

    /* Select random starting point in list of vertices. */
    vtx = 1 + drandom() * nvtxs;

    if (!using_ewgts || !HEAVY_MATCH) {	/* Choose first neighbor */
	for (i = nvtxs; i; i--) {
	    if (mflag[vtx] == 0) {	/* Not already matched. */
		/* Select first free edge. */
		matched = FALSE;
		for (j = 1; !matched && j < graph[vtx]->nedges; j++) {
		    neighbor = graph[vtx]->edges[j];
		    if (mflag[neighbor] == 0) {
			mflag[vtx] = neighbor;
			mflag[neighbor] = vtx;
			matched = TRUE;
			nmerged++;
		    }
		}
	    }

	    if (++vtx > nvtxs)
		vtx = 1;
	}
    }

    else {			/* Choose heavy edge neighbor */
	for (i = nvtxs; i; i--) {
	    if (mflag[vtx] == 0) {	/* Not already matched. */
		/* Select heaviest free edge. */
		jsave = 0;
		ewgt_max = 0;
		for (j = 1; j < graph[vtx]->nedges; j++) {
		    neighbor = graph[vtx]->edges[j];
		    if (mflag[neighbor] == 0 && graph[vtx]->ewgts[j] > ewgt_max) {
			ewgt_max = graph[vtx]->ewgts[j];
			jsave = j;
		    }
		}
		if (jsave > 0) {
		    neighbor = graph[vtx]->edges[jsave];
		    mflag[vtx] = neighbor;
		    mflag[neighbor] = vtx;
		    nmerged++;
		}
	    }

	    if (++vtx > nvtxs)
		vtx = 1;
	}
    }

    return (nmerged);
}
예제 #26
0
void Island_Initializer::init_particle(realkind& px, realkind& py, realkind& pz,
		 int& ix, int& iy, int& iz,
		 realkind& vx, realkind& vy, realkind& vz,int ispecies, int iptcl,
		 int nptcls,int ioffset)
{
	// Set Position Values, ifloat = 0-2
//	raised_cos cdf(alpha,1.0/kt);


	double temp_x;


	temp_x = distribution_intrp(drandom(),
			0.0,pdata->nx*pdata->ny,*cdf);

	int itemp = floor(temp_x);
	iy = itemp/pdata->nx ;
	ix = itemp - iy*pdata->nx -1;

	px = drandom();
	py = drandom();
//	int iptcl_new = iptcl;
//

//	int idist = iptcl_new%(pdata->nptcls/2);
//	int ivel = iptcl_new/(pdata->nptcls/2);
//
//	double temp_x;
//
//	if(ispecies == 0)
//		temp_x = distribution_intrp((idist+0.5)/(0.5*pdata->nptcls),0.0,pdata->Lx,cdf);
//	else
//		px = iptcl/(1.0*pdata->nptcls) * pdata->Lx + pdata->xmin;
	//px = box_muller(0.5,0.1);

	///px = ((2.0*iptcl)/((double)pdata->nptcls))*pdata->Lx+pdata->xmin;
	//vx = 1.0*(2*(ivel%2)-1)*(exp(-(ivel/2)/100.0));

	//vx = sqrt(2.0*pdata->Te/(pdata->mspecies[0]*mass_e))
	//	*sqrt(-2.0*log((ivel2+0.5)/((realkind)nv2)))*cos(2.0*3.14159265359*(ivel1)/((realkind)nv1));

	//temp_x = drandom();

	//printf("random number = %f\n",px);

	// Set Velocity Values, ifloat = 3-5

	vx = box_muller(0.0,1.0/sqrt(pdata->mspecies[ispecies]));
	vy = box_muller(0.0,1.0/sqrt(pdata->mspecies[ispecies]));
	vz = B0/(4*pi_const*lambda)*pdata->qspecies[ispecies];


	pz = 0.0;

	iz = 0;

	pz = 0;

	//px = drandom();

	ix = ((ix%pdata->nx)+pdata->nx)%pdata->nx;
	iy = ((iy%pdata->ny)+pdata->ny)%pdata->ny;

//	printf("ix,iy,iz[%i] = %i %i %i\n",iptcl,ix,iy,iz);


}