10 changed files with 1123 additions and 511 deletions
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -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"); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -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 |
|||
}; |
|||
} |
|||
} |
|||
@ -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)); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -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)); |
|||
} |
|||
} |
|||
} |
|||
@ -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 |
|||
}; |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue