Efficient indexing of bounded matrices without for loop

1 次查看(过去 30 天)
Hi there,
I have a matrix of tide data at irregular sub-minute intervals that includes time and water level heights (gMedt). Time is in the first column and water level in the second. I'm basically trying to resample the data to hourly data (tA1 and tA2) from the first available hour to the last available hour in two different ways as follows. Columns 3 and 4 represents the finer resolution time and water level just before the hourly mark and columns 5 and 6 represent the same just after the hourly mark. Column 2 would then be a linear interpolation between the two water levels of Columns 4 and 6.
res = 1/24;
tAst = ceil( gMedt( 1, 1 ) / res ) * res;
tAen = floor( gMedt( end, 1 ) / res ) * res;
tA1 = tAst:res:tAen; tA1 = tA1';
tA2 = tA1;
for i = 1:length( tA1 );
tA1( i, 3 ) = gMedt( numel( gMedt( gMedt( :, 1 ) < tA1( i, 1 ) ) ), 1 );
tA1( i, 4 ) = gMedt( numel( gMedt( gMedt( :, 1 ) < tA1( i, 1 ) ) ), 2 );
tA1( i, 5 ) = gMedt( 1+numel( gMedt( gMedt( :, 1 ) < tA1( i, 1 ) ) ), 1 );
tA1( i, 6 ) = gMedt( 1+numel( gMedt( gMedt( :, 1 ) < tA1( i, 1 ) ) ), 2 );
tA2( i, 3 ) = gMedt( find( gMedt( :, 1 ) < tA2( i, 1 ), ...
1, 'last' ), 1 );
tA2( i, 4 ) = gMedt( find( gMedt( :, 1 ) < tA2( i, 1 ), ...
1, 'last' ), 2 );
tA2( i, 5 ) = gMedt( find( gMedt( :, 1 ) > tA2( i, 1 ), ...
1, 'first' ), 1 );
tA2( i, 6 ) = gMedt( find( gMedt( :, 1 ) > tA2( i, 1 ), ...
1, 'first' ), 2 );
end
Neither of these ways is particularly fast especially since the gMedt variable is 16 million rows long and tA1 and tA2 are 43825 rows long. Is there a way to index the tA matrix by finding the correct gMedt row without a for loop?

采纳的回答

Walter Roberson
Walter Roberson 2016-3-1
Do not repeat the calculations, and do not index when you do not need to.
For example,
mask =
posn = sum(mask); %same as numel( gMedt(mask) )
tA1( i, 3 ) = gMedt( posn, 1 );
tA1( i, 4 ) = gMedt( posn, 2 );
tA1( i, 5 ) = gMedt( 1+posn, 1 );
tA1( i, 6 ) = gMedt( 1+posn, 2 );
This can in turn be shortened to
posn = sum( gMedt( :, 1 ) < tA1( i, 1 ) );
tA1(i, [3 4]) = gMedt( posn, 1:2 );
tA1(i, [5 6]) = gMedt( 1 + posn, 1:2 );
  3 个评论
curoi
curoi 2016-3-6
I don't just want it to produce NaN's, I'd like it to accept NaNs in the input. I've checked the file exchange and there are some functions that will interpolate over NaN inputs. However, what I'd like is the input NaNs to be used as NaN producers. If the output time falls between a NaN input and a non-NaN input time, the water level output should be NaN.

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Multirate Signal Processing 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by