short cut to subtract cells without replicating numbers

조회 수: 2 (최근 30일)
AA
AA 2014년 11월 26일
댓글: Stephen23 2014년 12월 1일
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
AA
AA 2014년 11월 26일
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 2014년 12월 1일
편집: Stephen23 2014년 12월 1일
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...

댓글을 달려면 로그인하십시오.

채택된 답변

Stephen23
Stephen23 2014년 12월 1일
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
AA
AA 2014년 12월 1일
편집: AA 2014년 12월 1일
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 2014년 12월 1일
Okay, thank you for clarifying that. I will answer your new question ;)

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Resizing and Reshaping Matrices에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by