I\'ve recently learned how to vectorize a \"simple\" nested loop in a previous question I\'ve asked. However, now I\'m trying also to vectorize the following loop
You were close. The vectorization you proposed indeed follows the (j,k) logic, but doing tril
adds zeros in places where the loop doesn't go into. Using the solution for your previous question (@david's) is not complete as it multiplies all elements including these zero value elements that the loop doesn't go into. My solution to that, is to find these zero elements and replace them with 1 (so simple):
Starting with your code:
B2=tril([ones(8,1)*B']');
B2(2:end,2:end)=2*B2(2:end,2:end);
and following the vectorization shown in the previous question:
s=size(A);
[b,c,d]=ndgrid(I,C,B2);
F=b.*c.*d;
F(F==0)=1; % this is the step that is important for your case.
A=reshape(A,s(1),s(2),[]);
A=bsxfun(@times,A,permute(F(:),[3 2 1]));
A=reshape(A,s);
For the size of A
used in the question this cuts about 50% of the run time, not bad...
In one of your comments to the accepted solution of the previous question, you mentioned that successive bsxfun(@times,..,permute..)
based codes were faster. If that's the case, you can use a similar approach here as well. Here's the code that uses such a pattern alongwith tril
-
B1 = tril(bsxfun(@times,B,[1 ones(1,numel(B)-1).*2]));
v1 = bsxfun(@times,B1, permute(C,[3 2 1]));
v2 = bsxfun(@times,v1, permute(I,[4 3 2 1]));
A = bsxfun(@times,A, permute(v2,[5 6 4 3 1 2]));