I wanted to use Mathematica to compute areas and volumes of various implicitly defined regions, so I ran a simple test case using the unit circle:
Integrate[Boole[x^2 + y^2 <= 1], {x, -1, 1}, {y, -1, 1}] // RepeatedTiming
(* {0.10, π} *)
RegionMeasure[ImplicitRegion[x^2 + y^2 <= 1, {{x, -1, 1}, {y, -1, 1}}]] // RepeatedTiming
(* {0.00735, π} *)
To my surprise, RegionMeasure[ImplicitRegion[...]]
is more than 10 times faster than Integrate[Boole[..]]
on this problem. NIntegrate
is only slightly slower than RegionMeasure
, but does not return a symbolic result.
On the other hand, on the areas I want to compute,
lerp[t_, a_, b_] := (1 - t) a + t b
f[f00_, f01_, f10_, f11_][x_, y_] :=
Evaluate@Expand@lerp[x, lerp[y, f00, f01], lerp[y, f10, f11]]
areaNIntegrate[f00_, f01_, f10_, f11_] :=
NIntegrate[
Boole[f[f00, f01, f10, f11][x, y] >= 0], {x, 0, 1}, {y, 0, 1}]
areaRegionMeasure[f00_, f01_, f10_, f11_] :=
RegionMeasure@
ImplicitRegion[
f[f00, f01, f10, f11][x, y] >= 0, {{x, 0, 1}, {y, 0, 1}}]
NIntegrate
is usually faster, sometimes by a lot:
timings =
Table[{areaNIntegrate @@ # // Timing // First,
areaRegionMeasure @@ # // Timing // First} &@
RandomReal[{-1, 1}, 4], 1000];
Show[ListPlot[timings, AspectRatio -> Automatic],
Plot[x, {x, 0, 0.020}, PlotStyle -> {Black, Thin, Dashed}],
PlotRange -> All, AxesOrigin -> {0, 0}]
(x-axis: NIntegrate
time, y-axis: RegionMeasure
time on same data)
Is this expected? Why is there such a difference? Practically, is there some rule of thumb to know which of (N
)Integrate[Boole[...]]
and RegionMeasure[ImplicitRegion[...]]
is better, or must we always test the performance of both?