Browse Source

quadrature: tests now verify argument checks

Signed-off-by: Christoph Ruegg <git@cdrnet.ch>
pull/2/head
Christoph Ruegg 17 years ago
parent
commit
097946b9a8
  1. 4
      src/Numerics/Integration/Algorithms/DoubleExponentialTransformation.cs
  2. 30
      src/Numerics/Integration/Algorithms/NewtonCotesTrapeziumRule.cs
  3. 14
      src/Numerics/Integration/Algorithms/SimpsonRule.cs
  4. 62
      src/UnitTests/IntegrationTests/IntegrationTest.cs

4
src/Numerics/Integration/Algorithms/DoubleExponentialTransformation.cs

@ -535,7 +535,7 @@ namespace MathNet.Numerics.Integration.Algorithms
/// Abscissa vector per level provider. /// Abscissa vector per level provider.
/// </summary> /// </summary>
/// <returns>Level Enumerator.</returns> /// <returns>Level Enumerator.</returns>
private static IEnumerable<double[]> ProvideLevelAbcissas() internal static IEnumerable<double[]> ProvideLevelAbcissas()
{ {
for (int i = 0; i < NumberOfMaximumLevels; i++) for (int i = 0; i < NumberOfMaximumLevels; i++)
{ {
@ -547,7 +547,7 @@ namespace MathNet.Numerics.Integration.Algorithms
/// Weight vector per level provider. /// Weight vector per level provider.
/// </summary> /// </summary>
/// <returns>Level Enumerator.</returns> /// <returns>Level Enumerator.</returns>
private static IEnumerable<double[]> ProvideLevelWeights() internal static IEnumerable<double[]> ProvideLevelWeights()
{ {
for (int i = 0; i < NumberOfMaximumLevels; i++) for (int i = 0; i < NumberOfMaximumLevels; i++)
{ {

30
src/Numerics/Integration/Algorithms/NewtonCotesTrapeziumRule.cs

@ -52,6 +52,11 @@ namespace MathNet.Numerics.Integration.Algorithms
double intervalBegin, double intervalBegin,
double intervalEnd) double intervalEnd)
{ {
if (f == null)
{
throw new ArgumentNullException("f");
}
return (intervalEnd - intervalBegin) / 2 * (f(intervalBegin) + f(intervalEnd)); return (intervalEnd - intervalBegin) / 2 * (f(intervalBegin) + f(intervalEnd));
} }
@ -69,6 +74,11 @@ namespace MathNet.Numerics.Integration.Algorithms
double intervalEnd, double intervalEnd,
int numberOfPartitions) int numberOfPartitions)
{ {
if (f == null)
{
throw new ArgumentNullException("f");
}
if (numberOfPartitions <= 0) if (numberOfPartitions <= 0)
{ {
throw new ArgumentOutOfRangeException("numberOfPartitions", Resources.ArgumentPositive); throw new ArgumentOutOfRangeException("numberOfPartitions", Resources.ArgumentPositive);
@ -102,6 +112,11 @@ namespace MathNet.Numerics.Integration.Algorithms
double intervalEnd, double intervalEnd,
double targetError) double targetError)
{ {
if (f == null)
{
throw new ArgumentNullException("f");
}
int numberOfPartitions = 1; int numberOfPartitions = 1;
double step = intervalEnd - intervalBegin; double step = intervalEnd - intervalBegin;
double sum = 0.5 * step * (f(intervalBegin) + f(intervalEnd)); double sum = 0.5 * step * (f(intervalBegin) + f(intervalEnd));
@ -147,6 +162,21 @@ namespace MathNet.Numerics.Integration.Algorithms
double levelOneStep, double levelOneStep,
double targetRelativeError) double targetRelativeError)
{ {
if (f == null)
{
throw new ArgumentNullException("f");
}
if (levelAbscissas == null)
{
throw new ArgumentNullException("levelAbscissas");
}
if (levelWeights == null)
{
throw new ArgumentNullException("levelWeights");
}
double linearSlope = 0.5 * (intervalEnd - intervalBegin); double linearSlope = 0.5 * (intervalEnd - intervalBegin);
double linearOffset = 0.5 * (intervalEnd + intervalBegin); double linearOffset = 0.5 * (intervalEnd + intervalBegin);
targetRelativeError /= 5 * linearSlope; targetRelativeError /= 5 * linearSlope;

14
src/Numerics/Integration/Algorithms/SimpsonRule.cs

@ -49,6 +49,11 @@ namespace MathNet.Numerics.Integration.Algorithms
double intervalBegin, double intervalBegin,
double intervalEnd) double intervalEnd)
{ {
if (f == null)
{
throw new ArgumentNullException("f");
}
double midpoint = (intervalEnd + intervalBegin) / 2; double midpoint = (intervalEnd + intervalBegin) / 2;
return (intervalEnd - intervalBegin) / 6 * (f(intervalBegin) + f(intervalEnd) + (4 * f(midpoint))); return (intervalEnd - intervalBegin) / 6 * (f(intervalBegin) + f(intervalEnd) + (4 * f(midpoint)));
} }
@ -67,6 +72,11 @@ namespace MathNet.Numerics.Integration.Algorithms
double intervalEnd, double intervalEnd,
int numberOfPartitions) int numberOfPartitions)
{ {
if (f == null)
{
throw new ArgumentNullException("f");
}
if (numberOfPartitions <= 0) if (numberOfPartitions <= 0)
{ {
throw new ArgumentOutOfRangeException("numberOfPartitions", Resources.ArgumentPositive); throw new ArgumentOutOfRangeException("numberOfPartitions", Resources.ArgumentPositive);
@ -85,7 +95,7 @@ namespace MathNet.Numerics.Integration.Algorithms
double sum = f(intervalBegin) + f(intervalEnd); double sum = f(intervalBegin) + f(intervalEnd);
for (int i = 0; i < numberOfPartitions - 1; i++) for (int i = 0; i < numberOfPartitions - 1; i++)
{ {
// NOTE (ruegg, 2009-01-07): Do not combine intervalBegin and offset (numerical stability) // NOTE (cdrnet, 2009-01-07): Do not combine intervalBegin and offset (numerical stability)
sum += m * f(intervalBegin + offset); sum += m * f(intervalBegin + offset);
m = 6 - m; m = 6 - m;
offset += step; offset += step;
@ -94,4 +104,4 @@ namespace MathNet.Numerics.Integration.Algorithms
return factor * sum; return factor * sum;
} }
} }
} }

62
src/UnitTests/IntegrationTests/IntegrationTest.cs

@ -26,13 +26,14 @@
// OTHER DEALINGS IN THE SOFTWARE. // OTHER DEALINGS IN THE SOFTWARE.
// </copyright> // </copyright>
namespace MathNet.Numerics.UnitTests.IntegrationTests namespace MathNet.Numerics.UnitTests.IntegrationTests
{ {
using System; using System;
using System.Linq.Expressions;
using Integration; using Integration;
using Integration.Algorithms; using Integration.Algorithms;
using MbUnit.Framework; using MbUnit.Framework;
using MbUnit.Framework.ContractVerifiers;
[TestFixture] [TestFixture]
public class IntegrationTest public class IntegrationTest
@ -65,6 +66,18 @@ namespace MathNet.Numerics.UnitTests.IntegrationTests
"Basic Target 1e-10"); "Basic Target 1e-10");
} }
[VerifyContract]
public readonly IContract FacadeIntegrateChecksArguments =
new ArgumentCheckContract<double>
{
TypicalUses =
new Expression<Func<double>>[]
{
() => Integrate.OnClosedInterval(x => 2 * x, StartA, StopA),
() => Integrate.OnClosedInterval(x => 2 * x, StartA, StopA, 1e-5)
}
};
[Test] [Test]
[Row(1e-5)] [Row(1e-5)]
[Row(1e-13)] [Row(1e-13)]
@ -79,6 +92,13 @@ namespace MathNet.Numerics.UnitTests.IntegrationTests
"DET Adaptive {0}", targetRelativeError); "DET Adaptive {0}", targetRelativeError);
} }
[VerifyContract]
public readonly IContract DoubleExponentialTransformationIntegrateChecksArguments =
new ArgumentCheckContract<double>
{
TypicalUse = () => (new DoubleExponentialTransformation()).Integrate(x => 2 * x, StartA, StopA, 1e-5)
};
[Test] [Test]
public void TrapeziumRuleSupportsTwoPointIntegration() public void TrapeziumRuleSupportsTwoPointIntegration()
{ {
@ -117,6 +137,28 @@ namespace MathNet.Numerics.UnitTests.IntegrationTests
"Adaptive {0}", targetRelativeError); "Adaptive {0}", targetRelativeError);
} }
[VerifyContract]
public readonly IContract TrapeziumRuleIntegrateChecksArguments =
new ArgumentCheckContract<double>
{
TypicalUses =
new Expression<Func<double>>[]
{
() => NewtonCotesTrapeziumRule.IntegrateTwoPoint(x => 2 * x, StartA, StopA),
() => NewtonCotesTrapeziumRule.IntegrateComposite(x => 2 * x, StartA, StopA, 2),
() => NewtonCotesTrapeziumRule.IntegrateAdaptive(x => 2 * x, StartA, StopA, 1e-5),
() => NewtonCotesTrapeziumRule.IntegrateAdaptiveTransformedOdd(
x => 2 * x,
StartA,
StopA,
DoubleExponentialTransformation.ProvideLevelAbcissas(),
DoubleExponentialTransformation.ProvideLevelWeights(),
1,
1e-5)
},
BadUse = () => NewtonCotesTrapeziumRule.IntegrateComposite(x => 2 * x, StartA, StopA, 0)
};
[Test] [Test]
public void SimpsonRuleSupportsThreePointIntegration() public void SimpsonRuleSupportsThreePointIntegration()
{ {
@ -141,5 +183,23 @@ namespace MathNet.Numerics.UnitTests.IntegrationTests
maxRelativeError * TargetAreaA, maxRelativeError * TargetAreaA,
"Composite {0} Partitions", partitions); "Composite {0} Partitions", partitions);
} }
[VerifyContract]
public readonly IContract SimpsonRuleIntegrateChecksArguments =
new ArgumentCheckContract<double>
{
TypicalUses =
new Expression<Func<double>>[]
{
() => SimpsonRule.IntegrateThreePoint(x => 2 * x, StartA, StopA),
() => SimpsonRule.IntegrateComposite(x => 2 * x, StartA, StopA, 2)
},
BadUses =
new Func<double>[]
{
() => SimpsonRule.IntegrateComposite(x => 2 * x, StartA, StopA, 0),
() => SimpsonRule.IntegrateComposite(x => 2 * x, StartA, StopA, 3)
}
};
} }
} }

Loading…
Cancel
Save