Ask Your Question
1

Limit of piecewise function

asked 2022-06-21 21:55:55 +0100

cav24 gravatar image

updated 2022-06-21 22:00:56 +0100

This exact question has been asked before (8 years ago, 2 years ago). So here goes, perhaps things have changed?

f(x) = piecewise([[(0,1),x],[[1,2],x/2]])
limit(f(x),x=1/2)

(Note that I'm not even looking at the point where the discontinuity occurs.)

I get the following error message

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/var/folders/mt/4xjm_x515mxdjkm49zmplt240000gq/T/ipykernel_84420/3847661288.py in <module>
----> 1 limit(f(x),x=Integer(1)/Integer(2))

/private/var/tmp/sage-9.6-current/local/var/lib/sage/venv-python3.10.3/lib/python3.10/site-packages/sage/calculus/calculus.py in limit(ex, dir, taylor, algorithm, **argv)
   1409     if algorithm == 'maxima':
   1410         if dir is None:
-> 1411             l = maxima.sr_limit(ex, v, a)
   1412         elif dir in dir_plus:
   1413             l = maxima.sr_limit(ex, v, a, 'plus')

/private/var/tmp/sage-9.6-current/local/var/lib/sage/venv-python3.10.3/lib/python3.10/site-packages/sage/interfaces/maxima_lib.py in sr_limit(self, expr, v, a, dir)
    985             elif dir == "minus":
    986                 L.append(max_minus)
--> 987             return max_to_sr(maxima_eval(([max_limit], L)))
    988         except RuntimeError as error:
    989             s = str(error)

/private/var/tmp/sage-9.6-current/local/var/lib/sage/venv-python3.10.3/lib/python3.10/site-packages/sage/interfaces/maxima_lib.py in max_to_sr(expr)
   1708             op=max_op_dict[op_max]
   1709         max_args=cdr(expr)
-> 1710         args=[max_to_sr(a) for a in max_args]
   1711         return op(*args)
   1712     elif expr.symbolp():

/private/var/tmp/sage-9.6-current/local/var/lib/sage/venv-python3.10.3/lib/python3.10/site-packages/sage/interfaces/maxima_lib.py in <listcomp>(.0)
   1708             op=max_op_dict[op_max]
   1709         max_args=cdr(expr)
-> 1710         args=[max_to_sr(a) for a in max_args]
   1711         return op(*args)
   1712     elif expr.symbolp():

/private/var/tmp/sage-9.6-current/local/var/lib/sage/venv-python3.10.3/lib/python3.10/site-packages/sage/interfaces/maxima_lib.py in max_to_sr(expr)
   1709         max_args=cdr(expr)
   1710         args=[max_to_sr(a) for a in max_args]
-> 1711         return op(*args)
   1712     elif expr.symbolp():
   1713         if not(expr in max_sym_dict):

TypeError: PiecewiseFunction.__call__() takes 2 positional arguments but 3 were given
edit retag flag offensive close merge delete

Comments

Correct conversion of piecewise functions to maxima is not implemented.

FrédéricC gravatar imageFrédéricC ( 2022-06-22 15:44:45 +0100 )edit

And there is a bug in libgiac conversion

sage: f(x) = piecewise([[(0,1),x],[[1,2],x/2]])
sage: f
x |--> piecewise(x|-->x on (0, 1), x|-->1/2*x on [1, 2]; x)
sage: giac(f)
piecewise(((sageVARx>0) and (1>sageVARx)),sageVARx,((sageVARx>=1) and (2>=sageVARx)),sageVARx/2)
sage: libgiac(f)
piecewise([0,1,x,[1,2],1/2*x],sageVARx)
FrédéricC gravatar imageFrédéricC ( 2022-06-22 16:24:43 +0100 )edit

1 Answer

Sort by » oldest newest most voted
1

answered 2022-06-22 03:59:07 +0100

Juanjo gravatar image

updated 2022-06-25 01:07:24 +0100

You can rely on Sympy instead of Maxima or you can extract the expression at the corresponding point and then compute the limit:

sage: f(x) = piecewise([[(0,1),x],[[1,2],x/2]])
sage: limit(f(x),x=1/2,algorithm="sympy")
1/2
sage: limit(f(x).expression_at(1/2),x=1/2)
1/2

Edit: It is clear that endpoints of the different pieces and points in the interior of a piece cannot receive the same treatment. For the latter, it suffices to compute a limit, as usual, of the corresponding function piece. For the former, one should compute and compare one sided limits. So, a complete solution could be obtained by defining a function that considers the different cases. As a proof of concept, such a function could be similar to the following one:

def p_limit(f, x0, eps=10^(-10), algorithm="maxima"):
    if x0 in f.end_points():
        funs = [f.expression_at(x0+s*eps) for s in [-1,1]]
        lims = [limit(fun, x=x0, dir=s, algorithm=algorithm) 
                for fun,s in zip(funs,["-","+"])]
        if lims[0]==lims[1]:
            return lims[0]
        else:
            return "undefined"
    else:
        return limit(f.expression_at(x0), x=x0, algorithm=algorithm)

Let us test it:

sage: f = piecewise([[(-infinity,-pi), sin(2*x)],  
....:                [(-pi,0), sin(x)/x],  
....:                [[0,0], 1],  
....:                [(0,pi/2), x/tan(x)], 
....:                [[pi/2,pi/2], 0], 
....:                [(pi/2,+infinity), cos(x)]]) 
....:                                                                           
sage: for x0 in [-9*pi/8, -pi, 0, pi/3, pi/2, 3*pi]: 
....:     print("The limit at ", x0, " is ", p_limit(f,x0)) 
....:                                                                           
The limit at  -9/8*pi  is  -1/2*sqrt(2)
The limit at  -pi  is  0
The limit at  0  is  1
The limit at  1/3*pi  is  1/9*sqrt(3)*pi
The limit at  1/2*pi  is  0
The limit at  3*pi  is  -1

One more test:

sage: f = piecewise([[[-4,-1], 2*x^2],  
....:                [(-1,0), (x^2-1)/(x^2+x)],  
....:                [(0,1), -log(x)], 
....:                [[1,2], x^2]]) 
....:                                                                           
sage: for x0 in [-2, -1, -0.5, 0, 1]: 
....:     print("The limit at ", x0, " is ", p_limit(f,x0)) 
....:                                                                           
The limit at  -2  is  8
The limit at  -1  is  2
The limit at  -0.500000000000000  is  3.0
The limit at  0  is  +Infinity
The limit at  1  is  undefined
edit flag offensive delete link more

Comments

@Juanjo : Where does expression_at comes from ?

Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2022-06-22 10:06:10 +0100 )edit

Thanks for your answer! I'm not sure I understand but I'll research "simpy" and expression_at. However: It seems like neither of these provides a full solution, because look what happens when I say

limit(f(x),x=1,algorithm="sympy")

... It still returns 1/2, when really it should say something along the lines of "undefined".

Given this, I guess what this is doing is to replace the piecewise function with the part that is relevant at the evaluated point, which is okay only when the function is continuous at that point.

cav24 gravatar imagecav24 ( 2022-06-22 10:39:24 +0100 )edit

Further evidence that this is what's happening:

f(x) = piecewise([[(0,1),x],[(1,2),x]])
limit(f(x).expression_at(1),x=1)

Here, we'd want Sage to return "1" even though the function is not defined at x=1. But it gives an error. I can't copy the error because it exceeds the character limit. But the important part is:

ValueError: point is not in the domain

If instead I use the "sympy" code, I get another long error message ending with

AttributeError: 'ExprCondPair' object has no attribute '_eval_is_meromorphic'
cav24 gravatar imagecav24 ( 2022-06-22 10:43:08 +0100 )edit

@Emmanuel Charpentier: It is one of the methods defined for piecewise functions. I found it here.

Juanjo gravatar imageJuanjo ( 2022-06-25 01:05:55 +0100 )edit

@cav24: See the edited answer

Juanjo gravatar imageJuanjo ( 2022-06-25 01:08:00 +0100 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2022-06-21 21:55:55 +0100

Seen: 939 times

Last updated: Jun 25 '22