zlon
zlon

Reputation: 834

Fast way to detect one of the value pairs in matlab array

My script generate some arrays. I have a list of value pairs which should not be in array. Pairs are symmetric, if i don't like pair [1 2], then pair [2 1] is also bad. To detect "bad" arrays I use the following approach:

%% SAMPLE DATA
Pair2Find=[1,2;4,6;7,10]; % value pairs to detect
Seq=randi(10,1,10000); % array where detect pairs
%% DETECTION
for iPair=1:size(Pair2Find)
   idx=find(or(Seq(1:end-1)==Pair2Find(iPair,1)&Seq(2:end)==Pair2Find(iPair,2),...
       Seq(1:end-1)==Pair2Find(iPair,2)&Seq(2:end)==Pair2Find(iPair,1)));
   if (~isempty(idx))
       display('Bad array')
       break
   end
end

Everything works fine, but it is the bottleneck of my program.

Could you help me to improve the quality and speed of this code

Upvotes: 0

Views: 41

Answers (2)

sco1
sco1

Reputation: 12214

If you're able to reshape your vector into an n x 2 array you can do this pretty simply with set operations like intersect. You can create a helper function to detect whether or not the bad pairs are present and return a boolean that you can use for further logic.

For example:

Pair2Find = [1,2;4,6;7,10]; % value pairs to detect
Seq = randi(10,1,1000000); % array where detect pairs
Seq = reshape(Seq, 2, []).';  % Reshape to a 2 column array

test = isbad(Seq, Pair2Find);

function [outbool] = isbad(Seq, Pair2Find)
sortSeq = sort(Seq, 2);  % Sort the pairs
uniquepairs = unique(sortSeq, 'rows');  % Find unique pairs
test = intersect(Pair2Find, uniquepairs, 'rows');  % Find pair intersection
outbool = ~isempty(test);
end

Upvotes: 0

Tommaso Belluzzo
Tommaso Belluzzo

Reputation: 23675

pairs = [1 2; 4 6; 7 10];
seq = randi(10,1,10000);

for i = 1:size(pairs,1)
    pair = pairs(i,:);
    res = strfind(seq,pair);

    if (~isempty(res))
        disp('Bad array!');
        break;
    end

    pair = fliplr(pair);
    res = strfind(seq,pair);

    if (~isempty(res))
        disp('Bad array!');
        break;
    end
end

If your pairs matrix is very big, you could also increase your loop time (a little bit) as follows:

pairs = [1 2; 4 6; 7 10];
pairs_flip = fliplr(pairs);

seq = randi(10,1,10000);

for i = 1:size(pairs,1)
    res = strfind(seq,pairs(i,:));

    if (~isempty(res))
        disp('Bad array!');
        break;
    end

    res = strfind(seq,pairs_flip(i,:));

    if (~isempty(res))
        disp('Bad array!');
        break;
    end
end

Upvotes: 1

Related Questions