Home > database >  MATLAB finding non-duplicating numbers in a matrix and returning their positions
MATLAB finding non-duplicating numbers in a matrix and returning their positions

Time:11-16

I have a set of elements from Abaqus modelling software, each of them has 8 nodes ( as in the picture https://postimg.cc/Mfy7zjsc). They are represented by a 53x9 matrix where the first column stores the names (numbers) of the elements and the other 8 store node numbers. I need to sort these elements ordering them as they appear in the model, as they are given pretty much random numbers (and so are nodes). I would then like my Matlab script to identify which of the rows in the matrix is either of the borderline elements (the one that only has 4 node numbers that are repeated in one of the other rows), set it at the start of a result matrix, and then find elements that are touching it (share the other 4 nodes) and follow later.

I haven't done programming in a while and I'm struggling with writing the loops correctly. I'm trying to get Matlab to first take one row of the matrix, take an element and go through all other to find duplicates. If it doesn't find any AND the row number is different to the one that is being worked on, it should increase a counter variable. If the variable reaches 4 then the script should return the number of the row, which will be the starting element. Right now I'm getting pretty random results and are finding it hard to debug it. 'elem' is the matrix with all values I have, 'nodess' is the same matrix with the column including element values deleted (i know it's probably stupid and useless but nvm). 'E' was supposed to be the result matrix.

% input data
in = [135346    135912  135913  20605   20606   51236   51237   8677    8678;...
135347  135913  135914  20604   20605   51237   51238   8676    8677;...
135348  135914  135915  20603   20604   51238   51239   8675    8676;...
135349  135915  135916  20602   20603   51239   51240   8674    8675;...
135350  135916  135917  20601   20602   51240   51241   8673    8674;...
135351  135917  135918  20600   20601   51241   51242   8672    8673;...
135352  135918  5057    107 20600   51242   5229    111 8672;...
135697  136514  20982   421 20868   136213  8585    184 20881;...
135698  136515  136514  20868   20869   136214  136213  20881   20880;...
135699  136516  136515  20869   20870   136215  136214  20880   20879;...
135700  136517  136516  20870   20871   136216  136215  20879   20878;...
135701  136518  136517  20871   20872   136217  136216  20878   20877;...
135702  136519  136518  20872   20873   136218  136217  20877   20876;...
135703  136520  136519  20873   20874   136219  136218  20876   20875;...
135704  20981   136520  20874   424 20896   136219  20875   425;...
232453  20982   192131  20715   421 8585    50247   8526    184;...
232454  192131  192132  20714   20715   50247   50248   8525    8526;...
232455  192132  192133  20713   20714   50248   50249   8524    8525;...
232456  192133  192134  20712   20713   50249   50250   8523    8524;...
232457  192134  192135  20711   20712   50250   50251   8522    8523;...
232458  192135  192136  20710   20711   50251   50252   8521    8522;...
232459  192136  192137  20709   20710   50252   50253   8520    8521;...
232460  192137  192138  20708   20709   50253   50254   8519    8520;...
232461  192138  192139  20707   20708   50254   50255   8518    8519;...
232462  192139  192140  20706   20707   50255   50256   8517    8518;...
232463  192140  192141  20705   20706   50256   50257   8516    8517;...
232464  192141  192142  20704   20705   50257   50258   8515    8516;...
232465  192142  192143  20703   20704   50258   50259   8514    8515;...
232466  192143  192144  20702   20703   50259   50260   8513    8514;...
232467  192144  192145  20701   20702   50260   50261   8512    8513;...
232468  192145  192146  20700   20701   50261   50262   8511    8512;...
232469  192146  20867   419 20700   50262   8628    183 8511;...
295505  2511    47  312217  297117  2683    51  312275  300385;...
295549  297117  312217  312216  297160  300385  312275  312276  300428;...
295593  297160  312216  312215  297203  300428  312276  312277  300471;...
295637  297203  312215  312214  297246  300471  312277  312278  300514;...
295681  297246  312214  312213  297289  300514  312278  312279  300557;...
295725  297289  312213  312212  297332  300557  312279  312280  300600;...
295769  297332  312212  312211  297375  300600  312280  312281  300643;...
295813  297375  312211  312210  297418  300643  312281  312282  300686;...
295857  297418  312210  312209  297461  300686  312282  312283  300729;...
295901  297461  312209  312208  297504  300729  312283  312284  300772;...
295945  297504  312208  312207  297547  300772  312284  312285  300815;...
295989  297547  312207  312206  297590  300815  312285  312286  300858;...
296033  297590  312206  312205  297633  300858  312286  312287  300901;...
296077  297633  312205  312204  297676  300901  312287  312288  300944;...
296121  297676  312204  312203  297719  300944  312288  312289  300987;...
296165  297719  312203  312202  297762  300987  312289  312290  301030;...
296209  297762  312202  312201  297805  301030  312290  312291  301073;...
296253  297805  312201  312200  297848  301073  312291  312292  301116;...
296297  297848  312200  312199  297891  301116  312292  312293  301159;...
296341  297891  312199  107 5057    301159  312293  111 5229];
E=0
for i=linspace(1,y,y)
    EL=elem(i,1);
    ns=nodess(i,:);
       for j=linspace(1,size(ns,2),size(ns,2))   
        a=0;
        for k=linspace(1,y,y)
            for l=linspace(1,size(ns,2),size(ns,2))
                wn=nodess(k,l);
                if k~=i && wn==ns(l)
                    a=a 1
                end
            end
        end
            if a==4
                E(1)=elem(i,1)
            end
       end
end

CodePudding user response:

Since the question is not completely clear, I am going to make several assumptions:

  • There is no element connected to 0 other element
  • There is no element connected to more than 2 elements
  • Elements share 4 nodes and 4 nodes only (i.e. your input is correct)
  • Note that I cannot assume that there is only one group of connected elements, since it is not the case in your example

The algorithm is in two parts. The first parts computes the adjacency matrix of the elements of your model. It basically checks if element ii and jj share elements.

n = size(in,1);
adj_matrix = zeros(n);

for ii=1:n
    for jj=(ii 1):n

        % adjacency matrix. 1 when node ii is connected to node jj
        adj_matrix(ii,jj) = ~isempty(intersect(in(ii,2:end),in(jj,2:end)));

    end
end

% fill lower triangular block
adj_matrix = adj_matrix   adj_matrix.'; 

Now, you can check which elements are "tail" elements. The amount of 1s in row k is the amount of elements connected to element k. The "tail" elements are elements connected to only one other element:

% find the index of the elements that are linked only to one other element
id_tails = find(sum(adj_matrix,2)==1);

The core of the last part of the algorithm is to travel through the adjacency matrix to build your output vector of indexes one at a time. When your current element is element k, and it is connected to 2 elements, one is already in your output vector, so you just pick the other one. Now since you have more than 2 "tail" elements in your example, you need a bit more magic to make it work. Basically, if your current element is a "tail" element, you just hop to the next tail:

% start building output index vector, with a randomly picked tail
idx_out = id_tails(1);

% Remove first tail from list
id_tails = setdiff(id_tails,idx_out);

while length(idx_out) < n

    if ismember(idx_out(end),id_tails)

        % If current index is a tail, next index is the next tail
        idx_out(end 1) = id_tails(1);
        % Remove first tail from list
        id_tails = setdiff(id_tails,idx_out);

    else

        % If not a tail, then next index is the only one that is not yet in
        % idx_out
        idx_out(end 1) = setdiff(find(adj_matrix(idx_out(end),:)),idx_out);

    end

end

Finally, you can use these indexes to sort your input matrix:

E = in(idx_out,:);
  • Related