add number to cell

18 vues (au cours des 30 derniers jours)
NA
NA le 31 Jan 2019
Modifié(e) : Jan le 6 Fév 2019
I have A={[1,2,4],[2,3,4],[2,4,5],[4,5,6,9,10,11],[4,7,9],[7,8],[6,12,13]} and ref={[1],[1],[1],[3],[2],[1]} (ref means that which index in A is chosen as reference). So according to each referance ang is calculated in each array. ang={[0; -0.08;-0.17],[0;-0.14;0.09],[0;-0.09;-0.05],[0.05; 0.09; 0; -0.02;-0.03;-0.03],[0;-0.02;-0.01],[0.004;0],[0;-0.02;-0.01]}
[0; -0.08;-0.17] means that first elemnt is chosen as referance so -0.08 is calculated according to 1 as reference.
As I want to change all referance according to 1.
[1,2,4]=[0; -0.08;-0.17] this one is not changing
[2,3,4] as 2 is reference here so I need scale up all element to -0.08 (add all element to -0.08)
[2,3,4]=[0+(-0.08);-0.14+(-0.08);-0.09+(-0.08)] =[-0.08;-0.22;-0.17]
for [2,4,5] as reference is not changing only need to add all to -0.08
[2,4,5]=[0;-0.09+(-0.08);-0.05+(-0.08)]=[0;-0.17;-0.13]
for [4,5,6,9,10,11] as 6 is reference, I need to scale up. we know that ang(4)should be-0.17 and ang(4) here is 0.05. need to change 0.05 to -0.17 .
(0.05+(X)=-0.17, X=-0.22) need to add all to -0.22
[4,5,6,9,10,11]=[0.05+(X); 0.09-0.22; 0+(-0.22); -0.02+(-0.22);-0.03+(-0.22);-0.03+(-0.22)] =[-0.17;-0.13;-0.22; -0.24;-0.25;-0.25]
for [4,7,9] ang(4) should be -0.17. so add all to -0.17
[4,7,9]=[0+(-0.17);-0.02+(-0.17);-0.01+(-0.17)]=[-0.17;-0.19;-0.18]
for [7,8] from the above we know ang(7) should be -0.19 so add all to -0.19
[7,8]=[0.004+(X);0+(-0.186)]=[-0.19;-0.186] 0.004+(X)=-0.19 X=-0.186
[6,12,13]=[0+(-0.22);-0.02+(-0.22);-0.01+(-0.22)]
result should be [1,2,3,4,5,6,7,8,9,10,11,12,13]=[0,-0.08,-0.22;-0.17;-0.13;-0.22;-0.19;-0.186; -0.18;-0.25;-0.25]]
I also try this
tmp = cellfun(@(c,p,m)c+c(p(m)),ang,A,ref,'uni',0);
but it is not working
  11 commentaires
Jan
Jan le 1 Fév 2019
Modifié(e) : Jan le 1 Fév 2019
@Naime: Whenever you mention in the forum, that you get an error, post a copy of the complete error message. Provide all information, which is required to help you.
NA
NA le 1 Fév 2019
Modifié(e) : NA le 1 Fév 2019
but I really don't get the "I need scale up all element to -0.08 (add all element to -0.08)". Where does that -0.08 come from?
I mean for this array [2,3,4], I need to add all ang [0;-0.14;0.09] to -0.08.
As in the first one [1,2,4]=[0; -0.08;-0.17] ang(2) is -0.08.
So, if I want to compare all ang I need to chage reference. as reference is different in each array of A.
Same for ''we know that ang(4)should be-0.17''Do we? Why?
After adding -0.08 to [0;-0.14;0.09] I have [-0.08;-0.22;-0.17]. so [-0.08;-0.22;-0.17] correspond to [2,3,4]. ang(4)=-0.17

Connectez-vous pour commenter.

Réponse acceptée

Jan
Jan le 6 Fév 2019
Modifié(e) : Jan le 6 Fév 2019
I haven't seen a demand for such an indirekt algorithm yet, but if this really satisfies your needs, there is no reason to change the code. With the above mentioned simplifications:
A = {[1,2,4],[2,3,4],[2,4,5],[4,5,6,9,10,11],[4,7,9],[7,8],[6,12,13]};
ref = {[1],[1],[1],[3],[1],[2],[1]};
ang = {[0; -0.08;-0.17],[0;-0.14;-0.09],[0;-0.09;-0.05],[0.05; 0.09; 0; -0.02;-0.03;-0.03],[0;-0.02;-0.07],[0.004;0],[0;-0.02;-0.01]};
new_ang = zeros(1, max([A{:}]));
for k = 1:numel(A)
index = A{k};
first = index(1);
if ang{k}(1) == 0
% if any(A{k} == 1)
% new_ang(index) = new_ang(first) + ang{k};
% elseif any(A{k} == first)
% new_ang(index) = new_ang(first) + ang{k};
% end
% Because both assigments are equal, this is more elegant:
if any(A{k} == 1) || any(A{k} == first)
new_ang(index) = new_ang(first) + ang{k};
end
else
new_ang(index) = new_ang(first) - ang{k}(1) + ang{k};
end
end
Or
new_ang = zeros(1, max([A{:}]));
for k = 1:numel(A)
index = A{k};
first = index(1);
if ang{k}(1) ~= 0 || (any(A{k} == 1) || any(A{k} == first))
new_ang(index) = new_ang(first) - ang{k}(1) + ang{k};
end
end

Plus de réponses (1)

Jan
Jan le 1 Fév 2019
I strongly recommend to avoid the smart and neat cellfun, if its compact notation confuses the programmer. A simple loop might look less professional, but it can save hours for debugging.
tmp = cell(size(ang));
for k = 1:numel(A)
tmp{k} = ang{k} + ang{A{ref{k}}};
end
In your cellfun approach, A is treated as 2nd input, such that the anoynmous function
@(c,p,m)c+c(p(m))
defines p=A{k}, but this is not wanted. I assume you want:
tmp = cellfun(@(c,m) c+c(A(m)), ang, ref, 'uni', 0);
Anonymous functions cannot be debugged directly, but the suggested loop can. So do not make the programming harder than needed.
  10 commentaires
NA
NA le 5 Fév 2019
A={[1,2,4],[2,3,4],[2,4,5],[4,5,6,9,10,11],[4,7,9],[7,8],[6,12,13]};
ref={[1],[1],[1],[3],[1],[2],[1]};
ang={[0; -0.08;-0.17],[0;-0.14;-0.09],[0;-0.09;-0.05],[0.05; 0.09; 0; -0.02;-0.03;-0.03],[0;-0.02;-0.07],[0.004;0],[0;-0.02;-0.01]};
idx = [A{:}];
new_ang = zeros(1,max(idx));
for k = 1:numel(A)
index=A{k};
first_element=index(1);
if ang{k}(1)==0
if any(ismember(A{k},1))==1
new_ang(index)=new_ang(first_element)+ang{k};
else
n=find(new_ang~=0);
if any(ismember(A{k},first_element))==1
new_ang(index)=new_ang(first_element)+ang{k};
end
end
else
X=new_ang(first_element)-ang{k}(1);
new_ang(index)=X+ang{k};
end
end
This one gives me correct result
But is there any short version for this?
Jan
Jan le 6 Fév 2019
The result of n=find(new_ang~=0) is not used anywhere, so simply omit it. You can abbreviate:
if any(ismember(A{k},first_element))==1
to
if any(A{k} == first_element)
Then see my answer.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Logical dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by