Browse Source

GoodnessOfFit: benchmarking indicates pearson correlation is twice as fast

optimization-3
Christoph Ruegg 13 years ago
parent
commit
3ba8773b30
  1. 37
      src/Numerics/GoodnessOfFit.cs
  2. 2
      src/Numerics/Numerics.csproj
  3. 12
      src/UnitTests/GoodnessOfFit/RSquaredTest.cs

37
src/Numerics/GoodnessOfFit/RSquared.cs → src/Numerics/GoodnessOfFit.cs

@ -1,4 +1,4 @@
// <copyright file="RSquared.cs">
// <copyright file="GoodnessOfFit.cs">
// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
@ -26,13 +26,12 @@
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
using System;
using System.Collections.Generic;
using System.Linq;
using MathNet.Numerics.Statistics;
namespace MathNet.Numerics.GoodnessOfFit
namespace MathNet.Numerics
{
public static class RSquared
public static class GoodnessOfFit
{
/// <summary>
/// Calculated the R-Squared value given modelled and observed values
@ -40,32 +39,10 @@ namespace MathNet.Numerics.GoodnessOfFit
/// <param name="modelledValues">The values expected from the modelled</param>
/// <param name="observedValues">The actual data set values obtained</param>
/// <returns></returns>
public static double RSqr(IEnumerable<double> modelledValues, IEnumerable<double> observedValues)
public static double RSquared(IEnumerable<double> modelledValues, IEnumerable<double> observedValues)
{
var modelledData = modelledValues as double[] ?? modelledValues.ToArray();
var observedData = observedValues as double[] ?? observedValues.ToArray();
var observedDataCount = observedData.Count();
if ( modelledData.Count() != observedDataCount)
{
throw new ArgumentException("Dataset length mismatch");
}
var observedSum = observedData.Sum();
var modelledSum = modelledData.Sum();
var sumObservedByModelled = 0d;
for (var itemIndex = 0; itemIndex < observedDataCount; itemIndex++)
{
sumObservedByModelled += (observedData[itemIndex] * modelledData[itemIndex]);
}
var sumObservedSquared = observedData.Sum(item => item * item);
var sumModelledSquared = modelledData.Sum(item => item * item);
return Math.Pow(( observedDataCount * sumObservedByModelled - observedSum * modelledSum ) /
Math.Sqrt((observedDataCount * sumObservedSquared - Math.Pow(observedSum, 2))
* (observedDataCount * sumModelledSquared - Math.Pow(modelledSum, 2))), 2);
var corr = Correlation.Pearson(modelledValues, observedValues);
return corr * corr;
}
}
}

2
src/Numerics/Numerics.csproj

@ -87,7 +87,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="GoodnessOfFit\RSquared.cs" />
<Compile Include="GoodnessOfFit.cs" />
<Compile Include="Precision.Comparison.cs" />
<Compile Include="Precision.Equality.cs" />
<Compile Include="Distributions\Bernoulli.cs" />

12
src/UnitTests/GoodnessOfFit/RSquaredTest.cs

@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MathNet.Numerics.GoodnessOfFit;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests.GoodnessOfFit
@ -21,11 +17,11 @@ namespace MathNet.Numerics.UnitTests.GoodnessOfFit
for (int i = 1; i <= 10; i++)
data.Add(i);
Assert.That(RSquared.RSqr(data, data), Is.EqualTo(1));
Assert.That(Numerics.GoodnessOfFit.RSquared(data, data), Is.EqualTo(1));
}
[Test]
[ExpectedException(typeof(ArgumentException))]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void WhenGivenTwoDatasetsOfDifferentSizeThenThrowsArgumentException()
{
var observedData = new List<double>()
@ -49,7 +45,7 @@ namespace MathNet.Numerics.UnitTests.GoodnessOfFit
,10
};
RSquared.RSqr(modelledData, observedData);
Numerics.GoodnessOfFit.RSquared(modelledData, observedData);
Assert.Fail("Expected ArgumentException exception wasn't thrown");
}
@ -67,7 +63,7 @@ namespace MathNet.Numerics.UnitTests.GoodnessOfFit
2.6, 2.8, 3.1, 4.7, 5.1, 5.3
};
Assert.That(Math.Round(RSquared.RSqr(modelledData, observedData), 11), Is.EqualTo(Math.Round(0.94878520708673d, 11)));
Assert.That(Math.Round(Numerics.GoodnessOfFit.RSquared(modelledData, observedData), 11), Is.EqualTo(Math.Round(0.94878520708673d, 11)));
}
}
}

Loading…
Cancel
Save