4

我定期收到一个数据缓冲区,其中包含许多在时间上相隔固定距离的值。我需要区分它们。好久没在学校学微积分了……

我想出的是:

function DifferentiateBuffer(
  ABuffer: TDoubleDynArray; AVPS: integer): TDoubleDynArray;
var
  i: integer;
  dt, dy: double;
begin
  if (AVPS = 0) then exit;

  // calc the delta time
  dt := 1 / AVPS;

  // run through the whole buffer
  for i := 0 to high(ABuffer) do begin
    if (i = 0) then
      if (IsNan(FLastDiffValue) = false) then
        dy := ABuffer[0] - FLastDiffValue
      else
        dy := ABuffer[0]
    else
      dy := Abuffer[i] - ABuffer[i -1];

    result[i] := dy / dt
  end;

  // remember the last value for next time
  FLastDiffValue := ABuffer[high(ABuffer)];
end;

AVPS 是每秒的值。一个典型的值在 10 到 100 之间。缓冲区的长度通常是 500 到 1000 个值。

我用与前一个数据块连续的新数据一次又一次地调用缓冲区,因此下次保留块的最后一个值。最后一个值在构造函数中设置为 NAN。

我所做的是否正确?即,它会正确区分这些值吗?

我还需要整合类似的数据……那可能是什么样子?

4

1 回答 1

4

我找不到任何错误。

第一次调用时返回的第一个值将(ABuffer[0] - 0.0) / dt是基于信号以零开始的假设。我想这就是你的意图。

现在,与其要求 Stack Overflow 社区检查您的代码,您自己可以做得更好。您应该测试代码以证明它是准确的。使用单元测试框架对其进行测试,例如 DUnitX。输入您可以预测输出的函数值。例如,输入 y = x 2或 y = sin(x) 的值。

编写测试的另一个好处是它们可以一次又一次地执行。在开发代码时,您会冒着引入错误的风险。今天的代码可能是正确的,但谁知道你明天修改后它是否仍然正确。如果您有一个强大的测试,您可以防御在维护期间引入的故障。

关于风格的一种评论是,你永远不应该测试= false= true. 该if语句对布尔表达式进行操作,因此与布尔值进行比较总是毫无意义的。我会这样写你的测试:

if not IsNan(FLastDiffValue) then
  dy := ABuffer[0] - FLastDiffValue
else
  dy := ABuffer[0]

或像这样:

if IsNan(FLastDiffValue) then
  dy := ABuffer[0]
else
  dy := ABuffer[0] - FLastDiffValue
于 2013-09-27T15:47:36.673 回答