|
|
@ -37,14 +37,11 @@ namespace MathNet.Numerics.Integration.Algorithms |
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
public class DoubleExponentialTransformation |
|
|
public class DoubleExponentialTransformation |
|
|
{ |
|
|
{ |
|
|
private const int NumberOfMaximumLevels = 10; |
|
|
|
|
|
|
|
|
|
|
|
private readonly NewtonCotesTrapeziumRule _trapezium = new NewtonCotesTrapeziumRule(); |
|
|
|
|
|
private IEnumerable<double[]> _levelAbcissas; |
|
|
|
|
|
private IEnumerable<double[]> _levelWeights; |
|
|
|
|
|
|
|
|
|
|
|
#region Precomputed Abcissas and Weights
|
|
|
#region Precomputed Abcissas and Weights
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Precomputed abscissa vector per level.
|
|
|
|
|
|
/// </summary>
|
|
|
private static readonly double[][] PrecomputedAbscissas = |
|
|
private static readonly double[][] PrecomputedAbscissas = |
|
|
new[] |
|
|
new[] |
|
|
{ |
|
|
{ |
|
|
@ -264,6 +261,9 @@ namespace MathNet.Numerics.Integration.Algorithms |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Precomputed weight vector per level.
|
|
|
|
|
|
/// </summary>
|
|
|
private static readonly double[][] PrecomputedWeights = |
|
|
private static readonly double[][] PrecomputedWeights = |
|
|
new[] |
|
|
new[] |
|
|
{ |
|
|
{ |
|
|
@ -485,9 +485,35 @@ namespace MathNet.Numerics.Integration.Algorithms |
|
|
|
|
|
|
|
|
#endregion
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Maximum number of iterations, until the asked
|
|
|
|
|
|
/// maximum error is (likely to be) satisfied.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private const int NumberOfMaximumLevels = 10; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Internal Trapezium Rule.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private readonly NewtonCotesTrapeziumRule _trapezium = new NewtonCotesTrapeziumRule(); |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Abscissa vector per level provider.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private IEnumerable<double[]> _levelAbcissas; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Weight vector per level provider.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private IEnumerable<double[]> _levelWeights; |
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// Approximate the integral by the double exponential transformation
|
|
|
/// Approximate the integral by the double exponential transformation
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="f">The analytic smooth function to integrate.</param>
|
|
|
|
|
|
/// <param name="intervalBegin">Where the interval starts, inclusive and finite.</param>
|
|
|
|
|
|
/// <param name="intervalEnd">Where the interval stops, inclusive and finite.</param>
|
|
|
|
|
|
/// <param name="targetRelativeError">The expected relative accuracy of the approximation.</param>
|
|
|
|
|
|
/// <returns>Approximation of the finite integral in the given interval.</returns>
|
|
|
public double Integrate( |
|
|
public double Integrate( |
|
|
Func<double, double> f, |
|
|
Func<double, double> f, |
|
|
double intervalBegin, |
|
|
double intervalBegin, |
|
|
@ -510,6 +536,10 @@ namespace MathNet.Numerics.Integration.Algorithms |
|
|
targetRelativeError); |
|
|
targetRelativeError); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Abscissa vector per level provider.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>Level Enumerator.</returns>
|
|
|
private static IEnumerable<double[]> ProvideLevelAbcissas() |
|
|
private static IEnumerable<double[]> ProvideLevelAbcissas() |
|
|
{ |
|
|
{ |
|
|
for (int i = 0; i < NumberOfMaximumLevels; i++) |
|
|
for (int i = 0; i < NumberOfMaximumLevels; i++) |
|
|
@ -518,6 +548,10 @@ namespace MathNet.Numerics.Integration.Algorithms |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Weight vector per level provider.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>Level Enumerator.</returns>
|
|
|
private static IEnumerable<double[]> ProvideLevelWeights() |
|
|
private static IEnumerable<double[]> ProvideLevelWeights() |
|
|
{ |
|
|
{ |
|
|
for (int i = 0; i < NumberOfMaximumLevels; i++) |
|
|
for (int i = 0; i < NumberOfMaximumLevels; i++) |
|
|
@ -526,6 +560,11 @@ namespace MathNet.Numerics.Integration.Algorithms |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Compute the abscissa vector for a single level.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="level">The level to evaluate the abscissa vector for.</param>
|
|
|
|
|
|
/// <returns>Abscissa Vector.</returns>
|
|
|
private static double[] EvaluateAbcissas(int level) |
|
|
private static double[] EvaluateAbcissas(int level) |
|
|
{ |
|
|
{ |
|
|
if (level < PrecomputedAbscissas.Length) |
|
|
if (level < PrecomputedAbscissas.Length) |
|
|
@ -550,6 +589,11 @@ namespace MathNet.Numerics.Integration.Algorithms |
|
|
return abcissas; |
|
|
return abcissas; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Compute the weight vector for a single level.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="level">The level to evaluate the weight vector for.</param>
|
|
|
|
|
|
/// <returns>Weight Vector.</returns>
|
|
|
private static double[] EvaluateWeights(int level) |
|
|
private static double[] EvaluateWeights(int level) |
|
|
{ |
|
|
{ |
|
|
if (level < PrecomputedWeights.Length) |
|
|
if (level < PrecomputedWeights.Length) |
|
|
|