【发布时间】:2015-12-29 23:45:11
【问题描述】:
我有这样的数据:
1 0 1
1 1 1
0 1 1
1 1 1
1 1 1
1 1 1
1 1 0
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
0 0 1
1 1 1
1 1 1
1 1 1
每一列代表一个设备,每一行代表一个时间段。每个数据点指示设备在该时间段内是否处于活动状态。我正在尝试计算每个设备处于活动状态的每个正常运行时间或“咒语”的长度。换句话说,每列中每个连续咒语的长度。在这种情况下,第一列将是 2 11 3,依此类推。
这很容易在一台设备上完成(单列数据):
rng(1)
%% Parameters
lambda = 0.05; % Pr(failure)
N = 1; % number of devices
T = 18; % number of time periods in sample
%% Generate example data
device_status = [rand(T, N) >= lambda ; false(1, N)];
%% Calculate spell lengths, i.e. duration of uptime for each device
cumul_status = cumsum(device_status);
% The 'cumul_status > 0' condition excludes the case where the vector begins with one
% or more zeros
cumul_uptimes = cumul_status(device_status == 0 & cumul_status > 0);
uptimes = cumul_uptimes - [0 ; cumul_uptimes(1:end-1)];
所以我可以简单地遍历列并一次执行一列,并使用parfor(例如)并行运行它。有没有办法使用矢量化矩阵运算同时在所有列上执行此操作?
编辑:我应该补充一点,这很复杂,因为每个设备可能有不同数量的正常运行时间。
【问题讨论】:
-
您可以尝试使用类似:
reshape(max(cumsum(cumprod(hankel([zeros(1,size(A,2));A])'))),size(A,1)+1,size(A,2));其中 A 是矩阵。然后你可以找到局部最大值,但有时使用循环会更好更快。 -
如果您没有那么多设备,那么我认为将这种方法与循环一起使用是非常好的。不要把事情复杂化。 Donald Knuth 说它是最好的“过早的优化是万恶之源”。除非您可以清楚地看到单独循环每个设备与尝试以矢量化方式对所有设备执行此操作之间存在巨大的运行时差异,否则不值得这样做。
-
另外作为旁注,您可能不会为每列获得相同数量的正常运行时间。特别是在您的示例中,第一列有三个正常运行时间实例,而最后两个有两个。这种“不均匀”已经阻碍了您的矢量化能力。
-
@rayryeng 这是一个很好的观点。我最初意识到这一点,但我忘了在我的问题中明确说明。我添加了一个编辑。另外,你说得对,循环可能是我最好的选择。我主要是为了教育而问这个问题,因为我在问 SO 的时候总是学到不少东西。
标签: arrays matlab matrix vectorization