diff --git a/.paket/Paket.Restore.targets b/.paket/Paket.Restore.targets
index 55292f31..e12083c1 100644
--- a/.paket/Paket.Restore.targets
+++ b/.paket/Paket.Restore.targets
@@ -71,7 +71,10 @@
false
true
-
+
+
+ true
+
@@ -132,11 +135,11 @@
-
+
-
+
$([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0])
$([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1])
diff --git a/src/Numerics.Tests/StatisticsTests/CorrelationTests.cs b/src/Numerics.Tests/StatisticsTests/CorrelationTests.cs
index 406acc8b..18369ba1 100644
--- a/src/Numerics.Tests/StatisticsTests/CorrelationTests.cs
+++ b/src/Numerics.Tests/StatisticsTests/CorrelationTests.cs
@@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
//
-// Copyright (c) 2009-2016 Math.NET
+// Copyright (c) 2009-2018 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -32,8 +32,6 @@ using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using MathNet.Numerics.Statistics;
-using MathNet.Numerics.LinearAlgebra.Double;
-using System.IO;
using MathNet.Numerics.TestData;
using System.Globalization;
@@ -67,24 +65,23 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests
[TestCase("numpy.CorrNumpyData_pwm.csv", 0.005)]
[TestCase("numpy.CorrNumpyData_sin.csv", 0.005)]
[TestCase("numpy.CorrNumpyData_rnd.csv", 0.005)]
- public void TestAutocorrelation(string fName, double tol)
+ public void AutoCorrelationTest(string fName, double tol)
{
-
var data = Data.ReadAllLines(fName)
- .Select(line =>
- {
- var vals = line.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
- return new Tuple(vals[0], vals[1]);
- }).ToArray();
+ .Select(line =>
+ {
+ var vals = line.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ return new Tuple(vals[0], vals[1]);
+ }).ToArray();
var series = data.Select(tuple => Double.Parse(tuple.Item1, CultureInfo.InvariantCulture)).ToArray();
var resNumpy = data.Select(tuple => Double.Parse(tuple.Item2, CultureInfo.InvariantCulture)).ToArray();
-
- var resMathNet = Statistics.Correlation.AutoCorrelation(series);
-
+ var resMathNet = Correlation.Auto(series);
for (int i = 0; i < resMathNet.Length; i++)
+ {
Assert.AreEqual(resNumpy[i], resMathNet[i], tol);
+ }
}
///
diff --git a/src/Numerics/Statistics/Correlation.cs b/src/Numerics/Statistics/Correlation.cs
index 013a9f38..a2b870b7 100644
--- a/src/Numerics/Statistics/Correlation.cs
+++ b/src/Numerics/Statistics/Correlation.cs
@@ -3,7 +3,7 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
//
-// Copyright (c) 2009-2014 Math.NET
+// Copyright (c) 2009-2018 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
@@ -42,81 +42,88 @@ namespace MathNet.Numerics.Statistics
///
public static class Correlation
{
-
- ///
- /// autocorrelation function (ACF) based on fft (usually faster then direct brute force implementation) for all possible lags k
- /// First element is hidden since ACF(k = 0) = 1
- /// data array to calculate auto correlation for
- /// an array with the ACF as a function of the lags k
- public static double[] AutoCorrelation(IEnumerable x)
+ ///
+ /// Autocorrelation function (ACF) based on FFT for all possible lags k.
+ /// The first element is hidden since ACF(k = 0) = 1.
+ ///
+ /// Data array to calculate auto correlation for.
+ /// An array with the ACF as a function of the lags k.
+ public static double[] Auto(IEnumerable x)
{
- return autoCorrelationFft(x, 0, x.Count() - 1);
+ return AutoCorrelationFft(x, 0, x.Count() - 1);
}
- ///
- /// autocorrelation function (ACF) based on fft (usually faster then direct brute force implementation) for lags
- /// between kMin and kMax
- /// First element is hidden since ACF(k = 0) = 1
- /// the data array to calculate auto correlation for
- /// max lag to calculate ACF for must be positive and smaller than x.Length-1
- /// min lag to calculate ACF for (0 = no shift with acf=1) must be zero or positive and smaller than x.Length-1
- /// an array with the ACF as a function of the lags k
- public static double[] AutoCorrelation(IEnumerable x, int kMax, int kMin = 0)
+ ///
+ /// Autocorrelation function (ACF) based on FFT for lags between kMin and kMax.
+ /// The first element is hidden since ACF(k = 0) = 1.
+ ///
+ /// The data array to calculate auto correlation for.
+ /// Max lag to calculate ACF for must be positive and smaller than x.Length-1.
+ /// Min lag to calculate ACF for (0 = no shift with acf=1) must be zero or positive and smaller than x.Length-1.
+ /// An array with the ACF as a function of the lags k.
+ public static double[] Auto(IEnumerable x, int kMax, int kMin = 0)
{
// assert max and min in proper order
var kMax2 = Math.Max(kMax, kMin);
var kMin2 = Math.Min(kMax, kMin);
- return (autoCorrelationFft(x, kMin2, kMax2));
+ return AutoCorrelationFft(x, kMin2, kMax2);
}
-
- ///
- /// autocorrelation function based on fft for lags k (faster than brute force calculation for big sample sizes).
- /// First element is skipped since ACF(k = 0) = 1
- /// the data array to calculate auto correlation for
- /// array with lags to calculate ACF for
- /// an array with the ACF as a function of the lags k
- public static double[] AutoCorrelation(IEnumerable x, int[] k)
+ ///
+ /// Autocorrelation function based on FFT for lags k.
+ /// The first element is hidden since ACF(k = 0) = 1.
+ ///
+ /// The data array to calculate auto correlation for.
+ /// Array with lags to calculate ACF for.
+ /// An array with the ACF as a function of the lags k.
+ public static double[] Auto(IEnumerable x, int[] k)
{
if (k == null)
- throw new ArgumentNullException("k");
+ {
+ throw new ArgumentNullException(nameof(k));
+ }
if (k.Length < 1)
+ {
throw new ArgumentException("k");
+ }
// get acf between full range
- var acf = autoCorrelationFft(x, k.Min(), k.Max());
+ var acf = AutoCorrelationFft(x, k.Min(), k.Max());
// map output by indexing
- var acfReturn = new double[k.Length];
- for (int i = 0; i < acfReturn.Length; i++)
- acfReturn[i] = acf[k[i]];
+ var result = new double[k.Length];
+ for (int i = 0; i < result.Length; i++)
+ {
+ result[i] = acf[k[i]];
+ }
- return acfReturn;
+ return result;
}
///
- /// this is the internal core method for calculating the autocorrelation
+ /// The internal core method for calculating the autocorrelation.
///
- /// the data array to calculate auto correlation for
- /// min lag to calculate ACF for (0 = no shift with acf=1) must be zero or positive and smaller than x.Length-1
- /// max lag to calculate ACF for must be positive and smaller than x.Length-1
- /// an array with the ACF as a function of the lags k
- private static double[] autoCorrelationFft(IEnumerable x, int k_low, int k_high)
+ /// The data array to calculate auto correlation for
+ /// Min lag to calculate ACF for (0 = no shift with acf=1) must be zero or positive and smaller than x.Length-1
+ /// Max lag to calculate ACF for must be positive and smaller than x.Length-1
+ /// An array with the ACF as a function of the lags k.
+ private static double[] AutoCorrelationFft(IEnumerable x, int k_low, int k_high)
{
if (x == null)
- throw new ArgumentNullException("x");
+ throw new ArgumentNullException(nameof(x));
- if (k_low < 0 || k_low >= x.Count())
- throw new ArgumentOutOfRangeException("kMin must be zero or positive and smaller than x.Length");
- if (k_high < 0 || k_high >= x.Count())
- throw new ArgumentOutOfRangeException("kMax must be positive and smaller than x.Length");
+ int N = x.Count(); // Sample size
+
+ if (k_low < 0 || k_low >= N)
+ throw new ArgumentOutOfRangeException(nameof(k_low), "kMin must be zero or positive and smaller than x.Length");
+ if (k_high < 0 || k_high >= N)
+ throw new ArgumentOutOfRangeException(nameof(k_high), "kMax must be positive and smaller than x.Length");
- if (x.Count() < 1)
+ if (N < 1)
return new double[0];
- int N = x.Count(); // Sample size
int nFFT = Euclid.CeilingToPowerOfTwo(N) * 2;
Complex[] x_fft = new Complex[nFFT];
@@ -133,7 +140,7 @@ namespace MathNet.Numerics.Statistics
if (ii < N)
{
if (!iex.MoveNext())
- throw new ArgumentOutOfRangeException("x");
+ throw new ArgumentOutOfRangeException(nameof(x));
xArrNow = iex.Current;
x_fft[ii] = new Complex(xArrNow - x_dash, 0.0); // copy values in range and substract mean
}
@@ -152,6 +159,7 @@ namespace MathNet.Numerics.Statistics
}
Fourier.Inverse(x_fft2, FourierOptions.Matlab);
+
double acf_Val1 = x_fft2[0].Real;
double[] acf_Vec = new double[k_high - k_low];
@@ -163,7 +171,7 @@ namespace MathNet.Numerics.Statistics
acf_Vec[ii] = x_fft2[k_low + ii + 1].Real / acf_Val1;
}
- return (acf_Vec);
+ return acf_Vec;
}
///
@@ -192,7 +200,7 @@ namespace MathNet.Numerics.Statistics
{
if (!ieB.MoveNext())
{
- throw new ArgumentOutOfRangeException("dataB", Resources.ArgumentArraysSameLength);
+ throw new ArgumentOutOfRangeException(nameof(dataB), Resources.ArgumentArraysSameLength);
}
double currentA = ieA.Current;
@@ -214,7 +222,7 @@ namespace MathNet.Numerics.Statistics
if (ieB.MoveNext())
{
- throw new ArgumentOutOfRangeException("dataA", Resources.ArgumentArraysSameLength);
+ throw new ArgumentOutOfRangeException(nameof(dataA), Resources.ArgumentArraysSameLength);
}
}
@@ -248,11 +256,11 @@ namespace MathNet.Numerics.Statistics
{
if (!ieB.MoveNext())
{
- throw new ArgumentOutOfRangeException("dataB", Resources.ArgumentArraysSameLength);
+ throw new ArgumentOutOfRangeException(nameof(dataB), Resources.ArgumentArraysSameLength);
}
if (!ieW.MoveNext())
{
- throw new ArgumentOutOfRangeException("weights", Resources.ArgumentArraysSameLength);
+ throw new ArgumentOutOfRangeException(nameof(weights), Resources.ArgumentArraysSameLength);
}
++n;
@@ -277,11 +285,11 @@ namespace MathNet.Numerics.Statistics
}
if (ieB.MoveNext())
{
- throw new ArgumentOutOfRangeException("dataB", Resources.ArgumentArraysSameLength);
+ throw new ArgumentOutOfRangeException(nameof(dataB), Resources.ArgumentArraysSameLength);
}
if (ieW.MoveNext())
{
- throw new ArgumentOutOfRangeException("weights", Resources.ArgumentArraysSameLength);
+ throw new ArgumentOutOfRangeException(nameof(weights), Resources.ArgumentArraysSameLength);
}
}
return covariance/Math.Sqrt(varA*varB);