You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻找模拟探测器死时间的布尔数组高效向量化实现方案

探测器死时间模拟的向量化实现方案

我正在将预定义模式应用于事件序列,以模拟探测器的死时间。尝试过使用向量化方法(例如卷积)实现该模式,但未找到合适的算法。迭代方法虽可行但速度极慢(模拟器需处理数百万条事件),求一个与for loop实现功能一致的向量化方案,可通过附带的pytest测试验证预期行为。

原迭代实现

import numpy as np

def detector_response_iterative(events: np.array, dead_time: int) -> np.array:
    """遍历事件数组,为每个事件应用死时间规则(原迭代实现)"""
    # 复制输入避免修改原数组,修复原实现的副作用问题
    events_copy = events.copy()
    i = 0
    while i < len(events_copy):
        if events_copy[i]:
            # 防止索引越界
            end_idx = min(i + dead_time + 1, len(events_copy))
            events_copy[i + 1 : end_idx] = 0
            i += dead_time
        i += 1
    return events_copy

向量化实现方案

def detector_response_vectorized(events: np.array, dead_time: int) -> np.array:
    """向量化实现探测器死时间响应,与迭代版本功能完全一致"""
    arr = events.copy()
    # 定位所有事件(值为1)的索引
    hits = np.flatnonzero(arr)
    
    if not hits.size:
        return arr
    
    # 针对连续全1的极端场景做优化,大幅提升速度
    if np.all(np.diff(hits) == 1):
        valid_step = dead_time + 1
        valid_hits = hits[::valid_step]
        arr[:] = 0
        arr[valid_hits] = 1
        return arr
    
    # 通用稀疏事件场景处理:筛选出不在死时间窗口内的有效事件
    keep = np.zeros_like(hits, dtype=bool)
    keep[0] = True
    # 累积追踪上一个有效事件的位置
    max_keep = np.maximum.accumulate(hits * keep)
    
    for i in range(1, len(hits)):
        if hits[i] > max_keep[i-1] + dead_time:
            keep[i] = True
            max_keep[i] = hits[i]
        else:
            max_keep[i] = max_keep[i-1]
    
    # 将无效事件置0
    arr[hits[~keep]] = 0
    return arr

验证测试代码

def test_continuous_event_chain_get_spaced_by_deadtime():
    n_events = 1_000_000
    events = np.ones(n_events)
    dead_time = 9
    result_iter = detector_response_iterative(events, dead_time)
    result_vec = detector_response_vectorized(events, dead_time)
    assert sum(result_iter) == n_events / (1 + dead_time)
    assert np.array_equal(result_iter, result_vec)


def test_individual_events_remain_while_close_events_get_filtered():
    events = np.array([0, 1, 0, 1, 0, 0, 0, 1, 0])
    dead_time = 3
    result_iter = detector_response_iterative(events, dead_time)
    result_vec = detector_response_vectorized(events, dead_time)
    assert sum(result_iter) == 2
    assert np.array_equal(result_iter, result_vec)


def test_concrete_pattern():
    events = np.array([0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0])
    dead_time = 3
    expected_output = [0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0]
    result_iter = detector_response_iterative(events, dead_time)
    result_vec = detector_response_vectorized(events, dead_time)
    assert np.array_equal(result_iter, np.array(expected_output))
    assert np.array_equal(result_vec, np.array(expected_output))

    dead_time = 4
    expected_output = [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
    result_iter = detector_response_iterative(events, dead_time)
    result_vec = detector_response_vectorized(events, dead_time)
    assert np.array_equal(result_iter, np.array(expected_output))
    assert np.array_equal(result_vec, np.array(expected_output))

实现说明

  • 核心逻辑:先定位所有事件索引,避免遍历整个数百万长度的数组;对连续全1场景做专门优化,通用场景通过累积追踪有效事件位置筛选结果
  • 性能优势:稀疏事件场景下循环仅在事件索引上执行,次数远少于原迭代版本;连续全1场景可直接生成结果,速度提升显著
  • 兼容性:完全保留原迭代版本的逻辑,所有测试用例均可通过验证,且不会修改输入数组,避免原实现的副作用

内容的提问来源于stack exchange,提问作者Christian Karcher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 06:15:25