使用 mathdotnet 进行互相关
Cross correlation using mathdotnet
我最近开始使用 Mathdotnet Numerics 统计包在 c# 中进行数据分析。
我正在寻找互相关函数。 Mathdotnet 是否为此提供 API?
以前我一直在使用 MATLAB xcorr
或 Python numpy.correlate
。所以我正在寻找与这些等效的 C#。
我查看了他们的文档,但不是很简单。
https://numerics.mathdotnet.com/api/
可以通过 MathNet.Numerics.Statistics.Correlation
中的任何方法计算相关性,例如 Pearson
或 Spearman
。但是,如果您正在寻找类似 Matlab 的 xcorr
或 autocorr
提供的结果,那么您必须使用这些方法为输入样本之间的每个 lag/delay 值手动计算相关性。请注意,此示例同时包括交叉相关和自相关。
double fs = 50; //sampling rate, Hz
double te = 1; //end time, seconds
int size = (int)(fs * te); //sample size
var t = Enumerable.Range(0, size).Select(p => p / fs).ToArray();
var y1 = t.Select(p => p < te / 2 ? 1.0 : 0).ToArray();
var y2 = t.Select(p => p < te / 2 ? 1.0 - 2*p : 0).ToArray();
var r12 = StatsHelper.CrossCorrelation(y1, y2); // Y1 * Y2
var r21 = StatsHelper.CrossCorrelation(y2, y1); // Y2 * Y1
var r11 = StatsHelper.CrossCorrelation(y1, y1); // Y1 * Y1 autocorrelation
StatsHelper:
public static class StatsHelper
{
public static LagCorr CrossCorrelation(double[] x1, double[] x2)
{
if (x1.Length != x2.Length)
throw new Exception("Samples must have same size.");
var len = x1.Length;
var len2 = 2 * len;
var len3 = 3 * len;
var s1 = new double[len3];
var s2 = new double[len3];
var cor = new double[len2];
var lag = new double[len2];
Array.Copy(x1, 0, s1, len, len);
Array.Copy(x2, 0, s2, 0, len);
for (int i = 0; i < len2; i++)
{
cor[i] = Correlation.Pearson(s1, s2);
lag[i] = i - len;
Array.Copy(s2,0,s2,1,s2.Length-1);
s2[0] = 0;
}
return new LagCorr { Corr = cor, Lag = lag };
}
}
延迟校正:
public class LagCorr
{
public double[] Lag { get; set; }
public double[] Corr { get; set; }
}
编辑:添加Matlab比较结果:
clear;
step=0.02;
t=[0:step:1-step];
y1=ones(1,50);
y1(26:50)=0;
y2=[1-2*t];
y2(26:50)=0;
[cor12,lags12]=xcorr(y1,y2);
[cor21,lags21]=xcorr(y2,y1);
[cor11,lags11]=xcorr(y1,y1);
[cor22,lags22]=xcorr(y2,y2);
subplot(2,3,1);
plot(t,y1);
title('Y1');
axis([0 1 -0.5 1.5]);
subplot(2,3,2);
plot(lags12,cor12);
title('Y1*Y2');
axis([-30 30 0 15]);
subplot(2,3,3);
plot(lags11,cor11);
title('Y1*Y1');
axis([-30 30 0 30]);
subplot(2,3,4);
plot(t,y2);
title('Y2');
axis([0 1 -0.5 1.5]);
subplot(2,3,5);
plot(lags21,cor21);
title('Y2*Y1');
axis([-30 30 0 15]);
subplot(2,3,6);
plot(lags22,cor22);
title('Y2*Y2');
axis([-30 30 0 10]);
我已经用相对于第一个正弦波向后移动 20 个时间单位的正弦波尝试了上述解决方案。它给了我正确的结果,即相关性的最大值为 -20(见下文)。人们可以讨论是否适合应用零填充,零通常不是信号的一部分。 MATLAB 互相关没有以相同的方式归一化,它不是上面示例中的“Pearson 相关”。
MATLAB 互相关的定义不同:对于缩放选项“none”,它是与时间反转信号的卷积。还有各种缩放选项,但其中 none 给出与 Pearson 相关性相同的结果:
matlab definition of xcorr
我的结果:sin(n*0.1)
与 sin(n*0.1 - 20*0.1)
使用上面的例子互相关:
我最近开始使用 Mathdotnet Numerics 统计包在 c# 中进行数据分析。
我正在寻找互相关函数。 Mathdotnet 是否为此提供 API?
以前我一直在使用 MATLAB xcorr
或 Python numpy.correlate
。所以我正在寻找与这些等效的 C#。
我查看了他们的文档,但不是很简单。 https://numerics.mathdotnet.com/api/
可以通过 MathNet.Numerics.Statistics.Correlation
中的任何方法计算相关性,例如 Pearson
或 Spearman
。但是,如果您正在寻找类似 Matlab 的 xcorr
或 autocorr
提供的结果,那么您必须使用这些方法为输入样本之间的每个 lag/delay 值手动计算相关性。请注意,此示例同时包括交叉相关和自相关。
double fs = 50; //sampling rate, Hz
double te = 1; //end time, seconds
int size = (int)(fs * te); //sample size
var t = Enumerable.Range(0, size).Select(p => p / fs).ToArray();
var y1 = t.Select(p => p < te / 2 ? 1.0 : 0).ToArray();
var y2 = t.Select(p => p < te / 2 ? 1.0 - 2*p : 0).ToArray();
var r12 = StatsHelper.CrossCorrelation(y1, y2); // Y1 * Y2
var r21 = StatsHelper.CrossCorrelation(y2, y1); // Y2 * Y1
var r11 = StatsHelper.CrossCorrelation(y1, y1); // Y1 * Y1 autocorrelation
StatsHelper:
public static class StatsHelper
{
public static LagCorr CrossCorrelation(double[] x1, double[] x2)
{
if (x1.Length != x2.Length)
throw new Exception("Samples must have same size.");
var len = x1.Length;
var len2 = 2 * len;
var len3 = 3 * len;
var s1 = new double[len3];
var s2 = new double[len3];
var cor = new double[len2];
var lag = new double[len2];
Array.Copy(x1, 0, s1, len, len);
Array.Copy(x2, 0, s2, 0, len);
for (int i = 0; i < len2; i++)
{
cor[i] = Correlation.Pearson(s1, s2);
lag[i] = i - len;
Array.Copy(s2,0,s2,1,s2.Length-1);
s2[0] = 0;
}
return new LagCorr { Corr = cor, Lag = lag };
}
}
延迟校正:
public class LagCorr
{
public double[] Lag { get; set; }
public double[] Corr { get; set; }
}
编辑:添加Matlab比较结果:
clear;
step=0.02;
t=[0:step:1-step];
y1=ones(1,50);
y1(26:50)=0;
y2=[1-2*t];
y2(26:50)=0;
[cor12,lags12]=xcorr(y1,y2);
[cor21,lags21]=xcorr(y2,y1);
[cor11,lags11]=xcorr(y1,y1);
[cor22,lags22]=xcorr(y2,y2);
subplot(2,3,1);
plot(t,y1);
title('Y1');
axis([0 1 -0.5 1.5]);
subplot(2,3,2);
plot(lags12,cor12);
title('Y1*Y2');
axis([-30 30 0 15]);
subplot(2,3,3);
plot(lags11,cor11);
title('Y1*Y1');
axis([-30 30 0 30]);
subplot(2,3,4);
plot(t,y2);
title('Y2');
axis([0 1 -0.5 1.5]);
subplot(2,3,5);
plot(lags21,cor21);
title('Y2*Y1');
axis([-30 30 0 15]);
subplot(2,3,6);
plot(lags22,cor22);
title('Y2*Y2');
axis([-30 30 0 10]);
我已经用相对于第一个正弦波向后移动 20 个时间单位的正弦波尝试了上述解决方案。它给了我正确的结果,即相关性的最大值为 -20(见下文)。人们可以讨论是否适合应用零填充,零通常不是信号的一部分。 MATLAB 互相关没有以相同的方式归一化,它不是上面示例中的“Pearson 相关”。
MATLAB 互相关的定义不同:对于缩放选项“none”,它是与时间反转信号的卷积。还有各种缩放选项,但其中 none 给出与 Pearson 相关性相同的结果: matlab definition of xcorr
我的结果:sin(n*0.1)
与 sin(n*0.1 - 20*0.1)
使用上面的例子互相关: