Subset of an array with a moving window
1 view (last 30 days)
Show older comments
I have the following code for computing structure functions. I have provided examples of "ULs" and "UTs" merely for simplicity.
ULs = rand(1,145); % called in from function
UTs = rand(1,145); % called in from function
nrmax = 145; % called in from function, I just happen to be using 145
for nr = 1:nrmax
Nts = numel(ULs); % number of elements
Umat_L = nan(Nts-nr,nr+1); % must be NaN, so zeros() won't work
Umat_T = nan(Nts-nr,nr+1); % must be NaN, so zeros() won't work
for i = 1:(Nts-nr) % this is
Umat_L(i,:)=ULs(i:i+nr); % the for loop
Umat_T(i,:)=UTs(i:i+nr); % I want to remove
end
end
The nested loop thus takes subsets ULs(1:1+nr), then ULs(2:2+nr), ULs(17:17+nr), etc. Is it possible to replicate this subsetting process without using a loop?
It would improve my code run time if I could remove the nested "for i = 1:(Nts-nr)". However, as I see it, there is no way around this because of the nature of the moving window. I tried the following substitution, but it didn't work.
i = (1:Nts-nr);
inr = i + nr;
Umat_L(i,:) = ULs(i:inr);
Umat_T(i,:) = UTs(i:inr);
2 Comments
Rik
on 16 Apr 2021
Many moving window operations can be replaced by movmean and other mov* functions, or by convolutions. The image processing toolbox also contains several useful functions.
Is this code representative of the result you actually want, or is there a further step in calculation?
Accepted Answer
Rik
on 16 Apr 2021
The code below relies on implicit expansion to create an index array, which replicates the results from the inner for-loop. Since your code overwrites the results every iteration, you can also have a substantial speed increase by only doing the last one.
nrmax = 145; % called in from function, I just happen to be using 145
ULs = rand(1,nrmax); % called in from function
UTs = rand(1,nrmax); % called in from function
%tic,toc is only an approximate, use timeit for real performance testing
tic,[Umat_L1,Umat_T1]=fun_original(nrmax,ULs,UTs);toc
tic,[Umat_L2,Umat_T2]=fun_unlooped(nrmax,ULs,UTs);toc
if ~isequal(Umat_L1,Umat_L2) || ~isequal(Umat_T1,Umat_T2)
error('results don''t match')
else
disp('everything OK')
end
function [Umat_L,Umat_T]=fun_original(nrmax,ULs,UTs)
for slowdown=1:100
for nr = 1:nrmax
Nts = numel(ULs); % number of elements
Umat_L = nan(Nts-nr,nr+1); % must be NaN, so zeros() won't work
Umat_T = nan(Nts-nr,nr+1); % must be NaN, so zeros() won't work
for i = 1:(Nts-nr) % this is
Umat_L(i,:)=ULs(i:i+nr); % the for loop
Umat_T(i,:)=UTs(i:i+nr); % I want to remove
end
end
end
end
function [Umat_L,Umat_T]=fun_unlooped(nrmax,ULs,UTs)
for slowdown=1:100
for nr = 1:nrmax
Nts = numel(ULs); % number of elements
ind=( 0:nr ) + ( 1:(Nts-nr) ).';
Umat_L=ULs(ind);
Umat_T=UTs(ind);
end
end
end
More Answers (0)
See Also
Categories
Find more on Structures in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!