Function limits at domain endpoints

My calculus text says that a function cannot have an ordinary limit at an endpoint of its domain, but it can have a one-sided limit.  So, in the case of f(x) = sqrt(4 - x^2), the text says (a) that it has a left-hand limit at x = 2 and a right-hand limit at x = -2, but it does not have a left-hand limit at x = -2 or a right-hand limit at x = 2 and (b) that it does not have ordinary two-sided limits at either -2 or 2.

So there are six possibilities.  Maple gives limit = 0 for all six.  Why the discrepancy?

Alla

Comments

alec's picture

Complex vs. Real

In Calculus, you work with real numbers. In Maple, numbers are complex, and the domain in this example is all complex plane (or, more precisely, the corresponding Riemannian surface, which you might study in further courses.)

Alec

Unhelpful answer

Alec:

Your answer was not helpful.  Let me put it this way: What command can I issue to Maple that will give me the results I specified in my previous entry?

Alla

alec's picture

Sorry

Sorry. I don't think you can, unless there is a special package for that which is not a part of the standard Maple distribution - in the Maple Application Center or elsewhere on the web.

Alec

RealDomain?

Apparently this is the stated purpose of 'RealDomain'. From ?RealDomain:

The RealDomain package provides an environment in which computations are performed under the assumption that the basic underlying number system is the field of real numbers.

3. Results returned by procedures are postprocessed by discarding values containing any detectable non-real answers or replacing them with undefined where appropriate.

But not the fact:

with(RealDomain):
limit(sqrt(4 - x^2),x=2);
                                  0

By the way, I see its code:

showstat(RealDomain:-limit);
RealDomain:-limit := proc()
   1   _EnvSolveOverReals := true;
   2   NumericEventHandler(('real_to_complex') = r2c_handler);
   3   clean(`assuming`([limit(args)],['real']))
end proc

and I wonder what 'clean' does.

PS Whatever it does, it seems that there is a bug here in that 'RealDomain:-' is missing, cf:

showstat(RealDomain:-sqrt);
RealDomain:-sqrt := proc()
   1   _EnvSolveOverReals := true;
   2   NumericEventHandler(('real_to_complex') = RealDomain:-r2c_handler);
   3   RealDomain:-clean(`assuming`([sqrt(args)],['real']))
end proc
JacquesC's picture

Not a 'real' bug

This would be a bug only if r2c_handler were defined globally when the RealDomain:-limit function was loaded into Maple's library.  Binding is done statically, not dynamically (not to be confused with evaluation, which is fully dynamic). 

In this case, it is perfectly safe because r2c_handler is actually a lexical-local (i.e. it is defined in the RealDomain module), so that in fact both are equivalent.  Same goes for the clean routine.

What you are seeing is an artifact of Maple's pretty-printer, which does not make a distinction between names that are bound in different ways.

clean

I meant RealDomain:-clean. Sounds that RealDomain:-limit could call another command 'clean' that could be around.

But if this were a printing artifact, how to know?

JacquesC's picture

Details

By printing artifact here I mean that 2 different things print the same way.

I used disassemble in this case to look at the actual code for RealDomain:-limit, but I could have used ToInert as well.  But of these are extremely precise as to the exact details.

Not enough

I was not aware that 'showstat' is not reliable in this sense ( printing different things the same way). This seems not to be documented.

I have tried your hints:

d:=[disassemble(addressof(RealDomain:-limit))];
	d := [8, 50221232, 51251268, 1768778092, 116]

but then 'pointto' gives error for d[1], d[4] and d[5]. And for d[2] I get the same printing "artifact". So, I do not see how to get the information this way.

On the other hand, with 'ToInert' I get:

ToInert([op(RealDomain:-limit)]);

...
_Inert_NAME("clean"), _Inert_LOCALNAME("clean",51227244,
_Inert_ATTRIBUTE(_Inert_ASSIGNEDLOCALNAME(":-5538","NAME",51243160,
...

Apparently, this is what you mean.

alec's picture

Another way to improve showstat

Another way to get a more correct reading from showstat is to evaluate the lexical table of a procedure before using showstat. In this example,

eval(op(7,op(RealDomain:-limit))):
showstat(RealDomain:-limit);

RealDomain:-limit := proc()
   1   _EnvSolveOverReals := true;
   2   NumericEventHandler(('real_to_complex') = RealDomain:-r2c_handler);
   3   RealDomain:-clean(`assuming`([limit(args)],['real']))
end proc

Alec

I wonder

why 'showstat' does not evaluate this table by default.

alec's picture

Debugging

It evaluates automatically if a procedure is executed. So running showstat after that should work OK. Originally, showstat was a debugging command, and it was usually run in the debugger after executing (or after starting to execute) a procedure, so such a problem, probably, didn't arise.

Alec

acer's picture

by address, again

Using addressof, once again, one can see that there is an instance of clean in the lexical table which is not the global :-clean. It must be a local.

> d:=[disassemble(addressof(eval(RealDomain:-limit)))]:

> pointto(d[9]);
               r2c_handler, r2c_handler, p, limit, clean, clean

> disassemble(d[9]);
           30, 6522504, 6522344, 6655128, 6539768, 6559816, 6654840

> addressof(:-clean);
                                    6559816

You can also see this using op() to get at the lexical table,

> select(t->type(convert(t,`global`),identical(clean)),
>        [op(7,eval(RealDomain:-limit))]);
                                [clean, clean]
 
> map(addressof,%);
                              [6559816, 6654840]
 
> addressof(:-clean);
                                    6559816

And, mixing and matching the fun and games,

> ToInert(pointto(6654840));
_Inert_ASSIGNEDLOCALNAME("clean", "PROC", 6654840, _Inert_ATTRIBUTE(
 
    _Inert_EXPSEQ(_Inert_EQUATION(_Inert_NAME("modulename"),
 
    _Inert_ASSIGNEDNAME("RealDomain", "MODULE", _Inert_ATTRIBUTE(_Inert_EXPSEQ(
 
    _Inert_NAME("protected", _Inert_ATTRIBUTE(_Inert_NAME("protected"))),
 
    _Inert_NAME("_syslib"))))))))

acer

alec's picture

Dismantle

Also, dismantle can be used,

dismantle(op(RealDomain:-limit));
PROC(10)
   EXPSEQ(1)
   EXPSEQ(1)
   EXPSEQ(1)
   EXPSEQ(1)
   STATSEQ(4)
      ASSIGN(3)
         NAME(8): _EnvSolveOverReals
         NAME(5): true #[protected]
      FUNCTION(3)
         NAME(8): NumericEventHandler #[protected]
         EXPSEQ(2)
            EQUATION(3)
               UNEVAL(2)
                  NAME(7): real_to_complex #[protected]
               LEXICAL(2): [1]
      FUNCTION(3)
         LEXICAL(2): [3]
         EXPSEQ(2)
            FUNCTION(3)
               NAME(6): `assuming` #[_syslib]
               EXPSEQ(3)
                  LIST(2)
                     EXPSEQ(2)
                        FUNCTION(3)
                           LEXICAL(2): [-2]
                           EXPSEQ(2)
                              PARAM(2): [-1]
                  LIST(2)
                     EXPSEQ(2)
                        UNEVAL(2)
                           NAME(5): real #[protected, _syslib]
   EXPSEQ(1)
   EXPSEQ(1)
   EXPSEQ(7)
      NAME(6): r2c_handler
      NAME(6): RealDomain:-r2c_handler #[modulename = RealDomain]
      NAME(4): p
      NAME(5): limit #[protected, _syslib]
      NAME(5): clean
      NAME(5): RealDomain:-clean #[modulename = RealDomain]
   BINARY(2)
      0

Alec

JacquesC's picture

Dismantle, yes

That was a mistake on my part, I meant dismantle all along, but I mistakenly typed disassemble.

alec's picture

I almost wrote that :)

I almost wrote that at the end - that Jacques, probably, meant dismantle when he wrote disassemble.

Alec

Axel Vogt's picture

well ...

The Maple command is limit( sqrt(4 - x^2), x=-2, left), etc, and
the help page for 'limit' will tell you a bit more.


What Alec wants to say is a bit difficult to understand, if you
have not had an Complex Analysis course (and quite difficult to say
it in a pricise and understandable way for that background).

You book may mean the following (let us think in intervals):

In *Real* Analysis sqrt(t) is defined for 0 < t= 4 - x^2. 

Which is to say, that x lives in the (open) interval ]-2, +2[.

Let us think in sequences for taking limits in a point t. Then you
can not use negative values in your sequence for sqrt(t_n), due to
the domain of definition for sqrt.

However a limit here always means to allow all sequences - but you
have only those 'from the right' in t=0.

Translated to t= 4 - x^2 it means one can only achieve by sequences
from *within* the interval. That's what your book intends to say.


Now Alec wanted to tell you in short: Maple does not restrict to
Real Analysis, but uses Complex Analysis.

So in sqrt(t) we can have t to be a complex number t = u + v*I,
where u and v are Reals, i.e. t is in the complex plane.

But for v=0 one has: sqrt allows negative inputs (using Complex
Analysis, the result however will be a complex number).

But then you *can* take a both sided limit for sqrt(t) and this
is what Maple does.

You just observed that everything fits together.


However sqrt in the complex plane behaves not as nice you might
expect: it should be solve the equation y=t^2 and one has always
2 solutions (except for y=0).

A sound way is to consider sqrt as a function not in the plane,
but as a function on a surface to live 'above the plane' and you
will learn more in the according course.


PS: this is an example for a possible dilemma for the depth of the
help pages in Maple - how much Math should be assumed or explained?

defining a new sqrt function

You can try this ( in real domain):

restart;

# Defining a new sqrt funtion in real domain:

mysqrt:=x->piecewise(x>=0,sqrt(x),undefined);

# Your function:

f:=x->mysqrt(4 - x^2);

limit(f(x),x=-2,left);

limit(f(x),x=-2,right);

limit(f(x),x=-2);

limit(f(x),x=2,left);

limit(f(x),x=2,right);

limit(f(x),x=2);

plot(f(x),x=-3..3);

 

RealDomain

My thanks to djc for the routine, which worked fine.

Two questions:

1) I notice RealDomain was not invoked in the routine.  I assume this is because it is loaded automatically when a worksheet is begun.  Correct?

2) Is it possible to call RealDomain generally so that for a given worksheet the real number environment would replace the complex number environment for every command?

AB

alec's picture

RealDomain

1) RealDomain was not loaded. The example worked because sqrt was redefined so that it was undefined except for non-negative real numbers.

2) It is possible to load RealDomain by executing

with(RealDomain):

However, that may be not such a good idea as it seems, and it doesn't replace all commands - just some of them.

Alec

real numbers

Alec is correct, I don't use RealDomains here, I just wanted to say that mysqrt works on real numbers correctly.

 

 

 

 

alec's picture

A nice construction

A very nice construction, by the way.

Alec

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
}