Browse Source

Fixed a bug with the order finding method.

Lowered the accuracy of StdDev computation on the numacc2 test to 13 significant digits.
jvangael 17 years ago
committed by Christoph Ruegg
parent
commit
0edb5ac469
  1. 3
      src/Managed.UnitTests/Managed.UnitTests.csproj
  2. 212
      src/Managed.UnitTests/StatisticsTests/DescriptiveStatisticsTests.cs
  3. 96
      src/Managed.UnitTests/StatisticsTests/StatTestData.cs
  4. 138
      src/Managed.UnitTests/StatisticsTests/StatisticsTests.cs
  5. 2
      src/Managed/Managed.csproj
  6. 9
      src/Managed/Properties/Resources.Designer.cs
  7. 3
      src/Managed/Properties/Resources.resx
  8. 9
      src/Managed/Sorting.cs
  9. 343
      src/Managed/Statistics/DescriptiveStatistics.cs
  10. 570
      src/Managed/Statistics/Statistics.cs
  11. 9
      src/Native.UnitTests/Native.UnitTests.csproj
  12. 6
      src/Native/Native.csproj

3
src/Managed.UnitTests/Managed.UnitTests.csproj

@ -72,6 +72,9 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SortingTests.cs" />
<Compile Include="SpecialFunctionsTest\ErfTests.cs" />
<Compile Include="StatisticsTests\DescriptiveStatisticsTests.cs" />
<Compile Include="StatisticsTests\StatisticsTests.cs" />
<Compile Include="StatisticsTests\StatTestData.cs" />
<Compile Include="ThreadingTests\ParallelTest.cs" />
</ItemGroup>
<ItemGroup>

212
src/Managed.UnitTests/StatisticsTests/DescriptiveStatisticsTests.cs

@ -0,0 +1,212 @@
// <copyright file="DescriptiveStatisticsTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://mathnet.opensourcedotnet.info
//
// Copyright (c) 2009 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.UnitTests.Statistics
{
using System;
using System.Collections.Generic;
using MathNet.Numerics.Statistics;
using MbUnit.Framework;
[TestFixture]
public class DescriptiveStatisticsTests
{
private readonly IDictionary<string, StatTestData> mData = new Dictionary<string, StatTestData>();
public DescriptiveStatisticsTests()
{
StatTestData lottery = new StatTestData("./data/NIST/Lottery.dat");
mData.Add("lottery", lottery);
StatTestData lew = new StatTestData("./data/NIST/Lew.dat");
mData.Add("lew", lew);
StatTestData mavro = new StatTestData("./data/NIST/Mavro.dat");
mData.Add("mavro", mavro);
StatTestData michelso = new StatTestData("./data/NIST/Michelso.dat");
mData.Add("michelso", michelso);
StatTestData numacc1 = new StatTestData("./data/NIST/NumAcc1.dat");
mData.Add("numacc1", numacc1);
StatTestData numacc2 = new StatTestData("./data/NIST/NumAcc2.dat");
mData.Add("numacc2", numacc2);
StatTestData numacc3 = new StatTestData("./data/NIST/NumAcc3.dat");
mData.Add("numacc3", numacc3);
StatTestData numacc4 = new StatTestData("./data/NIST/NumAcc4.dat");
mData.Add("numacc4", numacc4);
}
[Test]
public void Constructor_ThrowArgumentNullException()
{
const IEnumerable<double> data = null;
const IEnumerable<double?> nullableData = null;
Assert.Throws<ArgumentNullException>(() => new DescriptiveStatistics(data));
Assert.Throws<ArgumentNullException>(() => new DescriptiveStatistics(data, true));
Assert.Throws<ArgumentNullException>(() => new DescriptiveStatistics(nullableData));
Assert.Throws<ArgumentNullException>(() => new DescriptiveStatistics(nullableData, true));
}
[Test]
[Row("lottery", 15, -0.09333165310779, -1.19256091074856, 522.5, 4, 999, 218)]
[Row("lew", 15, -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)]
[Row("mavro", 12, 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)]
[Row("michelso", 12, -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)]
[Row("numacc1", 15, 0, 0, 10000002, 10000001, 10000003, 3)]
[Row("numacc2", 13, 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)]
[Row("numacc3", 9, 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)]
[Row("numacc4", 8, 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)]
public void IEnumerableDouble(string dataSet, int digits, double skewness, double kurtosis, double median, double min, double max, int count)
{
StatTestData data = mData[dataSet];
DescriptiveStatistics stats = new DescriptiveStatistics(data.Data);
AssertHelpers.AlmostEqual(data.Mean, stats.Mean, 15);
AssertHelpers.AlmostEqual(data.StandardDeviation, stats.StandardDeviation, digits);
AssertHelpers.AlmostEqual(skewness, stats.Skewness, 7);
AssertHelpers.AlmostEqual(kurtosis, stats.Kurtosis, 7);
AssertHelpers.AlmostEqual(median, stats.Median, 15);
Assert.AreEqual(stats.Minimum, min);
Assert.AreEqual(stats.Maximum, max);
Assert.AreEqual(stats.Count, count);
}
[Test]
[Row("lottery", -0.09333165310779, -1.19256091074856, 522.5, 4, 999, 218)]
[Row("lew", -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)]
[Row("mavro", 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)]
[Row("michelso", -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)]
[Row("numacc1", 0, 0, 10000002, 10000001, 10000003, 3)]
[Row("numacc2", 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)]
[Row("numacc3", 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)]
[Row("numacc4", 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)]
public void IEnumerableDoubleHighAccuracy(string dataSet, double skewness, double kurtosis, double median, double min, double max, int count)
{
StatTestData data = mData[dataSet];
DescriptiveStatistics stats = new DescriptiveStatistics(data.Data, true);
AssertHelpers.AlmostEqual(data.Mean, stats.Mean, 15);
AssertHelpers.AlmostEqual(data.StandardDeviation, stats.StandardDeviation, 15);
AssertHelpers.AlmostEqual(skewness, stats.Skewness, 9);
AssertHelpers.AlmostEqual(kurtosis, stats.Kurtosis, 9);
AssertHelpers.AlmostEqual(median, stats.Median, 15);
Assert.AreEqual(stats.Minimum, min);
Assert.AreEqual(stats.Maximum, max);
Assert.AreEqual(stats.Count, count);
}
[Test]
[Row("lottery", 15, -0.09333165310779, -1.19256091074856, 522.5, 4, 999, 218)]
[Row("lew", 15, -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)]
[Row("mavro", 12, 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)]
[Row("michelso", 12, -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)]
[Row("numacc1", 15, 0, 0, 10000002, 10000001, 10000003, 3)]
[Row("numacc2", 13, 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)]
[Row("numacc3", 9, 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)]
[Row("numacc4", 8, 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)]
public void IEnumerableDoubleLowAccuracy(string dataSet, int digits, double skewness, double kurtosis, double median, double min, double max, int count)
{
StatTestData data = mData[dataSet];
DescriptiveStatistics stats = new DescriptiveStatistics(data.Data, false);
AssertHelpers.AlmostEqual(data.Mean, stats.Mean, 15);
AssertHelpers.AlmostEqual(data.StandardDeviation, stats.StandardDeviation, digits);
AssertHelpers.AlmostEqual(skewness, stats.Skewness, 7);
AssertHelpers.AlmostEqual(kurtosis, stats.Kurtosis, 7);
AssertHelpers.AlmostEqual(median, stats.Median, 15);
Assert.AreEqual(stats.Minimum, min);
Assert.AreEqual(stats.Maximum, max);
Assert.AreEqual(stats.Count, count);
}
[Test]
[Row("lottery", 15, -0.09333165310779, -1.19256091074856, 522.5, 4, 999, 218)]
[Row("lew", 15, -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)]
[Row("mavro", 12, 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)]
[Row("michelso", 12, -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)]
[Row("numacc1", 15, 0, 0, 10000002, 10000001, 10000003, 3)]
[Row("numacc2", 13, 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)]
[Row("numacc3", 9, 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)]
[Row("numacc4", 8, 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)]
public void IEnumerableNullableDouble(string dataSet, int digits, double skewness, double kurtosis, double median, double min, double max, int count)
{
StatTestData data = mData[dataSet];
DescriptiveStatistics stats = new DescriptiveStatistics(data.DataWithNulls);
AssertHelpers.AlmostEqual(data.Mean, stats.Mean, 15);
AssertHelpers.AlmostEqual(data.StandardDeviation, stats.StandardDeviation, digits);
AssertHelpers.AlmostEqual(skewness, stats.Skewness, 7);
AssertHelpers.AlmostEqual(kurtosis, stats.Kurtosis, 7);
AssertHelpers.AlmostEqual(median, stats.Median, 15);
Assert.AreEqual(stats.Minimum, min);
Assert.AreEqual(stats.Maximum, max);
Assert.AreEqual(stats.Count, count);
}
[Test]
[Row("lottery", -0.09333165310779, -1.19256091074856, 522.5, 4, 999, 218)]
[Row("lew", -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)]
[Row("mavro", 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)]
[Row("michelso", -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)]
[Row("numacc1", 0, 0, 10000002, 10000001, 10000003, 3)]
[Row("numacc2", 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)]
[Row("numacc3", 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)]
[Row("numacc4", 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)]
public void IEnumerableNullableDoubleHighAccuracy(string dataSet, double skewness, double kurtosis, double median, double min, double max, int count)
{
StatTestData data = mData[dataSet];
DescriptiveStatistics stats = new DescriptiveStatistics(data.DataWithNulls, true);
AssertHelpers.AlmostEqual(data.Mean, stats.Mean, 15);
AssertHelpers.AlmostEqual(data.StandardDeviation, stats.StandardDeviation, 15);
AssertHelpers.AlmostEqual(skewness, stats.Skewness, 9);
AssertHelpers.AlmostEqual(kurtosis, stats.Kurtosis, 9);
AssertHelpers.AlmostEqual(median, stats.Median, 15);
Assert.AreEqual(stats.Minimum, min);
Assert.AreEqual(stats.Maximum, max);
Assert.AreEqual(stats.Count, count);
}
[Test]
[Row("lottery", 15, -0.09333165310779, -1.19256091074856, 522.5, 4, 999, 218)]
[Row("lew", 15, -0.050606638756334, -1.49604979214447, -162, -579, 300, 200)]
[Row("mavro", 12, 0.64492948110824, -0.82052379677456, 2.0018, 2.0013, 2.0027, 50)]
[Row("michelso", 12, -0.0185388637725746, 0.33968459842539, 299.85, 299.62, 300.07, 100)]
[Row("numacc1", 15, 0, 0, 10000002, 10000001, 10000003, 3)]
[Row("numacc2", 13, 0, -2.003003003003, 1.2, 1.1, 1.3, 1001)]
[Row("numacc3", 9, 0, -2.003003003003, 1000000.2, 1000000.1, 1000000.3, 1001)]
[Row("numacc4", 8, 0, -2.00300300299913, 10000000.2, 10000000.1, 10000000.3, 1001)]
public void IEnumerableNullableDoubleLowAccuracy(string dataSet, int digits, double skewness, double kurtosis, double median, double min, double max, int count)
{
StatTestData data = mData[dataSet];
DescriptiveStatistics stats = new DescriptiveStatistics(data.DataWithNulls, false);
AssertHelpers.AlmostEqual(data.Mean, stats.Mean, 15);
AssertHelpers.AlmostEqual(data.StandardDeviation, stats.StandardDeviation, digits);
AssertHelpers.AlmostEqual(skewness, stats.Skewness, 7);
AssertHelpers.AlmostEqual(kurtosis, stats.Kurtosis, 7);
AssertHelpers.AlmostEqual(median, stats.Median, 15);
Assert.AreEqual(stats.Minimum, min);
Assert.AreEqual(stats.Maximum, max);
Assert.AreEqual(stats.Count, count);
}
}
}

96
src/Managed.UnitTests/StatisticsTests/StatTestData.cs

@ -0,0 +1,96 @@
// <copyright file="StatTestData.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://mathnet.opensourcedotnet.info
//
// Copyright (c) 2009 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.UnitTests.Statistics
{
using System.IO;
using System.Linq;
using System.Collections.Generic;
internal class StatTestData
{
public readonly double[] Data;
public readonly double?[] DataWithNulls;
public readonly double Mean;
public readonly double StandardDeviation;
public StatTestData(string file)
{
using (StreamReader reader = new StreamReader(file))
{
string line = reader.ReadLine().Trim();
while (!line.StartsWith("--"))
{
if (line.StartsWith("Sample Mean"))
{
Mean = GetValue(line);
}
else if (line.StartsWith("Sample Standard Deviation"))
{
StandardDeviation = GetValue(line);
}
line = reader.ReadLine().Trim();
}
line = reader.ReadLine();
IList<double> list = new List<double>();
while (line != null)
{
line = line.Trim();
if (!line.Equals(string.Empty))
{
list.Add(double.Parse(line));
}
line = reader.ReadLine();
}
Data = list.ToArray();
}
DataWithNulls = new double?[Data.Length + 2];
for (int i = 0; i < Data.Length; i++)
{
DataWithNulls[i + 1] = Data[i];
}
}
private static double GetValue(string str)
{
int start = str.IndexOf(":");
string value = str.Substring(start + 1).Trim();
if (value.Equals("NaN"))
{
return 0;
}
return double.Parse(str.Substring(start + 1).Trim());
}
}
}

138
src/Managed.UnitTests/StatisticsTests/StatisticsTests.cs

@ -0,0 +1,138 @@
// <copyright file="StatisticsTests.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://mathnet.opensourcedotnet.info
//
// Copyright (c) 2009 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.UnitTests.Statistics
{
using System;
using System.Collections.Generic;
using System.Text;
using MbUnit.Framework;
using MathNet.Numerics.Statistics;
[TestFixture]
public class StatisticsTests
{
private readonly IDictionary<string, StatTestData> mData = new Dictionary<string, StatTestData>();
public StatisticsTests()
{
StatTestData lottery = new StatTestData("./data/NIST/Lottery.dat");
mData.Add("lottery", lottery);
StatTestData lew = new StatTestData("./data/NIST/Lew.dat");
mData.Add("lew", lew);
StatTestData mavro = new StatTestData("./data/NIST/Mavro.dat");
mData.Add("mavro", mavro);
StatTestData michelso = new StatTestData("./data/NIST/Michelso.dat");
mData.Add("michelso", michelso);
StatTestData numacc1 = new StatTestData("./data/NIST/NumAcc1.dat");
mData.Add("numacc1", numacc1);
StatTestData numacc2 = new StatTestData("./data/NIST/NumAcc2.dat");
mData.Add("numacc2", numacc2);
StatTestData numacc3 = new StatTestData("./data/NIST/NumAcc3.dat");
mData.Add("numacc3", numacc3);
StatTestData numacc4 = new StatTestData("./data/NIST/NumAcc4.dat");
mData.Add("numacc4", numacc4);
}
[Test]
[Row("lottery")]
[Row("lew")]
[Row("mavro")]
[Row("michelso")]
[Row("numacc1")]
[Row("numacc2")]
[Row("numacc3")]
[Row("numacc4")]
public void Mean(string dataSet)
{
StatTestData data = mData[dataSet];
AssertHelpers.AlmostEqual(data.Mean, data.Data.Mean(), 15);
}
[Test]
[Row("lottery")]
[Row("lew")]
[Row("mavro")]
[Row("michelso")]
[Row("numacc1")]
[Row("numacc2")]
[Row("numacc3")]
[Row("numacc4")]
public void NullableMean(string dataSet)
{
StatTestData data = mData[dataSet];
AssertHelpers.AlmostEqual(data.Mean, data.DataWithNulls.Mean(), 15);
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void Mean_ThrowsArgumentNullException()
{
double[] data = null;
MathNet.Numerics.Statistics.Statistics.Mean(data);
}
[Test]
[Row("lottery", 15)]
[Row("lew", 15)]
[Row("mavro", 12)]
[Row("michelso", 12)]
[Row("numacc1", 15)]
[Row("numacc2", 14)]
[Row("numacc3", 9)]
[Row("numacc4", 8)]
public void StandardDeviation(string dataSet, int digits)
{
StatTestData data = mData[dataSet];
AssertHelpers.AlmostEqual(data.StandardDeviation, data.Data.StandardDeviation(), digits);
}
[Test]
[Row("lottery", 15)]
[Row("lew", 15)]
[Row("mavro", 12)]
[Row("michelso", 12)]
[Row("numacc1", 15)]
[Row("numacc2", 14)]
[Row("numacc3", 9)]
[Row("numacc4", 8)]
public void NullableStandardDeviation(string dataSet, int digits)
{
StatTestData data = mData[dataSet];
AssertHelpers.AlmostEqual(data.StandardDeviation, data.DataWithNulls.StandardDeviation(), digits);
}
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void StandardDeviation_ThrowsArgumentNullException()
{
double[] data = null;
MathNet.Numerics.Statistics.Statistics.StandardDeviation(data);
}
}
}

2
src/Managed/Managed.csproj

@ -82,6 +82,8 @@
<Compile Include="Sorting.cs" />
<Compile Include="SpecialFunctions.cs" />
<Compile Include="SpecialFunctions\Erf.cs" />
<Compile Include="Statistics\DescriptiveStatistics.cs" />
<Compile Include="Statistics\Statistics.cs" />
<Compile Include="Threading\AggregateException.cs" />
<Compile Include="Threading\Parallel.cs" />
<Compile Include="Threading\Task.cs" />

9
src/Managed/Properties/Resources.Designer.cs

@ -375,6 +375,15 @@ namespace MathNet.Numerics.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to The supplied collection is empty..
/// </summary>
internal static string CollectionEmpty {
get {
return ResourceManager.GetString("CollectionEmpty", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This feature is not implemented yet (but is planned)..
/// </summary>

3
src/Managed/Properties/Resources.resx

@ -249,4 +249,7 @@
<data name="ArgumentItemNull" xml:space="preserve">
<value>At least one item of {0} is a null reference (Nothing in Visual Basic).</value>
</data>
<data name="CollectionEmpty" xml:space="preserve">
<value>The supplied collection is empty.</value>
</data>
</root>

9
src/Managed/Sorting.cs

@ -566,9 +566,12 @@ namespace MathNet.Numerics
/// <param name="b">The index of the second element of the swap.</param>
internal static void Swap<T>(IList<T> keys, int a, int b)
{
T local = keys[a];
keys[a] = keys[b];
keys[b] = local;
if(a != b)
{
T local = keys[a];
keys[a] = keys[b];
keys[b] = local;
}
}
}
}

343
src/Managed/Statistics/DescriptiveStatistics.cs

@ -0,0 +1,343 @@
// <copyright file="DescriptiveStatistics.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://mathnet.opensourcedotnet.info
//
// Copyright (c) 2009 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.Statistics
{
using System.Collections.Generic;
/// <summary>
/// Computes the basic statistics of data set. The class meets the
/// NIST standard of accuracy for mean, variance, and standard deviation
/// (the only statistics they provide exact values for) and exceeds them
/// in increased accuracy mode.
/// </summary>
public class DescriptiveStatistics
{
/// <summary>
/// Initializes a new instance of the <see cref="DescriptiveStatistics"/> class.
/// </summary>
/// <param name="data">The sample data.</param>
public DescriptiveStatistics(IEnumerable<double> data) : this(data, false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="DescriptiveStatistics"/> class.
/// </summary>
/// <param name="data">The sample data.</param>
public DescriptiveStatistics(IEnumerable<double?> data) : this(data, false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="DescriptiveStatistics"/> class.
/// </summary>
/// <param name="data">The sample data.</param>
/// <param name="increasedAccuracy">if set to <c>true</c>, increased accuracy mode used.
/// Increased accuracy mode uses <see cref="decimal"/> types for internal calculations.</param>
/// <remarks>Don't use increased accuracy for data sets containing large values (in absolute value).
/// This may cause the calculations to overflow.</remarks>
public DescriptiveStatistics(IEnumerable<double> data, bool increasedAccuracy)
{
if (increasedAccuracy)
{
ComputeHA(data);
}
else
{
Compute(data);
}
Median = data.Median();
Maximum = data.Maximum();
Minimum = data.Minimum();
}
/// <summary>
/// Initializes a new instance of the <see cref="DescriptiveStatistics"/> class.
/// </summary>
/// <param name="data">The sample data.</param>
/// <param name="increasedAccuracy">if set to <c>true</c>, increased accuracy mode used.
/// Increased accuracy mode uses <see cref="decimal"/> types for internal calculations.</param>
/// <remarks>Don't use increased accuracy for data sets containing large values (in absolute value).
/// This may cause the calculations to overflow.</remarks>
public DescriptiveStatistics(IEnumerable<double?> data, bool increasedAccuracy)
{
if (increasedAccuracy)
{
ComputeHA(data);
}
else
{
Compute(data);
}
Median = data.Median();
Maximum = data.Maximum();
Minimum = data.Minimum();
}
/// <summary>
/// Gets the size of the sample.
/// </summary>
/// <value>The size of the sample.</value>
public int Count { get; private set; }
/// <summary>
/// Gets the sample mean.
/// </summary>
/// <value>The sample mean.</value>
public double Mean { get; private set; }
/// <summary>
/// Gets the sample variance.
/// </summary>
/// <value>The sample variance.</value>
public double Variance { get; private set; }
/// <summary>
/// Gets the sample standard deviation.
/// </summary>
/// <value>The sample standard deviation.</value>
public double StandardDeviation { get; private set; }
/// <summary>
/// Gets the sample skewness.
/// </summary>
/// <value>The sample skewness.</value>
/// <remarks>Returns zero if <see cref="Count"/> is less than three. </remarks>
public double Skewness { get; private set; }
/// <summary>
/// Gets the sample median.
/// </summary>
/// <value>The sample median.</value>
public double Median { get; private set; }
/// <summary>
/// Gets the sample kurtosis.
/// </summary>
/// <value>The sample kurtosis.</value>
/// <remarks>Returns zero if <see cref="Count"/> is less than four. </remarks>
public double Kurtosis { get; private set; }
/// <summary>
/// Gets the maximum sample value.
/// </summary>
/// <value>The maximum sample value.</value>
public double Maximum { get; private set; }
/// <summary>
/// Gets the minimum sample value.
/// </summary>
/// <value>The minimum sample value.</value>
public double Minimum { get; private set; }
/// <summary>
/// Computes descriptive statistics from a stream of data values.
/// </summary>
/// <param name="data">A sequence of datapoints.</param>
private void Compute(IEnumerable<double> data)
{
Mean = data.Mean();
double variance = 0;
double correction = 0;
double skewness = 0;
double kurtosis = 0;
int n = 0;
foreach (var xi in data)
{
double diff = xi - Mean;
correction += diff;
double tmp = diff*diff;
variance += tmp;
tmp *= diff;
skewness += tmp;
tmp *= diff;
kurtosis += tmp;
n++;
}
Count = n;
Variance = (variance - (correction*correction)/n)/(n - 1);
StandardDeviation = System.Math.Sqrt(Variance);
if (Variance != 0)
{
if (n > 2)
{
Skewness = (double) n/((n - 1)*(n - 2))*(skewness/(Variance*StandardDeviation));
}
if (n > 3)
{
Kurtosis = ((double) n*(n + 1))/((n - 1)*(n - 2)*(n - 3))*(kurtosis/(Variance*Variance)) - (3.0*(n - 1)*(n - 1))/((n - 2)*(n - 3));
}
}
}
/// <summary>
/// Computes descriptive statistics from a stream of nullable data values.
/// </summary>
/// <param name="data">A sequence of datapoints.</param>
private void Compute(IEnumerable<double?> data)
{
Mean = data.Mean();
double variance = 0;
double correction = 0;
double skewness = 0;
double kurtosis = 0;
int n = 0;
foreach (var xi in data)
{
if (xi.HasValue)
{
double diff = xi.Value - Mean;
double tmp = diff*diff;
correction += diff;
variance += tmp;
tmp *= diff;
skewness += tmp;
tmp *= diff;
kurtosis += tmp;
n++;
}
}
Count = n;
if (n > 0)
{
Variance = (variance - (correction*correction)/n)/(n - 1);
StandardDeviation = System.Math.Sqrt(Variance);
if (Variance != 0)
{
if (n > 2)
{
Skewness = (double) n/((n - 1)*(n - 2))*(skewness/(Variance*StandardDeviation));
}
if (n > 3)
{
Kurtosis = ((double) n*(n + 1))/((n - 1)*(n - 2)*(n - 3))*(kurtosis/(Variance*Variance)) - (3.0*(n - 1)*(n - 1))/((n - 2)*(n - 3));
}
}
}
}
/// <summary>
/// Computes descriptive statistics from a stream of data values using high accuracy.
/// </summary>
/// <param name="data">A sequence of datapoints.</param>
private void ComputeHA(IEnumerable<double> data)
{
Mean = data.Mean();
decimal mean = (decimal) Mean;
decimal variance = 0;
decimal correction = 0;
decimal skewness = 0;
decimal kurtosis = 0;
int n = 0;
foreach (decimal xi in data)
{
decimal diff = xi - mean;
decimal tmp = diff*diff;
correction += diff;
variance += tmp;
tmp *= diff;
skewness += tmp;
tmp *= diff;
kurtosis += tmp;
n++;
}
Count = n;
Variance = (double) (variance - (correction*correction)/n)/(n - 1);
StandardDeviation = System.Math.Sqrt(Variance);
if (Variance != 0)
{
if (n > 2)
{
Skewness = (double) n/((n - 1)*(n - 2))*((double) skewness/(Variance*StandardDeviation));
}
if (n > 3)
{
Kurtosis = ((double) n*(n + 1))/((n - 1)*(n - 2)*(n - 3))*((double) kurtosis/(Variance*Variance)) - (3.0*(n - 1)*(n - 1))/((n - 2)*(n - 3));
}
}
}
/// <summary>
/// Computes descriptive statistics from a stream of nullable data values using high accuracy.
/// </summary>
/// <param name="data">A sequence of datapoints.</param>
private void ComputeHA(IEnumerable<double?> data)
{
Mean = data.Mean();
decimal mean = (decimal) Mean;
decimal variance = 0;
decimal correction = 0;
decimal skewness = 0;
decimal kurtosis = 0;
int n = 0;
foreach (decimal? xi in data)
{
if (xi.HasValue)
{
decimal diff = xi.Value - mean;
decimal tmp = diff*diff;
correction += diff;
variance += tmp;
tmp *= diff;
skewness += tmp;
tmp *= diff;
kurtosis += tmp;
n++;
}
}
Count = n;
if (n > 0)
{
Variance = (double) (variance - (correction*correction)/n)/(n - 1);
StandardDeviation = System.Math.Sqrt(Variance);
if (Variance != 0)
{
if (n > 2)
{
Skewness = (double) n/((n - 1)*(n - 2))*((double) skewness/(Variance*StandardDeviation));
}
if (n > 3)
{
Kurtosis = ((double) n*(n + 1))/((n - 1)*(n - 2)*(n - 3))*((double) kurtosis/(Variance*Variance)) - (3.0*(n - 1)*(n - 1))/((n - 2)*(n - 3));
}
}
}
}
}
}

570
src/Managed/Statistics/Statistics.cs

@ -0,0 +1,570 @@
// <copyright file="Statistics.cs" company="Math.NET">
// Math.NET Numerics, part of the Math.NET Project
// http://mathnet.opensourcedotnet.info
//
// Copyright (c) 2009 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
// </copyright>
namespace MathNet.Numerics.Statistics
{
using System;
using System.Collections.Generic;
using MathNet.Numerics.Properties;
using MathNet.Numerics.NumberTheory;
/// <summary>
/// Extension methods to return basic statistics on set of data.
/// </summary>
public static class Statistics
{
/// <summary>
/// Calculates the sample mean.
/// </summary>
/// <param name="data">The data to calculate the mean of.</param>
/// <returns>The mean of the sample.</returns>
public static double Mean(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
double mean = 0;
int m = 0;
foreach (var item in data)
{
mean += (item - mean)/++m;
}
return mean;
}
/// <summary>
/// Calculates the sample mean.
/// </summary>
/// <param name="data">The data to calculate the mean of.</param>
/// <returns>The mean of the sample.</returns>
public static double Mean(this IEnumerable<double?> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
double mean = 0;
int m = 0;
foreach (var item in data)
{
if (item.HasValue)
{
mean += (item.Value - mean)/++m;
}
}
return mean;
}
/// <summary>
/// Calculates the unbiased population variance estimator (on a dataset of size N will use an N-1 normalizer).
/// </summary>
/// <param name="data">The data to calculate the variance of.</param>
/// <returns>The unbiased population variance of the sample.</returns>
public static double Variance(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
double variance = 0;
double t = 0;
int j = 0;
IEnumerator<double> iterator = data.GetEnumerator();
if (iterator.MoveNext())
{
j++;
t = iterator.Current;
}
while (iterator.MoveNext())
{
j++;
double xi = iterator.Current;
t += xi;
double diff = j*xi - t;
variance += (diff*diff)/(j*(j - 1));
}
return variance/(j - 1);
}
/// <summary>
/// Computes the unbiased population variance estimator (on a dataset of size N will use an N-1 normalizer) for nullable data.
/// </summary>
/// <param name="data">The data to calculate the variance of.</param>
/// <returns>The population variance of the sample.</returns>
public static double Variance(this IEnumerable<double?> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
double variance = 0;
double t = 0;
int j = 0;
IEnumerator<double?> iterator = data.GetEnumerator();
while (true)
{
bool hasNext = iterator.MoveNext();
if (!hasNext)
{
break;
}
if (iterator.Current.HasValue)
{
j++;
t = iterator.Current.Value;
break;
}
}
while (iterator.MoveNext())
{
if (iterator.Current.HasValue)
{
j++;
double xi = iterator.Current.Value;
t += xi;
double diff = j*xi - t;
variance += (diff*diff)/(j*(j - 1));
}
}
return variance/(j - 1);
}
/// <summary>
/// Calculates the biased population variance estimator (on a dataset of size N will use an N normalizer).
/// </summary>
/// <param name="data">The data to calculate the variance of.</param>
/// <returns>The biased population variance of the sample.</returns>
public static double PopulationVariance(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
double variance = 0;
double t = 0;
int j = 0;
IEnumerator<double> iterator = data.GetEnumerator();
if (iterator.MoveNext())
{
j++;
t = iterator.Current;
}
while (iterator.MoveNext())
{
j++;
double xi = iterator.Current;
t += xi;
double diff = j * xi - t;
variance += (diff * diff) / (j * (j - 1));
}
return variance / j;
}
/// <summary>
/// Computes the biased population variance estimator (on a dataset of size N will use an N normalizer) for nullable data.
/// </summary>
/// <param name="data">The data to calculate the variance of.</param>
/// <returns>The population variance of the sample.</returns>
public static double PopulationVariance(this IEnumerable<double?> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
double variance = 0;
double t = 0;
int j = 0;
IEnumerator<double?> iterator = data.GetEnumerator();
while (true)
{
bool hasNext = iterator.MoveNext();
if (!hasNext)
{
break;
}
if (iterator.Current.HasValue)
{
j++;
t = iterator.Current.Value;
break;
}
}
while (iterator.MoveNext())
{
if (iterator.Current.HasValue)
{
j++;
double xi = iterator.Current.Value;
t += xi;
double diff = j * xi - t;
variance += (diff * diff) / (j * (j - 1));
}
}
return variance / j;
}
/// <summary>
/// Calculates the unbiased sample standard deviation (on a dataset of size N will use an N-1 normalizer).
/// </summary>
/// <param name="data">The data to calculate the standard deviation of.</param>
/// <returns>The standard deviation of the sample.</returns>
public static double StandardDeviation(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
return System.Math.Sqrt(Variance(data));
}
/// <summary>
/// Calculates the unbiased sample standard deviation (on a dataset of size N will use an N-1 normalizer).
/// </summary>
/// <param name="data">The data to calculate the standard deviation of.</param>
/// <returns>The standard deviation of the sample.</returns>
public static double StandardDeviation(this IEnumerable<double?> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
return System.Math.Sqrt(Variance(data));
}
/// <summary>
/// Calculates the biased sample standard deviation (on a dataset of size N will use an N normalizer).
/// </summary>
/// <param name="data">The data to calculate the standard deviation of.</param>
/// <returns>The standard deviation of the sample.</returns>
public static double PopulationStandardDeviation(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
return System.Math.Sqrt(PopulationVariance(data));
}
/// <summary>
/// Calculates the biased sample standard deviation (on a dataset of size N will use an N normalizer).
/// </summary>
/// <param name="data">The data to calculate the standard deviation of.</param>
/// <returns>The standard deviation of the sample.</returns>
public static double PopulationStandardDeviation(this IEnumerable<double?> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
return System.Math.Sqrt(PopulationVariance(data));
}
/// <summary>
/// Returns the minimum value in the sample data.
/// </summary>
/// <param name="data">The sample data.</param>
/// <returns>The minimum value in the sample data.</returns>
public static double Minimum(this IEnumerable<double?> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
double min = double.MaxValue;
int count = 0;
foreach (double? d in data)
{
if (d.HasValue)
{
min = System.Math.Min(min, d.Value);
count++;
}
}
if (count == 0)
{
throw new ArgumentException(Resources.CollectionEmpty, "data");
}
return min;
}
/// <summary>
/// Returns the maximum value in the sample data.
/// </summary>
/// <param name="data">The sample data.</param>
/// <returns>The maximum value in the sample data.</returns>
public static double Maximum(this IEnumerable<double?> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
double max = double.MinValue;
int count = 0;
foreach (double? d in data)
{
if (d.HasValue)
{
max = System.Math.Max(max, d.Value);
count++;
}
}
if (count == 0)
{
throw new ArgumentException(Resources.CollectionEmpty, "data");
}
return max;
}
/// <summary>
/// Returns the minimum value in the sample data.
/// </summary>
/// <param name="data">The sample data.</param>
/// <returns>The minimum value in the sample data.</returns>
public static double Minimum(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
double min = double.MaxValue;
int count = 0;
foreach (double d in data)
{
min = System.Math.Min(min, d);
count++;
}
if (count == 0)
{
throw new ArgumentException(Resources.CollectionEmpty, "data");
}
return min;
}
/// <summary>
/// Returns the maximum value in the sample data.
/// </summary>
/// <param name="data">The sample data.</param>
/// <returns>The maximum value in the sample data.</returns>
public static double Maximum(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
double max = double.MinValue;
int count = 0;
foreach (double d in data)
{
max = System.Math.Max(max, d);
count++;
}
if (count == 0)
{
throw new ArgumentException(Resources.CollectionEmpty, "data");
}
return max;
}
/// <summary>
/// Calculates the sample median.
/// </summary>
/// <param name="data">The data to calculate the median of.</param>
/// <returns>The median of the sample.</returns>
public static double Median(this IEnumerable<double> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
List<double> dataArray = new List<double>(data);
int index = dataArray.Count/2 + 1;
if (dataArray.Count % 2 == 0)
{
double lower = OrderSelect(dataArray, 0, dataArray.Count - 1, index - 1);
double upper = OrderSelect(dataArray, 0, dataArray.Count - 1, index);
return (lower + upper) / 2.0;
}
else
{
return OrderSelect(dataArray, 0, dataArray.Count - 1, index);
}
}
/// <summary>
/// Calculates the sample median.
/// </summary>
/// <param name="data">The data to calculate the median of.</param>
/// <returns>The median of the sample.</returns>
public static double Median(this IEnumerable<double?> data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
List<double> nonNull = new List<double>();
foreach (double? value in data)
{
if (value.HasValue)
{
nonNull.Add(value.Value);
}
}
if (nonNull.Count == 0)
{
throw new ArgumentException(Resources.CollectionEmpty, "data");
}
return nonNull.Median();
}
/// <summary>
/// Evaluate the i-order (1..N) statistic of the provided samples.
/// </summary>
/// <param name="data">The sample data.</param>
/// <returns>The i'th order statistic in the sample data.</returns>
public static double OrderStatistic(IEnumerable<double> samples, int order)
{
if (order == 1)
{
// Can be done in linear time by Min()
return Minimum(samples);
}
List<double> list = new List<double>(samples);
if (order < 1 || order > list.Count)
{
throw new ArgumentOutOfRangeException("order", Resources.ArgumentInIntervalXYInclusive);
}
if (order == list.Count)
{
// Can be done in linear time by Max()
return Maximum(list);
}
return OrderSelect(list, 0, list.Count - 1, order);
}
/// <summary>
/// Implementation of the order statistics finding algorithm based on the algorithm in
/// "Introduction to Algorithms", Cormen et al. section 7.1.
/// </summary>
/// <param name="samples">The sample data.</param>
/// <param name="left">The left bound in which to order select.</param>
/// <param name="right">The right bound in which to order select.</param>
/// <param name="order">The order we are trying to find.</param>
/// <returns>The <paramref name="order"/> order statistic.</returns>
static double OrderSelect(IList<double> samples, int left, int right, int order)
{
// Order most always be positive.
System.Diagnostics.Debug.Assert(order > 0);
// Left side must always be positive and smaller than right side.
System.Diagnostics.Debug.Assert(left >= 0 && left <= right);
// Right side must always be smaller than number of elements in list.
System.Diagnostics.Debug.Assert(right < samples.Count);
// Make sure there are at least order items in the segment [left, right].
System.Diagnostics.Debug.Assert(right - left + 1 >= order);
if (left == right)
{
return samples[left];
}
// The pivot point.
double pivot = samples[right];
// The partioning code.
int i = left - 1;
for(int j = left; j <= right - 1; j++)
{
if(samples[j] <= pivot)
{
i++;
Sorting.Swap(samples, i, j);
}
}
Sorting.Swap(samples, i+1, right);
// Recursive order finding algorithm.
if(order == (i-left)+2)
{
return pivot;
}
else if (order < (i-left)+2)
{
return OrderSelect(samples, left, i, order);
}
else
{
return OrderSelect(samples, i+2, right, order - i + left - 2);
}
}
}
}

9
src/Native.UnitTests/Native.UnitTests.csproj

@ -95,6 +95,15 @@
<Compile Include="..\Managed.UnitTests\SpecialFunctionsTest\ErfTests.cs">
<Link>SpecialFunctionsTest\ErfTests.cs</Link>
</Compile>
<Compile Include="..\Managed.UnitTests\StatisticsTests\DescriptiveStatisticsTests.cs">
<Link>StatisticsTests\DescriptiveStatisticsTests.cs</Link>
</Compile>
<Compile Include="..\Managed.UnitTests\StatisticsTests\StatisticsTests.cs">
<Link>StatisticsTests\StatisticsTests.cs</Link>
</Compile>
<Compile Include="..\Managed.UnitTests\StatisticsTests\StatTestData.cs">
<Link>StatisticsTests\StatTestData.cs</Link>
</Compile>
<Compile Include="..\Managed.UnitTests\ThreadingTests\ParallelTest.cs">
<Link>ThreadingTests\ParallelTest.cs</Link>
</Compile>

6
src/Native/Native.csproj

@ -140,6 +140,12 @@
<Compile Include="..\Managed\SpecialFunctions\Erf.cs">
<Link>SpecialFunctions\Erf.cs</Link>
</Compile>
<Compile Include="..\Managed\Statistics\DescriptiveStatistics.cs">
<Link>Statistics\DescriptiveStatistics.cs</Link>
</Compile>
<Compile Include="..\Managed\Statistics\Statistics.cs">
<Link>Statistics\Statistics.cs</Link>
</Compile>
<Compile Include="..\Managed\Threading\AggregateException.cs">
<Link>Threading\AggregateException.cs</Link>
</Compile>

Loading…
Cancel
Save