我正在更新一些继承的遗留代码,并找到了一种有趣的“方法”来解决我无法优化的问题。
有一组数据可以使用以下方法进行某种程度的模拟:
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
- 其余所有匹配项为零。