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