content: package edu.stanford.rsl.tutorial.motion.estimation;
  import edu.stanford.rsl.conrad.data.numeric.Grid1D;
  import edu.stanford.rsl.conrad.data.numeric.Grid1DComplex;
  import edu.stanford.rsl.conrad.data.numeric.Grid2D;
  import edu.stanford.rsl.conrad.data.numeric.Grid3D;
  import edu.stanford.rsl.conrad.utils.FFTUtil;
  import edu.stanford.rsl.conrad.utils.VisualizationUtil;
  import edu.stanford.rsl.tutorial.filters.GridKernel;
  /**
   * This class implements the 1-D version of a smoothing kernel (1 1 1)
   * @author Marco Boegel
   *
   */
  public class SmoothKernel1D extends Grid1DComplex implements GridKernel {
  	private int width = 0;
  	/**
  	 * 
  	 * @param size
  	 * @param width odd number!
  	 */
  	public SmoothKernel1D(final int size,int width) {
  		super(FFTUtil.getNextPowerOfTwo(size));
  		this.width = width;
  		final int paddedSize = getSize()[0];
  
  		for (int i = 0; i < paddedSize / 2; ++i) {
  				setAtIndex(i, 0 );
  		}
  		for (int i = paddedSize / 2; i < paddedSize ; ++i) {
  				setAtIndex(i, 0);
  		}
  		for(int i = 0; i <= width/2; i++) {
  			setAtIndex(i, 1.f/width);
  		}
  		for(int i = 1; i <= width/2;i++) {
  			setAtIndex(paddedSize-i, 1.f/width);
  		}
  		transformForward();
  	}
  	
  	public Grid1D paddGrid(Grid1D input, int width) {
  		Grid1D out = new Grid1D(input.getSize()[0]+width);
  		int size = input.getSize()[0];
  		for(int i = 0 ; i < width/2; i++) {
  			out.setAtIndex(i, input.getAtIndex(0));
  		}
  		for(int i = width/2; i < width/2+size; i++) {
  			out.setAtIndex(i, input.getAtIndex(i-width/2));
  		}
  		for(int i = width/2+size; i<size+width; i++) {
  			out.setAtIndex(i, input.getAtIndex(size-1));
  		}
  		
  		return out;
  	}
  	/**
  	 * This method implements the Convolution in Fourier Space for a 1-D Grid.
  	 * @param input 1-D Image
  	 */
  	public void applyToGrid(Grid1D input) {
  
  		Grid1D paddedInput = paddGrid(input, width);
  		Grid1DComplex subGrid = new Grid1DComplex(paddedInput);
  		int size = subGrid.getSize()[0];
  		subGrid.transformForward();
  		for (int idx = 0; idx < size; ++idx) {
  			subGrid.multiplyAtIndex(idx, getRealAtIndex(idx),
  					getImagAtIndex(idx));
  		}
  		subGrid.transformInverse();
  
  		Grid1D filteredSinoSub = subGrid.getRealSubGrid(width/2, input.getSize()[0]);
  		for(int i = 0 ; i < input.getSize()[0]; i++) {			
  			input.setAtIndex(i, filteredSinoSub.getAtIndex(i));
  		}
  
  	}
  	
  	/**
  	 * This method implements the Convolution with a 2-D Image by applying the Filter to each 1-D subgrid.
  	 * @param input 2-D Image
  	 */
  	public void applyToGrid(Grid2D input) {
  		
  		int iter = input.getSize()[1];
  		
  		for(int i = 0; i < iter; i++) {
  			applyToGrid(input.getSubGrid(i));
  		}
  	}
  	
  	/**
  	 * This method implements the Convolution with a 3-D Image by applying the Filter recursively to each 2-D subgrid.
  	 * @param input 3-D Image
  	 */
  	public void applyToGrid(Grid3D input) {
  		
  		int iter = input.getSize()[2];
  			
  		for(int i = 0; i < iter; i++) {
  			applyToGrid(input.getSubGrid(i));
  		}
  	}
  
  	public final static void main(String[] args) {
  		final int size = 200;
  		SmoothKernel1D r = new SmoothKernel1D(size,9);
  		Grid1D in = new Grid1D(new float[size]);
  		
  		for(int i= 0 ; i < size; i++) in.setAtIndex(i, 0);
  		int k = 30;
  		for(int i = 0; i< size/2; i++) {
  			in.setAtIndex(i, k);
  		}
  		for(int i = size/2; i < 5*size/8; i++) {
  			in.setAtIndex(i, k);
  		}
  		VisualizationUtil.createPlot("before",in.getBuffer()).show();
  		VisualizationUtil.createPlot("Filter",r.getSubGrid(0, FFTUtil.getNextPowerOfTwo(size)).getBuffer()).show();
  		r.applyToGrid(in);
  		VisualizationUtil.createPlot("after",in.getBuffer()).show();
  		
  	}
  
  }
  /*
   * Copyright (C) 2010-2014 Marco B�gel
   * CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
  */
  