10
$\begingroup$

The command

Limit[(Sin[x^2] + Sin[y^2])/ (x - y) /. x -> 0, y -> 0]
(*
   0
*)

I think that Mathematica finds the iterated limit instead of the double limit. It should be noted that WolframAlpha produces the correct answer, when asking for

"limit (sin(x^2)+sin(y^2))/(x-y) as x->0 and y->0"

enter image description here

$\endgroup$
3
  • 2
    $\begingroup$ By the way, Mathematica's natural language interpretation translates "limit (sin(x^2)+sin(y^2))/(x-y) as x->0 and y->0", to Limit[(Sin[x^2] + Sin[y^2])/(x - y), {x -> 0, y -> 0}], which of course is something different because Limit is Listable. Just saying $\endgroup$
    – Rojo
    Commented May 17, 2013 at 15:25
  • 1
    $\begingroup$ @Rojo: the output of Limit[(Sin[x^2] + Sin[y^2])/(x - y), {x -> 0, y -> 0}] is {-(Sin[y^2]/y), Sin[x^2]/x} $\endgroup$
    – user64494
    Commented May 17, 2013 at 15:43
  • 1
    $\begingroup$ I think WolframAlpha must use heuristics sometimes to guess the answer. This one it gets wrong: "limit (x y^2/(x^2-y^4)) as x->0 and y->0" -- says it's zero, but it doesn't exist. $\endgroup$
    – Michael E2
    Commented May 18, 2013 at 20:19

5 Answers 5

9
$\begingroup$

Let

f = (Sin[x^2] + Sin[y^2])/(x - y)

be the function in question.

As pointed out in the answers to this question, finding multivariable limits automatically computationally is full of pitfalls. The idea behind the function lim in this answer was to use Maximum and Minimum to find bounds on the function and apply the squeeze theorem. It fails here because Maximum and Minimum fail on f. However the concept is sound. The first two methods below apply this concept. A third method of testing for nonexistence is included at the end.

Numerical approximation

A nonrigorous way to go is to get numerical evidence.

NMaximize[{f, -0.01 < x < 0.01 && -0.01 < y < 0.01}, {x, y}]
NMaximize::cvdiv: Failed to converge to a solution. The function may be unbounded. >>

{1.53512*10^13, {x -> 0.00893814, y -> 0.00893814}}
NMinimize[f, -0.01 < x < 0.01 && -0.01 < y < 0.01}, {x, y}]
NMinimize::cvdiv: Failed to converge to a solution. The function may be unbounded. >>

{-2.44609*10^11, {x -> -0.0085679, y -> -0.0085679}}

It appears the function diverges. How close to {0, 0} to restrict {x, y} would have to be decided in each particular case.

One can automatically check smaller and smaller neighborhoods:

limitExistQ[f_, vars_, point_, epsilon_: 0.001, delta0_: 0.1] :=
 Module[{notExists},
  NestWhile[#/10 &, 
   delta0,
   (notExists = 
     First @ NMaximize[{f, And @@ MapThread[Less, {point - #, vars, point + #}]}, vars] -
     First @ NMinimize[{f, And @@ MapThread[Less, {point - #, vars, point + #}]}, vars] >= epsilon) &,
   1, 5];
  ! notExists]

Example:

limitExistQ[f, {x, y}, {0, 0}]
NMaximize::cvdiv: Failed to converge to a solution. The function may be unbounded. >>
NMinimize::cvdiv: Failed to converge to a solution. The function may be unbounded. >>
,,,

False

It is still only approximate, as can be seen from varying epsilon and delta0 in the following limit, which exists:

limitExistQ[(x^3 + y^3)/(x^2 + y^2), {x, y}, {0, 0}]
True
limitExistQ[(x^3 + y^3)/(x^2 + y^2), {x, y}, {0, 0}, 10^-6]
False
limitExistQ[(x^3 + y^3)/(x^2 + y^2), {x, y}, {0, 0}, 10^-6, 0.001]
True

A sometimes rigorous method

Sometimes, the method in the referenced answer can be adapted by substituting Taylor polynomial approximations to the numerator or denominator of the function, since rational functions are easier to deal with than transcendental or algebraic functions. For it to be rigorous, you have to know (be able to prove) that the limit of the approximation is the same as the limit of the function.

For instance, one might know how to bound the error of the Taylor approximation and deduce that the error is negligible. In the case of the function in the question, there is in the numerator Sin[x^2], whose Taylor series at x == 0 is alternating and absolutely decreasing for Abs[x] < 1. It follows that the numerator of f is bounded successive Taylor polynomials (for example, of degrees 2 and 6 in this case).

Below is code for handling such cases. The first functions replace the numerator and/or the denominator with a Taylor polynomial approximation, unless it is already a polynomial or the degree specified is Infinity. The variable deg in getApproximations is a list of two degrees: the degree to be used for approximating the function to be maximized, typically a lower bound, and the degree to be used for approximating the function to be minimized, typically an upper bound. (If one wants different degrees for the numerators and denominators, adapt as desired.)

  (* does not expand polynomials -- change if desired *)
makeApproximation[f0_, deg0_, vars_, centers_] := 
  If[deg0 === Infinity || PolynomialQ[f0, vars], f0, 
   Normal@Series[f0, 
     Sequence @@ MapThread[{#1, #2, deg0} &, {vars, centers}]]
   ];
getApproximations[f_, deg_List, vars_, centers_] := 
  Module[{num, den, minNum, maxNum, minDen, maxDen},
   {num, den} = {Numerator[#], Denominator[#]} &@Together[f];
   {minNum, maxNum} = makeApproximation[num, #, vars, centers] & /@ deg;
   {minDen, maxDen} = makeApproximation[den, #, vars, centers] & /@ deg,
   {minNum, maxNum, minDen, maxDen}
   ];

The modification to use polynomial approximations is as follows. The Print statements are included to reveal a little of what's going on and may be omitted.

serlim[f0_, deg_, vars_List -> point_List] := 
 Module[{lim0, d, max, min, minNum, maxNum, minDen, maxDen},
  {minNum, maxNum, minDen, maxDen} = getApproximations[f0, deg, vars, point];
  max = Maximize[{maxNum/maxDen, 
     0 < d < 1 && And @@ MapThread[-d <= #1 - #2 <= d &, {vars, point}]},
     vars, Reals];
  If[Head[max] === Maximize,(*Maximize failed to find a max*)
   Return[$Failed], max = Simplify[First @ max, d > 0];
   Print[Row @ {"Max ", max}];
   min = Minimize[{minNum/minDen, 
      0 < d < 1 && And @@ MapThread[-d <= #1 - #2 <= d &, {vars, point}]},
      vars, Reals];
   If[Head[min] === Minimize,(*Minimize failed to find a min*)
    Return[$Failed], min = Simplify[First @ min, d > 0]]];
  Print[Row @ {"Min ", min}];
  lim0 = Limit[max, d -> 0];
  If[lim0 == Limit[min, d -> 0], lim0, "Does not exist."]]

Here is the result of applying it to f

serlim[f, {2, 6}, {x, y} -> {0, 0}]
Max \[Piecewise]   \[Infinity]    d$1011674 < 1
                  -\[Infinity]    True

Min \[Piecewise]  -\[Infinity]    d$1011674 < 1
                   \[Infinity]    True

"Does not exist."

The approximations being used are constructed from

getApproximations[f, {2, 6}, {x, y}, {0, 0}]
{x^2 + y^2, x^2 - x^6/6 + y^2 - y^6/6, x - y ,  x - y}
(* minNum ,       maxNum             , minDen, maxDen *)         

Thus serlim is maximizing the lower bound (x^2 - x^6/6 + y^2 - y^6/6) / (x - y) and minimizing the upper bound (x^2 + y^2) / (x - y). Since they do not converge to the same finite number, the limit does not exist.

Edit: Remark on the present case. In fact, for $-1 < x,y < 1$, $x \ne y$, we can easily deduce that our function lies between $(x^2+y^2)/[3\,(x-y)]$ and $(x^2+y^2)/(x-y)$. If $(x^2+y^2)/(x-y)$ goes to infinity then both bounds go to infinity and f with them. Hence this somewhat faster calculation may be used to determine the limit does not exist:

serlim[f, {2, 2}, {x, y} -> {0, 0}]

A less robust approach

This will work sometimes. We find the curve along which the denominator is zero, and approach along various paths approaching the curve. It is reliable if it finds the limit does not exist, but otherwise it is unreliable.

rule = Reduce[1/f == 0, {x, y}] // ToRules // First
y -> x
If[Equal @@ #, First[#], "Does not exist."] &@
 With[{sub = First[rule] -> Last[rule] + delta},
  Table[
   Limit[f /. sub /. {x -> t, y -> t}, t -> 0],
   {delta, {t, t^2, t^5, t^10, E^(-1/t^2)}}]]
"Does not exist."

Solve might be used in place of Reduce. Sometimes there may be many solutions corresponding to many curves where the denominator is zero; the code above would have to be adapted to handle such cases.

$\endgroup$
1
  • 1
    $\begingroup$ This is a great answer. $\endgroup$
    – user64494
    Commented May 18, 2013 at 16:44
4
$\begingroup$

Well, Mathematica gives you the correct answer to your input. You first specify that x should be replaced by 0 and afterwards the limit of y->0 should be calculated. The correct answer to that is 0. And yes, this is exactly the same as taking the limit x->0 first and taking the limit y->0 afterwards. If the double limit exists it is the same as taking the limits in any order. Unfortunately there seems to be no method integrated into mathematica to check for the existence of the limit with respect to a certain norm.

$\endgroup$
4
  • 2
    $\begingroup$ Hey look everybody, another Wizard. :-) $\endgroup$
    – Mr.Wizard
    Commented May 17, 2013 at 13:19
  • 1
    $\begingroup$ Yeah, always loved wizards. It's my pleasure to meat another one :). $\endgroup$
    – Wizard
    Commented May 17, 2013 at 13:29
  • $\begingroup$ Whoa, slow down, I don't want to get that friendly! =:O ("meat" lol) $\endgroup$
    – Mr.Wizard
    Commented May 17, 2013 at 13:35
  • 1
    $\begingroup$ @Mr.Wizard you'll have to go back to Spartacus $\endgroup$
    – Rojo
    Commented May 17, 2013 at 15:12
3
$\begingroup$

If you enter it this way

Limit[(Sin[x]^2 + Sin[y]^2)/(x - y), {x -> y}]
(* Output: {DirectedInfinity[…]} *)

or alternatively you can try

Limit[(Sin[x]^2 + Sin[y]^2)/(x - y) /. x -> y, y -> 0]
(* Output: ComplexInfinity *)

In your input, you have used ReplaceAll, /., to first Replace all x's with zero, after which you find the limit as y -> 0. This may not be what you intend.

Note that if you wish you can use the Assumptions option as the third argument to Limit to restrict your variables to Reals, for example.

$\endgroup$
1
  • 1
    $\begingroup$ Unfortunately, these are not the same as the double limit under consideration. $\endgroup$
    – user64494
    Commented May 17, 2013 at 12:59
3
$\begingroup$

Start from v11.2, Limit is able to calculate multivariate limit, and it correctly finds the limit doesn't exist:

Limit[(Sin[x^2] + Sin[y^2])/(x - y), {x, y} -> {0, 0}]
(* Indeterminate *)
$\endgroup$
2
$\begingroup$

Maybe another way to look at it is to change variables :

subs = {x -> Sqrt[a + b], y -> Sqrt[a - b]};
expr = FullSimplify[(Sin[x^2] + Sin[y^2])/(x - y) /. subs]
(* -((2 Cos[b] Sin[a])/(Sqrt[a - b] - Sqrt[a + b])) *)

This should make the path dependence of the limit a bit more explicit :

Limit[expr, a -> b]
(* (Sqrt[2] Cos[b] Sin[b])/Sqrt[b] *)
$\endgroup$
3
  • 1
    $\begingroup$ Unfortunately, the relation a->b does not imply x->0, only y->0. This is not it at all. $\endgroup$
    – user64494
    Commented May 17, 2013 at 13:31
  • $\begingroup$ Of course, but you can take the limit b->0 if you want to. $\endgroup$ Commented May 17, 2013 at 13:36
  • $\begingroup$ Limit[Sqrt[2]* Cos[b] *Sin[b]/Sqrt[b], b -> 0] produces 0. $\endgroup$
    – user64494
    Commented May 17, 2013 at 13:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.