Code covered by the BSD License  

Highlights from
fft_upsample

from fft_upsample by Ohad Gal
Upsamples a complex series to form time domain interpolation for a fixed spaced grid.

fft_upsample( in_m,upsample_factor )
function out_m = fft_upsample( in_m,upsample_factor )
%
% fft_upsample  -   upsamples a given input "in_m" by an INTEGER factor using the Fourier Domain
%
% Format:   out_m = fft_upsample( in_m,upsample_factor )
%
% Input:    in_m            -   a given distribution to be upsampled
%           upsample_factor -   upsampling factor (integer, rounding towards zero if not) 
%
% Output:   out_m           -   the given distribution upsampled by factor: floor(upsample_factor)
%


% 
% Theory:   the upsampling is done by zero-padding in the input domain BETWEEN the samples,
%           then at the fourier domain, taking the single spectrum (out of the repetition of spectrums)
%           i.e. low pass with Fcutoff=PI/upsample_factor, zeroing the rest of the spectrum
%           and then doing ifft to the distribution.
%           since we have a zero padding operation in time, we need to multiply by the fourier gain.
%
%              +-----------+     +-------+     +---------+     +--------+     +--------+
%   y[n,m] --> | up-sample | --> |  FFT  | --> |   LPF   | --> | * Gain | --> |  IFFT  | --> interpolated 
%              | factor M  |     +-------+     | Fc=PI/M |     +--------+     +--------+
%              +-----------+                   +---------+
%
%           this operation is the same as the following one (which has less operations):
%
%              +-------+     +--------+     +--------------+     +--------+
%   y[n,m] --> |  FFT  | --> | * Gain | --> | Zero Padding | --> |  IFFT  | --> interpolated 
%              +-------+     +--------+     +--------------+     +--------+
%
%           NOTE THAT, the zero-padding must be such that the D.C. ferquency remains the D.C. frequency
%           and that the zero padding is applied to both positive and negative frequencies. 
%           The zero padding actually condences the frequency -> which yields a longer series in the 
%           image domain, but without any additional information, thus the operation must be an interpolation.
%
%           We would like to interpolate the data BETWEEN the samples of the given distribution
%           therefore, the output array should be of size: (input_array_size-1)*up_sample_factor + 1
%


% do rounding
upsample_factor = floor( upsample_factor + 10*eps );

% calculate target sizes
initial_x_size  = size(in_m,2);
initial_y_size  = size(in_m,1);
target_x_size   = initial_x_size*upsample_factor;
target_y_size   = initial_y_size*upsample_factor;
fourier_gain    = (upsample_factor*upsample_factor);

% calculate user sizes
center_x    = floor(target_x_size/2);
center_y    = floor(target_y_size/2);
span_x      = [1:initial_x_size]-ceil(initial_x_size/2);
span_y      = [1:initial_y_size]-ceil(initial_y_size/2);

% transform to fourier domain
spectrum_m = fftshift( fft2( in_m )*fourier_gain );

% zero padding (=condensing the frequency domain)
padded_specturm_m = zeros( target_y_size,target_x_size );
padded_specturm_m( center_y+span_y+1,center_x+span_x+1 ) = spectrum_m; 

% inverse transform to reveal the interpolated series in space domain. 
out_m = ifft2( ifftshift( padded_specturm_m ) );

% we want values which are ONLY between the given points (interpolation and not extrapolation)
out_m = out_m(1:end-upsample_factor+1,1:end-upsample_factor+1);

Contact us at files@mathworks.com