MATLAB:搜索匹配多维条件的数组中的元素

时间:2014-04-11 13:14:52

标签: arrays matlab conditional-statements

我有一个实数的列向量(V1),如:

123.2100
125.1290
...
954.2190

如果我添加,让我们说,这个向量中每行的数字1,我​​会得到(V2):

124.2100
126.1290
...
955.2190

我需要找出V2中创建的一些错误窗口中有多少来自V2的元素。例如,error-window = 0.1(但在我的情况下,V1中的每个元素都有它自己的错误窗口):

123.1100 123.3100
125.0290 125.2290
...
954.1190 954.3190

我可以创建一些像这样的代码:

% x - my vector
% ppm - a variable responsible for error-window
window = [(1-(ppm/1000000))*x, (1+(ppm/1000000))*x]; % - error-window
mdiff = 1:0.001:20; % the numbers I will iteratively add to x 
                    % (like the number 1 in the example)
cdiff = zeros(length(mdiff),1); % a vector that will contain counts of elements
                                % corresponding to different mdiff temp = 0;

for i = 1:length(mdiff)
    for j = 1:size(window,1)
        xx = x + mdiff(i);
        indxx = find( xx => window(j,1) & xx <= window(j,2) );
        if any(indxx)
            temp = temp + length(indxx); %edited
        end
    end
    cdiff(i) = temp;
    temp = 0;
end

所以,最后cdiff将包含与mdiff对应的所有计数。唯一的,我想让代码更快。或者有没有办法避免使用第二个循环(使用j)?我的意思是直接使用多维条件。

修改

我决定简化这样的代码(感谢我在这里得到的反馈):

% x - my vector
% ppm - a variable responsible for error-window
window = [(1-(ppm/1000000))*x, (1+(ppm/1000000))*x]; % - error-window
mdiff = 1:0.001:20; % the numbers I will iteratively add to x 
                    % (like the number 1 in the example)
cdiff = zeros(length(mdiff),1); % a vector that will contain counts of elements
                                % corresponding to different mdiff temp = 0;

for i = 1:length(mdiff)
    xx = x + mdiff(i);
    cdiff(i) = sum(sum(bsxfun(@and,bsxfun(@ge,xx,window(:,1)'),bsxfun(@le,xx,window(:,2)'))));
end

在这种情况下,代码运行得更快,看起来正确

2 个答案:

答案 0 :(得分:0)

认为这可能适合你 -

%%// Input data
V1 = 52+rand(4,1)

V2 = V1+1;
t= 0.1;

low_bd = any(abs(bsxfun(@minus,V2,[V1-t]'))<t,2); %%//'
up_bd = any(abs(bsxfun(@minus,V2,[V1+t]'))<t,2); %%//'
count = nnz( low_bd | up_bd )

也可以将其写成 -

diff_map = abs(bsxfun(@minus,[V1-t V1+t],permute(V2,[3 2 1])));
count = nnz(any(any(diff_map<t,2),1))

修改1:

low_bd = any(abs(bsxfun(@minus,V2,window(:,1)'))<t,2); %%//'
up_bd = any(abs(bsxfun(@minus,V2,window(:,2)'))<t,2); %%//'
count = nnz( low_bd | up_bd )

编辑2:已编辑代码的矢量化表单

t1 = bsxfun(@plus,x,mdiff);
d1 = bsxfun(@ge,t1,permute(window(:,1),[3 2 1]));
d2 = bsxfun(@le,t1,permute(window(:,2),[3 2 1]));
t2 = d1.*d2;
cdiff_vect = max(sum(t2,3),[],1)';

答案 1 :(得分:0)

add = 1; %// how much to add
error = .1; %// maximum allowed error

V2 = V1 + add; %// build V2   
ind = sum(abs(bsxfun(@minus, V1(:).', V2(:)))<error)>1; %'// index of elements
%// of V1 satisfying the maximum error condition. ">1" is used to because each 
%// element is at least equal to itself
count = nnz(ind);