What is incorrect in my autocorrelation computation?

55 views Asked by At

In the following source codes, Python and R are giving the same result.

However, C# is giving an incorrect result.

How can I fix the C# code?

Input data:

[1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 3.33]

Python code:

import numpy as np
data = np.array([1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 3.33])
n = len(data)
mean = np.mean(data)
autocorrelations = {}
for lag in range(1, n):
    cov = np.sum((data[:-lag] - mean) * (data[lag:] - mean))
    var = np.sum((data - mean) ** 2)
    autocorrelations[lag] = cov / var
print(autocorrelations)

Output:

{1: 0.3907255328740364, 2: 0.13718688954560562, 
3: -0.08148897368528898, 4: -0.24787066676987946, 
5: -0.3445267996593978, 6: -0.3540259823050758}

R code:

values <- c(1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 3.33)
autocorrelations <- sapply(1:(length(values)-1), function(lag) {
  acf(values, lag.max=lag, plot=FALSE)$acf[lag + 1]
})
autocorrelations

Output:

0.39072553  0.13718689 -0.08148897 -0.24787067 -0.34452680 -0.35402598

C# code:

using MathNet.Numerics.Statistics;
using System;
using System.Collections.Generic;
using System.Linq;

namespace AutoCorrUsingMathNet
{
    public class Statistics
    {
        private List<double> data_;

        public Statistics(List<double> data)
        {
            if (data == null || !data.Any())
                throw new ArgumentException("Data cannot be null or empty.", nameof(data));
            data_ = data;
        }        

        public double AutocorrelationCoeff(int lag)
        {
            if (lag >= data_.Count || lag < 0)
                throw new ArgumentException("Lag is out of range.", nameof(lag));

            var laggedData = data_.Skip(lag).ToList();
            var originalData = data_.Take(data_.Count - lag).ToList();

            return Correlation.Pearson(originalData, laggedData);
        }

        public (List<double>, List<double>) AutoCorrelationPoints(double thresholdMin = 0.0001, double thresholdMax = 0.9999, double numLag = 1000)
        {
            List<double> tau = new List<double>();
            List<double> autocorrelationValues = new List<double>();
            for (int lag = 0; lag < numLag; lag++)
            {
                double autoCorr = AutocorrelationCoeff(lag);
                if (thresholdMin < autoCorr && autoCorr < thresholdMax)
                {
                    tau.Add(lag);
                    autocorrelationValues.Add(autoCorr);
                }
            }

            return (tau, autocorrelationValues);
        }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            List<double> dataList = new List<double>(new double[] { 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 3.33 });
            List<double> autoCorrExpectedList = new List<double>(new double[] { 0.3907, 0.1372, -0.0029, -0.2479 });
            Statistics stats = new Statistics(dataList);
            var autoCorr = stats.AutoCorrelationPoints(numLag: dataList.Count - 1);
            List<double> lagList = autoCorr.Item1;
            List<double> autoCorrActualList = autoCorr.Item2;

            foreach (var item in autoCorrActualList)
            {
                Console.WriteLine(item);
            }

            Console.ReadKey();
        }
    }
}

Output:

0.937411546203842
0.928784324059631
0.926084997966767
0.940797041158867
0

There are 0 answers