【问题标题】:Matlab vectorisation of loop "tracking value increments"循环“跟踪值增量”的Matlab矢量化
【发布时间】:2014-09-25 09:31:21
【问题描述】:

我一直在努力优化一个需要处理很长数组的 matlab 脚本。

基本上有 2 个数组:AbsoluteTimeTagChannel

AbsoluteTimeTag 将保存表示使用 16 位计数器记录的时间的 int 值。由于计数器限制为 2^16 个值,因此在测量过程中它经常会翻转。 Channel 注册它,当它注册时,bitand(Channel,2048) 将评估为真。

这些数组的生成方式超出了我的控制范围,溢出标记与传入的数据“同步”发生。

现在很容易重建绝对时间:

AbsoluteTimeTag(i) = NoOfOverflows * 65536 + TimeTag(i);

在循环中:

for i=1:NumberOfRecords

    %Running through all records, if we meet anything other than an
    %overflow record, we van just calculate its absolute time based on
    %current overflow count and its timetag.
    AbsoluteTimeTag(i) = NoOfOverflows * 65536 + TimeTag(i);

    % We are running through all records so if we encounter an overflow
    % (signified by bitand(..., 2048), we add 1 to the overflow count.
    if bitand(Channel(i),2048)
        NoOfOverflows = NoOfOverflows + 1;
    end;
end;

我真的很想知道如何将这个向量化(因为 Matlab 不擅长循环)。然而,到目前为止,由于某种原因,我没有看到光明。

问题是沿着AbsoluteTimeTag 的某个记录索引的溢出次数可能会随着您从头到尾遍历向量而改变。

我不知道如何在向量化操作中表达“计数到此为止所有发生的溢出”。

有人可以评论这是否可行吗?

编辑

示例数据如下所示:

TimeTag(为简单起见,每个元素都是一个事件,其时间在 2^3 寄存器中计数):

[ 01 03 04 07 xx 02 03 04 05 xx 01 03 04 07 xx ... ]

溢出:

[ 00 00 00 00 01 00 00 00 00 01 00 00 00 00 01 ... ]

这需要让步

[ 01 03 04 07 xx 10 11 12 13 xx 17 19 20 23 xx ... ]

存在 xx 的原因是因为最初,所有记录,包括事件和溢出都在一个大的 uint32 数组中,其中每条记录在不同位上保存不同类型的信息。 xx 个位置可以进行任何操作,但在考虑 TimeTag 记录时它们进一步没有意义。我有一个逻辑数组来跟踪哪些位置保存了实际有意义的数据。

【问题讨论】:

  • 嗨,我最终需要计算溢出的数量。但是,如果有意义的话,我需要仅使用“直到该点”的溢出事件对时间标签数组的每个元素执行与溢出计数的乘法...我将使用示例数据修改 Q...
  • 那么,对于xx locationsAbsoluteTimeTag 值将与对应的TimeTag 值相同?你是说你有另一个数组告诉我们这些值是否为xx?如果是这样,那将具有与AbsoluteTimeTagTimetag 相同数量的元素,对吧?
  • 嗨 Divakar,确实,对于 xx 位置,我将应用相同的乘法,即 65536 * noOfOverflows(到那时)+ 16 位时间标签。基本上,这些 xx 位置保存溢出事件本身的 16 位时间标签,而其他时间标签位置是有趣事件(光子检测)的时间标签。

标签: matlab for-loop vectorization


【解决方案1】:

"count all occurrences of ... to this point" in a vectored operation 最好表示为 cumsum

假设NoOfOverflows 在循环开始之前被初始化为零并且AbsoluteTimeTagTimetagNumberOfRecords 作为它们的元素数,看看这是否适合你-

%// Get the overflow for all Channel entries in one go
bitand_all = bitand(Channel,2048)~=0; 

%// AbsoluteTimeTag appears to be a cumsum of overflows plus Timetag
AbsoluteTimeTag = [0 ; cumsum(bitand_all(1:end-1).*65536)]+ TimeTag;

%// Get the count of overflows as NoOfOverflows
NoOfOverflows = sum(bitand_all);

【讨论】:

  • 我不知道cumsum的存在......有时这些事情完全让我逃脱了。我会检查一下。已经感谢您的建议。
  • @Kris 所以,对于 xx 位置的事情,您需要在最后添加它 - AbsoluteTimeTag(logical_array_xx_locations) = TimeTag,其中 logical_array_xx_locations 是逻辑数组,其中 xx 位置和否则为零。
  • 嗨 Divakar,您的解决方案就像一个魅力,几乎就像是一样(xx 的事情并不重要)。您的代码输出与 Q 中的循环相同。非常感谢先生! :) 一个小评论:为了能够对+ TimeTag 求和,我需要将 + 之前的数组转换为 uint32,因为 TimeTag 本身就是 uint32。无论如何,在某些情况下,我不禁对 Matlab 的简洁性感到惊讶。循环很糟糕,但矢量化可以非常快。
  • @Kris 太棒了!好吧,我也认为 xx 不需要,但我不是 100% 确定它,所以把它作为评论。关于类转换的要点!
  • @Kris 向量化规则!! ;) 好吧,只要有可能(没有可以跟踪依赖关系的依赖情况或依赖情况),就必须尝试矢量化! :) 例如在这种情况下,我们有依赖关系,但依赖关系是一个简单的运行总和,所以它起作用了。
猜你喜欢
  • 2014-09-25
  • 1970-01-01
  • 2011-11-26
  • 2015-02-03
  • 2017-01-04
  • 2014-05-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多