TransWikia.com

Are there any alternatives for NIntegrate to calculate the area for which $f(x,y)<0$?

Mathematica Asked by user80186 on August 12, 2021

I have this two-variable function
$$f(x,y)= (8 cos (x+y)+7)cos left(frac{x}{2}right)+cos frac{x-2 y}{2}+2 cos left(frac{3 x}{2}right) $$
where $0<x,y<pi$. I want to calculate numerically the area for which the function is negative $f(x,y)<0$. I use this code

NIntegrate[
 Boole[2 Cos[(3 x)/2] + Cos[1/2 (x - 2 y)] + 
    Cos[x/2] (7 + 8 Cos[x + y]) < 0], {x, 0, Pi}, {y, 0, Pi}] 

and it gives the answer $3.49458$, but Mathematica gives the following warnings. Are there any other ways to calculate this value that is more reliable and more accurate than this method?

NIntegrate::slwcon: Numerical integration converging too slowly; suspect one of the following: singularity, value of the integration is 0, highly oscillatory integrand, or WorkingPrecision too small.

NIntegrate::eincr: The global error of the strategy GlobalAdaptive has increased more than 2000 times. The global error is expected to decrease monotonically after a number of integrand evaluations. Suspect one of the following: the working precision is insufficient for the specified precision goal; the integrand is highly oscillatory or it is not a (piecewise) smooth function; or the true value of the integral is 0. Increasing the value of the GlobalAdaptive option MaxErrorIncreases might lead to a convergent numerical integration. NIntegrate obtained 3.494581434480605 and 0.002397336775896384 for the integral and error estimates.

4 Answers

Clear["Global`*"]

RegionPlot[
 2 Cos[(3 x)/2] + Cos[1/2 (x - 2 y)] + Cos[x/2] (7 + 8 Cos[x + y]) < 0,
 {x, 0, Pi}, {y, 0, Pi},
 Frame -> True]

enter image description here

rgn = ImplicitRegion[{2 Cos[(3 x)/2] + Cos[1/2 (x - 2 y)] + 
       Cos[x/2] (7 + 8 Cos[x + y]) < 0 && 0 < x < Pi && 
     0 < y < Pi}, {x, y}];

Area[rgn, WorkingPrecision -> MachinePrecision]

(* 3.49805 *)

Area[rgn, WorkingPrecision -> 15]

(* 3.49805 *)

Answered by Bob Hanlon on August 12, 2021

Let us name the function of interest f[x,y]:

f[x_, y_] := (8 Cos[x + y] + 7) Cos[x/2] + Cos[(x - 2 y)/2] + 2 Cos[3 x/2]

Attempt to ContourPlot to find the zero lines:

ContourPlot[f[x, y] == 0, {x, 0, Pi}, {y, 0, Pi}]

Contour plot of zero lines for f[x,y]

Simple numerical evaluation determines that the negative region is the inside of these two curves. Notice that the ContourPlot is quite rapid and has very clean lines. Interesting coincidence. Perhaps there exists an analytical solution to these curve lines?

sol = Solve[{f[x, y] == 0}]

This returns a list of 4 possible curves, while also stating that some solutions may be missing. By manual inspection (such as by using Plot), we can find that the 2nd and 4th solutions are of interest to us, so we shall label them:

upperCurve = y /. sol[[2]];
lowerCurve = y /. sol[[4]];
Plot[{upperCurve, lowerCurve}, {x, 0, Pi}, PlotRange -> {0, Pi}]

Plots of the 2nd (blue) and 4th (yellow) curves

Checking the curves manually by plotting them against the original ContourPlot, we see that upperCurve matches the upper line for the whole domain, and that lowerCurve matches the lower line up until it reaches its minimum.

Find the minimum of the lowerCurve:

FindMinimum[{lowerCurve, 0 < x < Pi}, x, WorkingPrecision -> 25]

{1.872299341324760554288429*10^-8, {x -> 2.094395111754692173633430}}

The warning about a small imaginary part is of little concern here, but you can increase the WorkingPrecision and PrecisionGoal if you would like more digits.

Michael Seifert also pointed out that an exact form can be found for this solution by applying TrigFactor to f[x,y]:

TrigFactor[f[x,y]]

2 (Cos[x/2 - y/2] + 2 Cos[x/2 + y/2]) (2 Cos[x + y/2] + Cos[y/2]) == 0

The lower line happens to correspond to the second variable factor in this expression, and its minimum is found when y is set to 0 and solved.

Solve[{(2 Cos[x + y/2] + Cos[y/2]) == 0 /. y -> 0, 0 < x < Pi}, x]

{{ x -> 2 Pi/ 3 }}

Integrate the area below the 2nd curve over the whole domain minus the area under the 4th curve for 0 through 2.094...

NIntegrate[upperCurve, {x, 0, Pi}, WorkingPrecision -> 25] - 
 NIntegrate[lowerCurve, {x, 0, 2.09439511175469217363342977478168904781`25.},
   WorkingPrecision -> 25]

3.49805583366099845069196

Or with the exact form, we can see a slightly different answer:

NIntegrate[upperCurve, {x, 0, Pi}, WorkingPrecision -> 25] - 
 NIntegrate[lowerCurve, {x, 0, 2 Pi/3}, WorkingPrecision -> 25]

3.49805583366099836305434

While this method is not universally applicable, it does work for this function and is much faster than Area or direct application of NIntegrate and Boole for high precisions. As yarchik notes, you can swap NIntegrate for Integrate here to acquire an exact solution, though it takes a bit longer to evaluate.

Answered by eyorble on August 12, 2021

Method ->"LocalAdaptive" evaluates without errormessage

NIntegrate[Boole[2 Cos[(3 x)/2] + Cos[1/2 (x - 2 y)] +Cos[x/2] (7 + 8 Cos[x + y]) < 0], {x, 0, Pi}, {y,0, Pi}, Method -> "LocalAdaptive"]
(*3.49818*)

Answered by Ulrich Neumann on August 12, 2021

A similar way is

reg=ImplicitRegion[
   2 Cos[(3 x)/2] + Cos[1/2 (x - 2 y)] + Cos[x/2] (7 + 8 Cos[x + y]) <
     0, {{x, 0, Pi}, {y, 0, Pi}}];
NIntegrate[1, {x, y} ∈ reg]

3.49485

Answered by cvgmt on August 12, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP