Ejemplo n.º 1
0
int main(int argc, const char* argv[]) {
   double results[RUN_COUNT];
   int i;
   
   /* Alternatively, we can try this, although I was a bit hesitant given that
    * they each get the same thread ID...*/

   pthread_t p1;

   for (i = 0; i < RUN_COUNT; i++) {

      // Time the creation and joining with a thread.
      double start = TIMER_START;
      pthread_create(&p1, NULL, &exit_self, NULL);
      pthread_join(p1, NULL);
      double stop = TIMER_STOP;
      results[i] = stop - start;
   }

   array_to_csv(results, RUN_COUNT, "threadcreate.csv");
   double res_min = array_min(results, RUN_COUNT);
   printf("Min = %lf\nMin count = %d\n", res_min, occur_of(results, RUN_COUNT, res_min));
   

   return(0);
}
Ejemplo n.º 2
0
// Linearly rescale input such that its values are in the range [0, 1].
void linear_conversion(const float *in, float *out, int l)
{
    float a, b;
    float min = array_min(in, l);
    float max = array_max(in, l);

    // skip the normalization if max = min
    if( max > min + 0.00001){
        a = (1.0 - 0.0) / (max - min);
        b = -a * min;
        for (int i = 0; i < l; i++)
            out[i] = a * in[i] + b;
    }
    else{
        for (int i = 0; i < l; i++)
            out[i] = in[i];
    }
}
Ejemplo n.º 3
0
/*
 * Creates RUN_COUNT threads, 1 at a time and has each record the time to call
 * pthread_equal.
 */
int main(int argc, const char* argv[]) {
   double results[RUN_COUNT];   
   int i;
   
   /* I was a bit hesitant given that they each get the same thread ID...*/
   pthread_t p1;

   // Create threads one at a time and pass them a pointer to record their
   // results.
   for (i = 0; i < RUN_COUNT; i++) {
      pthread_create(&p1, NULL, &time_self, (void*)&results[i]);
      pthread_join(p1, NULL);
   }

   // Print the results to a csv and the minimum to the console.
   array_to_csv(results, RUN_COUNT, "equals.csv");
   double res_min = array_min(results, RUN_COUNT);
   printf("Min = %lf\nMin count = %d\n", res_min, occur_of(results, RUN_COUNT, res_min));

   return(0);
}
Ejemplo n.º 4
0
/** @brief gray 2 Msh
 *
 *      @param in : array of w*h float  
 *      @param out : array of w*h color points in Msh color space (polar Lab)
 *                     ... of 3*w*h float 
 * 
 *
 */
void gray2Msh2rgb(const _myfloat* in, _myfloat* out, int w, int h)
{
    _myfloat M, s, hue,    L, a, b,   x, y, z ;
    _myfloat max = array_max(in, w*h);
    _myfloat min = array_min(in, w*h);
    _myfloat mid = (max + min)/2.0;

    for(int i = 0; i < w*h; i++){
        if ( in[i] < mid ){
            _myfloat a = (in[i] - min) / (mid - min);
            M = 80.0 + (88.0 - 80.0)*a;
            s = 1.08 - 1.08*a;
            hue = 0.50 + (1.061 - 0.5)*a; 
        }else{
            _myfloat a = (in[i] - mid) / (max - mid);
            M = 88.0 + (80.0 - 88.0)*a;
            s = 1.08*a;
            hue = 1.061 + (-1.1 - 1.061)*a;
        }
        Msh2Lab(M, s, hue, &L, &a, &b);
        Lab2xyz(L, a, b, &x, &y, &z);
        xyz2rgb(x, y, z, &out[i], &out[w*h+i], &out[2*w*h+i]);
    }
}
Ejemplo n.º 5
0
/*
** Triangles passed to this function have already been clipped by
** the clip box.
*/
static void render_triangle_1(WILLUSBITMAP *bmap,TRIANGLE2D *srctri,
                              RENDER_COLOR *rcolor,
                              RENDER_COLOR *bgcolor,int render_type)

    {
    TRIANGLE2D *tri,_tri;
    int     row,bottom_row,top_row;

/*
{
int i;
printf("@render_triangle_1\n");
for (i=0;i<4;i++)
printf("%6.4f %6.4f\n",srctri->p[i%3].x*bmap->width,srctri->p[i%3].y*bmap->height);
printf("//nc\n");
}
*/
    if (render_type==RENDER_TYPE_SET)
        {
        render_triangle_2(bmap,srctri,rcolor);
        return;
        }
    tri=&_tri;
    if (tri2d_zero_area(srctri))
        return;
    (*tri)=(*srctri);
    tri2d_sort_ypoints(tri);
    bottom_row = render_row(bmap,tri->p[0].y);
    top_row = render_row(bmap,tri->p[2].y);
    for (row=bottom_row;row<=top_row;row++)
        {
        int     nx,i,j,k,col,left_col,right_col;
        double  y0,y1;
        static double x[9];

// printf("row=%d\n",row);
        y0 = (double)row/bmap->height;
        y1 = (double)(row+1)/bmap->height;
        i=0;
        /* Create array of possible extreme x-coords */
        /* Triangle vertices */
        for (j=0;j<3;j++)
            if (y0<=tri->p[j].y && y1>=tri->p[j].y)
                x[i++] = tri->p[j].x;
        /* Segments intercepting y0 */
        for (j=0;j<2;j++)
            for (k=j+1;k<3;k++)
                if (tri->p[j].y < y0 && tri->p[k].y > y0)
                    x[i++] = p2d_x_intercept(y0,tri->p[j],tri->p[k]);
        /* Segments intercepting y1 */
        for (j=0;j<2;j++)
            for (k=j+1;k<3;k++)
                if (tri->p[j].y < y1 && tri->p[k].y > y1)
                    x[i++] = p2d_x_intercept(y1,tri->p[j],tri->p[k]);
        nx=i;
        left_col  = render_col(bmap,array_min(x,nx));
        right_col = render_col(bmap,array_max(x,nx));
// printf("    %d to %d\n",left_col,right_col);
        for (col=left_col;col<=right_col;col++)
            {
            if (render_type==RENDER_TYPE_ANTIALIASED)
                render_pixelset(bmap,col,row,rcolor,
                       render_type,bgcolor,
                       tri2d_intersection_area(bmap,tri,row,col));
            else
                if (render_pixel_contained(bmap,tri,row,col))
                    render_pixelset(bmap,col,row,rcolor,
                                      render_type,bgcolor,1.);
            }
        }
    }
Ejemplo n.º 6
0
/** @brief Gray to false color (using the HSV colormap)
 *
 *   for DoG illustration in new code
 *
 */
void gray2hsv(const _myfloat *gray, _myfloat *rgb, int w, int h, _myfloat vmin, _myfloat vmax)
{
    // The color wheel used as a colormap here is a restriction of the hsv
    // color space to the circle defined by
    _myfloat saturation = 1.0;
    _myfloat value = 1.0;
    // and hue \in [0,360].

    for (int i = 0; i < 3 * w * h; i++)  rgb[i] = 0;

    _myfloat max = array_max(gray, w*h);
    _myfloat min = array_min(gray, w*h);

    for (int i = 0; i < w * h; i++) {
        _myfloat hue = (gray[i] - min) / (max - min) * 359.0;

        int t = (int) (hue / 60.0);
        _myfloat red, green, blue;
        /*
         * The color map is defined by a set of 3 piecewise linear
         * functions
         */
        switch (t) {
        case 0:
            red = value;
            green =  value * (1.0 - (1.0 - (hue / 60.0 - (_myfloat) t)) * saturation);
            blue = value * (1.0 - saturation);
            break;
        case 1:
            red = value * (1.0 - (hue / 60.0 - (_myfloat) t) * saturation);
            green = value;
            blue = value * (1.0 - saturation);
            break;
        case 2:
            red = value * (1.0 - saturation);
            green = value;
            blue =
                value * (1.0 - (1.0 - (hue / 60.0 - (_myfloat) t)) * saturation);
            break;
        case 3:
            red = value * (1.0 - saturation);
            green = value * (1.0 - (hue / 60.0 - (_myfloat) t) * saturation);
            blue = value;
            break;
        case 4:
            red =  value * (1.0 - (1.0 - (hue / 60.0 - (_myfloat) t)) * saturation);
            green = value * (1.0 - saturation);
            blue = value;
            break;
        case 5:
            red = value;
            green = value * (1.0 - saturation);
            blue = value * (1.0 - (hue / 60.0 - (_myfloat) t) * saturation);
            break;
        default:
            red =0;
            green = 0;
            blue = 0;
            break;
        }
        rgb[i] = 250 * red;
        rgb[w * h + i] = 250 * green;
        rgb[2 * w * h + i] = 250 * blue;
    }
}
Ejemplo n.º 7
0
int main(int argc, char **argv) {
 FILE *fp;
 surfspline_desc sspline;
 int err, npoints, itempart=0;
 int binary_output=FALSE, matlab_output=FALSE, mtv_output=FALSE, interpolate_only=FALSE;
 float fbuf, external_value=0.0;
 DATATYPE f, x, y, xmin, xmax, ymin, ymax, xstep, ystep;
 array index;
 pid_t pid;
 char outname[L_tmpnam], inname[L_tmpnam], **inargs, *infile;

 /*{{{  Read command line args*/
 for (inargs=argv+1; inargs-argv<argc && **inargs=='-'; inargs++) {
  switch(inargs[0][1]) {
   case 'B':
    binary_output=TRUE;
    break;
   case 'I':
    if (inargs[0][2]!='\0') {
     itempart=atoi(*inargs+2);
    }
    break;
   case 'i':
    interpolate_only=TRUE;
    if (inargs[0][2]!='\0') {
     external_value=atof(*inargs+2);
    }
    break;
   case 'M':
    matlab_output=TRUE;
    break;
   case 'm':
    mtv_output=TRUE;
    break;
   default:
    fprintf(stderr, "%s: Ignoring unknown option %s\n", argv[0], *inargs);
    continue;
  }
 }
 if (argc-(inargs-argv)!=3) {
  fprintf(stderr, "Usage: %s array_filename degree npoints\n"
          "Options:\n"
          " -Iitem: Use item number item as z-axis (2+item'th column); default: 0\n"
          " -i[value]: Interpolate only; set external values to value (default: 0.0)\n"
          " -B: Binary output (gnuplot floats)\n"
          " -M: Matlab output (x, y vectors and z matrix)\n"
          " -m: Plotmtv output\n"
  	  , argv[0]);
  return -1;
 }
 infile= *inargs++;
 if ((fp=fopen(infile, "r"))==NULL) {
  fprintf(stderr, "Can't open %s\n", infile);
  return -2;
 }
 array_undump(fp, &sspline.inpoints);
 fclose(fp);
 if (sspline.inpoints.message==ARRAY_ERROR) {
  fprintf(stderr, "Error in array_undump\n");
  return -3;
 }
 if (sspline.inpoints.nr_of_elements<3+itempart) {
  fprintf(stderr, "Not enough columns in array %s\n", *(inargs-1));
  return -3;
 }
 sspline.degree=atoi(*inargs++);;
 npoints=atoi(*inargs++);
 /*}}}  */

 /*{{{  Get the index of qhull point pairs by running qhull*/
 tmpnam(outname); tmpnam(inname);
 if ((pid=fork())==0) {	/* I'm the child */
#define LINEBUF_SIZE 128
  char linebuf[LINEBUF_SIZE];
  array tmp_array;

  /*{{{  Dump xy positions to tmp file inname*/
  tmp_array.nr_of_elements=2;
  tmp_array.nr_of_vectors=sspline.inpoints.nr_of_vectors;
  tmp_array.element_skip=1;
  if (array_allocate(&tmp_array)==NULL) {
   fprintf(stderr, "Error allocating tmp_array\n");
   return -4;
  }
  array_reset(&sspline.inpoints);
  do {
   array_write(&tmp_array, array_scan(&sspline.inpoints));
   array_write(&tmp_array, array_scan(&sspline.inpoints));
   array_nextvector(&sspline.inpoints);
  } while (tmp_array.message!=ARRAY_ENDOFSCAN);
  if ((fp=fopen(inname, "w"))==NULL) {
   fprintf(stderr, "Can't open %s\n", inname);
   return -5;
  }
  array_dump(fp, &tmp_array, ARRAY_ASCII);
  fclose(fp);
  array_free(&tmp_array);
  /*}}}  */

  snprintf(linebuf, LINEBUF_SIZE, "qhull C0 i b <%s >%s", inname, outname);
  execl("/bin/sh", "sh", "-c", linebuf, 0);
#undef LINEBUF_SIZE
 } else {
  wait(NULL);
 }
 unlink(inname);
 if ((fp=fopen(outname, "r"))==NULL) {
  fprintf(stderr, "Can't open %s\n", outname);
  return -6;
 }
 array_undump(fp, &index);
 fclose(fp);
 unlink(outname);
 /*}}}  */

 /*{{{  Find min, max and mean coordinates*/
 array_transpose(&sspline.inpoints);
 array_reset(&sspline.inpoints);
 xmin=array_min(&sspline.inpoints);
 ymin=array_min(&sspline.inpoints);
 array_reset(&sspline.inpoints);
 xmax=array_max(&sspline.inpoints);
 ymax=array_max(&sspline.inpoints);
 array_reset(&sspline.inpoints);
 xmean=array_mean(&sspline.inpoints);
 ymean=array_mean(&sspline.inpoints);
 xstep=(xmax-xmin)/npoints;
 ystep=(ymax-ymin)/npoints;
 array_transpose(&sspline.inpoints);
 array_reset(&sspline.inpoints);
 /*}}}  */

 /*{{{  Copy itempart to 3rd location if necessary*/
 /* Note: For this behavior it is essential that array_surfspline
  * will accept vectors of any size >=3 and only process the first three
  * elements ! */
 if (itempart>0) {
  DATATYPE hold;
  do {
   sspline.inpoints.current_element=2+itempart;
   hold=READ_ELEMENT(&sspline.inpoints);
   sspline.inpoints.current_element=2;
   WRITE_ELEMENT(&sspline.inpoints, hold);
   array_nextvector(&sspline.inpoints);
  } while (sspline.inpoints.message!=ARRAY_ENDOFSCAN);
 }
 /*}}}  */

 /*{{{  Do surface spline*/
 if ((err=array_surfspline(&sspline))!=0) {
  fprintf(stderr, "Error %d in array_surfspline\n", err);
  return err;
 }
 xmin-=xstep; xmax+=2*xstep;
 ymin-=ystep; ymax+=2*ystep;

 if (binary_output) {
  /*{{{  Gnuplot binary output*/
  int n_xval=(xmax-xmin)/xstep+1, n;	/* Number of x values */

  fbuf=n_xval;
  fwrite(&fbuf, sizeof(float), 1, stdout);
  for (fbuf=xmin, n=0; n<n_xval; fbuf+=xstep, n++) {	/* x values */
   fwrite(&fbuf, sizeof(float), 1, stdout);
  }
  for (y=ymin; y<=ymax; y+=ystep) {
   fbuf=y; fwrite(&fbuf, sizeof(float), 1, stdout);
   for (x=xmin, n=0; n<n_xval; x+=xstep, n++) {
    if (interpolate_only && !is_inside(&index, &sspline.inpoints, x, y)) {
     f=external_value;
    } else {
     f=array_fsurfspline(&sspline, x, y);
    }
    fbuf=f; fwrite(&fbuf, sizeof(float), 1, stdout);
   }
  }
  /*}}}  */
 } else if (matlab_output) {
  /*{{{  Matlab output*/
  array xm, ym, zm;
  xm.nr_of_elements=ym.nr_of_elements=1;
  xm.nr_of_vectors=zm.nr_of_elements=(xmax-xmin)/xstep+1;
  ym.nr_of_vectors=zm.nr_of_vectors=(ymax-ymin)/ystep+1;
  xm.element_skip=ym.element_skip=zm.element_skip=1;
  array_allocate(&xm); array_allocate(&ym); array_allocate(&zm);
  if (xm.message==ARRAY_ERROR || ym.message==ARRAY_ERROR || zm.message==ARRAY_ERROR) {
   fprintf(stderr, "Error allocating output arrays\n");
   return -7;
  }
  x=xmin; do {
   array_write(&xm, x);
   x+=xstep;
  } while (xm.message!=ARRAY_ENDOFSCAN);
  y=ymin; do {
   array_write(&ym, y);
   x=xmin; do {
    if (interpolate_only && !is_inside(&index, &sspline.inpoints, x, y)) {
     f=external_value;
    } else {
     f=array_fsurfspline(&sspline, x, y);
    }
    array_write(&zm, f);
    x+=xstep;
   } while (zm.message==ARRAY_CONTINUE);
   y+=ystep;
  } while (zm.message!=ARRAY_ENDOFSCAN);
  array_dump(stdout, &xm, ARRAY_MATLAB);
  array_dump(stdout, &ym, ARRAY_MATLAB);
  array_dump(stdout, &zm, ARRAY_MATLAB);
  array_free(&xm); array_free(&ym); array_free(&zm);
  /*}}}  */
 } else if (mtv_output) {
  /*{{{  Plotmtv output*/
  array zm;
  DATATYPE zmin=FLT_MAX, zmax= -FLT_MAX;
  zm.nr_of_elements=(xmax-xmin)/xstep+1;
  zm.nr_of_vectors=(ymax-ymin)/ystep+1;
  zm.element_skip=1;
  array_allocate(&zm);
  if (zm.message==ARRAY_ERROR) {
   fprintf(stderr, "Error allocating output arrays\n");
   return -7;
  }
  y=ymin; do {
   x=xmin; do {
    if (interpolate_only && !is_inside(&index, &sspline.inpoints, x, y)) {
     f=external_value;
    } else {
     f=array_fsurfspline(&sspline, x, y);
    }
    array_write(&zm, f);
    if (f<zmin) zmin=f;
    if (f>zmax) zmax=f;
    x+=xstep;
   } while (zm.message==ARRAY_CONTINUE);
   y+=ystep;
  } while (zm.message!=ARRAY_ENDOFSCAN);
  /*{{{  Print file header*/
  printf(
  "# Output of Spline_Gridder (C) Bernd Feige 1995\n\n"
  "$ DATA=CONTOUR\n\n"
  "%% toplabel   = \"Spline_Gridder output\"\n"
  "%% subtitle   = \"File: %s\"\n\n"
  "%% interp     = 0\n"
  "%% contfill   = on\n"
  "%% meshplot   = off\n\n"
  "%% xmin = %g  xmax = %g\n"
  "%% ymin = %g  ymax = %g\n"
  "%% zmin = %g  zmax = %g\n"
  "%% nx   = %d\n"
  "%% ny   = %d\n"
  , infile, 
  xmin, xmax, 
  ymin, ymax, 
  zmin, zmax, 
  zm.nr_of_elements, 
  zm.nr_of_vectors);
  /*}}}  */
  array_dump(stdout, &zm, ARRAY_MATLAB);
  array_free(&zm);
  /*}}}  */
 } else {
  /*{{{  Gnuplot output*/
  for (x=xmin; x<=xmax; x+=xstep) {
   for (y=ymin; y<=ymax; y+=ystep) {
    if (interpolate_only && !is_inside(&index, &sspline.inpoints, x, y)) {
     f=external_value;
    } else {
     f=array_fsurfspline(&sspline, x, y);
    }
    printf("%g %g %g\n", x, y, f);
   }
   printf("\n");
  }
  /*}}}  */
 }
 /*}}}  */

 return 0;
}
Ejemplo n.º 8
0
double modelhess(double *A,int N,double *dx,double *L) {
	/*
	 * Algorithm 5.5.1 Dennis, Schnabel, Numerical Methods for Unconstrained Optimization and 
	 * Non-Linear Equations
	 */ 
	 double *U22;
	 double sqrteps,maxdiag,mindiag,maxposdiag,u;
	 double maxoffdiag,maxinp,maxadd;
	 double maxev,minev,offrow,sdd;
	 int step,i,j,k;
	 
	 sqrteps = sqrt((double) FDVAL);
	 
	 U22 = (double*) malloc(sizeof(double) * N * N);
	 
	//scale
	
	for(i = 0;i < N;++i) {
		step = i*N;
		for(j = 0;j < N;++j) {
			A[step+j] /= (dx[i] * dx[j]);
		}
	}
	
	for(i = 0; i < N;++i) {
		U22[i] = A[i+i*N];
	}
	
	maxdiag = array_max(U22,N);
	mindiag = array_min(U22,N);
	
	maxposdiag = 0.0;
	
	if (maxdiag > maxposdiag) {
		maxposdiag = maxdiag;
	}
	
	for(i = 0; i < N;++i) {
		U22[i] = 0.0;
	}
	u = 0.0;
	if (mindiag <= sqrteps*maxposdiag) {
		u = 2 * (maxposdiag - mindiag) * sqrteps - mindiag;
		maxdiag += u;
	}
	k = 0;
	for (i = 0; i < N;++i) {
		for(j = 0;j < N;++j) {
			if (j > i) {
				U22[k] = A[i*N+j];
				k++;
			}
		}
	}
	
	maxoffdiag = array_max_abs(U22,k);
	
	if ( maxoffdiag*(1+2*sqrteps) > maxdiag) {
		u += (maxoffdiag - maxdiag) + 2*sqrteps*maxoffdiag;
		maxdiag = maxoffdiag*(1+2*sqrteps);
	}
	
	if (maxdiag == 0) {
		u = 1;
		maxdiag = 1;
	}
	
	if (u > 0) {
		for(i=0;i < N;++i) {
			A[i*N+i] += u;
		}
	}
	
	if (maxdiag > maxoffdiag / N) {
		maxinp = sqrt(maxdiag);
	} else {
		maxinp = sqrt(maxoffdiag / N);
	}
	
	maxadd = cholmod(A,N,L,maxinp);
	
	if (maxadd > 0) {
		maxev = minev = A[0];
		for(i = 0; i < N;++i) {
			offrow = 0.0;
			step = i*N;
			
			for(j = 0; j < i;++j) {
				offrow += fabs(A[step+j]);
			}
			
			for(j = i+1; j < N;++j) {
				offrow += fabs(A[step+j]);
			}
			
			if (maxev < A[step+i] + offrow) {
				maxev = A[step+i] + offrow;
			}
			if (minev > A[step+i] - offrow) {
				minev = A[step+i] - offrow;
			}
			
		}
		sdd = (maxev - minev) * sqrteps - minev;
		if (sdd < 0) {
			sdd = 0;
		}
		if (maxadd > sdd) {
			u = sdd;
		} else {
			u = maxadd;
		}
		
		for(i = 0; i < N;++i) {
			A[i*N+i] += u; 
		}
	}
	
	maxadd = cholmod(A,N,L,0.0);
	
	//unscale
	
	for(i = 0;i < N;++i) {
		step = i*N;
		for(j = 0;j < N;++j) {
			A[step+j] *= (dx[i] * dx[j]);
		}
	}
	
	for(i = 0;i < N;++i) {
		step = i*N;
		for(j = 0;j < i;++j) {
			L[step+j] *= dx[i];
		}
	}
	
	free(U22);
	
	return maxadd;
	 
}
Ejemplo n.º 9
0
void circEnvelope_append(circEnvelope* env, data_t x) {
	env->time++;
	steps_t r = env->r;
	int width = 2 * r + 1;
	circBuffer_append(env->recentData, x);
	
//	printf("env width, time = %d, %ld\n", width, env->time);
	
	// if we haven't gotten enough data yet to determine the
	// max/min for the first window, just return
	if (env->time < r) return;

	data_t *recentDataEnd = env->recentData->head;
	int offset;

	if (env->time < width -1) {
		offset = (int) env->time;
	} else {
		offset = width - 1;
	}
	data_t *recentDataStart = recentDataEnd - offset;
	
//	printf("t=%ld, tstart=%ld\n", env->time, env->time - offset);
//	array_print_with_name(recentDataStart, offset+1, "recentData");
	
	int recentDataLen = offset +1;
//	printf("recent data len = %d\n", recentDataLen);
	data_t max = array_max(recentDataStart, recentDataLen);
	data_t min = array_min(recentDataStart, recentDataLen);
//	printf("pushing u,l = %.1f, %.1f\n", max, min);
	
	circBuffer_append(env->u, max);
	circBuffer_append(env->l, min);
	
	// if r > 0, we need to fill out the rest of the buffer, which we aren't sure
	// is optimal
	if (r <= 0) return;
	
	data_t uTmp[width];
	data_t lTmp[width];
	build_envelope(recentDataStart,recentDataLen, r, lTmp, uTmp);

	data_t *uEnd = env->u->head;
	data_t *lEnd = env->l->head;
	
	
	data_t uShouldBeTheSame = uTmp[r];
	data_t lShouldBeTheSame = lTmp[r];
	if (uShouldBeTheSame != *uEnd || lShouldBeTheSame != *lEnd) {
		printf("Bro, this doesn't work how you think it does\n");
		printf("uHead, lHead = %.3f, %.3f\n", *uEnd, *lEnd);
		array_print_with_name(uTmp, recentDataLen, "uTmp");
		array_print_with_name(lTmp, recentDataLen, "lTmp");
		exit(1);
	}
//
//	array_print_with_name(uTmp, recentDataLen, "uTmp");
//	array_print_with_name(lTmp, recentDataLen, "lTmp");
	
	memcpy(uEnd+1, uTmp+r+1, r*sizeof(data_t));
	memcpy(lEnd+1, lTmp+r+1, r*sizeof(data_t));
	
//	array_print_with_name(uEnd, r+1, "uPastEnd");
//	array_print_with_name(lTmp, r+1, "lPastEnd");
	
	//TODO create an online version of build_envelope() function using
	//deques to get constant-time updates instead of O(r)
}