【问题标题】:Detecting and fixing overflows检测和修复溢出
【发布时间】:2009-05-29 04:13:48
【问题描述】:

我们有一个粒子探测器硬连线以使用 16 位和 8 位缓冲区。时不时地,有某些[预测的]粒子通量峰值穿过它;没关系。 好的是这些通量通常达到超过缓冲区存储它们的容量的数量级。因此,会发生溢出。在图表上,它们看起来像通量突然下降并再次开始增长。您能否提出一种 [大部分] 准确的方法来检测遭受溢出的数据点?

附:探测器在物理上无法访问,因此通过更换缓冲区以“正确的方式”修复它似乎不是一种选择。

更新:应要求作出一些澄清。我们在数据处理设施中使用 python;检测器本身使用的技术非常晦涩(将其视为由完全不相关的第三方开发),但它绝对不复杂,即不运行“真正的”操作系统,只是一些低级的东西来记录检测器读数并响应远程命令,如电源循环。内存损坏和其他问题现在不是问题。发生溢出仅仅是因为探测器的设计者使用 16 位缓冲区来计算粒子通量,有时通量超过每秒 65535 个粒子。

更新 2: 正如几位读者指出的那样,预期的解决方案与分析通量剖面以检测急剧下降(例如,一个数量级)以尝试分离他们从正常的波动。另一个问题出现了:是否可以通过简单地针对恢复的(按 x 轴)通量剖面运行校正程序来检测恢复(原始通量下降到溢出水平以下的点)?

【问题讨论】:

  • 负值监控不起作用?
  • 不,变量是无符号的。

标签: math overflow data-analysis


【解决方案1】:
int32[] unwrap(int16[] x)
{
   // this is pseudocode
   int32[] y = new int32[x.length];
   y[0] = x[0];
   for (i = 1:x.length-1)
   {
      y[i] = y[i-1] + sign_extend(x[i]-x[i-1]);
      // works fine as long as the "real" value of x[i] and x[i-1]
      // differ by less than 1/2 of the span of allowable values
      // of x's storage type (=32768 in the case of int16)
      // Otherwise there is ambiguity.
   }
   return y;
}

int32 sign_extend(int16 x)
{
   return (int32)x; // works properly in Java and in most C compilers
}

// exercise for the reader to write similar code to unwrap 8-bit arrays
// to a 16-bit or 32-bit array

【讨论】:

    【解决方案2】:

    当然,理想情况下,您最好将检测器软件修复为最大 65535,以防止导致您悲伤的那种环绕。我知道这并不总是可能的,或者至少并不总是可以快速做到。

    当粒子通量超过65535时,是这么快,还是通量逐渐增加,然后逐渐减少?这会影响您可以使用哪种算法来检测这一点。例如,如果通量上升足够慢:

    true flux     measurement  
     5000           5000
    10000          10000
    30000          30000
    50000          50000
    70000           4465
    90000          24465
    60000          60000
    30000          30000
    10000          10000
    

    那么当你溢出时,你往往会有一个负下降。比您在任何其他时间都大得多的负下降。这可以作为您已经溢出的信号。要查找溢出时间段的结束,您可以查找到距离 65535 不远的值的大跳转。

    所有这些都取决于可能的最大真实通量以及通量上升和下降的速度。例如,是否有可能在一个测量周期内获得超过 128k 的计数?是否有可能一次测量为 5000,而下一次测量为 50000?如果数据表现得不够好,你可能只能对何时溢出进行统计判断。

    【讨论】:

    • 1) 是的,不幸的是,可能会导致多次溢出。 2)一般轮廓是可预测的,即当由两个或三个相邻点平均时,轮廓变得[几乎]平滑。然而,原始数据有很多随机波动,所以这里和那里有多次[急剧]下降。尽管寻找非常大的下跌可能会有所帮助。但是,如果原始值接近例如,这将不起作用。从下面看 128k,因为当它被 64k 切割时,它看起来是通量分布的自然延续。
    【解决方案3】:

    您的问题需要提供有关您的实施的更多信息 - 您使用的是什么语言/框架?

    软件中的数据溢出(我认为您正在谈论)是不好的做法,应该避免。虽然您看到(奇怪的数据输出)只是遇到数据溢出时可能出现的一种副作用,但这只是您可以看到的各种问题的冰山一角。

    您可能很容易遇到更严重的问题,例如内存损坏,这可能导致程序严重崩溃,或者更糟的是,不明显

    您是否可以进行任何验证来防止溢出发生?

    【讨论】:

    • 在问题文本中添加了说明。
    【解决方案4】:

    我真的不认为你可以在不修复底层缓冲区的情况下修复它。您应该如何区分值序列 (0, 1, 2, 1, 0) 和 (0, 1, 65538, 1, 0) 之间的区别?你不能。

    【讨论】:

    • 也许通过计算导数并寻找它与预测的不同的点?我不太确定如何,这就是我要问的原因,但提取信息特征到描述通量分布的函数似乎是要走的路。
    【解决方案5】:

    如何使用 HMM,其中隐藏状态是您是否处于溢出状态并且排放是观察到的粒子通量?

    棘手的部分是为转换(基本上将编码峰值的时间尺度)和排放(如果您知道通量如何表现以及溢出如何影响测量,您可以构建它)的概率模型)。这些是特定领域的问题,因此可能没有现成的解决方案。

    但是你有模型,其他一切——拟合你的数据、量化不确定性、模拟等等——都是例行公事。

    【讨论】:

      【解决方案6】:

      只有在连续值之间的实际跳跃远小于 65536 时,您才能执行此操作。否则,溢出引起的山谷伪影与真正的山谷无法区分,您只能猜测。您可以尝试通过同时分析来自右侧和左侧的信号(假设存在可识别的基线),将溢出与相应的恢复进行匹配。

      除此之外,你所能做的就是调整你的实验,用不同的原始粒子流重复它,这样真正的山谷不会移动,但人工山谷会移动到溢出点。

      【讨论】:

        猜你喜欢
        • 2023-03-22
        • 1970-01-01
        • 1970-01-01
        • 2011-09-18
        • 1970-01-01
        • 2011-12-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多