short cut to subtract cells without replicating numbers

1 view (last 30 days)
Hi guys, assume the following: Cell array mx (100x61), Cell array mn (100x61), Cell array a (100x61).
These cell arrays consists of multiple matrix tables. Matrix table 'a' has 7 columns and matrix table mx/mn have one column. I want to carry out the following calculation between the corresponding matrix tables in the cell array: (a{column7row n}-mn{n})/(mx{n}-mn{n}). n=n+1 which increases after each row.
For that purpose I have been given this formula on the forum: Hi guys, assume the following: Cell array mx (100x61), Cell array mn (100x61), Cell array a (100x61).
These cell arrays consists of multiple matrix tables. Matrix table a has 7 columns and matrix table mx/mn have one column. I want to carry out the following calculation between the corresponding matrix tables in the cell array: (a{column7row n}-mn{n})/(mx{n}-mn{n}). n=n+1 which increases after each row.
For that purpose I have been given this formula on the forum:
q = (a{1}(:,7)-mx{:})./(mx{:}-mn{:});
The formula is great but for that formula to work I had to replicate the numbers in the matrices of the cell array mx and mn with the following formula:
n=61
for f = 1:n
for k=1:length(mx)
mx{k, f} = [kron(mx{k, f}, ones(60, 1))];
end
end
n=61
for f = 1:n
for k=1:length(mn)
mn{k, f} = [kron(mn{k, f}, ones(60, 1))];
end
end
The problem is that this process uses a lot of memory. Is there a short cut to carry out the calculation without first replicating the cells.The replication was necessary as each matrix in the original mn/mk had 60 times less rows than in the matrices of cell array a, i.e. when mn{1,1} had 6000 rows then the corresponding cell in a{1,1} had 360000. So in order to carry out a calculation I had to replicate the rows in mn first. I want the calculation to be carried out with the corresponding replicated rows without replicating the actual rows.
  4 Comments
AA
AA on 26 Nov 2014
Consider the following example for the aforementioned post:
a = {randi(50,600,9)};
mx = {randi(50,10,1)};
mn = {randi(50,10,1)};
q = (a{1}(:,7)-mn{:})./(mx{:}-mn{:});
*matrix dimensions do not agree. So I do a replication:*
n=1
for f = 1:n
for k=1:length(mn)
mn{k, f} = [kron(mn{k, f}, ones(60, 1))];
end
end
n=1
for f = 1:n
for k=1:length(mx)
mx{k, f} = [kron(mx{k, f}, ones(60, 1))];
end
end
only then i can carry out the calculation:
q = (a{1}(:,7)-mn{:})./(mx{:}-mn{:});
_ *How can I carry the calculation for the variable q getting the same results without first replicating mx and mn?* _
thanks a lot for your help guys. I really appreciate it.
Stephen23
Stephen23 on 1 Dec 2014
Edited: Stephen23 on 1 Dec 2014
This seems to be a good example of where the OP is asking about solving a particular issue (something regarding loops and the Kronecker tensor product), but does not actually address their basic intention. The statements made, eg " a is a cell array (100x61) where each element is a single cell." indicate some basic misunderstanding of cell arrays (as based on the code they gave in the above comment, all of a, mn and mx are actually 1x1 cell arrays containing numeric arrays), so perhaps some loose interpretation is required of the problem...
Thus it seems that those cell arrays and for-loops are a red-herring: it appears that the question is essentially "how do I replicate an array X so that it is the same size as another array Y, thus allowing operation fn(X,Y) to be performed". Important is perhaps the request "...without replicating the actual rows": perhaps bsxfun would be a suitable solution? Certainly this could be done without resorting to loops and the like...

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 1 Dec 2014
Based on my comment above (that the cell arrays and loops are red-herrings), then this simplifies down to "how to replicate the arrays mn and mx to the same size as a, then apply some function to them all". Of course, the answer is to not replicate them, but to use bsxfun instead:
a = randi(50,600,9);
mx = randi(50,10,1);
mn = randi(50,10,1);
q = bsxfun(@minus,reshape(a(:,7),10,[]),mx);
q = bsxfun(@rdivide,q,mx-mn);
q = reshape(q,[],1);
Note the last three lines are derived from the given function:
q = (a{1}(:,7)-mx{:})./(mx{:}-mn{:});
after removing the (useless?) cell array references. To get exactly the same behavior as the OP's code, it might be required to perform some nonconjugate transpose operations at some steps.
  4 Comments
AA
AA on 1 Dec 2014
Edited: AA on 1 Dec 2014
you are right. I forgot to mention the condition that the rows of variable a are always a multiple of mx/mn. Thus
a = randi(50,600,9);
mx = randi(50,60,1);
mn = randi(50,60,1);
I wish to subtract mx(1) from the first ten consecutive values of a. q(1:10) = a(1:10) - mx(1) q(11:20)=a(11:20)-mx(2) ... q(591:600)=a(591:600)-mx(60).
Stephen23
Stephen23 on 1 Dec 2014
Okay, thank you for clarifying that. I will answer your new question ;)

Sign in to comment.

More Answers (0)

Categories

Find more on Resizing and Reshaping Matrices 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!