Skip to content

Commit be09c63

Browse files
committed
WIP #1034 implemement NIntegrates `Method->DoubleExponential
example for the "tanh-sinh" strategy
1 parent eb6acdd commit be09c63

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/eval/Errors.java

+1
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ public static void initGeneralMessages() {
226226
"For compiling functions, Symja needs to be executed on a Java Development Kit with javax.tools.JavaCompiler installed.", //
227227
"nconvss",
228228
"The argument `1` cannot be converted to a NumericArray of type `2` using method `3`", //
229+
"ncvi", "NIntegrate failed to converge after `1` refinements in `2` in the region `3`.", //
229230
"nliter", "Non-list iterator `1` at position `2` does not evaluate to a real numeric value.", //
230231
"nil", "unexpected NIL expression encountered.", //
231232
"ninv", "`1` is not invertible modulo `2`.", //

symja_android_library/matheclipse-core/src/main/java/org/matheclipse/core/reflection/system/NIntegrate.java

+14
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
import org.matheclipse.core.interfaces.IExpr;
3030
import org.matheclipse.core.interfaces.IReal;
3131
import org.matheclipse.core.interfaces.ISymbol;
32+
import org.matheclipse.core.numerics.integral.Quadrature;
33+
import org.matheclipse.core.numerics.integral.Quadrature.QuadratureResult;
34+
import org.matheclipse.core.numerics.integral.TanhSinh;
3235
import de.labathome.AdaptiveQuadrature;
3336

3437
/**
@@ -124,6 +127,17 @@ public static double integrate(String method, IAST list, final double min, final
124127
integrator = new TrapezoidIntegrator();
125128
} else if ("GaussKronrod".equalsIgnoreCase(method)) {
126129
return gausKronrodRule(maxIterations, f, min, max);
130+
} else if ("DoubleExponential".equalsIgnoreCase(method)) {
131+
Quadrature quadrature = new TanhSinh(1e-8, 1000);
132+
QuadratureResult result = quadrature.integrate(f, min, max);
133+
if (result.converged) {
134+
return result.estimate;
135+
}
136+
// NIntegrate failed to converge after `1` refinements in `2` in the region `3`.
137+
throw new ArgumentTypeException("ncvi", F.List(F.ZZ(result.evaluations), xVar, list.rest()));
138+
// Errors. printMessage(S.NIntegrate, "ncvi", F.List(F.ZZ(result.evaluations), xVar,
139+
// list.rest()),
140+
// engine);
127141
} else {
128142
if (maxPoints > 1000) {
129143
// github 150 - avoid StackOverflow from recursion

symja_android_library/matheclipse-core/src/test/java/org/matheclipse/core/system/IntegrateTest.java

+71
Original file line numberDiff line numberDiff line change
@@ -294,4 +294,75 @@ public void testIntegrate() {
294294
}
295295

296296

297+
@Test
298+
public void testNIntegrate() {
299+
// "tanh-sinh" strategy
300+
checkNumeric("NIntegrate(Exp(x)/x, {x, -Infinity, -1}, Method ->DoubleExponential)", //
301+
"-0.2193839343955203");
302+
// message NIntegrate failed to converge after 1000 refinements in x in the region
303+
// {-Infinity,-1}.
304+
checkNumeric("NIntegrate(x, {x, -Infinity, -1}, Method ->DoubleExponential)", //
305+
"NIntegrate(x,{x,-Infinity,-1},Method->doubleexponential)");
306+
307+
// https://github.com/Hipparchus-Math/hipparchus/issues/279
308+
checkNumeric("NIntegrate(Exp(-x),{x,0,Infinity})", //
309+
"1.0");
310+
checkNumeric("NIntegrate(Exp(-x^2),{x,0,Infinity})", //
311+
"0.8862269254527579");
312+
checkNumeric("NIntegrate(Exp(-x^2),{x,-Infinity,Infinity})", //
313+
"1.772453850905516");
314+
315+
// TOTO integrable singularity at x==0
316+
checkNumeric("NIntegrate(1/Sqrt(x),{x,0,1}, Method->GaussKronrod)", //
317+
"NIntegrate(1/Sqrt(x),{x,0,1},Method->gausskronrod)");
318+
checkNumeric("NIntegrate(1/Sqrt(x),{x,0,1}, Method->LegendreGauss )", //
319+
"1.9913364016175945");
320+
checkNumeric("NIntegrate(Cos(200*x),{x,0,1}, Method->GaussKronrod)", //
321+
"-0.0043664864860701");
322+
checkNumeric("NIntegrate(Cos(200*x),{x,0,1}, Method->LegendreGauss )", //
323+
"-0.0043664864860699");
324+
325+
// github #150
326+
// NIntegrate: (method=LegendreGauss) 1,001 is larger than the maximum (1,000)
327+
checkNumeric("NIntegrate(1/x, {x, 0, 1}, MaxPoints->1001)", //
328+
"NIntegrate(1/x,{x,0,1},MaxPoints->1001)");
329+
// wrong result
330+
checkNumeric("NIntegrate(1/x, {x,0,5}, Method->LegendreGauss)", //
331+
"10.374755035279286");
332+
333+
// github #61
334+
// these methods correctly show "NIntegrate(method=method-nsme) maximal count (xxxxx) exceeded"
335+
checkNumeric("NIntegrate(1/x, {x,0,5}, Method->Romberg)", //
336+
"NIntegrate(1/x,{x,0,5},Method->romberg)");
337+
checkNumeric("NIntegrate(1/x, {x,0,5}, Method->Simpson)", //
338+
"NIntegrate(1/x,{x,0,5},Method->simpson)");
339+
checkNumeric("NIntegrate(1/x, {x,0,5}, Method->Trapezoid)", //
340+
"NIntegrate(1/x,{x,0,5},Method->trapezoid)");
341+
342+
// github #26
343+
checkNumeric(
344+
"NIntegrate(ln(x^2), {x, -5, 99}, Method->Romberg, MaxPoints->400, MaxIterations->10000000)", //
345+
"717.9282476448197");
346+
347+
checkNumeric("NIntegrate((x-1)*(x-0.5)*x*(x+0.5)*(x+1), {x,0,1})", //
348+
"-0.0208333333333333");
349+
// LegendreGauss is default method
350+
checkNumeric("NIntegrate((x-1)*(x-0.5)*x*(x+0.5)*(x+1), {x,0,1}, Method->LegendreGauss)", //
351+
"-0.0208333333333333");
352+
checkNumeric("NIntegrate((x-1)*(x-0.5)*x*(x+0.5)*(x+1), {x,0,1}, Method->Simpson)", //
353+
"-0.0208333320915699");
354+
checkNumeric("NIntegrate((x-1)*(x-0.5)*x*(x+0.5)*(x+1), {x,0,1}, Method->Trapezoid)", //
355+
"-0.0208333271245165");
356+
checkNumeric(
357+
"NIntegrate((x-1)*(x-0.5)*x*(x+0.5)*(x+1), {x,0,1}, Method->Trapezoid, MaxIterations->5000)", //
358+
"-0.0208333271245165");
359+
checkNumeric("NIntegrate((x-1)*(x-0.5)*x*(x+0.5)*(x+1), {x,0,1}, Method->Romberg)", //
360+
"-0.0208333333333333");
361+
checkNumeric("NIntegrate (x, {x, 0,2}, Method->Simpson)", //
362+
"2.0");
363+
checkNumeric("NIntegrate(Cos(x), {x, 0, Pi})", //
364+
"1.0E-16");
365+
checkNumeric("NIntegrate(1/Sin(Sqrt(x)), {x, 0, 1}, PrecisionGoal->10)", //
366+
"2.1108620052");
367+
}
297368
}

0 commit comments

Comments
 (0)