Exemple #1
0
double compare(int xsize, int ysize) {
    int ix, iy;
    double max_sq_err;

    cart_vgrid(xsize, ysize, fft_rhot, fftvxt, fftvyt);
    cart_vgrid(xsize, ysize, clt_rhot, cltvxt, cltvyt);

    max_sq_err = 0;
    for (ix=0; ix<=xsize; ix++) {
        for (iy=0; iy<=ysize; iy++) {
            double dx = fftvxt[ix][iy] - cltvxt[ix][iy];
            double dy = fftvyt[ix][iy] - cltvyt[ix][iy];

            double sq_err = dx*dx + dy*dy;
            if (sq_err > max_sq_err) max_sq_err = sq_err;
        }
    }

    return sqrt(max_sq_err);
}
Exemple #2
0
void cart_makecart(double *pointx, double *pointy, int npoints,
		   int xsize, int ysize, double blur)
{
  int s,sp;
  int step;
  double t,h;
  double error,dr;
  double desiredratio;

  /* Calculate the initial density and velocity for snapshot zero */

  cart_density(0.0,0,xsize,ysize);
  cart_vgrid(0,xsize,ysize);
  s = 0;

  /* Now integrate the points in the polygons */

  step = 0;
  t = 0.5*blur*blur;
  h = INITH;

  do {

    /* Do a combined (triple) integration step */

    cart_twosteps(pointx,pointy,npoints,t,h,s,xsize,ysize,&error,&dr,&sp);

    /* Increase the time by 2h and rotate snapshots */

    t += 2.0*h;
    step += 2;
    s = sp;

    /* Adjust the time-step.  Factor of 2 arises because the target for
     * the two-step process is twice the target for an individual step */

    desiredratio = pow(2*TARGETERROR/error,0.2);
    if (desiredratio>MAXRATIO) h *= MAXRATIO;
    else h *= desiredratio;

    /* If no point moved then we are finished */

  } while (dr>0.0);

}
/* Function to do the transformation of the given set of points
 * to the cartogram */
void cart_makecart(double *pointx, double *pointy, int npoints,
				   int xsize, int ysize, double blur)
{
	int i;
	int s,sp;
	int step;
	int done;
	double t,h;
	double error,dr;
	double desiredratio;
	
	/* Calculate the initial density and velocity for snapshot zero */
	
	cart_density(0.0,0,xsize,ysize);
	cart_vgrid(0,xsize,ysize);
	s = 0;
	
	/* Now integrate the points in the polygons */
	
	step = 0;
	t = 0.5*blur*blur;
	h = INITH;
	
	do {
		
		/* Do a combined (triple) integration step */
		
		cart_twosteps(pointx,pointy,npoints,t,h,s,xsize,ysize,&error,&dr,&sp);
		
		/* Increase the time by 2h and rotate snapshots */
		
		t += 2.0*h;
		step += 2;
		s = sp;
		
		/* Adjust the time-step.  Factor of 2 arises because the target for
		 * the two-step process is twice the target for an individual step */
		
		desiredratio = pow(2*TARGETERROR/error,0.2);
		if (desiredratio>MAXRATIO) h *= MAXRATIO;
		else h *= desiredratio;
		
		done = cart_complete(t);
#ifdef PERCENT
		fprintf(stdout,"%i\n",done);
#endif
#ifndef NOPROGRESS
		fprintf(stderr,"  %3i%%  |",done);
		for (i=0; i<done/2; i++) fprintf(stderr,"=");
		for (i=done/2; i<50; i++) fprintf(stderr," ");
		fprintf(stderr,"|\r");
#endif
		
		/* If no point moved then we are finished */
		
	} while (dr>0.0);
	
#ifdef PERCENT
	fprintf(stdout,"\n");
#endif
#ifndef NOPROGRESS
	fprintf(stderr,"  100%%  |==================================================|\n");
#endif
}
/* Function to integrate 2h time into the future two different ways using
 * four-order Runge-Kutta and compare the differences for the purposes of
 * the adaptive step size.  Parameters are:
 *   *pointx = array of x-coords of points
 *   *pointy = array of y-coords of points
 *   npoints = number of points
 *   t = current time, i.e., start time of these two steps
 *   h = delta t
 *   s = snapshot index of the initial time
 *   xsize, ysize = size of grid
 *   *errorp = the maximum integration error found for any polygon vertex for
 *             the complete two-step process
 *   *drp = maximum distance moved by any point
 *   *spp = the snapshot index for the final function evaluation
 */
void cart_twosteps(double *pointx, double *pointy, int npoints,
				   double t, double h, int s, int xsize, int ysize,
				   double *errorp, double *drp, int *spp)
{
	int s0,s1,s2,s3,s4;
	int p;
	double rx1,ry1;
	double rx2,ry2;
	double rx3,ry3;
	double v1x,v1y;
	double v2x,v2y;
	double v3x,v3y;
	double v4x,v4y;
	double k1x,k1y;
	double k2x,k2y;
	double k3x,k3y;
	double k4x,k4y;
	double dx1,dy1;
	double dx2,dy2;
	double dx12,dy12;
	double dxtotal,dytotal;
	double ex,ey;
	double esq,esqmax;
	double drsq,drsqmax;
	
	s0 = s;
	s1 = (s+1)%5;
	s2 = (s+2)%5;
	s3 = (s+3)%5;
	s4 = (s+4)%5;
	
	/* Calculate the density field for the four new time slices */
	
	cart_density(t+0.5*h,s1,xsize,ysize);
	cart_density(t+1.0*h,s2,xsize,ysize);
	cart_density(t+1.5*h,s3,xsize,ysize);
	cart_density(t+2.0*h,s4,xsize,ysize);
	
	/* Calculate the resulting velocity grids */
	
	cart_vgrid(s1,xsize,ysize);
	cart_vgrid(s2,xsize,ysize);
	cart_vgrid(s3,xsize,ysize);
	cart_vgrid(s4,xsize,ysize);
	
	/* Do all three RK steps for each point in turn */
	
	esqmax = drsqmax = 0.0;
	
#pragma omp parallel for default(shared) private(p, rx1, ry1, v1x, v1y, k1x, k1y, v2x, v2y, k2x, k2y, v3x, v3y, k3x, k3y, v4x, v4y, k4x, k4y, dx12, dy12, dx1, dy1, rx2, ry2, dx2, dy2, ex, ey, esq, dxtotal, dytotal, drsq, rx3, ry3)
	for (p = 0; p < npoints; p++) {
		
		rx1 = pointx[p];
		ry1 = pointy[p];
		
		/* Do the big combined (2h) RK step */
		
		cart_velocity(rx1, ry1, s0, xsize, ysize, &v1x, &v1y);
		k1x = 2*h*v1x;
		k1y = 2*h*v1y;
		cart_velocity(rx1+0.5*k1x, ry1+0.5*k1y, s2, xsize, ysize, &v2x, &v2y);
		k2x = 2*h*v2x;
		k2y = 2*h*v2y;
		cart_velocity(rx1+0.5*k2x, ry1+0.5*k2y, s2, xsize, ysize, &v3x, &v3y);
		k3x = 2*h*v3x;
		k3y = 2*h*v3y;
		cart_velocity(rx1+k3x, ry1+k3y, s4, xsize, ysize, &v4x, &v4y);
		k4x = 2*h*v4x;
		k4y = 2*h*v4y;
		
		dx12 = (k1x+k4x+2.0*(k2x+k3x))/6.0;
		dy12 = (k1y+k4y+2.0*(k2y+k3y))/6.0;
		
		/* Do the first small RK step.  No initial call to cart_velocity() is done
		 * because it would be the same as the one above, so there's no need
		 * to do it again */
		
		k1x = h*v1x;
		k1y = h*v1y;
		cart_velocity(rx1+0.5*k1x, ry1+0.5*k1y, s1, xsize, ysize, &v2x, &v2y);
		k2x = h*v2x;
		k2y = h*v2y;
		cart_velocity(rx1+0.5*k2x, ry1+0.5*k2y, s1, xsize, ysize, &v3x, &v3y);
		k3x = h*v3x;
		k3y = h*v3y;
		cart_velocity(rx1+k3x, ry1+k3y, s2, xsize, ysize, &v4x, &v4y);
		k4x = h*v4x;
		k4y = h*v4y;
		
		dx1 = (k1x+k4x+2.0*(k2x+k3x))/6.0;
		dy1 = (k1y+k4y+2.0*(k2y+k3y))/6.0;
		
		/* Do the second small RK step */
		
		rx2 = rx1 + dx1;
		ry2 = ry1 + dy1;
		
		cart_velocity(rx2,ry2,s2,xsize,ysize,&v1x,&v1y);
		k1x = h*v1x;
		k1y = h*v1y;
		cart_velocity(rx2+0.5*k1x,ry2+0.5*k1y,s3,xsize,ysize,&v2x,&v2y);
		k2x = h*v2x;
		k2y = h*v2y;
		cart_velocity(rx2+0.5*k2x,ry2+0.5*k2y,s3,xsize,ysize,&v3x,&v3y);
		k3x = h*v3x;
		k3y = h*v3y;
		cart_velocity(rx2+k3x,ry2+k3y,s4,xsize,ysize,&v4x,&v4y);
		k4x = h*v4x;
		k4y = h*v4y;
		
		dx2 = (k1x+k4x+2.0*(k2x+k3x))/6.0;
		dy2 = (k1y+k4y+2.0*(k2y+k3y))/6.0;
		
		/* Calculate the (squared) error */
		
		ex = (dx1+dx2-dx12)/15;
		ey = (dy1+dy2-dy12)/15;
		esq = ex*ex + ey*ey;
		if (esq > esqmax) {
			esqmax = esq;
		}
		
		/* Update the position of the vertex using the more accurate (two small
		 * steps) result, and deal with the boundary conditions.  This code
		 * does 5th-order "local extrapolation" (which just means taking
		 * the estimate of the 5th-order term above and adding it to our
		 * 4th-order result get a result accurate to the next highest order) */
		
		dxtotal = dx1 + dx2 + ex;   // Last term is local extrapolation
		dytotal = dy1 + dy2 + ey;   // Last term is local extrapolation
		drsq = dxtotal*dxtotal + dytotal*dytotal;
		if (drsq > drsqmax) {
			drsqmax = drsq;
		}
		
		rx3 = rx1 + dxtotal;
		ry3 = ry1 + dytotal;
		
		if (rx3<0) {
			rx3 = 0;
		}
		else if (rx3>xsize) {
			rx3 = xsize;
		}
		if (ry3<0) {
			ry3 = 0;
		}
		else if (ry3>ysize) {
			ry3 = ysize;
		}
		
		pointx[p] = rx3;
		pointy[p] = ry3;
		
	}
	
	*errorp = sqrt(esqmax);
	*drp =  sqrt(drsqmax);
	*spp = s4;
}
Exemple #5
0
void cart_makecart(double *pointx, double *pointy, int npoints,
		   int xsize, int ysize, options_t *options)
{
  int i;
  int s,sp;
  int step;
  int done;
  double t,h,prev_h;
  double error,dr;
  double desiredratio, chosenratio;
  double *pointx_copy, *pointy_copy;

  pointx_copy = malloc(npoints * sizeof(double));
  pointy_copy = malloc(npoints * sizeof(double));

  /* Calculate the initial velocity for snapshot zero */

  cart_vgrid(0, xsize, ysize);
  s = 0;

  /* Now integrate the points in the polygons */

  step = 0;
  t = 0.5*options->blur*options->blur;
  h = INITH;

  do {

    /* Do a combined (triple) integration step */

    memcpy(pointx_copy, pointx, npoints * sizeof(double));
    memcpy(pointy_copy, pointy, npoints * sizeof(double));
    cart_twosteps(pointx, pointy, npoints, t, h, s, xsize, ysize, &error, &dr, &sp);

    while(error > MAXERROR) {
      h /= 2;
      if (options->progress_mode == DETAILED)
        fprintf(stderr, "dr = %g and error = %g, so retrying with h = %g\n", dr, error, h);
    
      memcpy(pointx, pointx_copy, npoints * sizeof(double));
      memcpy(pointy, pointy_copy, npoints * sizeof(double));
      cart_twosteps(pointx,pointy,npoints,t,h,s,xsize,ysize,&error,&dr,&sp);
    }

    /* Increase the time by 2h and rotate snapshots */

    t += 2.0*h;
    step += 2;
    s = sp;

    /* Adjust the time-step.  Factor of 2 arises because the target for
     * the two-step process is twice the target for an individual step */

    desiredratio = pow(2 * TARGETERROR / error, 0.2);
    if (desiredratio > MAXRATIO) chosenratio = MAXRATIO;
    else chosenratio = desiredratio;
    
    prev_h = h;
    if (h * chosenratio <= options->max_h)
      h *= chosenratio;
    else
      fprintf(stderr, "h * chosenratio = %g, which is > max_h = %g\n", h * chosenratio, options->max_h);

    done = cart_complete(t);
    switch (options->progress_mode) {
      case NONE:
        break;
      case NORMAL:
        fprintf(stderr,"  %3i%%  |",done);
        for (i=0; i < done/2; i++) fprintf(stderr,"=");
        for (i=done/2; i < 50; i++) fprintf(stderr," ");
        fprintf(stderr,"|\r");
        break;
      case PERCENT:
        fprintf(stderr, "%i\n",done);
        break;
      case DETAILED:
        fprintf(stderr, "step=%d, t=%g, h=%g, dr=%g, error=%g, done=%d%%\n", step, t, h, dr, error, done);
        break;
    }
    
    /* If no point moved then we are finished */

  } while (dr > 0.0);

  switch (options->progress_mode) {
    case PERCENT:
      fprintf(stderr, "\n");
      break;
    case NORMAL:
      fprintf(stderr,"  100%%  |==================================================|\n");
      break;
    default:
      break;
  }
  
  free(pointx_copy);
  free(pointy_copy);
}