I wanted to find the roots of the function $f(x,y)=\sin(3.2x)\sin(1.3y)-2.1 \sin(1.3x)\sin(3.2y)$. This is what the function looks like:
f[x_, y_] = Sin[3.2 x]*Sin[1.3*y] - 2.1*Sin[1.3*x]*Sin[3.2*y]
Plot3D[f[x, y], {x, 0, 20}, {y, 0, 20}, PlotPoints -> 50, MeshFunctions -> {#3 &}, Mesh -> 1, MeshStyle -> {Red, Thick}, AxesLabel -> {"x", "y", "f(x,y)"}]
Then, as I was looking for the roots (the $\color{red}{\text{red}}$ curves, actually), I started to do use some root-finding procedures, using FindRoot
and perturbating manually the initial conditions. This worked OK, but I faced some problems (unequal roots density along a curve, missing some parts, etc.). Also, the computations were taking about 10-20 seconds with my procedure (surely not optimal).
Just to give an idea of what I'm talking about, this is an example of the result I had (with different parameters, but I does not matter) (the $\color{green}{\text{green}}$ points are the results of my computations and took 10 seconds to calculate):
Then I switched my brain on and realized that Mathematica had already calculated many roots to plot the red curve above. So I tried:
plot = ContourPlot[f[x, y] == 0, {x, 0, 10}, {y, 0, 10}, PlotPoints -> 50, ContourStyle -> Red]
which yields:
plot[[1,1]]
contains more than 7000 points calculated in less than a second. The worst root Map[f, plot[[1, 1]]] // Max // Abs
gives 0.01
corresponding to a "poor" accuracy, but using PlotPoints -> 50, MaxRecursion -> 7
lowered this upper bound to 0.0002 on 85000 points in 9 seconds, which remains very acceptable.
Question Is Mathematica really more efficient with ContourPlot
than with other root-finding numerical functions (hard to believe)? Would it be possible to have the same efficiency using FindRoot
or NSolve
, etc.?
Table[{x, y} /. NSolve[f[x, y] == 0 && 0 <= y <= 10, y, Reals], {x, 0, 10, 0.1}]
. The difference in speed is becauseNSolve
tries to get all roots with machine-precision accuracy, about $10^{-16}$, whereasContourPlot
is content with much lower accuracy and possibly missing some roots. $\endgroup$Experimental`NumericalFunction
for optimizations. ContourPlot3D may need millions of evaluations and still works reasonably fast when used with formulae (not numerical blackboxes). $\endgroup$