First time here? Check out the FAQ!

Ask Your Question
1

Limit of piecewise function

asked 2 years ago

cav24 gravatar image

updated 2 years ago

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
Preview: (hide)

Comments

Correct conversion of piecewise functions to maxima is not implemented.

FrédéricC gravatar imageFrédéricC ( 2 years ago )

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 ( 2 years ago )

1 Answer

Sort by » oldest newest most voted
1

answered 2 years ago

Juanjo gravatar image

updated 2 years ago

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
Preview: (hide)
link

Comments

@Juanjo : Where does expression_at comes from ?

Emmanuel Charpentier gravatar imageEmmanuel Charpentier ( 2 years ago )

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 ( 2 years ago )

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 ( 2 years ago )

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

Juanjo gravatar imageJuanjo ( 2 years ago )

@cav24: See the edited answer

Juanjo gravatar imageJuanjo ( 2 years ago )

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: 2 years ago

Seen: 1,166 times

Last updated: Jun 25 '22