0

我正在更新一些继承的遗留代码,并找到了一种有趣的“方法”来解决我无法优化的问题。

有一组数据可以使用以下方法进行某种程度的模拟:

approximateEntries = 5e6;
maxEntryValue = 5e12;
maxExtraEvents = 10e3;

event1 = randperm( maxEntryValue, approximateEntries + randi( maxExtraEvents ) );
event1 = sort(event1);
event2 = randperm( maxEntryValue, approximateEntries + randi( maxExtraEvents ) );
event2 = sort(event2);
event3 = randperm( maxEntryValue, approximateEntries + randi( maxExtraEvents ) );
event3 = sort(event3);
event4 = randperm( maxEntryValue, approximateEntries + randi( maxExtraEvents ) );
event4 = sort(event4);

data = [[ones(length(event1),1); 2*ones(length(event2),1); 3*ones(length(event3),1); 4*ones(length(event4),1)], ...
       [event1'; event2'; event3'; event4']];
data = sortrows(data,2);

clear approximateEntries;
clear maxEntryValue;
clear maxExtraEvents;

也就是说,由于之前编写代码的方式,我可以访问四个数组,每个数组大约有 500 万个元素和一个包含四个数组的大数组,这些数组在另一列中连接、排序和标记元素最初是哪个数组来自。如果我可以避免在解决此问题时使用单个大数组,则可以从代码中消除它,因为以后不需要它。

我们正在寻找在四个“事件”矩阵中的值之间找到接近(在 +/- 1000 以内)匹配的不同特征。这些值可能不一定在相同的索引处,但每个“事件”矩阵将按升序排序。我们正在寻找:

  • 每个“事件”矩阵中的值对于该矩阵是唯一的(在 +/- 1000 范围内)的总次数。
  • 每个“事件”矩阵中的值仅在两个矩阵中出现 +/- 1000 的总次数,每个可能的矩阵对都有单独的总数。
  • 每个“事件”矩阵 +/- 1000 的值仅在三个矩阵中出现的总次数,每个矩阵的三元组有一个单独的总数。
  • 值 +/- 1000 在所有四个矩阵中出现的总次数

遗留代码尝试以以下令人难以置信的方式执行此操作(我知道它并不完全正确,这就是它正在更新的原因)

onlyEvent1 = 0;
onlyEvent2 = 0;
onlyEvent3 = 0;
onlyEvent4 = 0;
onlyEvent1Event2 = 0;
onlyEvent1Event3 = 0;
onlyEvent1Event4 = 0;
onlyEvent2Event3 = 0;
onlyEvent2Event4 = 0;
onlyEvent3Event4 = 0;
onlyEvent1Event2Event3 = 0;
onlyEvent1Event2Event4 = 0;
onlyEvent1Event3Event4 = 0;
onlyEvent2Event3Event4 = 0;
allEvents = 0;

maxIndex = length(data);
workingIndex = 1;

fullGate = 2000;

while workingIndex < maxIndex 
    subIndex = 0;

    withinRange = true;

    % Prepare a buffer
    buffer = zeros(200,2);

    while ((workingIndex + subIndex) < maxIndex) && (withinRange == true)

        if subIndex > 0

            timeDifference = data(workingIndex + subIndex,2) - buffer(subIndex,2);

            if timeDifference <= fullGate
                buffer(subIndex + 1,:) = data(workingIndex + subIndex,:);
                subIndex = subIndex + 1; 
            else
                withinRange = false;
            end % if

        else

            buffer(subIndex + 1,:) = data(workingIndex + subIndex,:);
            subIndex = subIndex + 1; 

        end % if      

    end % while

        event1 = false;
        event2 = false;
        event3 = false;
        event4 = false;

        compareIndex = 1;

        while (buffer(compareIndex) ~= 0) && (compareIndex < length(buffer))
            if buffer(compareIndex,1) == 1
                event1 = true; 
            else
                if buffer(compareIndex,1) == 2
                    event2 = true; 
                else
                    if buffer(compareIndex,1) == 3
                        event3 = true; 
                    else
                        % Should really only be four
                       event4 = true; 
                    end % if is 3
                end % if is 2
            end % if is 1
            compareIndex = compareIndex + 1;
        end % while buffer

        if (event1 == true) && (event2 == true) && (event3 == true) && (event4 == true)
            allEvents = allEvents + 1;
        else
            if (event1 == true) && (event2 == true) && (event3 == true) && (event4 == false)
                onlyEvent1Event2Event3 = onlyEvent1Event2Event3 + 1;
            else
                if (event1 == true) && (event2 == true) && (event3 == false) && (event4 == true)
                    onlyEvent1Event2Event4 = onlyEvent1Event2Event4 + 1;
                else
                    if (event1 == true) && (event2 == false) && (event3 == true) && (event4 == true)
                        onlyEvent1Event3Event4 = onlyEvent1Event3Event4 + 1;
                    else
                        if (event1 == false) && (event2 == true) && (event3 == true) && (event4 == true)
                            onlyEvent2Event3Event4 = onlyEvent2Event3Event4 + 1;
                        else
                            if (event1 == true) && (event2 == true) && (event3 == false) && (event4 == false)
                                onlyEvent1Event2 = onlyEvent1Event2 + 1;
                            else
                                if (event1 == true) && (event2 == false) && (event3 == true) && (event4 == false)
                                    onlyEvent1Event3 = onlyEvent1Event3 + 1;
                                else
                                    if (event1 == true) && (event2 == false) && (event3 == false) && (event4 == true)
                                        onlyEvent1Event4 = onlyEvent1Event4 + 1;
                                    else
                                        if (event1 == false) && (event2 == true) && (event3 == true) && (event4 == false)
                                            onlyEvent2Event3 = onlyEvent2Event3 + 1;
                                        else
                                            if (event1 == false) && (event2 == true) && (event3 == false) && (event4 == true)
                                                onlyEvent2Event4 = onlyEvent2Event4 + 1;
                                            else
                                                if (event1 == false) && (event2 == false) && (event3 == true) && (event4 == true)
                                                    onlyEvent3Event4 = onlyEvent3Event4 + 1;
                                                else
                                                    if (event1 == true) && (event2 == false) && (event3 == false) && (event4 == false)
                                                        onlyEvent1 = onlyEvent1 + 1;
                                                    else
                                                        if (event1 == false) && (event2 == true) && (event3 == false) && (event4 == false)
                                                            onlyEvent2 = onlyEvent2 + 1;
                                                        else
                                                            if (event1 == false) && (event2 == false) && (event3 == true) && (event4 == false)
                                                                onlyEvent3 = onlyEvent3 + 1;
                                                            else
                                                                onlyEvent4 = onlyEvent4 + 1;
                                                            end % if 3
                                                        end % if 2
                                                    end % if 1
                                                end % if 3&4
                                            end % if 2&4
                                        end % if 2&3
                                    end % if 1&4
                                end % if 1&3
                            end % if 1&2
                        end % if 2,3&4
                    end % if 1,3&4
                end % if 1,2&4
            end % if 1,2&3
        end % if all events

        workingIndex = workingIndex + subIndex;

end % while

我提出了以下方法的基础:

temp=bsxfun(@plus, event1', -1000:1000);
matchOneTwo=sum(ismember(event2,temp));
matchOneThree=sum(ismember(event3,temp));
matchOneFour=sum(ismember(event4,temp));
temp=bsxfun(@plus, event2', -1000:1000);

等等...但是由于在生成“临时”时内存不足而失败。任何人都可以提供另一种方法吗?

[编辑] 按照 Dennis Jaheruddin 的要求提供一个小规模的例子。这是手工制作的,不是真实数据。周期性只是为了帮助读者了解comaprisons中使用的事件。

event1=[125, 1500, 5000, 15000, 22349,25000, 35000, 45000, 55000, 60325, 65000, 75000, 85000, 91117, 95000];
event2=[1750, 7000, 17000, 21562, 27000, 37000, 47000, 57000, 60256, 67000, 77000, 87000, 97000];
event3=[1126, 9000, 19000, 29000, 30130, 39000, 49000, 59000, 69000, 79000, 89000, 91560, 99000, 120000];
event4=[1, 1975, 11000, 21000, 31000, 31159, 41000, 51000, 60112, 61000, 71000, 81000, 91000, 91001, 101000, 130000];

然后:

  • 匹配 1、2、3 和 4 = 1
  • 匹配 1 & 2 = 1
  • 匹配 3 & 4 = 1
  • 匹配 1、2 和 4 = 1
  • 匹配 1、3 和 4 = 1
  • 其余所有匹配项为零。
4

1 回答 1

0

根据问题和评论,我认为关键是ismemberf文件交换提交

它允许您检查一组中的哪些值出现在具有一定容差的另一组中。例如:

% How many elements from event1 are close to an element of event2?
% 3 elements
sum(ismemberf(event1,event2,'tol',1000)) 
% At how many positions are both event1 and event2 are close to an element in event4?
% At exactly 1 position
sum(ismemberf(event1(1:13),event4,'tol',1000)&ismemberf(event2,event4,'tol',1000)) 

可能这不是您所需要的全部,但从这里开始构建应该很容易。

于 2013-08-21T11:35:58.200 回答