Cell contents reference from a non-cell array object.

How to delete an element k in a cell array in a for loop? l have a set called neighbour_n{i} where i varies from 1 to n
But it returns me this error :
??? Cell contents reference from a non-cell array object.
Error in ==> @(d)setxor([d{:}],[k])
Error in ==> broadcastelimination at 118 cellfun(fun, neighbour_n, 'UniformOutput', false)
neighbour_n=cell(N,1);
N = numel(neighbour_n);
for i=1:N
if (ismember(k, neighbour_n{i}));
idx = find(cell2mat(neighbour_n{i}) == k);
neighbour_n{i}(idx) = [];
end
end

8 Comments

This is a follow-up to your previous question:
You are using the code that the cyclist provided, but have not taken into account their edit and minor change of code. Put simply: you need to try the other code that they provided. They even explains this in their comment.
Instead of asking new questions, you should post a comment to their answer if you have any questions about what they are doing, or if it does not work as you expect it to.
l did it but it doesn't work here is my complete code :
X=100;
Y=100;
N=200; %number of nodes
nodesX(1)=rand*X;
nodesY(1)=rand*Y;
for i=2:N
nodesX(i)=rand*X;
nodesY(i)=rand*Y;
d(i-1) =((nodesX(i)-nodesX(i-1)).^2+(nodesY(i)-nodesY(i-1)).^2).^0.5;
while (d(i-1)>200)
nodesX(i)=rand*X;
nodesY(i)=rand*Y;
d(i-1) =((nodesX(i)-nodesX(i-1)).^2+(nodesY(i)-nodesY(i-1)).^2).^0.5;
end
end
h_old=plot(nodesX,nodesY,'m*');
labels=[1:N]';
labels=num2str(labels);
text(nodesX,nodesY,labels);
xlabel('X (Meters)');
ylabel('Y (Meters)');
title(['Network Topology with',num2str(N),'nodes']);
hold on
A= zeros(N,N);
neighbour_n=cell(N,1);
m=0;
for k=1:N;
for j=1:N;
if (k~=j)
d=((nodesX(k)-nodesX(j))^2+(nodesY(k)-nodesY(j))^2)^0.5;
end
if (k~=j);
if(d < 50);
line([nodesX(k),nodesX(j)],[nodesY(k),nodesY(j)]);
neighbour_n{k}= [neighbour_n{k} j];
m=m+1;% the number of created links
A(k, j)=1;
if (A(k, j)==1);
A(j, k)=1;
end
else
A(k, j)=0;
end
end
end;
display(['the neighbours of ', num2str(k), ' are ', ' = ' , num2str(neighbour_n{k})]);
end;
display(A);
display(['the total number of edges is: ', num2str(m)]);
deleted_node=cell(N,1);
for k=1:N;
for j=1:N;
if (((all(ismember(neighbour_n{k}, neighbour_n{j})))||(isequal(neighbour_n{j}, neighbour_n{k})))&&(k~=j));% incorrect syntax
delete(line([nodesX(k),nodesX(j)],[nodesY(k),nodesY(j)]));
display(['the line between ', num2str(k), ' and ', num2str(j), ' is deleted']);
deleted_node{i}= [deleted_node{i} k];
F=Unique(deleted_node{i});
L=length(F);
end
end
end
display(['the deleted nodes are ', ' = ' , num2str(F)]);
display(['the number of deleted nodes is ', ' = ' , num2str(L)]);
eliminated_all=cell(N,1);
candidate_node=cell(N,1);
N = numel(neighbour_n);
for i=1:N
result = cellfun(@(x) x(~ismember([x{:}], F)), neighbour_n, 'uniformoutput', 0);
display(['Display new neighbour of ', num2str(i), ' are: ', num2str(neighbour_n{i})]);
end
The code above includes this:
cellfun(@(x) x(~ismember([x{:}], F)), neighbour_n, 'uniformoutput', 0)
whereas the cyclist's (current) final answer was this:
cellfun(@(x)setdiff(x,8),stated_n,'UniformOutput',false)
The first assumes that the elements are cell arrays, the second assumes that they are numeric arrays.
This means that you did not use the cyclist's latest answer: if they fixed their code in their answer then you need to include this change in your code too.
Yes stephen in my code l must delete a set of value which called F that contains a lots of value not only one.And working with cellfun(@(x) x(~ismember([x{:}], F)), neighbour_n, 'uniformoutput', 0) doesn't make any changes. The second solution (cellfun(@(x)setdiff(x,8),stated_n,'UniformOutput',false)) is just for a constant = 8 but l need to delete a set of value F=Unique(deleted_node{i}); Hope you got my worry
Replace the 8 with F like this: setdiff(x,F)
it executes but it doesn't delete the values. the set remains the same
I have no idea what "it doesn't delete the values" means.
The setdiff documentation states "setdiff(A,B) returns the data in A that is not in B."
This means if you still have values in the output that you do not expect to have then the you need to check that the input values are correct. If an element of A is not in B then it will be in the output.
And I note that the cyclist is also giving advice on your original question here:
Which is a good example of why I said at the start of this thread that you should not ask new questions about the same topic, but you should keep communicating on the same thread until the topic is resolved.
l think the problem is in the last instruction it deletes the values but doesn't update the the neighbour_n when it displays.?
display(['Display new neighbour of ', num2str(i), ' are: ', num2str(neighbour_n{i})]);

Sign in to comment.

 Accepted Answer

the answer is :
neighbour_n{i}= setdiff(neighbour_n{i},F);
problem solved

More Answers (1)

Not sure what's going on in your parallel discussion, but if you have a cell array called neighbour and you want to delete the k'th cell from that cell array, you can do this:
neighbour_n(k) = []; % Note parentheses, not braces.
You don't need to put it in a loop. See the FAQ: http://matlab.wikia.com/wiki/FAQ#What_is_a_cell_array.3F to get a better intuitive feeling for cell arrays.

3 Comments

no for exemple l have n = 3 so neighbours_n{1}={1,4,7,8} neighbours_n{2}={1,7,9,13,27} neighbours_n{3}={8,4,7,12} and k= {4,7,12,27} if ismember(k,neighbours_n{i}) neighbours_n{1}={1,7,8} neighbours_n{2}={1,9,13} neighbours_n{3}={8}.
My problem right now is how to update the display of the neighbours after the execution ,it displays the initial values of neighbours_n{i} how to update that? here is my code
X=100;
Y=100;
N=200; %number of nodes
nodesX(1)=rand*X;
nodesY(1)=rand*Y;
for i=2:N
nodesX(i)=rand*X;
nodesY(i)=rand*Y;
d(i-1) =((nodesX(i)-nodesX(i-1)).^2+(nodesY(i)-nodesY(i-1)).^2).^0.5;
while (d(i-1)>200)
nodesX(i)=rand*X;
nodesY(i)=rand*Y;
d(i-1) =((nodesX(i)-nodesX(i-1)).^2+(nodesY(i)-nodesY(i-1)).^2).^0.5;
end
end
h_old=plot(nodesX,nodesY,'m*');
labels=[1:N]';
labels=num2str(labels);
text(nodesX,nodesY,labels);
xlabel('X (Meters)');
ylabel('Y (Meters)');
title(['Network Topology with',num2str(N),'nodes']);
hold on
A= zeros(N,N);
neighbour_n=cell(N,1);
m=0;
for k=1:N;
for j=1:N;
if (k~=j)
d=((nodesX(k)-nodesX(j))^2+(nodesY(k)-nodesY(j))^2)^0.5;
end
if (k~=j);
if(d < 50);
line([nodesX(k),nodesX(j)],[nodesY(k),nodesY(j)]);
neighbour_n{k}= [neighbour_n{k} j];
m=m+1;% the number of created links
A(k, j)=1;
if (A(k, j)==1);
A(j, k)=1;
end
else
A(k, j)=0;
end
end
end;
display(['the neighbours of ', num2str(k), ' are ', ' = ' , num2str(neighbour_n{k})]);
end;
display(A);
display(['the total number of edges is: ', num2str(m)]);
deleted_node=cell(N,1);
for k=1:N;
for j=1:N;
if (((all(ismember(neighbour_n{k}, neighbour_n{j})))||(isequal(neighbour_n{j}, neighbour_n{k})))&&(k~=j));% incorrect syntax
delete(line([nodesX(k),nodesX(j)],[nodesY(k),nodesY(j)]));
display(['the line between ', num2str(k), ' and ', num2str(j), ' is deleted']);
deleted_node{i}= [deleted_node{i} k];
F=Unique(deleted_node{i});
L=length(F);
end
end
end
display(['the deleted nodes are ', ' = ' , num2str(F)]);
display(['the number of deleted nodes is ', ' = ' , num2str(L)]);
eliminated_all=cell(N,1);
candidate_node=cell(N,1);
N = numel(neighbour_n);
for i=1:N
result = cellfun(@(x) x(~ismember([x{:}], F)), neighbour_n, 'uniformoutput', 0);
display(['Display new neighbour of ', num2str(i), ' are: ', num2str(neighbour_n{i})]);
end
Sorry - it's too late at night for me to delve into all that. I suggest you keep at it with your original thread.

Sign in to comment.

Categories

Community Treasure Hunt

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

Start Hunting!