Improving MATLAB code ideas? - cells and matrices
이전 댓글 표시
Hello!
I have 2 sets of 2 matrices: a1,a2 and b1,b2. I calculate then c1 to c4 which are
c1=a1*b1
c2=a1*b2
c3=a2*b1
c4=a2*b2
I can also do this with cells and with for loops:
for j=1:2
for i=1:2
C{i,j}=A{i}*B{j};
end
end
where I have prealocated the cells and defined the cell A to contain all the elements in the set. Now the thing is, that the second way, because it uses for loops is twice as slow as the first method, but the first method (where I type every combination is not flexible because if the elements in a and b increase, I have to type it manually.
Do you know a third way, where I do not face this tradeoff between efficiency versus flexibility? Any ideas?
Much appreciated!
댓글 수: 14
Robert Cumming
2012년 4월 3일
The second method is faster for me...
Boris
2012년 4월 3일
Boris
2012년 4월 3일
Robert Cumming
2012년 4월 3일
Wither your code:
Elapsed time is 0.004131 seconds.
Elapsed time is 0.007464 seconds.
Elapsed time is 0.006580 seconds.
So not twice as slow but still slower... Its still not really slow though... Are you doing a lot of these?
Boris
2012년 4월 3일
Boris
2012년 4월 3일
Daniel Shub
2012년 4월 4일
Timing things that take between 6 and 12 ms (or even worse 4 and 8 ms) is not that reliable. You should adjust your matrix and loop sizes so things that a reasonable amount of time (i.e., at least a second).
Boris
2012년 4월 4일
Daniel Shub
2012년 4월 4일
Yes, timing short things is problematic with a nonrealtime OS. It is possible, even probable, that your OS can do something that adds a few ms to a computation. The resolution of the clock used by tic/toc is finite and on the order of milliseconds.
Boris
2012년 4월 4일
Daniel Shub
2012년 4월 4일
My comment really had nothing to do with the question, just your way of timing things. The 15 min vs 30 min real world difference is what matters. I haven't looked at what is causing the slow down. To really evaluate the efficiency of things it helps to know the sizes of the matrices, their classes (e.g., double), the number of loops, etc. What is fast for small matrices might not be fast for large matrices.
Boris
2012년 4월 5일
Sean de Wolski
2012년 4월 5일
Boris, my code below _will_ do this for you. You just have to tell us how you're generating a1,a2...
If these are outputs from a function call or a data read, then this is simple. Stack the results into matrices similar to what I did below as you generate them (rather than generating a1, a2, ... an).
Boris
2012년 4월 10일
답변 (2개)
Jonathan Sullivan
2012년 4월 3일
You can use a very handy function created by James Tursa called mtimesx. It is for this exact type of problem. It does vectorized matrix multiplication.
You can setup your problem by first concatenating matrixes a1 and a2 into a variable A. We will concatenate them in the 3rd dimension.
A = cat(3,a1,a2);
We then concatenate matrixes b1 and b2 into variable B. We will do this in the 4th dimension. Since we want to do all combinations of A and B, it is important that A and B are concatenated in different dimensions.
B = cat(4,b1,b2);
Now for the calculation:
C = mtimesx(A,B);
C will be (in your case) a 2x2x2x2 array. It has arrays of matrixes. If you want to access a1*b1, you would call:
a1b1 = C(:,:,1,1);
Likewise, if you wanted to access a2*b1 you would call:
a2b1 = C(:,:,2,1);
James has written a rather well thought out help file at the link I attached above. You'll need to download it. Assuming you run windows, it should compile itself for you the first time you run it. It is very straight forward.
Sean de Wolski
2012년 4월 3일
How are you generating a1,a2,b1,b2,etc.? Store the 'a's along the third dimension of a matrix and concatenate the 'b's columnwise. Example to follow. Then store the results in a numeric matrix rather than a cell. You know all of the 'submatrices' are square. So the results should be storable with each position known. Then run your for-loop accordingly along pages of the 'a' matrix using multiplying by the whole b at once.
clearvars;
sz = 3;
a = cat(3,magic(sz),ones(sz),pi*ones(sz)); %pagewise
b = a;
b = reshape(b,sz,numel(b)/sz); %columnwise
for ii = size(a,3):-1:1
iiv = ((ii-1)*sz+1):ii*sz;
M(iiv,:) = a(:,:,ii)*b;
end
Now the M matrix will contain all the results. This should be pretty optimized for speed right now. Let me know if anything isn't clear here.
More: You could actually skip the for-loop altogether by stacking the transposed submatrices, concatenating them column-wise and then transposing the result:
a = reshape(permute(a,[2 1 3]),sz,[])';
M2 = a*b;
Check
isequal(M2,M)
ans =
1
카테고리
도움말 센터 및 File Exchange에서 Logical에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!