Is interpolation (interp1) better than FIR filtering when rational integers are close to 1? Question
I've been attempting to resample a GPS signal in MATLAB. I've built a few FIR filters using fvatool and from handmade transfer functions (punched out with a HP-35s). Most are kaiser-windowed LPFs, but some are least-squared LPFs. All of the filters I've built have nominal responses that should adequately filter the aliasing out of the interpolations. I've also built a FFT-Resampling tool that resamples well and very quickly. However, I've hit a strange anomoly, at least as I see it. A simple 'nearest' neighbor interpolation using interp1 seems to much more accurately resample my signal than any FFT-Resampling I have done, or any upsample, filter, decimate tool I've used, to include dsp.FIRRateConverter, resample,upfirdn, and even straight upsample, filter,decimate. Why is this? Can anyone explain why this occurs? My theory is that when the rational integers of your sampling ratio are very close to one, straight interpolation will provide more accurate results because you reduce occilations and/or other noise distortion. 

Background
My signal is a standard collected GPS signal, pulled from the air, sampled at 25e6 sps and saved in a binary file using signed 16-bit integers. When pulled into MATLAB (has to be done in chunks due to size) the signal is a complex row vector.

I'm upsampling to 26.25e6 sps, therefore my rational integers p and q are 21 and 20, respectively. To use interp1 I simply build two time vectors:

 t0 = (0:1:numSamples - 1)*1/sampleRate;
 t1 = (0:1:numResamples - 1)*1/resampleRate;


where

 sampleRate= 25e6;
 resampleRate = 26.25e6;
 samplingRatio = resampleRate/sampleRate;
 numSamples = length(s0) % length of my original signal, sampled at 25e6 samples
 numResamples = length(s0)*samplingRatio % length of my sampled signal; should equal length(s1)
 s1 = interp1(t0,s0,t1,'nearest','extrap');


When using a FIR filter, I have used many methods. But the simpliest is to call resample like this (resample is a least squares FIR filter with a kaiser window called through firls that gets pushed through upfirdn):

 s1 = resample(s0,p,q);


where

 [p,q] = rat(resampleRate/sampleRate,1e-12);
You are looking at the wrong metric of "correctness".  Nearest neighbor is introducing significant discontinuities that are showing up as massive quantities of noise in the result.

The problem is that you should be comparing to the result you would have gotten if you had sampled at 26.25MHz in the first place.

Let's try it (sample a 12Hz sine wave at 26 Hz for 2 seconds):

numResamples = 52;
resampleRate = 26;
t1 = (0:1:numResamples - 1) * 1/resampleRate;
s1correct = sin(t1 * 24 * pi);
plot(t1,s1correct);
plot(t1,abs(fft(s1correct)));




Ok.  Now let's see what happened if we had sampled a 12Hz signal at 25Hz, and then interpolate up to 26Hz using matlab's linear interpolation.  (Actually, I'm using Octave because I'm on a machine without matlab today) 

numSamples = 50;
sampleRate = 25;
t0 = (0:1:numSamples - 1) * 1/sampleRate;
s0 = sin(t0 * 24 * pi);
s1linear = interp1(t0, s0, t1, 'linear', 'extrap');
plot(t1,s1linear);
plot(t1,abs(fft(s1linear)));




Pretty good.  Now let's look at nearest neighbor interpolation.

s1nearest = interp1(t0, s0, t1, 'nearest', 'extrap');
plot(t1,s1nearest);
plot(t1,abs(fft(s1nearest)));




It's completely different, and filled with noise at all frequencies!!!  (The "beat pattern" in the nearest neighbor result is the beat pattern from sampling at 25Hz instead of 26Hz.)  The noise is because nearest neighbor is compressing the 12Hz signal to 12.48Hz, and then inserting an extra sample every 26th sample to get us back to 24 peaks.  That extra sample is the discontinuity that is creating all that extra noise.

I think you'll find that cubic interpolation is even better than linear.