Combine two different matrices to create one new matrix of all matrix combinations

Hi, I have the following matrices
WT_energy_supply(:,:,M) and PV_power_output(:,:,K)
which are 365 x 24 matrices and M = 3 and K = 10. Therefore there are 30 possible combinations of WY_energy_supply and PV_power_output. I am looking to create a set of matrices (in the form (:,:,Z)) that add corresponding elements in each matrix to form this new set (again 365x24 with 30 different matrices) Does anyone have any idea where to start coding this?
Thank you

 Accepted Answer

Nice brain teaser!
%Sample data:
A = ones(4,4,5);
B = bsxfun(@times,ones(4,4,3),cat(3,1,2,3));
%Nice to know:
sz = size(B);
%Engine:
C = reshape(bsxfun(@plus,A, reshape(B,sz(1),sz(2),1,sz(3))),sz(1),sz(2),[]);

18 Comments

thanks for the reply Sean, but I am now a bit confused.
The bsxfun you suggest uses @times, I guess this should be @plus since I want to add the corresponding elements of each matrix.
Also, about the C = reshape(bsxfun code you have suggested, will this give me a matrix C of 365x24 elements with 30 of these matrices that each represent a combination?
If you could please explain this code a little bit further since I don't really understand how you have developed it.
Glad I could provide a nice brain teaser!
Thank you
yes, 365x24x30.
The first bsxfun() (the one with times) is just to create sample data that is easy to check the results with. B will be a 4x4x3 matrix where the first slice(B(:,:,1)) is all ones, the second all twos etc. This way, then I add it to A, I can check quickly that it did what I want. (It did). If you inspect each variable (A,B,C) it will be obvious what I did.
Thanks Sean
so the above code will provide a 365x24x30 matrix
How can I access each matrix individually, say I want to view or write an excel spreadsheet of each one?
Thank you
It is the C matrix in my example. it will be a (m x n x p*k) matrix where in your case m is 365, n is 23 p is 10 and k is 3.
ok both matrices are 365x24, its the number of matrices that are different.
so if I replace A and B in your example with WT_energy_supply and PV_power_output which I have in the initial question above it should work?
I though you said they were 365x24x10 and 365x24x3?
Look at my example and see what it is doing. This will confirm or deny my algorithm.
they are 365x24x10 and 365x24x3 where the 10 and 3 represent 10 and 3 different manufacturers respectively. I want the sum of the PV and WT at each element in the 365x24 matrix to create a third matrix of 365x24. The third matrix however must be all the combinations of 10 and 3 and therefore a 365x24x30 matrix.
does this make things clearer?
like glass. That's _exactly_ what I have above.
nice, thanks Sean.
Therefore, to modify your code above I need the following
A = PV_power_output(:,:,K)
B = WT_energy_supply(:,:,M)
sz = size(WT_energy_supply(:,:,M));
C = reshape(bsxfun(@plus,A,reshape(B,sz(1),sz(2),1,sz(3))),sz(1),sz(2),[]);
and the just access say the fifth combination of the C matrices via C(:,:,5)
having tried this i get the "Index exceeds matrix dimensions" error
on the line of code where "C" is.
I'm quite confused now since i was expecting a 365x24x30 matrix! any thoughts?
No.
A = PV_power_output;
B = WT_energy_supply;
This is the only change!!!
Now the engine stays the same
sz = size(B); %needs to know the size of the whole thing, not one slice
C = reshape(...)
I think you are being confused by the 3d indexing.
We want to do the whole operation at once, thus the individual slice extracton (i.e Matrix(:,:,page)) is going to throw off the calculation. Instead we want to pass this block, (think of it like a rubik's cube) into the engine. We then take two rubik's cubes and add the second rubik's cube to each slice (as if you were to cur off 9 cubes) of the first rubik's cube. Hope this helps.
Hi Sean! In one row:
C = reshape(bsxfun(@plus,A, permute(B,[1 2 4 3])),size(A).*[1 1 size(B,3)])
andrei, thanks, what is the permute(B,[1 2 4 3... based on?
@Andrei, permute is much slower than reshape!
@Sean
Still a bit confused on how to code "C" to take the form
C(:,:,Z) = ...

Sign in to comment.

More Answers (2)

eg:
M = 3;
K = 10;
WT_energy_supply = randi(10,10,4,M);
PV_power_output = randi([10 50],10,4,K);
%solution
ij = fullfact([M K]);
out = WT_energy_supply(:,:,ij(:,1)) + PV_power_output(:,:,ij(:,2)) ;

5 Comments

+1 for fullfact().
It's like a simple way to do the [xx yy zz ww] = meshgrid(blah)
[xx(:) yy(:)...
Learn something new everyday!
Awesome-o!
thanks guys
If i have understood correctly, you have given me two possible solutions to my question.
which do you recommend I use :P
really, you shoudl decide based on:
-importance of speed.
-importance of being able to understand what's going on.
-whichever side of a coin flips up (or rand > 0.5)
having tried this code i get the following error "Array dimensions must match for binary array op."
Do I need to define M and K as 3 and 10 since I have them previously in the code for working out WT_energy_supply and PV_power_output?
This may be a stupid question but why can't I just add WT_energy_supply(:,:,M) to PV_power_output(:,:,K) since this is really what I am trying to do?
Thank you
That's what bsxfun does for you!
think about it, how can you add two things that are different sizes?

Sign in to comment.

To generate all combinations of K and M, check out the file exchange function "allcomb": href=""<http://www.mathworks.com/matlabcentral/fileexchange/10064</a>>
Ive been using it for years, works with more than 2 parameters as well.

Community Treasure Hunt

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

Start Hunting!