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