Browse Source

interpolation: refactored unit tests

Signed-off-by: Christoph Ruegg <git@cdrnet.ch>
pull/36/head
Christoph Ruegg 17 years ago
parent
commit
d5c9182f1e
  1. 2
      src/Numerics/Interpolation/Algorithms/SplineInterpolation.cs
  2. 104
      src/UnitTests/InterpolationTests/FunctionalHelpers.cs
  3. 378
      src/UnitTests/InterpolationTests/InterpolationContract.cs
  4. 201
      src/UnitTests/InterpolationTests/InterpolationFunctionalContract.cs
  5. 122
      src/UnitTests/InterpolationTests/InterpolationFunctionalTest.cs
  6. 265
      src/UnitTests/InterpolationTests/InterpolationInfrastructureContract.cs
  7. 343
      src/UnitTests/InterpolationTests/InterpolationInfrastuctureTest.cs
  8. 130
      src/UnitTests/InterpolationTests/InterpolationTest.cs
  9. 81
      src/UnitTests/InterpolationTests/SampleProvider.cs
  10. 8
      src/UnitTests/UnitTests.csproj

2
src/Numerics/Interpolation/Algorithms/SplineInterpolation.cs

@ -111,7 +111,7 @@ namespace MathNet.Numerics.Interpolation.Algorithms
throw new ArgumentNullException("splineCoefficients"); throw new ArgumentNullException("splineCoefficients");
} }
if (samplePoints.Count < 1) if (samplePoints.Count < 2)
{ {
throw new ArgumentOutOfRangeException("samplePoints"); throw new ArgumentOutOfRangeException("samplePoints");
} }

104
src/UnitTests/InterpolationTests/FunctionalHelpers.cs

@ -0,0 +1,104 @@
// <copyright file="FunctionalHelpers.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>
using System.Collections.Generic;
using System.Linq.Expressions;
using MathNet.Numerics.Interpolation;
namespace MathNet.Numerics.UnitTests.InterpolationTests
{
using System;
internal static class FunctionalHelpers
{
internal static Expression[] ApplySingleMap(
IList<Expression> list,
int index,
Func<Expression, Expression> replace)
{
var newList = new Expression[list.Count];
for (int i = 0; i < list.Count; i++)
{
newList[i] = (i == index) ? replace(list[i]) : list[i];
}
return newList;
}
internal static IEnumerable<Expression<Func<IInterpolation>>> ApplySingleMapEachArgument(
this LambdaExpression lambda,
Func<Type, bool> predicate,
Func<Expression, Expression> replace)
{
var body = lambda.Body;
var arguments =
body is NewExpression
? ((NewExpression)body).Arguments
: ((MethodCallExpression)body).Arguments;
for (int i = 0; i < arguments.Count; i++)
{
if (!predicate(arguments[i].Type))
{
continue;
}
var mappedArguments = ApplySingleMap(arguments, i, replace);
yield return Expression.Lambda<Func<IInterpolation>>(
body is NewExpression
? (Expression)Expression.New(
((NewExpression)body).Constructor,
mappedArguments)
: (Expression)Expression.Call(
((MethodCallExpression)body).Method,
mappedArguments));
}
}
internal static T ApplyReduceArgument<T>(
this LambdaExpression lambda,
Func<Expression, T, T> reduce,
T init)
{
var body = lambda.Body;
var arguments =
body is NewExpression
? ((NewExpression)body).Arguments
: ((MethodCallExpression)body).Arguments;
T value = init;
foreach (var argument in arguments)
{
value = reduce(argument, value);
}
return value;
}
}
}

378
src/UnitTests/InterpolationTests/InterpolationContract.cs

@ -1,378 +0,0 @@
// <copyright file="InterpolationContracts.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.InterpolationTests
{
using System;
using System.Collections.Generic;
using Gallio.Framework.Assertions;
using Interpolation;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
internal class InterpolationContract<TInterpolation> : AbstractContract
where TInterpolation : IInterpolation
{
public Func<IList<double>, IList<double>, IInterpolation> Factory { get; set; }
public int MinimumSampleCount { get; set; }
public bool NonStandardParameters { get; set; }
public bool LinearBehavior { get; set; }
public bool PolynomialBehavior { get; set; }
public bool RationalBehavior { get; set; }
protected override IEnumerable<Test> GetContractVerificationTests()
{
// Infrastructure Tests
yield return CreateFactoryReturnsCorrectTypeTest("FactoryReturnsCorrectType");
yield return CreateConsistentCapabilityBehaviorTest("ConsistentCapabilityBehavior");
yield return CreateInitChecksForNullTest("InitChecksForNull");
yield return CreateInitChecksForMatchingCountTest("InitChecksForMatchingCount");
yield return CreateInitChecksForMinimumCountTest("InitChecksForMinimumCount");
if (!NonStandardParameters)
{
yield return CreateConstructorInitShortcutTest("ConstructorInitShortcut");
}
// Numerics Behavior Tests
yield return CreateInterpolationMatchesNodePointsTest("InterpolationMatchesNodePoints");
if (LinearBehavior && !NonStandardParameters)
{
yield return CreateLinearBehaviorTest("LinearBehavior");
}
if (PolynomialBehavior && !NonStandardParameters)
{
yield return CreatePolynomialBehaviorTest("PolynomialBehavior");
}
if (RationalBehavior && !NonStandardParameters)
{
yield return CreateRationalBehaviorTest("RationalBehavior");
}
}
private Test CreateFactoryReturnsCorrectTypeTest(string name)
{
return new TestCase(name, () =>
{
double[] points, values;
SampleFunctionEquidistant(t => 5 + 10 * t, -2.0, 8.0, MinimumSampleCount, out points, out values);
var interpolation = Factory(points, values);
AssertionHelper.Verify(() =>
{
// verify returned interpolation has the expected type
if (interpolation.GetType() == typeof(TInterpolation))
{
return null;
}
return new AssertionFailureBuilder(
"Expected the factory to return the correct type.")
.AddRawLabeledValue("Interpolation Type", typeof(TInterpolation))
.SetStackTrace(Context.GetStackTraceData())
.ToAssertionFailure();
});
});
}
private Test CreateInitChecksForNullTest(string name)
{
return new TestCase(name, () =>
{
var points = new List<double> { 1, 2, 3, 4, 5 };
var values = new List<double> { 10, 20, 30, 40, 50 };
Assert.DoesNotThrow(() => Factory(points, values));
Assert.Throws(typeof(ArgumentNullException), () => Factory(points, null));
Assert.Throws(typeof(ArgumentNullException), () => Factory(null, values));
Assert.Throws(typeof(ArgumentNullException), () => Factory(null, null));
});
}
private Test CreateInitChecksForMatchingCountTest(string name)
{
return new TestCase(name, () =>
{
var points = new List<double> { 1, 2, 3, 4, 5 };
var valuesOk = new List<double> { 10, 20, 30, 40, 50 };
var valuesFail1 = new List<double> { 10, 20, 30, 40 };
var valuesFail2 = new List<double> { 10, 20, 30, 40, 50, 60 };
Assert.DoesNotThrow(() => Factory(points, valuesOk));
Assert.Throws(typeof(ArgumentException), () => Factory(points, valuesFail1));
Assert.Throws(typeof(ArgumentException), () => Factory(points, valuesFail2));
});
}
private Test CreateInitChecksForMinimumCountTest(string name)
{
return new TestCase(name, () =>
{
double[] pointsOk, valuesOk;
SampleFunctionEquidistant(t => 5 + 10 * t, -2.0, 8.0, MinimumSampleCount, out pointsOk, out valuesOk);
Assert.DoesNotThrow(() => Factory(pointsOk, valuesOk));
double[] pointsFail, valuesFail;
SampleFunctionEquidistant(t => 5 + 10 * t, -2.0, 8.0, MinimumSampleCount - 1, out pointsFail, out valuesFail);
Assert.Throws(typeof(ArgumentOutOfRangeException), () => Factory(pointsFail, valuesFail));
});
}
private Test CreateConstructorInitShortcutTest(string name)
{
return new TestCase(name, () =>
{
var points = new List<double> { 1, 2, 3, 4, 5 };
var values = new List<double> { 10, 20, 30, 40, 50 };
var ctor = typeof(TInterpolation).GetConstructor(
new[] { typeof (IList<double>), typeof (IList<double>) }
);
var interpolation = (IInterpolation)ctor.Invoke(
new[] { points, values }
);
Assert.AreApproximatelyEqual(20, interpolation.Interpolate(2), 1e-12);
});
}
private Test CreateConsistentCapabilityBehaviorTest(string name)
{
return new TestCase(name, () =>
{
double[] points, values;
SampleFunctionEquidistant(t => 5 + 10 * t, -2.0, 8.0, MinimumSampleCount, out points, out values);
var interpolation = Factory(points, values);
// verify consistent differentiation capability
if (interpolation.SupportsDifferentiation)
{
double a, b;
Assert.DoesNotThrow(() => interpolation.Differentiate(1.2));
Assert.DoesNotThrow(() => interpolation.Differentiate(1.2, out a, out b));
}
else
{
double a, b;
Assert.Throws(
typeof(NotSupportedException),
() => interpolation.Differentiate(1.2));
Assert.Throws(
typeof(NotSupportedException),
() => interpolation.Differentiate(1.2, out a, out b));
}
// verify consistent integration capability
if (interpolation.SupportsIntegration)
{
Assert.DoesNotThrow(() => interpolation.Integrate(1.2));
}
else
{
Assert.Throws(
typeof(NotSupportedException),
() => interpolation.Integrate(1.2));
}
});
}
private Test CreateInterpolationMatchesNodePointsTest(string name)
{
return new TestCase(name, () =>
{
var points = new List<double> { 1, 2, 2.3, 3, 8 };
var values = new List<double> { 50, 20, 30, 10, -20 };
var interpolation = Factory(points, values);
for (int i = 0; i < points.Count; i++)
{
Assert.AreApproximatelyEqual(
values[i],
interpolation.Interpolate(points[i]),
1e-12);
}
});
}
private Test CreateLinearBehaviorTest(string name)
{
return new TestCase(name, () =>
{
const double yOffset = 2.0;
const double xOffset = 4.0;
Random random = new Random();
int[] orders = { MinimumSampleCount, MinimumSampleCount + 1, MinimumSampleCount + 5 };
for (int k = 0; k < orders.Length; k++)
{
int order = orders[k];
// build linear samples
double[] points = new double[order];
double[] values = new double[order];
for (int i = 0; i < points.Length; i++)
{
points[i] = xOffset + i;
values[i] = yOffset + i;
}
var interpolation = Factory(points, values);
// build linear test vectors randomly between the sample points
double[] testPoints = new double[order + 1];
double[] testValues = new double[order + 1];
if (order == 1)
{
testPoints[0] = xOffset - random.NextDouble();
testPoints[1] = xOffset + random.NextDouble();
testValues[0] = testValues[1] = yOffset;
}
else
{
for (int i = 0; i < testPoints.Length; i++)
{
double z = (i - 1) + random.NextDouble();
testPoints[i] = xOffset + z;
testValues[i] = yOffset + z;
}
}
// verify interpolation with test samples
for (int i = 0; i < testPoints.Length; i++)
{
Assert.AreApproximatelyEqual(
testValues[i],
interpolation.Interpolate(testPoints[i]),
1e-12);
}
}
});
}
private Test CreatePolynomialBehaviorTest(string name)
{
return new TestCase(name, () =>
{
var points = new List<double> { -2.0, -1.0, 0.0, 1.0, 2.0 };
var values = new List<double> { 1.0, 2.0, -1.0, 0.0, 1.0 };
var interpolation = Factory(points, values);
// Maple: "with(CurveFitting);"
// Maple: "PolynomialInterpolation([[-2,1],[-1,2],[0,-1],[1,0],[2,1]], x);"
Assert.AreApproximatelyEqual(-4.5968, interpolation.Interpolate(-2.4), 1e-6, "A -2.4");
Assert.AreApproximatelyEqual(1.65395, interpolation.Interpolate(-0.9), 1e-6, "A -0.9");
Assert.AreApproximatelyEqual(0.21875, interpolation.Interpolate(-0.5), 1e-6, "A -0.5");
Assert.AreApproximatelyEqual(-0.84205, interpolation.Interpolate(-0.1), 1e-6, "A -0.1");
Assert.AreApproximatelyEqual(-1.10805, interpolation.Interpolate(0.1), 1e-6, "A 0.1");
Assert.AreApproximatelyEqual(-1.1248, interpolation.Interpolate(0.4), 1e-6, "A 0.4");
Assert.AreApproximatelyEqual(0.5392, interpolation.Interpolate(1.2), 1e-6, "A 1.2");
Assert.AreApproximatelyEqual(-4431.0, interpolation.Interpolate(10.0), 1e-6, "A 10.0");
Assert.AreApproximatelyEqual(-5071.0, interpolation.Interpolate(-10.0), 1e-6, "A -10.0");
});
}
private Test CreateRationalBehaviorTest(string name)
{
return new TestCase(name, () =>
{
double[] points, values;
SampleFunctionEquidistant(t => 1 / (1 + (t * t)), -5.0, 5.0, 41, out points, out values);
var interpolation = Factory(points, values);
for (int i = 0; i < points.Length; i++)
{
Assert.AreApproximatelyEqual(
values[i],
interpolation.Interpolate(points[i]),
1e-12,
"Match on knots");
}
double[] testPoints, testValues;
SampleFunctionEquidistant(t => 1 / (1 + (t * t)), -5.0, 5.0, 81, out testPoints, out testValues);
for (int i = 0; i < testPoints.Length; i++)
{
Assert.AreApproximatelyEqual(
testValues[i],
interpolation.Interpolate(testPoints[i]),
1e-5,
"Match between knots");
}
});
}
private static void SampleFunctionEquidistant(
Func<double, double> f,
double start,
double stop,
int samples,
out double[] points,
out double[] values)
{
points = new double[samples];
values = new double[samples];
if(samples == 0)
{
return;
}
if(samples == 1)
{
double t = points[0] = 0.5 * (start + stop);
values[0] = f(t);
return;
}
double step = (stop - start) / (samples - 1);
for (int i = 0; i < points.Length; i++)
{
double t = start + (i * step);
points[i] = t;
values[i] = f(t);
}
}
}
}

201
src/UnitTests/InterpolationTests/InterpolationFunctionalContract.cs

@ -0,0 +1,201 @@
// <copyright file="InterpolationFunctionalContract.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.InterpolationTests
{
using System;
using System.Collections.Generic;
using Interpolation;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
internal class InterpolationFunctionalContract<TInterpolation> : AbstractContract
where TInterpolation : IInterpolation
{
public Func<IList<double>, IList<double>, IInterpolation> Factory { get; set; }
public int MinimumSampleCount { get; set; }
public bool LinearBehavior { get; set; }
public bool PolynomialBehavior { get; set; }
public bool RationalBehavior { get; set; }
protected override IEnumerable<Test> GetContractVerificationTests()
{
yield return CreateInterpolationMatchesNodePointsTest();
if (LinearBehavior)
{
yield return CreateLinearBehaviorTest();
}
if (PolynomialBehavior)
{
yield return CreatePolynomialBehaviorTest();
}
if (RationalBehavior)
{
yield return CreateRationalBehaviorTest();
}
}
private Test CreateInterpolationMatchesNodePointsTest()
{
return new TestCase(
"InterpolationMatchesNodePoints",
() =>
{
var points = new List<double> { 1, 2, 2.3, 3, 8 };
var values = new List<double> { 50, 20, 30, 10, -20 };
var interpolation = Factory(points, values);
for (int i = 0; i < points.Count; i++)
{
Assert.AreApproximatelyEqual(
values[i],
interpolation.Interpolate(points[i]),
1e-12);
}
});
}
private Test CreateLinearBehaviorTest()
{
return new TestCase(
"LinearBehavior",
() =>
{
const double yOffset = 2.0;
const double xOffset = 4.0;
var random = new Random();
int[] orders = { MinimumSampleCount, MinimumSampleCount + 1, MinimumSampleCount + 5 };
for (int k = 0; k < orders.Length; k++)
{
int order = orders[k];
// build linear samples
var points = new double[order];
var values = new double[order];
for (int i = 0; i < points.Length; i++)
{
points[i] = xOffset + i;
values[i] = yOffset + i;
}
var interpolation = Factory(points, values);
// build linear test vectors randomly between the sample points
var testPoints = new double[order + 1];
var testValues = new double[order + 1];
if (order == 1)
{
testPoints[0] = xOffset - random.NextDouble();
testPoints[1] = xOffset + random.NextDouble();
testValues[0] = testValues[1] = yOffset;
}
else
{
for (int i = 0; i < testPoints.Length; i++)
{
double z = (i - 1) + random.NextDouble();
testPoints[i] = xOffset + z;
testValues[i] = yOffset + z;
}
}
// verify interpolation with test samples
for (int i = 0; i < testPoints.Length; i++)
{
Assert.AreApproximatelyEqual(
testValues[i],
interpolation.Interpolate(testPoints[i]),
1e-12);
}
}
});
}
private Test CreatePolynomialBehaviorTest()
{
return new TestCase(
"PolynomialBehavior",
() =>
{
var points = new List<double> { -2.0, -1.0, 0.0, 1.0, 2.0 };
var values = new List<double> { 1.0, 2.0, -1.0, 0.0, 1.0 };
var interpolation = Factory(points, values);
// Maple: "with(CurveFitting);"
// Maple: "PolynomialInterpolation([[-2,1],[-1,2],[0,-1],[1,0],[2,1]], x);"
Assert.AreApproximatelyEqual(-4.5968, interpolation.Interpolate(-2.4), 1e-6, "A -2.4");
Assert.AreApproximatelyEqual(1.65395, interpolation.Interpolate(-0.9), 1e-6, "A -0.9");
Assert.AreApproximatelyEqual(0.21875, interpolation.Interpolate(-0.5), 1e-6, "A -0.5");
Assert.AreApproximatelyEqual(-0.84205, interpolation.Interpolate(-0.1), 1e-6, "A -0.1");
Assert.AreApproximatelyEqual(-1.10805, interpolation.Interpolate(0.1), 1e-6, "A 0.1");
Assert.AreApproximatelyEqual(-1.1248, interpolation.Interpolate(0.4), 1e-6, "A 0.4");
Assert.AreApproximatelyEqual(0.5392, interpolation.Interpolate(1.2), 1e-6, "A 1.2");
Assert.AreApproximatelyEqual(-4431.0, interpolation.Interpolate(10.0), 1e-6, "A 10.0");
Assert.AreApproximatelyEqual(-5071.0, interpolation.Interpolate(-10.0), 1e-6, "A -10.0");
});
}
private Test CreateRationalBehaviorTest()
{
return new TestCase(
"RationalBehavior",
() =>
{
double[] points, values;
SampleProvider.Equidistant(t => 1 / (1 + (t * t)), -5.0, 5.0, 41, out points, out values);
var interpolation = Factory(points, values);
for (int i = 0; i < points.Length; i++)
{
Assert.AreApproximatelyEqual(
values[i],
interpolation.Interpolate(points[i]),
1e-12,
"Match on knots");
}
double[] testPoints, testValues;
SampleProvider.Equidistant(t => 1 / (1 + (t * t)), -5.0, 5.0, 81, out testPoints, out testValues);
for (int i = 0; i < testPoints.Length; i++)
{
Assert.AreApproximatelyEqual(
testValues[i],
interpolation.Interpolate(testPoints[i]),
1e-5,
"Match between knots");
}
});
}
}
}

122
src/UnitTests/InterpolationTests/InterpolationFunctionalTest.cs

@ -0,0 +1,122 @@
// <copyright file="InterpolationFunctionalTest.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.InterpolationTests
{
using Interpolation;
using Interpolation.Algorithms;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
[TestFixture]
public class InterpolationFunctionalTest
{
/**** Direct Algorithms (without precomputations) ****/
[VerifyContract]
public readonly IContract NevillePolynomialFunctionalTests =
new InterpolationFunctionalContract<NevillePolynomialInterpolation>
{
Factory = (t, x) => new NevillePolynomialInterpolation(t, x),
MinimumSampleCount = 1,
LinearBehavior = true,
PolynomialBehavior = true,
RationalBehavior = false
};
[VerifyContract]
public readonly IContract BulirschStoerRationalFunctionalTests =
new InterpolationFunctionalContract<BulirschStoerRationalInterpolation>
{
Factory = Interpolate.RationalWithPoles,
MinimumSampleCount = 1,
LinearBehavior = false,
PolynomialBehavior = true,
RationalBehavior = true
};
/**** Barycentric Algorithms ****/
[VerifyContract]
public readonly IContract FloaterHormannRationalFunctionalTests =
new InterpolationFunctionalContract<FloaterHormannRationalInterpolation>
{
Factory = Interpolate.RationalWithoutPoles,
MinimumSampleCount = 1,
LinearBehavior = true,
PolynomialBehavior = true,
RationalBehavior = true
};
[VerifyContract]
public readonly IContract EquidistantPolynomialFunctionalTests =
new InterpolationFunctionalContract<EquidistantPolynomialInterpolation>
{
Factory = (t, x) => new EquidistantPolynomialInterpolation(t, x),
MinimumSampleCount = 1,
LinearBehavior = true,
PolynomialBehavior = true,
RationalBehavior = false
};
/**** Spline Algorithms ****/
[VerifyContract]
public readonly IContract LinearSplineFunctionalTests =
new InterpolationFunctionalContract<LinearSplineInterpolation>
{
Factory = Interpolate.LinearBetweenPoints,
MinimumSampleCount = 2,
LinearBehavior = true,
PolynomialBehavior = false,
RationalBehavior = false
};
[VerifyContract]
public readonly IContract CubicSplineFunctionalTests =
new InterpolationFunctionalContract<CubicSplineInterpolation>
{
Factory = (t, x) => new CubicSplineInterpolation(t, x),
MinimumSampleCount = 2,
LinearBehavior = true,
PolynomialBehavior = false,
RationalBehavior = false
};
[VerifyContract]
public readonly IContract AkimaSplineFunctionalTests =
new InterpolationFunctionalContract<AkimaSplineInterpolation>
{
Factory = (t, x) => new AkimaSplineInterpolation(t, x),
MinimumSampleCount = 5,
LinearBehavior = true,
PolynomialBehavior = false,
RationalBehavior = false
};
}
}

265
src/UnitTests/InterpolationTests/InterpolationInfrastructureContract.cs

@ -0,0 +1,265 @@
// <copyright file="InterpolationInfrastructureContract.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.InterpolationTests
{
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Interpolation;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
internal class InterpolationInfrastructureContract<TInterpolation> : AbstractContract
where TInterpolation : IInterpolation
{
public Func<IInterpolation>[] UninitializedFactories { get; set; }
public Expression<Func<IInterpolation>>[] InitializedFactories { get; set; }
public int MinimumSampleCount { get; set; }
protected override IEnumerable<Test> GetContractVerificationTests()
{
yield return CreateLoadUninitializedFactoryTest();
yield return CreateLoadInitializedFactoryTest();
yield return CreateInitializedFactoryChecksForNullTest();
yield return CreateInitializedFactoryChecksForToFewSamplesTest();
yield return CreateInitializedFactoryChecksForCountMismatchTest();
yield return CreateConsistentCapabilityBehaviorTest();
}
private Test CreateLoadUninitializedFactoryTest()
{
return new TestCase(
"LoadUninitializedFactory",
() =>
{
Assert.IsNotNull(UninitializedFactories);
Assert.LessThan(0, UninitializedFactories.Length);
foreach (var factory in UninitializedFactories)
{
var interpolation = factory();
Assert.IsNotNull(interpolation);
Assert.IsInstanceOfType(typeof(TInterpolation), interpolation);
}
});
}
private Test CreateLoadInitializedFactoryTest()
{
return new TestCase(
"LoadInitializedFactory",
() =>
{
Assert.IsNotNull(InitializedFactories);
Assert.LessThan(0, InitializedFactories.Length);
foreach (var factory in InitializedFactories)
{
var interpolation = factory.Compile()();
Assert.IsNotNull(interpolation);
Assert.IsInstanceOfType(typeof(TInterpolation), interpolation);
Assert.DoesNotThrow(() => interpolation.Interpolate(0.0));
}
});
}
private Test CreateInitializedFactoryChecksForNullTest()
{
return new TestCase(
"InitializedFactoryChecksForNull",
() =>
{
foreach (var factory in InitializedFactories)
{
// we only support method calls and constructors for now.
if (factory.Body.NodeType != ExpressionType.New
&& factory.Body.NodeType != ExpressionType.Call)
{
Assert.Fail(
"Factory '{0}' is neither a constructor or a method call.",
factory.ToString());
continue;
}
var modifiedFactories = factory.ApplySingleMapEachArgument(
t => !t.IsValueType,
e => Expression.Constant(null, e.Type));
foreach (var modifiedFactory in modifiedFactories)
{
var closureFactoryReference = modifiedFactory;
Assert.Throws(
typeof(ArgumentNullException),
() => closureFactoryReference.Compile()(),
"Factory must check for null arguments ({0})",
closureFactoryReference.ToString());
}
}
});
}
private Test CreateInitializedFactoryChecksForToFewSamplesTest()
{
return new TestCase(
"InitializedFactoryChecksForToFewSamples",
() =>
{
foreach (var factory in InitializedFactories)
{
// we only support method calls and constructors for now.
if (factory.Body.NodeType != ExpressionType.New
&& factory.Body.NodeType != ExpressionType.Call)
{
Assert.Fail(
"Factory '{0}' is neither a constructor or a method call.",
factory.ToString());
continue;
}
var modifiedFactories = factory.ApplySingleMapEachArgument(
t => !t.IsValueType,
e => Expression.Constant(new double[MinimumSampleCount - 1], typeof(double[])));
foreach (var modifiedFactory in modifiedFactories)
{
var closureFactoryReference = modifiedFactory;
Assert.Throws(
typeof(ArgumentException),
() => closureFactoryReference.Compile()(),
"Factory must check to ensure there are enough samples ({0})",
closureFactoryReference.ToString());
}
}
});
}
private Test CreateInitializedFactoryChecksForCountMismatchTest()
{
return new TestCase(
"InitializedFactoryChecksForCountMismatch",
() =>
{
foreach (var factory in InitializedFactories)
{
// we only support method calls and constructors for now.
if (factory.Body.NodeType != ExpressionType.New
&& factory.Body.NodeType != ExpressionType.Call)
{
Assert.Fail(
"Factory '{0}' is neither a constructor or a method call.",
factory.ToString());
continue;
}
// mismatch doesn't make sense when there are less than two list arguments.
int listCount = factory.ApplyReduceArgument(
(e, count) => typeof(IList<double>).IsAssignableFrom(e.Type) ? count + 1 : count,
0);
if (listCount < 2)
{
continue;
}
var modifiedFactories = factory.ApplySingleMapEachArgument(
t => !t.IsValueType,
e =>
{
// add a single entry to the end of the list
var originalList = Expression.Lambda<Func<double[]>>(e).Compile()();
var newList = new double[originalList.Length + 1];
originalList.CopyTo(newList, 0);
newList[newList.Length - 1] = -1;
return Expression.Constant(newList, e.Type);
});
foreach (var modifiedFactory in modifiedFactories)
{
var closureFactoryReference = modifiedFactory;
Assert.Throws(
typeof(ArgumentException),
() => closureFactoryReference.Compile()(),
"Factory must check for matching sample lengths ({0})",
closureFactoryReference.ToString());
}
}
});
}
private Test CreateConsistentCapabilityBehaviorTest()
{
return new TestCase(
"ConsistentCapabilityBehavior",
() =>
{
var interpolation = InitializedFactories[0].Compile()();
// verify consistent differentiation capability
if (interpolation.SupportsDifferentiation)
{
double a, b;
Assert.DoesNotThrow(() => interpolation.Differentiate(1.2));
Assert.DoesNotThrow(() => interpolation.Differentiate(1.2, out a, out b));
}
else
{
double a, b;
Assert.Throws(
typeof(NotSupportedException),
() => interpolation.Differentiate(1.2));
Assert.Throws(
typeof(NotSupportedException),
() => interpolation.Differentiate(1.2, out a, out b));
}
// verify consistent integration capability
if (interpolation.SupportsIntegration)
{
Assert.DoesNotThrow(() => interpolation.Integrate(1.2));
}
else
{
Assert.Throws(
typeof(NotSupportedException),
() => interpolation.Integrate(1.2));
}
});
}
}
}

343
src/UnitTests/InterpolationTests/InterpolationInfrastuctureTest.cs

@ -0,0 +1,343 @@
// <copyright file="InterpolationInfrastuctureTest.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.InterpolationTests
{
using System;
using System.Linq.Expressions;
using Interpolation;
using Interpolation.Algorithms;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
[TestFixture]
public class InterpolationInfrastuctureTest
{
/**** Direct Algorithms (without precomputations) ****/
[VerifyContract]
public readonly IContract NevillePolynomialInfrastructureTests =
new InterpolationInfrastructureContract<NevillePolynomialInterpolation>
{
MinimumSampleCount = 1,
UninitializedFactories =
new Func<IInterpolation>[]
{
() => new NevillePolynomialInterpolation()
},
InitializedFactories =
new Expression<Func<IInterpolation>>[]
{
() => new NevillePolynomialInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5))
}
};
[VerifyContract]
public readonly IContract BulirschStoerRationalInfrastructureTests =
new InterpolationInfrastructureContract<BulirschStoerRationalInterpolation>
{
MinimumSampleCount = 1,
UninitializedFactories =
new Func<IInterpolation>[]
{
() => new BulirschStoerRationalInterpolation()
},
InitializedFactories =
new Expression<Func<IInterpolation>>[]
{
() => new BulirschStoerRationalInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5)),
() => Interpolate.RationalWithPoles(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5))
}
};
/**** Barycentric Algorithms ****/
[VerifyContract]
public readonly IContract BarycentricInfrastructureTests =
new InterpolationInfrastructureContract<BarycentricInterpolation>
{
MinimumSampleCount = 3,
UninitializedFactories =
new Func<IInterpolation>[]
{
() => new BarycentricInterpolation()
},
InitializedFactories =
new Expression<Func<IInterpolation>>[]
{
() => new BarycentricInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5),
SampleProvider.LinearEquidistant(10, 1, 0.1)),
() => new BarycentricInterpolation(
SampleProvider.LinearEquidistant(10, 5, -1),
SampleProvider.LinearEquidistant(10, -2, 0.5),
SampleProvider.LinearEquidistant(10, 1, 0.1))
}
};
[VerifyContract]
public readonly IContract FloaterHormannRationalInfrastructureTests =
new InterpolationInfrastructureContract<FloaterHormannRationalInterpolation>
{
MinimumSampleCount = 1,
UninitializedFactories =
new Func<IInterpolation>[]
{
() => new FloaterHormannRationalInterpolation()
},
InitializedFactories =
new Expression<Func<IInterpolation>>[]
{
() => new FloaterHormannRationalInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5)),
() => new FloaterHormannRationalInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5),
5),
() => Interpolate.RationalWithoutPoles(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5)),
() => Interpolate.Common(
SampleProvider.LinearEquidistant(10, 5, -1),
SampleProvider.LinearEquidistant(10, -2, 0.5))
}
};
[VerifyContract]
public readonly IContract EquidistantPolynomialInfrastructureTests =
new InterpolationInfrastructureContract<EquidistantPolynomialInterpolation>
{
MinimumSampleCount = 1,
UninitializedFactories =
new Func<IInterpolation>[]
{
() => new EquidistantPolynomialInterpolation()
},
InitializedFactories =
new Expression<Func<IInterpolation>>[]
{
() => new EquidistantPolynomialInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5)),
() => new EquidistantPolynomialInterpolation(
SampleProvider.LinearEquidistant(10, 5, -1),
SampleProvider.LinearEquidistant(10, -2, 0.5)),
() => new EquidistantPolynomialInterpolation(
-5,
4,
SampleProvider.LinearEquidistant(10, -2, 0.5))
}
};
/**** Spline Algorithms ****/
[VerifyContract]
public readonly IContract SplineInfrastructureTests =
new InterpolationInfrastructureContract<SplineInterpolation>
{
MinimumSampleCount = 2,
UninitializedFactories =
new Func<IInterpolation>[]
{
() => new SplineInterpolation()
},
InitializedFactories =
new Expression<Func<IInterpolation>>[]
{
() => new SplineInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(4 * (10 - 1), -2, 0.5)),
() => new SplineInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
AkimaSplineInterpolation.EvaluateSplineCoefficients(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5))),
() => new SplineInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
CubicSplineInterpolation.EvaluateSplineCoefficients(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5),
SplineBoundaryCondition.Natural,
1.0,
SplineBoundaryCondition.Natural,
-1.0))
}
};
[VerifyContract]
public readonly IContract CubicHermiteSplineInfrastructureTests =
new InterpolationInfrastructureContract<CubicHermiteSplineInterpolation>
{
MinimumSampleCount = 2,
UninitializedFactories =
new Func<IInterpolation>[]
{
() => new CubicHermiteSplineInterpolation()
},
InitializedFactories =
new Expression<Func<IInterpolation>>[]
{
() => new CubicHermiteSplineInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5),
SampleProvider.LinearEquidistant(10, 1, 0.1))
}
};
[VerifyContract]
public readonly IContract LinearSplineInfrastructureTests =
new InterpolationInfrastructureContract<LinearSplineInterpolation>
{
MinimumSampleCount = 2,
UninitializedFactories =
new Func<IInterpolation>[]
{
() => new LinearSplineInterpolation()
},
InitializedFactories =
new Expression<Func<IInterpolation>>[]
{
() => new LinearSplineInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5)),
() => Interpolate.LinearBetweenPoints(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5))
}
};
[VerifyContract]
public readonly IContract CubicSplineInfrastructureTests =
new InterpolationInfrastructureContract<CubicSplineInterpolation>
{
MinimumSampleCount = 2,
UninitializedFactories =
new Func<IInterpolation>[]
{
() => new CubicSplineInterpolation()
},
InitializedFactories =
new Expression<Func<IInterpolation>>[]
{
() => new CubicSplineInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5)),
() => new CubicSplineInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5),
SplineBoundaryCondition.FirstDerivative,
1.0,
SplineBoundaryCondition.FirstDerivative,
-1.0),
() => new CubicSplineInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5),
SplineBoundaryCondition.Natural,
1.0,
SplineBoundaryCondition.Natural,
-1.0),
() => new CubicSplineInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5),
SplineBoundaryCondition.ParabolicallyTerminated,
1.0,
SplineBoundaryCondition.ParabolicallyTerminated,
-1.0),
() => new CubicSplineInterpolation(
SampleProvider.LinearEquidistant(2, -5, 1),
SampleProvider.LinearEquidistant(2, -2, 0.5),
SplineBoundaryCondition.ParabolicallyTerminated,
1.0,
SplineBoundaryCondition.ParabolicallyTerminated,
-1.0)
}
};
[VerifyContract]
public readonly IContract AkimaSplineInfrastructureTests =
new InterpolationInfrastructureContract<AkimaSplineInterpolation>
{
MinimumSampleCount = 5,
UninitializedFactories =
new Func<IInterpolation>[]
{
() => new AkimaSplineInterpolation()
},
InitializedFactories =
new Expression<Func<IInterpolation>>[]
{
() => new AkimaSplineInterpolation(
SampleProvider.LinearEquidistant(10, -5, 1),
SampleProvider.LinearEquidistant(10, -2, 0.5))
}
};
[Test]
public void FloaterHormannRationalThrowsOnBadOrder()
{
Assert.Throws(
typeof(ArgumentOutOfRangeException),
() => new FloaterHormannRationalInterpolation(
new double[5],
new double[5],
10));
}
[Test]
public void CubicSplineThrowsOnBadBoundaryCondition()
{
Assert.Throws(
typeof(NotSupportedException),
() => new CubicSplineInterpolation(
new double[5],
new double[5],
(SplineBoundaryCondition)(-1),
0,
SplineBoundaryCondition.Natural,
0));
Assert.Throws(
typeof(NotSupportedException),
() => new CubicSplineInterpolation(
new double[5],
new double[5],
SplineBoundaryCondition.Natural,
0,
(SplineBoundaryCondition)(-1),
0));
}
}
}

130
src/UnitTests/InterpolationTests/InterpolationTest.cs

@ -1,130 +0,0 @@
// <copyright file="InterpolationTest.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.InterpolationTests
{
using System;
using Interpolation;
using Interpolation.Algorithms;
using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
[TestFixture]
public class InterpolationTest
{
// Direct Algorithms (without precomputations)
[VerifyContract]
public readonly IContract NevillePolynomialContractTests = new InterpolationContract<NevillePolynomialInterpolation>()
{
Factory = (t, x) => new NevillePolynomialInterpolation(t, x),
MinimumSampleCount = 1,
LinearBehavior = true,
PolynomialBehavior = true,
RationalBehavior = false
};
[VerifyContract]
public readonly IContract BulirschStoerRationalContractTests = new InterpolationContract<BulirschStoerRationalInterpolation>()
{
Factory = Interpolate.RationalWithPoles,
MinimumSampleCount = 1,
LinearBehavior = false,
PolynomialBehavior = true,
RationalBehavior = true
};
// Barycentric Algorithms
[VerifyContract]
public readonly IContract BarycentricContractTests = new InterpolationContract<BarycentricInterpolation>()
{
Factory = (t, x) => new BarycentricInterpolation(t, x, FloaterHormannRationalInterpolation.EvaluateBarycentricWeights(t, x, 2)),
MinimumSampleCount = 3,
NonStandardParameters = true,
};
[VerifyContract]
public readonly IContract FloaterHormannRationalContractTests = new InterpolationContract<FloaterHormannRationalInterpolation>()
{
Factory = Interpolate.RationalWithoutPoles,
MinimumSampleCount = 1,
LinearBehavior = true,
PolynomialBehavior = true,
RationalBehavior = true
};
// Spline Algorithms
[VerifyContract]
public readonly IContract SplineContractTests = new InterpolationContract<SplineInterpolation>()
{
Factory = (t, x) => new SplineInterpolation(t, LinearSplineInterpolation.EvaluateSplineCoefficients(t, x)),
MinimumSampleCount = 2,
NonStandardParameters = true,
};
[VerifyContract]
public readonly IContract CubicHermiteSplineContractTests = new InterpolationContract<CubicHermiteSplineInterpolation>()
{
Factory = (t, x) => new CubicHermiteSplineInterpolation(t, x, CubicSplineInterpolation.EvaluateSplineDerivatives(t, x, SplineBoundaryCondition.Natural, 0.0, SplineBoundaryCondition.Natural, 0.0)),
MinimumSampleCount = 2,
NonStandardParameters = true,
};
[VerifyContract]
public readonly IContract LinearSplineContractTests = new InterpolationContract<LinearSplineInterpolation>()
{
Factory = Interpolate.LinearBetweenPoints,
MinimumSampleCount = 2,
LinearBehavior = true,
PolynomialBehavior = false,
RationalBehavior = false
};
[VerifyContract]
public readonly IContract CubicSplineContractTests = new InterpolationContract<CubicSplineInterpolation>()
{
Factory = (t, x) => new CubicSplineInterpolation(t, x),
MinimumSampleCount = 2,
LinearBehavior = true,
PolynomialBehavior = false,
RationalBehavior = false
};
[VerifyContract]
public readonly IContract AkimaSplineContractTests = new InterpolationContract<AkimaSplineInterpolation>()
{
Factory = (t, x) => new AkimaSplineInterpolation(t, x),
MinimumSampleCount = 5,
LinearBehavior = true,
PolynomialBehavior = false,
RationalBehavior = false
};
}
}

81
src/UnitTests/InterpolationTests/SampleProvider.cs

@ -0,0 +1,81 @@
// <copyright file="SampleProvider.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.InterpolationTests
{
using System;
internal static class SampleProvider
{
internal static double[] LinearEquidistant(int count, double start, double step)
{
var samples = new double[count];
var nextValue = start;
for (int i = 0; i < samples.Length; i++)
{
samples[i] = nextValue;
nextValue += step;
}
return samples;
}
internal static void Equidistant(
Func<double, double> f,
double start,
double stop,
int samples,
out double[] points,
out double[] values)
{
points = new double[samples];
values = new double[samples];
if (samples == 0)
{
return;
}
if (samples == 1)
{
double t = points[0] = 0.5 * (start + stop);
values[0] = f(t);
return;
}
double step = (stop - start) / (samples - 1);
for (int i = 0; i < points.Length; i++)
{
double t = start + (i * step);
points[i] = t;
values[i] = f(t);
}
}
}
}

8
src/UnitTests/UnitTests.csproj

@ -74,8 +74,12 @@
<Compile Include="IntegralTransformsTests\InverseTransformTest.cs" /> <Compile Include="IntegralTransformsTests\InverseTransformTest.cs" />
<Compile Include="IntegralTransformsTests\SampleProvider.cs" /> <Compile Include="IntegralTransformsTests\SampleProvider.cs" />
<Compile Include="IntegrationTests\IntegrationTest.cs" /> <Compile Include="IntegrationTests\IntegrationTest.cs" />
<Compile Include="InterpolationTests\InterpolationContract.cs" /> <Compile Include="InterpolationTests\FunctionalHelpers.cs" />
<Compile Include="InterpolationTests\InterpolationTest.cs" /> <Compile Include="InterpolationTests\InterpolationInfrastuctureTest.cs" />
<Compile Include="InterpolationTests\InterpolationFunctionalContract.cs" />
<Compile Include="InterpolationTests\InterpolationInfrastructureContract.cs" />
<Compile Include="InterpolationTests\InterpolationFunctionalTest.cs" />
<Compile Include="InterpolationTests\SampleProvider.cs" />
<Compile Include="LinearAlgebraTests\Double\DenseVectorTests.cs" /> <Compile Include="LinearAlgebraTests\Double\DenseVectorTests.cs" />
<Compile Include="LinearAlgebraTests\Double\VectorTests.cs" /> <Compile Include="LinearAlgebraTests\Double\VectorTests.cs" />
<Compile Include="NumberTheoryTests\GcdRelatedTest.cs" /> <Compile Include="NumberTheoryTests\GcdRelatedTest.cs" />

Loading…
Cancel
Save