【问题标题】:Cross correlation using mathdotnet使用 mathdotnet 的互相关
【发布时间】:2017-09-26 06:33:26
【问题描述】:

我最近开始使用 Mathdotnet Numerics 统计包在 c# 中进行数据分析。

我正在寻找互相关函数。 Mathdotnet 有这方面的 API 吗?

之前我一直在使用 MATLAB xcorr 或 Python numpy.correlate。所以我正在寻找与这些等效的 C#。

我查看了他们的文档,但不是很简单。 https://numerics.mathdotnet.com/api/

【问题讨论】:

    标签: c# matlab math cross-correlation math.net


    【解决方案1】:

    可以通过MathNet.Numerics.Statistics.Correlation 中的任何方法计算相关性,例如PearsonSpearman。但是,如果您正在寻找像 Matlab 的 xcorrautocorr 提供的结果,那么您必须使用这些方法手动计算输入样本之间的每个滞后/延迟值的相关性。请注意,此示例包括交叉关联和自动关联。

    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 };
        }
    }
    

    LagCorr:

    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]);
    

    【讨论】:

    • 我尝试使用此解决方案,但我总是在滞后 0 时获得最大相关性。我的源数据肯定会偶尔发生明显的滞后。当我使用 Pandas 包在 Python 中运行此程序时,我能够检测到大多数具有延迟的地方,因为最强的相关性将处于某些滞后状态,但在 Math.Net 中,它始终处于滞后 0 并且随后的每个滞后都在减少。
    【解决方案2】:

    我已经尝试了上述解决方案,正弦波相对于第一个正弦波向后移动了 20 个时间单位。它给了我正确的结果,即相关性的最大值为 -20(见下文)。可以讨论应用零填充是否合适,零通常不是信号的一部分。 MATLAB 互相关不是以同样的方式归一化的,它不是上面示例中的“Pearson 相关”。

    MATLAB 互相关的定义不同:对于缩放选项“无”,它是与时间反转信号的卷积。还有各种缩放选项,但没有一个给出与 Pearson 相关性相同的结果: matlab definition of xcorr

    我的结果:sin(n*0.1)sin(n*0.1 - 20*0.1) 的互相关使用上面的示例:

    【讨论】:

      猜你喜欢
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      • 1970-01-01
      • 2013-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多