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 件のコメント

Adam Danz
Adam Danz 2019 年 1 月 31 日
I'm having a hard time following this. For example, what does this mean?
I want to change all referance to 1. (ang{1}(2)= -0.08)
Could you cut-and-paste a clean version of your code with comments in the code, using the formatted code option (press alt+enter)?
Jan
Jan 2019 年 1 月 31 日
編集済み: Jan 2019 年 1 月 31 日
@Adam: Alt-Enter? Do you mean Strg-E?
@Naime: I do not undestand the question also.
Stephen23
Stephen23 2019 年 1 月 31 日
Note strg == ctrl on English keyboards.
Adam Danz
Adam Danz 2019 年 1 月 31 日
@jan, I was just refering to the keyboard shortcut for inserting formatted code. 190131 105014-add number to cell - MATLAB Answers - MATLAB Central.jpg
Rik
Rik 2019 年 1 月 31 日
@Adam, you might be surprised to know that ctrl-E also does that. You can use it to toggle between modes, while alt-enter will add a new line in code mode.
Adam Danz
Adam Danz 2019 年 1 月 31 日
@Rik
nice
Didn't know
that!
NA
NA 2019 年 2 月 1 日
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],[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.01],[0.004;0],[0;-0.02;-0.01]};
tmp = cellfun(@(c,p,m)c+(p(m)),ang,A,ref,'uni',0);
idx = [A{:}];
correct = zeros(1,max(idx));
correct(idx) = vertcat(tmp{:}); % Vertically concatenate tmp{1}, tmp{2}, ...
correct=correct';
Guillaume
Guillaume 2019 年 2 月 1 日
編集済み: Guillaume 2019 年 2 月 1 日
As stated by Adam and Rik, it's really not hard to press CTRL+E or ALT+ENTER or whatever key combination is required on your OS, or simply click on the button to format the code as code.
I've done this for you this time, but please make an effort as this makes your post much easier to read.
The latest code you've posted would work if ref had 7 elements like the other cell arrays. That's exactly what the error message tells you.
I assume you didn't write that code. I doubt that it does what you want but your question is really not clear. I understand most of it 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? Same for "we know that ang(4)should be-0.17". Do we? Why?
"and ang(4) here is 0.05"
No, it's {[0.05; 0.09; 0; -0.02;-0.03;-0.03]}
NA
NA 2019 年 2 月 1 日
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.01],[0.004;0],[0;-0.02;-0.01]};
tmp = cellfun(@(c,p,m)c+c(p(m)),ang,A,ref,'uni',0);
idx = [A{:}];
correct = zeros(1,max(idx));
correct(idx) = vertcat(tmp{:}); % Vertically concatenate tmp{1}, tmp{2}, ...
correct=correct';
I change ref and tmp, according to explanation
tmp = cellfun(@(c,p,m)c+c(p(m)),ang,A,ref,'uni',0);
By this I have error
Jan
Jan 2019 年 2 月 1 日
編集済み: Jan 2019 年 2 月 1 日
@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 2019 年 2 月 1 日
編集済み: NA 2019 年 2 月 1 日
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

サインインしてコメントする。

 採用された回答

Jan
Jan 2019 年 2 月 6 日
編集済み: Jan 2019 年 2 月 6 日

1 投票

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

その他の回答 (1 件)

Jan
Jan 2019 年 2 月 1 日

1 投票

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 件のコメント

NA
NA 2019 年 2 月 1 日
編集済み: NA 2019 年 2 月 1 日
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.01],[0.004;0],[0;-0.02;-0.01]};
tmp = cell(size(ang));
for k = 1:numel(A)
tmp{k} = ang{k} + ang{A{ref{k}}};
end
I try this one but have error
Error using +
Too many input arguments.
Adam Danz
Adam Danz 2019 年 2 月 1 日
@Naime, Jan has converted your cellfun() to a loop which is more readable and easier to debug. The reason you're getting an error on the first iteration is because the last term is producing 3 outputs:
K>> ang{A{ref{k}}}
ans =
0
-0.08
-0.17
ans =
0
-0.14
0.09
ans =
0.05
0.09
0
-0.02
-0.03
-0.03
Those outputs could be put into a vector which would prevent the error but I'm not sure this is what you are really trying to do (it's still highly unclear to me).
cell2mat(ang(A{ref{k}})')
ans =
0
-0.08
-0.17
0
-0.14
0.09
0.05
0.09
0
-0.02
-0.03
-0.03
Adam Danz
Adam Danz 2019 年 2 月 2 日
The numbers on the left are the loop iterations. Is that correct?
So, the result of the 3rd iteration is -0.22. Please explain why the 3rd iteration equals -0.22 and why the 4th equals -0.17. I'm still not seeing the pattern here.
NA
NA 2019 年 2 月 4 日
編集済み: NA 2019 年 2 月 4 日
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]}
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]}
for [1,2,4] ang(1)=0, ang(2)=-0.08, ang(4)=-0.17.
for [2,3,4] we know from above that ang(2)=-0.08, so add all [0;-0.14;-0.09] to -0.08, ang(2)=-0.08, ang(3)=-0.14-0.08=-0.22, ang(4)=-0.09-0.08=-0.17.
[2,4,5] we know from above that ang(2)=-0.08, so add all [0;-0.09;-0.05] to -0.08, ang(2)=-0.08, ang(4)=-0.09-0.08=-0.17, ang(5)=-0.05-0.08=-0.13.
[4,5,6,9,10,11] we know from above that ang(4)=-0.17, in [0.05; 0.09; 0; -0.02;-0.03;-0.03] ang(4) is not zero so 0.05+X= -0.17 , X=-0.22
So add all to -0.22, ang(4)= 0.05+-0.22= -0.17, ang(5)= 0.09+-0.22=-0.13,
ang(6)= 0+-0.22=-0.22, ang(9)= -0.02+-0.22=-0.24, ang(10)= -0.03+-0.22=-0.25, ang(11)= -0.03+-0.22=-0.25,
[4,7,9] we know from above that ang(4)=-0.17 so add all [0;-0.02;-0.07] to -0.17, ang(4)= -0.17, ang(7)= -0.02-0.17=-0.19 ,ang(9)= -0.07-0.17=-0.24
for [7,8] we know from above that ang(7)=-0.19, in [0.004;0] ang(7)=0.004
ang(7) is not zero so 0.004+X= -0.19 , X=-0.186, So add all to -0.186, ang(7)= -0.19, ang(8)= 0+-0.186=-0.186
for [6,12,13] we know from above that ang(6)=-0.22 so add all [0;-0.02;-0.01] to -0.22, ang(6)= -0.22, ang(12)= -0.02-0.22=-0.24 ,ang(13)= -0.01-0.22=-0.23
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.24;-0.25;-0.25;-0.24,-0.23]]
NA
NA 2019 年 2 月 4 日
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]};
tmp = cell(size(ang));
for k = 1:numel(A)
tmp{k} = ang{k} + ang{ref{k}}(ref{k});
end
This one is running but gives wrong result
Jan
Jan 2019 年 2 月 4 日
編集済み: Jan 2019 年 2 月 4 日
@Naime: Reading your previous comment, I'm getting such confused, that I loose the overview completely. Too many numbers and fragments. So I'm not sure, what you want to achieve. The loop is short and easy, and I'm convinced, that you can modify it, when you know, what you want.
Maybe if you post the input data with one input only, and with the wrong current result and the wanted one, I can understand, what the problem is. Forn whihc k does the code reply an unexpected result?
By the way, in your code, the variable A is used only to determine the size, but the elements are not used.
I'm lost in the original question already:
[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 do not undestand, what this notation means.
Adam Danz
Adam Danz 2019 年 2 月 4 日
Also, when you delete previous comments, it becomes more difficult to follow the thread.
NA
NA 2019 年 2 月 4 日
the variable A is used only to determine the size, but the elements are not used.
in this system I have a 13 measurements (1 to 13) and measuremnts is grouped according to A={[1,2,4],[2,3,4],[2,4,5],[4,5,6,9,10,11],[4,7,9],[7,8],[6,12,13]};
So, A is important as illustrate which measurement has which value (ang).
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]};
In each group base measuremnet (measurement that is zero) is different. As I want to compare all 13 measurements, I need to have one base and other values changing according to this base (measurement 1)
this base measurement is understandable according to ref={[1],[1],[1],[3],[1],[2],[1]} ;
Correct one
[7,8]=[0.004+(X);0+(-0.194)]=[-0.19;-0.194]
0.004+(X)=-0.19 X=-0.194
As measurement 8 is located only in one group [7,8], I could not compare value of this measurement according to other. But 7 is in group [4,7,9] and calculate ang(7) = -0.02-0.17=-0.19 , ang (7) should be -0.19 in all groups
[7,8] without changing to one base is [0.004;0]. if I change to one base ang(7) = -0.19
for this reason 0.004 should be change to -0.19 so, need to add 0.004 to -0.194 to get -0.19.
So ang(8) become-0.194
NA
NA 2019 年 2 月 5 日
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 2019 年 2 月 6 日
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.

サインインしてコメントする。

カテゴリ

質問済み:

NA
2019 年 1 月 31 日

編集済み:

Jan
2019 年 2 月 6 日

Community Treasure Hunt

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

Start Hunting!

Translated by