Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

How to determine if a row appears more than once in an array in MATLAB

  1. Jan 23, 2013 #1
    I'm working on a project for myself that I started some time ago. This question only covers a small part of what I am doing. In my program I have vertices that I read in from a text file. They are read and stored in a matrix where each row of the matrix is a facet (triangle) created by the 2 (x,y) vertices. I end up with a N X 3 matrix of vertices where N is the number of facets. I then pass these through a function that determines what the intersection points are for each facet that is intersected by a plane at x = some value. The intersection points are stored in a N X 2 cell array (say B) where each row is a line segment created by the intersection points of each facet. I wrote a function that takes this cell array and "connects" the line segments by finding the common point (cell) of a row to another row. I have this working to a certain extent. The catch is that it only works if the first row in B is a line segment that has only one point in common with one other row. What I want to do is figure out a way to find which row in B has only one point in common with the one other row. There should be 2 rows in B for this (one for the start and one for the end of the line). Below is the code that I have written thus far. A represents the starting line segment to begin the sorting. Right now A is set as the first row in B in order for the program to run. Try changing A to any other row besides an end line segment to understand what I am getting at.

    Code (Text):

    function [line] = connect(B)
    clear all

    % Build the example cell arrays
    A = {[4,-1],[3,0]};     %Initial test row value
    B = {[4,-1],[3,0];     %end line segment      
         [-1,4],[-3,5];     %end line segment

    ANumVec = cell2mat(A);
    ANum = reshape(ANumVec, 2, 2)';
    Bmat = cell2mat(B);

    line = A;
    m = length(Bmat);
    count = 2;

    while  m ~= 1
        I1 = ismember(Bmat(:, 1:2), ANum, 'rows');      %check first two columns
        I2 = ismember(Bmat(:, 3:4), ANum, 'rows');      %check last two columns    
        I = [I1, I2];
        B(all(I == 1,2),:) = {[], []};      %replace start row with empty cells to remove from list for next iteration
        I(all(I == 1,2),:) = 0;             %Find indice of the row in B that contains a matching vertice of the vertices in A
        A = Bmat(I > 0,:);                  %Get next test row vertices
        ANum = reshape(A,2,2)';
        line(1,count:count+1) = {A(1,[1 2]), A(1,[3 4])};      %Assemble connectivity array

        empty_row = ~cellfun('isempty',B);
        B = B(empty_row(:,1),:);                %Resize B array by removing empty rows
        Bmat = cell2mat(B);
        [m n] = size(Bmat);

        count = count+1;    
  2. jcsd
  3. Jan 24, 2013 #2


    User Avatar
    Gold Member

    I think the 'isequal' operator might be of some help?

    >> A = [1 1 1; 1 1 1;0 0 0;0 0 0]

    A =

    1 1 1
    1 1 1
    0 0 0
    0 0 0

    >> B = [1 1 1]

    B =

    1 1 1

    >> for i=1:size(A,2)
    C(i) = isequal(A(i,:),B);
    >> C

    C =

    1 1 0 0
  4. Jan 24, 2013 #3
    Thanks for the reply. I actually figure this out last night using a combination of ismember and if/then logic statements. This works, however it is in a separate while loop than the one that does the "connecting". Right now I'm trying to optimize the code and trying to figure out how to combine the two while loops.
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook