diff --git a/src/Numerics/Integration/Algorithms/DoubleExponentialTransformation.cs b/src/Numerics/Integration/Algorithms/DoubleExponentialTransformation.cs
index e9458a0c..06a3d187 100644
--- a/src/Numerics/Integration/Algorithms/DoubleExponentialTransformation.cs
+++ b/src/Numerics/Integration/Algorithms/DoubleExponentialTransformation.cs
@@ -535,7 +535,7 @@ namespace MathNet.Numerics.Integration.Algorithms
/// Abscissa vector per level provider.
///
/// Level Enumerator.
- private static IEnumerable ProvideLevelAbcissas()
+ internal static IEnumerable ProvideLevelAbcissas()
{
for (int i = 0; i < NumberOfMaximumLevels; i++)
{
@@ -547,7 +547,7 @@ namespace MathNet.Numerics.Integration.Algorithms
/// Weight vector per level provider.
///
/// Level Enumerator.
- private static IEnumerable ProvideLevelWeights()
+ internal static IEnumerable ProvideLevelWeights()
{
for (int i = 0; i < NumberOfMaximumLevels; i++)
{
diff --git a/src/Numerics/Integration/Algorithms/NewtonCotesTrapeziumRule.cs b/src/Numerics/Integration/Algorithms/NewtonCotesTrapeziumRule.cs
index a3b5cc91..5b2d6902 100644
--- a/src/Numerics/Integration/Algorithms/NewtonCotesTrapeziumRule.cs
+++ b/src/Numerics/Integration/Algorithms/NewtonCotesTrapeziumRule.cs
@@ -52,6 +52,11 @@ namespace MathNet.Numerics.Integration.Algorithms
double intervalBegin,
double intervalEnd)
{
+ if (f == null)
+ {
+ throw new ArgumentNullException("f");
+ }
+
return (intervalEnd - intervalBegin) / 2 * (f(intervalBegin) + f(intervalEnd));
}
@@ -69,6 +74,11 @@ namespace MathNet.Numerics.Integration.Algorithms
double intervalEnd,
int numberOfPartitions)
{
+ if (f == null)
+ {
+ throw new ArgumentNullException("f");
+ }
+
if (numberOfPartitions <= 0)
{
throw new ArgumentOutOfRangeException("numberOfPartitions", Resources.ArgumentPositive);
@@ -102,6 +112,11 @@ namespace MathNet.Numerics.Integration.Algorithms
double intervalEnd,
double targetError)
{
+ if (f == null)
+ {
+ throw new ArgumentNullException("f");
+ }
+
int numberOfPartitions = 1;
double step = intervalEnd - intervalBegin;
double sum = 0.5 * step * (f(intervalBegin) + f(intervalEnd));
@@ -147,6 +162,21 @@ namespace MathNet.Numerics.Integration.Algorithms
double levelOneStep,
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 linearOffset = 0.5 * (intervalEnd + intervalBegin);
targetRelativeError /= 5 * linearSlope;
diff --git a/src/Numerics/Integration/Algorithms/SimpsonRule.cs b/src/Numerics/Integration/Algorithms/SimpsonRule.cs
index 1d2def00..bc563d14 100644
--- a/src/Numerics/Integration/Algorithms/SimpsonRule.cs
+++ b/src/Numerics/Integration/Algorithms/SimpsonRule.cs
@@ -49,6 +49,11 @@ namespace MathNet.Numerics.Integration.Algorithms
double intervalBegin,
double intervalEnd)
{
+ if (f == null)
+ {
+ throw new ArgumentNullException("f");
+ }
+
double midpoint = (intervalEnd + intervalBegin) / 2;
return (intervalEnd - intervalBegin) / 6 * (f(intervalBegin) + f(intervalEnd) + (4 * f(midpoint)));
}
@@ -67,6 +72,11 @@ namespace MathNet.Numerics.Integration.Algorithms
double intervalEnd,
int numberOfPartitions)
{
+ if (f == null)
+ {
+ throw new ArgumentNullException("f");
+ }
+
if (numberOfPartitions <= 0)
{
throw new ArgumentOutOfRangeException("numberOfPartitions", Resources.ArgumentPositive);
@@ -85,7 +95,7 @@ namespace MathNet.Numerics.Integration.Algorithms
double sum = f(intervalBegin) + f(intervalEnd);
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);
m = 6 - m;
offset += step;
@@ -94,4 +104,4 @@ namespace MathNet.Numerics.Integration.Algorithms
return factor * sum;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/UnitTests/IntegrationTests/IntegrationTest.cs b/src/UnitTests/IntegrationTests/IntegrationTest.cs
index e2dee5d8..0038941a 100644
--- a/src/UnitTests/IntegrationTests/IntegrationTest.cs
+++ b/src/UnitTests/IntegrationTests/IntegrationTest.cs
@@ -26,13 +26,14 @@
// OTHER DEALINGS IN THE SOFTWARE.
//
-
namespace MathNet.Numerics.UnitTests.IntegrationTests
{
using System;
+ using System.Linq.Expressions;
using Integration;
using Integration.Algorithms;
using MbUnit.Framework;
+ using MbUnit.Framework.ContractVerifiers;
[TestFixture]
public class IntegrationTest
@@ -65,6 +66,18 @@ namespace MathNet.Numerics.UnitTests.IntegrationTests
"Basic Target 1e-10");
}
+ [VerifyContract]
+ public readonly IContract FacadeIntegrateChecksArguments =
+ new ArgumentCheckContract
+ {
+ TypicalUses =
+ new Expression>[]
+ {
+ () => Integrate.OnClosedInterval(x => 2 * x, StartA, StopA),
+ () => Integrate.OnClosedInterval(x => 2 * x, StartA, StopA, 1e-5)
+ }
+ };
+
[Test]
[Row(1e-5)]
[Row(1e-13)]
@@ -79,6 +92,13 @@ namespace MathNet.Numerics.UnitTests.IntegrationTests
"DET Adaptive {0}", targetRelativeError);
}
+ [VerifyContract]
+ public readonly IContract DoubleExponentialTransformationIntegrateChecksArguments =
+ new ArgumentCheckContract
+ {
+ TypicalUse = () => (new DoubleExponentialTransformation()).Integrate(x => 2 * x, StartA, StopA, 1e-5)
+ };
+
[Test]
public void TrapeziumRuleSupportsTwoPointIntegration()
{
@@ -117,6 +137,28 @@ namespace MathNet.Numerics.UnitTests.IntegrationTests
"Adaptive {0}", targetRelativeError);
}
+ [VerifyContract]
+ public readonly IContract TrapeziumRuleIntegrateChecksArguments =
+ new ArgumentCheckContract
+ {
+ TypicalUses =
+ new Expression>[]
+ {
+ () => 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]
public void SimpsonRuleSupportsThreePointIntegration()
{
@@ -141,5 +183,23 @@ namespace MathNet.Numerics.UnitTests.IntegrationTests
maxRelativeError * TargetAreaA,
"Composite {0} Partitions", partitions);
}
+
+ [VerifyContract]
+ public readonly IContract SimpsonRuleIntegrateChecksArguments =
+ new ArgumentCheckContract
+ {
+ TypicalUses =
+ new Expression>[]
+ {
+ () => SimpsonRule.IntegrateThreePoint(x => 2 * x, StartA, StopA),
+ () => SimpsonRule.IntegrateComposite(x => 2 * x, StartA, StopA, 2)
+ },
+ BadUses =
+ new Func[]
+ {
+ () => SimpsonRule.IntegrateComposite(x => 2 * x, StartA, StopA, 0),
+ () => SimpsonRule.IntegrateComposite(x => 2 * x, StartA, StopA, 3)
+ }
+ };
}
}