コード例 #1
0
ファイル: phaselock.c プロジェクト: nhanh0/hah
int contemplate_data(unsigned int absolute, double skew, double errorbar, int freq)
{
	/*  Here is the actual phase lock loop.
	 *  Need to keep a ring buffer of points to make a rational
	 *  decision how to proceed.  if (debug) print a lot.
	 */
	static int rp=0, valid=0;
	int both_sides_now=0;
	int j, n, c, max_avail, min_avail, dinit;
	int nextj=0;	/* initialization not needed; but gcc can't figure out my logic */
	double cum;
	struct _seg check, save_min, save_max;
	double last_slope;
	int delta_freq;
	double delta_f;
	int inconsistent=0, max_imax, max_imin=0, min_imax, min_imin=0;
	int computed_freq=freq;

	if (debug) printf("xontemplate %u %.1f %.1f %d\n",absolute,skew,errorbar,freq);
	d_ring[rp].absolute = absolute;
	d_ring[rp].skew     = skew;
	d_ring[rp].errorbar = errorbar - 800.0;   /* quick hack to speed things up */
	d_ring[rp].freq     = freq;

	if (valid<RING_SIZE) ++valid;
	if (valid==RING_SIZE) {
		/*
		 * Pass 1: correct for wandering freq's */
		cum = 0.0;
		if (debug) printf("\n");
		for (j=rp; ; j=n) {
			d_ring[j].s.s.max = d_ring[j].skew - cum + d_ring[j].errorbar;
			d_ring[j].s.s.min = d_ring[j].skew - cum - d_ring[j].errorbar;
			if (debug) printf("hist %d %d %f %f %f\n",j,d_ring[j].absolute-absolute,
				cum,d_ring[j].s.s.min,d_ring[j].s.s.max);
			n=next_dn(j);
			if (n == rp) break;
			/* Assume the freq change took place immediately after
			 * the data was taken; this is valid for the case where
			 * this program was responsible for the change.
			 */
			cum = cum + (d_ring[j].absolute-d_ring[n].absolute) *
				(double)(d_ring[j].freq-freq)/65536;
		}
		/*
		 * Pass 2: find the convex down envelope of s.max, composed of
		 * line segments in s.max vs. absolute space, which are
		 * points in freq vs. dt space.  Find points in order of increasing
		 * slope == freq */
		dinit=1; last_slope=-100;
		for (c=1, j=next_up(rp); ; j=nextj) {
			nextj = search(rp, j, 1, 1, 0, &maxseg[c]);
			        search(rp, j, 0, 1, 1, &check);
			if (check.slope < maxseg[c].slope && check.slope > last_slope &&
			    (dinit || check.slope < save_min.slope)) {dinit=0; save_min=check; }
			if (debug) printf("maxseg[%d] = %f *x+ %f\n",
				 c, maxseg[c].slope, maxseg[c].offset);
			last_slope = maxseg[c].slope;
			c++;
			if (nextj == rp) break;
		}
		if (dinit==1) inconsistent=1;
		if (debug && dinit==0) printf ("mincross %f *x+ %f\n", save_min.slope, save_min.offset);
		max_avail=c;
		/*
		 * Pass 3: find the convex up envelope of s.min, composed of
		 * line segments in s.min vs. absolute space, which are
		 * points in freq vs. dt space.  These points are found in
		 * order of decreasing slope. */
		dinit=1; last_slope=+100.0;
		for (c=1, j=next_up(rp); ; j=nextj) {
			nextj = search(rp, j, 0, 0, 1, &minseg[c]);
			        search(rp, j, 1, 0, 0, &check);
			if (check.slope > minseg[c].slope && check.slope < last_slope &&
			    (dinit || check.slope < save_max.slope)) {dinit=0; save_max=check; }
			if (debug) printf("minseg[%d] = %f *x+ %f\n",
				 c, minseg[c].slope, minseg[c].offset);
			last_slope = minseg[c].slope;
			c++;
			if (nextj == rp) break;
		}
		if (dinit==1) inconsistent=1;
		if (debug && dinit==0) printf ("maxcross %f *x+ %f\n", save_max.slope, save_max.offset);
		min_avail=c;
		/*
		 * Pass 4: splice together the convex polygon that forms
		 * the envelope of slope/offset coordinates that are consistent
		 * with the observed data.  The order of calls to polygon_point
		 * doesn't matter for the frequency shift determination, but
		 * the order chosen is nice for visual display. */
		if (!inconsistent) {
		polygon_reset();
		polygon_point(&save_min);
		for (dinit=1, c=1; c<max_avail; c++) {
			if (dinit && maxseg[c].slope > save_min.slope) {
				max_imin = c-1;
				maxseg[max_imin] = save_min;
				dinit = 0;
			}
			if (maxseg[c].slope > save_max.slope)
				break;
			if (dinit==0) polygon_point(&maxseg[c]);
		}
		if (dinit && debug) printf("found maxseg vs. save_min inconsistency\n");
		if (dinit) inconsistent=1;
		max_imax = c;
		maxseg[max_imax] = save_max;

		polygon_point(&save_max);
		for (dinit=1, c=1; c<min_avail; c++) {
			if (dinit && minseg[c].slope < save_max.slope) {
				max_imin = c-1;
				minseg[min_imin] = save_max;
				dinit = 0;
			}
			if (minseg[c].slope < save_min.slope)
				break;
			if (dinit==0) polygon_point(&minseg[c]);
		}
		if (dinit && debug) printf("found minseg vs. save_max inconsistency\n");
		if (dinit) inconsistent=1;
		min_imax = c;
		minseg[min_imax] = save_max;

		/* not needed for analysis, but shouldn't hurt either */
		if (debug) polygon_point(&save_min);
		} /* !inconsistent */

		/*
		 * Pass 5: decide on a new freq */
		if (inconsistent) {
			printf("# inconsistent\n");
		} else {
			delta_f = find_df(&both_sides_now);
			if (debug) printf("find_df() = %e\n", delta_f);
			delta_f += find_df_center(&save_min,&save_max, delta_f);
			delta_freq = delta_f*65536+.5;
			if (debug) printf("delta_f %f  delta_freq %d  bsn %d\n", delta_f, delta_freq, both_sides_now);
			computed_freq -= delta_freq;
			printf ("# box [( %.3f , %.1f ) ",  save_min.slope, save_min.offset);
			printf (      " ( %.3f , %.1f )] ", save_max.slope, save_max.offset);
			printf (" delta_f %.3f  computed_freq %d\n", delta_f, computed_freq);

			if (computed_freq < -6000000) computed_freq=-6000000;
			if (computed_freq >  6000000) computed_freq= 6000000;
		}
	}
	rp = (rp+1)%RING_SIZE;
	return computed_freq;
}
コード例 #2
0
ファイル: cubism.c プロジェクト: AjayRamanathan/gegl
static gboolean
process (GeglOperation       *operation,
         GeglBuffer          *input,
         GeglBuffer          *output,
         const GeglRectangle *result,
         gint                 level)
{
  GeglChantO              *o            = GEGL_CHANT_PROPERTIES (operation);
  GeglOperationAreaFilter *op_area      = GEGL_OPERATION_AREA_FILTER (operation);
  GeglRectangle            boundary     = get_effective_area (operation);
  GeglRectangle            extended;
  const Babl              *format       = babl_format ("RGBA float");

  GRand  *gr = g_rand_new_with_seed (o->seed);
  gfloat  color[4];
  gint    cols, rows, num_tiles, count;
  gint   *random_indices;
  gfloat *dst_buf;

  Polygon poly;
  gint    i;

  extended.x      = CLAMP (result->x - op_area->left, boundary.x, boundary.x +
                           boundary.width);
  extended.width  = CLAMP (result->width + op_area->left + op_area->right, 0,
                           boundary.width);
  extended.y      = CLAMP (result->y - op_area->top, boundary.y, boundary.y +
                           boundary.width);
  extended.height = CLAMP (result->height + op_area->top + op_area->bottom, 0,
                           boundary.height);

  dst_buf = g_new0 (gfloat, extended.width * extended.height * 4);

  cols = (result->width + o->tile_size - 1) / o->tile_size;
  rows = (result->height + o->tile_size - 1) / o->tile_size;

  num_tiles = (rows + 1) * (cols + 1);

  random_indices = g_new0 (gint, num_tiles);

  for (i = 0; i < num_tiles; i++)
    random_indices[i] = i;

  randomize_indices (num_tiles, random_indices, gr);

  for (count = 0; count < num_tiles; count++)
    {
      gint i, j, ix, iy;
      gdouble x, y, width, height, theta;

      i = random_indices[count] / (cols + 1);
      j = random_indices[count] % (cols + 1);

      x = j * o->tile_size + (o->tile_size / 4.0)
        - g_rand_double_range (gr, 0, (o->tile_size /2.0)) + result->x;

      y = i * o->tile_size + (o->tile_size / 4.0)
        - g_rand_double_range (gr, 0, (o->tile_size /2.0)) + result->y;

      width  = (o->tile_size +
                g_rand_double_range (gr, -o->tile_size / 8.0, o->tile_size / 8.0))
        * o->tile_saturation;

      height = (o->tile_size +
                g_rand_double_range (gr, -o->tile_size / 8.0, o->tile_size / 8.0))
        * o->tile_saturation;

      theta = g_rand_double_range (gr, 0, 2 * G_PI);

      polygon_reset (&poly);
      polygon_add_point (&poly, -width / 2.0, -height / 2.0);
      polygon_add_point (&poly,  width / 2.0,  -height / 2.0);
      polygon_add_point (&poly,  width / 2.0,   height / 2.0);
      polygon_add_point (&poly, -width / 2.0,  height / 2.0);
      polygon_rotate (&poly, theta);
      polygon_translate (&poly, x, y);

      ix = CLAMP (x, boundary.x, boundary.x + boundary.width - 1);
      iy = CLAMP (y, boundary.y, boundary.y + boundary.height - 1);

      gegl_buffer_sample (input, ix, iy, NULL, color, format,
                          GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);

      fill_poly_color (&poly, &extended, &boundary, dst_buf, color);
    }

  gegl_buffer_set (output, &extended, 0, format, dst_buf, GEGL_AUTO_ROWSTRIDE);

  g_free (dst_buf);
  g_free (random_indices);
  g_free (gr);

  return TRUE;
}