Pregunta

I have two variables in a .mat file here: https://www.yousendit.com/download/UW13UGhVQXA4NVVQWWNUQw

testz is a vector of cumulative distance (in meters, monotonically and regularly increasing)

testSDT is a vector of integrated (cumulative) sound wave travel time (in milliseconds) generated using the distance vector and a vector of velocities (there is an intermediate step of creating interval travel times)

Since velocity is a continuously variable function the resulting interval travelt times and also the integrated travel times are non integers and variable in magnitude

What I want is to resample the distance vector at regular time intervals (e.g. 1 ms, 2 ms, ..., n ms)

What makes it difficult is that the maximum travel time, 994.6659, is less than the number of samples in the 2 vectors, therefore it is not straightforward to use interp1. i.e.:

X=testSDT -> 1680 samples

Y=testz -> 1680 samples

XI=[1:1:994] -> 994 samples

This is the code I've come up with. It is a working code and it is not too bad I think.

%% Initial chores
M=fix(max(testSDT));
L=(1:1:M);     

%% Create indices
% this loops finds the samples in the integrated travel time vector
% that are closest to integer milliseconds and their sample number
for i=1:M
  [cl(i) ind(i)] = min(abs(testSDT-L(i)));
  nearest(i) = testSDT(ind(i)); 
end

%% Remove duplicates
% this is necessary to remove duplicates in the index vector (happens in this test). 
% For example: 2.5 ms would be the closest to both 2 ms and 2 ms
[clsst,ia,ic] = unique(nearest);
idx=(ind(ia));

%% Interpolation
% this uses the index vectors to resample the depth vectors at
% integer times
newz=interp1(clsst,testz(idx),[1:1:length(idx)],'cubic')';

As far as I can see there is one issue with this code: I rely on the vector idx as my XI for interpolation. Vector idx is 1 sample shorter than vector ind (one duplicate was removed).

Therefore my new times will stop one millisecond short. This is a very small issue, and duplicate are unlikely but I am wondering if anybody can think of a workaround, or of a different way to approach the problem altogether.

Thank you

¿Fue útil?

Solución

If I understand you correctly, you want to extrapolate to that extra point. you can do this is many ways, one is to add that extra point to the interp1 line. If you have some function you expect to follow your data you can use it by fitting it to the data and then obtaining that extra point or with a tool like fnxtr.

But I have a problem understanding what you want because of the way you used the line. The third argument you use, [1:1:length(idx)], is just the series [1 2 3 ...], usually when interpolating, one uses some vector x_i of points of interest, though I doubt your points of interest happen to be the series of integers 1:length(idx), what you want is just [1:length(idx) xi], where xi is that extra point x-axis value.

EDIT:

Instead of the loop just produce matrix forms out of L and testSDT, then matrix operation is somewhat faster in doing the min(abs(...:

  MM=ones(numel(testSDT),1)*L;
  TT=testSDT*ones(1,numel(L));
  [cl ind]=(min(abs(TT-MM)));
  nearest=testSDT(ind);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top