关联 C# 中两个不同长度的信号

Correlate two signals in C# with different length

我有一个信号,我将它实时存储在 c# 的列表中。我还有一个参考信号,我想将其与实时信号进行比较。这两个信号的大小不同。我怎样才能对齐这两个信号?我如何在 c# 中关联它们我的意思是有计算相关性的函数吗?

我认为您需要重新考虑您的数据结构。目前尚不清楚信号是否;

  1. 涵盖不同的时间跨度;
  2. 读数之间有不同的时间步长;
  3. 或两者兼而有之。

在第一种情况下,您可以简单地裁剪系列,使它们具有相同的长度并覆盖相同的时间跨度。但是,数字列表只能包含 ,而不是它们对应的时间。如果您不将此信息存储在程序的其他位置,那么您将无法进行剪辑。

在第二种情况下,您需要选择一个合适的系列或时间,并使您的两个信号都符合它。这可能会采取一系列 lerp 操作的形式来填充目标点。

// x - the first value
// y - the second value
// t - the distance from the first to the second value, normalized to 0..1
public static float Lerp(float x, float y, float t) {

    return x + t * (y - x);
}

如您所见,执行Lerp需要t,这可以根据两个已知点的时间值计算得出。

更好的数据结构可能是时间到值的映射:

var signal = new Dictionary<DateTime, double>();

这样您就可以更轻松地跟踪阅读发生的时间。

Whosebug 上已经有 question about performing the actual correlation

顺便说一句,R 让这件事变得相当容易 - 查看 zoo 包以获得灵感。

您将无法找到不同长度数组之间的相关性。您需要使较短的数组变长,或使较长的数组变短。我建议您考虑 Autoregressive conditional heteroskedasticity and/or Vector autoregression 以便通过延长或缩短数组来进行操作。之后就可以进行相关计算了。

使用以下 VB.NET 代码创建相同大小的数组。它基本上 stretch/compress 一个数组,同时它将保持值的线性序列。

例如{2, 4, 6} 将被拉伸到 9 作为 {2.0、2.5、3.0、3.5、4.0、4.5、5.0、5.5、6.0}

Public Sub Process
        Dim requiredLength As Integer = 10
        Dim originalArr() As Double = {2.2, 3.3, 4.4, 4}

        Dim lcm As Integer = GetLCM(originalArr.Length - 1, requiredLength - 1)

        Dim finalArr(requiredLength - 1) As Double
        Dim finalIndex As Integer = 0
        Dim originalIndex As Integer = 0
        Dim currentValue As Double

        Dim portionRatio As Integer = (lcm / (originalArr.Length - 1))
        Dim portionValue As Double = 0
        For i = 0 To lcm
            If portionRatio = 1 Or (i + 1) Mod portionRatio = 1 Then
                currentValue = originalArr(originalIndex)

                If originalIndex < originalArr.Length - 1 Then portionValue = (originalArr(originalIndex + 1) - originalArr(originalIndex)) / (lcm - 1)

                originalIndex += 1
            Else
                currentValue += portionValue
            End If

            If i Mod (lcm / (requiredLength - 1)) = 0 Then
                finalArr(finalIndex) = currentValue
                finalIndex += 1
            End If
        Next
End Sub

Private Function GetGCD(num1 As Integer, num2 As Integer) As Integer
    While (Not num1 = num2)
        If num1 > num2 Then num1 = num1 - num2
        If num2 > num1 Then num2 = num2 - num1
    End While

    Return num1
End Function

Private  Function GetLCM(num1 As Integer, num2 As Integer) As Integer
    Return (num1 * num2) / GetGCD(num1, num2)
End Function

如果您在过程前后的 excel 图表上绘制数组。您会看到图表线具有相同的形状。

然后使用任何相关系数公式将其与所需数组进行比较。