关联 C# 中两个不同长度的信号
Correlate two signals in C# with different length
我有一个信号,我将它实时存储在 c# 的列表中。我还有一个参考信号,我想将其与实时信号进行比较。这两个信号的大小不同。我怎样才能对齐这两个信号?我如何在 c# 中关联它们我的意思是有计算相关性的函数吗?
我认为您需要重新考虑您的数据结构。目前尚不清楚信号是否;
- 涵盖不同的时间跨度;
- 读数之间有不同的时间步长;
- 或两者兼而有之。
在第一种情况下,您可以简单地裁剪系列,使它们具有相同的长度并覆盖相同的时间跨度。但是,数字列表只能包含 值 ,而不是它们对应的时间。如果您不将此信息存储在程序的其他位置,那么您将无法进行剪辑。
在第二种情况下,您需要选择一个合适的系列或时间,并使您的两个信号都符合它。这可能会采取一系列 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 图表上绘制数组。您会看到图表线具有相同的形状。
然后使用任何相关系数公式将其与所需数组进行比较。
我有一个信号,我将它实时存储在 c# 的列表中。我还有一个参考信号,我想将其与实时信号进行比较。这两个信号的大小不同。我怎样才能对齐这两个信号?我如何在 c# 中关联它们我的意思是有计算相关性的函数吗?
我认为您需要重新考虑您的数据结构。目前尚不清楚信号是否;
- 涵盖不同的时间跨度;
- 读数之间有不同的时间步长;
- 或两者兼而有之。
在第一种情况下,您可以简单地裁剪系列,使它们具有相同的长度并覆盖相同的时间跨度。但是,数字列表只能包含 值 ,而不是它们对应的时间。如果您不将此信息存储在程序的其他位置,那么您将无法进行剪辑。
在第二种情况下,您需要选择一个合适的系列或时间,并使您的两个信号都符合它。这可能会采取一系列 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 图表上绘制数组。您会看到图表线具有相同的形状。
然后使用任何相关系数公式将其与所需数组进行比较。