diff --git a/src/Numerics/Statistics/Correlation.cs b/src/Numerics/Statistics/Correlation.cs index e2646a2b..fb096fa7 100644 --- a/src/Numerics/Statistics/Correlation.cs +++ b/src/Numerics/Statistics/Correlation.cs @@ -146,9 +146,8 @@ namespace MathNet.Numerics.Statistics meanB += rY; varB += sumWeight*deltaY*rY; + covariance += deltaX*deltaY*wi*(sumWeight/temp); sumWeight = temp; - - covariance += deltaX*deltaY*(n - 1)*wi/n; } if (ieB.MoveNext()) { diff --git a/src/UnitTests/StatisticsTests/CorrelationTests.cs b/src/UnitTests/StatisticsTests/CorrelationTests.cs index b2da9c84..7afd9c43 100644 --- a/src/UnitTests/StatisticsTests/CorrelationTests.cs +++ b/src/UnitTests/StatisticsTests/CorrelationTests.cs @@ -104,6 +104,36 @@ namespace MathNet.Numerics.UnitTests.StatisticsTests AssertHelpers.AlmostEqual(corr, corr2, 14); } + /// + /// Correlation between two identical data sets should always equal one, + /// regardless of the weights used. + /// + [Test] + public void WeightedPearsonCorrelationEqualsOneTest() + { + int n = 5; + double maxWeight = 1e5; + var dataA = Generate.LinearRange(1, n); + var dataB = Generate.LinearRange(1, n); + var weights1 = Generate.LinearRange(1, n); + var weights2 = Generate.LogSpaced(n, 1, 5); + var weights3 = Generate.LogSpaced(n, 5, 1); + var weights4 = Generate.Repeat(n, maxWeight); + var weights5 = Generate.Repeat(n, 1/maxWeight); + + var corr1 = Correlation.WeightedPearson(dataA, dataB, weights1); + var corr2 = Correlation.WeightedPearson(dataA, dataB, weights2); + var corr3 = Correlation.WeightedPearson(dataA, dataB, weights3); + var corr4 = Correlation.WeightedPearson(dataA, dataB, weights4); + var corr5 = Correlation.WeightedPearson(dataA, dataB, weights5); + + AssertHelpers.AlmostEqual(corr1, 1, 14); + AssertHelpers.AlmostEqual(corr2, 1, 14); + AssertHelpers.AlmostEqual(corr3, 1, 14); + AssertHelpers.AlmostEqual(corr4, 1, 14); + AssertHelpers.AlmostEqual(corr5, 1, 14); + } + /// /// Pearson correlation test fail. ///