1

If I want to find a root $(x^*,y^*)$ of functions $f(x,y),g(x,y)$ in the rectangular region ${\cal R}=[x_i,x_f]\times [y_i,y_f]$ I can write

FindRoot[{f[x,y],g(x,y)},{x,x0,xi,xf},{y,y0,yi,yf}]

which starts searching for the solution near $(x_0,y_0)$. Is there any simple way to do the same thing in a non-rectangular region? I am thinking in particular about a triangular region $y>x,x\in[0,x_f]$.

I am relatively confident there is only one root in the region I care about, and that there are many roots outside of it, furthermore the function evaluation of $f$ is much more costly outside of it - I therefore don't want to just try lots of initial guesses $(x_0,y_0)$ and throw away the ones outside of ${\cal R}$.

jacob1729
  • 197
  • 3

3 Answers3

1

Edit

FindInstance work fine when the region doesn't contain it's boundary.

f[x_, y_] = x - y^2 Cos[y];
g[x_, y_] = -y + x*Sin[x];
reg = ImplicitRegion[{-10 < x < 10, x < y < 10}, {x, y}];
pts1 = {x, y} /. 
   FindInstance[{f[x, y] == 0, 
     g[x, y] == 0, {x, y} ∈ reg}, {x, y}, Reals, 20];
ContourPlot[{f[x, y], g[x, y]}, {x, y} ∈ reg, 
 PlotPoints -> 100, MaxRecursion -> 0, 
 Epilog -> {PointSize -> Large, Red, Point /@ pts1}]

enter image description here

f[x_, y_] = x - y^2 Cos[y];
g[x_, y_] = -y + x*Sin[x];
reg = ImplicitRegion[{-10 < x < 10, x < y < 10}, {x, y}];
plot = ContourPlot[{f[x, y] == 0, g[x, y] == 0}, {x, y} ∈ 
    reg, PlotPoints -> 100, MaxRecursion -> 0, PlotRange -> All, 
   AspectRatio -> Automatic];
intersections = 
  Graphics`Mesh`FindIntersections[plot, 
   Graphics`Mesh`AllPoints -> False];
roots = {x, y} /. 
     FindRoot[{f[x, y] == 0, g[x, y] == 0}, {{x, #1}, {y, #2}}] & @@@ 
   intersections;
Show[plot, Graphics[{PointSize[Large], Red, Point /@ roots}]]

enter image description here

Original

Since FindInstance or NMinimize can not work for the case as below, we have to try to use ContourPlot to draw such plot and locate the initial point.

f[x_, y_] = -Cos[y] + 2 y Cos[y^2] Cos[2 x];
g[x_, y_] = -Sin[x] + 2 Sin[y^2] Sin[2 x]; plot = 
 ContourPlot[{f[x, y] == 0, g[x, y] == 0}, {x, y} ∈ 
   ImplicitRegion[{y > x, 0 < x < 2}, {x, y}], PlotPoints -> 50, 
  MaxRecursion -> 2, PlotRange -> All, AspectRatio -> Automatic];
pts = Graphics`Mesh`FindIntersections[plot, 
  Graphics`Mesh`AllPoints -> False]
FindRoot[{f[x, y] == 0, g[x, y] == 0}, {{x, #1}, {y, #2}}] & @@@ pts

(* FindInstance[{f[x,y]==0,g[x,y]==0,y>x,0<x<2},{x,y},Method-> Automatic]//N ) ( NMinimize[{f[x,y]^2+g[x,y]^2,y>x,0<x<2},{x,y}] *)

{x -> 0.24248, y -> 0.510362}

enter image description here

cvgmt
  • 72,231
  • 4
  • 75
  • 133
  • With tighter bounds from the ContourPlot you can use NSolve[{f[x, y] == 0, g[x, y] == 0, 0 < x < 1/2, 0 < y < 1}, {x, y}] – Bob Hanlon Dec 12 '21 at 01:39
1

If you want to use FindRoot in any case, you can implement restrictions y > x or y < x with an additional variable a. Choose random starting values for x,y,a until all solutions are found. ( Excluded th solution at x==0)

f[x_, y_] = -Cos[y] + 2 y Cos[y^2] Cos[2 x];
g[x_, y_] = -Sin[x] + 2 Sin[y^2] Sin[2 x]; plot = 
ContourPlot[{f[x, y] == 0, g[x, y] == 0, x == y}, {x, 10^-3, 2}, {y, 
            10^-3, 2}, PlotPoints -> 50, GridLines -> Automatic]

enter image description here

fr1 := (ff = 
FindRoot[{f[x, y] == 0, g[x, y] == 0, 
 y == x - a}, {{x, RandomReal[{10^-3, 2}], 10^-3, 2}, {y, 
  RandomReal[{10^-3, 2}], 10^-3, 2}, {a, RandomReal[{10^-3, 2}], 
  10^-3, 2}}, Method -> "Secant", WorkingPrecision -> 15]; ff)

fr2 := (ff = FindRoot[{f[x, y] == 0, g[x, y] == 0, y == x + a}, {{x, RandomReal[{10^-3, 2}], 10^-3, 2}, {y, RandomReal[{10^-3, 2}], 10^-3, 2}, {a, RandomReal[{10^-3, 2}], 10^-3, 2}}, Method -> "Secant", WorkingPrecision -> 15]; ff)

w1 := (While[Check[fr1, True], fr1] // Quiet; ff)

w2 := (While[Check[fr2, True], fr2] // Quiet; ff)

({x, y, a} /. Table[w1, {30}]) // Union[#, SameTest -> (Rationalize[#1, 10^-5] == Rationalize[#2, 10^-5] &)] &

(* {{1.3163, 1.29964, 0.0166549}} *)

({x, y, a} /. Table[w2, {30}]) // Union[#, SameTest -> (Rationalize[#1, 10^-5] == Rationalize[#2, 10^-5] &)] &

(* {{0.24248, 0.510362, 0.267882}, {0.769709, 1.66914, 0.899426}} *)

Akku14
  • 17,287
  • 14
  • 32
1

Using the system defined by cvgmt but also including the boundaries

Clear["Global`*"]

f[x_, y_] = -Cos[y] + 2 y Cos[y^2] Cos[2 x]; g[x_, y_] = -Sin[x] + 2 Sin[y^2] Sin[2 x];

eqns = {f[x, y] == 0, g[x, y] == 0, 0 <= x <= 2, x <= y <= 2};

The solutions are

sol1 = NSolve[eqns, {x, y}, WorkingPrecision -> 10]

(* {{x -> 0, y -> 0.4584575234}, {x -> 0, y -> 1.188862545}, {x -> 0.2424802952, y -> 0.5103619318}, {x -> 0.7697090252, y -> 1.669135177}} *)

Verifying the solutions

(And @@ eqns) /. sol1

(* {True, True, True, True} *)

Graphically,

rgn = ImplicitRegion[{y >= x, 0 <= x <= 2}, {x, y}];

ContourPlot[{f[x, y], g[x, y]}, {x, -0.025, 2}, {y, 0, 2}, Contours -> {{0}}, RegionFunction -> Function[{x, y}, {x, y} ∈ rgn], PlotPoints -> 200, MaxRecursion -> 5, Epilog -> {Red, AbsolutePointSize[4], Point[{x, y} /. sol1]}, PlotLegends -> Placed[ Thread[{f[x, y], g[x, y]} == 0], {2/3, 1/5}]]

enter image description here

sol2 = FindRoot[{f[x, y] == 0, g[x, y] == 0},
    {{x, #[[1]]}, {y, #[[2]]}}, WorkingPrecision -> 10] & /@
  {{0, 1/2}, {0, 6/5}, {1/4, 1/2}, {3/4, 5/3}}

(* {{x -> 0, y -> 0.4584575234}, {x -> 0, y -> 1.188862545}, {x -> 0.2424802952, y -> 0.5103619318}, {x -> 0.7697090252, y -> 1.669135177}} *)

Verifying,

(And @@ eqns) /. sol2

(* {True, True, True, True} *)

Bob Hanlon
  • 157,611
  • 7
  • 77
  • 198