//Extend the image using linear predictive algorithm. For more details please see
//chapter 13.6 of numerical recipes in C, second edition 1992
//http://www.nr.com/oldverswitcher.html
float *extend_image_linear_prediction(float *fringes, int *image_width_ptr, int *image_height_ptr, int extend_by_pixels)
{
	int image_width  = *image_width_ptr;
	int image_width_new  = *image_width_ptr + 2 * extend_by_pixels;
	int image_height = *image_height_ptr;
	int i, j;
	float *extended_fringes = (float *) calloc( image_width_new * image_height, sizeof(float) );

	//add zero padding to the right and left of the image (zero padding)
	for (i=0; i < image_height; ++i)
	{
		for (j=extend_by_pixels; j < image_width_new - extend_by_pixels; ++j)
		{
			extended_fringes[i*image_width_new + j] = fringes[i*image_width + j - extend_by_pixels];			
		}
	}

	//predict the right border of the image
	int no_of_coeffs = 100;
	float error = 0; 
	float *coeffs = vector(1,no_of_coeffs);

	for (i=0; i < image_height; ++i)
	{
		memcof(extended_fringes + i*image_width_new + extend_by_pixels - 1, image_width, no_of_coeffs, &error, coeffs);
		predic(extended_fringes + i*image_width_new + extend_by_pixels - 1, image_width, coeffs, no_of_coeffs, 
			extended_fringes + i*image_width_new + extend_by_pixels + image_width - 1, extend_by_pixels);
	}

	//predict the left border of the image
	for (i=0; i < image_height; ++i)
	{
		flipLRrow(extended_fringes + i*image_width_new, image_width_new);
		memcof(extended_fringes + i*image_width_new + extend_by_pixels - 1, image_width, no_of_coeffs, &error, coeffs);
		predic(extended_fringes + i*image_width_new + extend_by_pixels - 1, image_width, coeffs, no_of_coeffs, 
			extended_fringes + i*image_width_new + extend_by_pixels + image_width - 1, extend_by_pixels);
		flipLRrow(extended_fringes + i*image_width_new, image_width_new);

	}

	
	//Update the image width and free allocated memory
	*image_width_ptr = image_width_new;
	free(fringes);
	free_vector(coeffs, 1, no_of_coeffs+1);

	return extended_fringes;
}
int main(void)
{
	int i;
	float dum,*d,*future,*data;

	d=vector(1,NPOLES);
	future=vector(1,NFUT);
	data=vector(1,NPTS);
	for (i=1;i<=NPTS;i++)
		data[i]=f(i,NPTS);
	memcof(data,NPTS,NPOLES,&dum,d);
	fixrts(d,NPOLES);
	predic(data,NPTS,d,NPOLES,future,NFUT);
	printf("%6s %11s %12s\n","I","Actual","PREDIC");
	for (i=1;i<=NFUT;i++)
		printf("%6d %12.6f %12.6f\n",i,f(i+NPTS,NPTS),future[i]);
	free_vector(data,1,NPTS);
	free_vector(future,1,NFUT);
	free_vector(d,1,NPOLES);
	return 0;
}