Opened 2 years ago

Closed 6 weeks ago

# Derivative of piecewise function returns junk

Reported by: Owned by: rburing major sage-9.5 symbolics piecewise, derivative, diff tscrim, slelievre, gh-kliem Frédéric Chapoton Travis Scrimshaw N/A 2f0c828 2f0c8282bee61453e962f57cdc2a16be746ba097

### Description

Reported in Ask SageMath question #47169, we can't differentiate the bump function:

```sage: f(x) = piecewise([((-oo, -1), 0), ((-1, 1), exp(-1/(1 - x^2))), ((1, oo), 0)])
sage: f.diff()
x |--> (0, 0, 0)*D[0]piecewise(x|-->0 on (-oo, -1), x|-->e^(1/(x^2 - 1)) on (-1, 1), x|-->0 on (1, +oo); x) + D[1]piecewise(x|-->0 on (-oo, -1), x|-->e^(1/(x^2 - 1)) on (-1, 1), x|-->0 on (1, +oo); x)
sage: f.diff()(0)
(0, 0, 0)*e^(-1) + e^(-1)
sage: f.diff()(0) in RR
False
```

That's not right...

### comment:1 Changed 2 years ago by embray

• Milestone changed from sage-8.9 to sage-9.1

Ticket retargeted after milestone closed

### comment:2 Changed 20 months ago by mkoeppe

• Milestone changed from sage-9.1 to sage-9.2

Batch modifying tickets that will likely not be ready for 9.1, based on a review of the ticket title, branch/review status, and last modification date.

### comment:3 Changed 16 months ago by mkoeppe

• Milestone changed from sage-9.2 to sage-9.3

### comment:4 Changed 10 months ago by mkoeppe

• Milestone changed from sage-9.3 to sage-9.4

Setting new milestone based on a cursory review of ticket status, priority, and last modification date.

### comment:5 Changed 5 months ago by mkoeppe

• Milestone changed from sage-9.4 to sage-9.5

### comment:6 Changed 7 weeks ago by chapoton

• Authors set to Frédéric Chapoton
• Branch set to u/chapoton/28207
• Cc tscrim slelievre gh-kliem added
• Status changed from new to needs_review

here is a tentative ; certainly better than before, but not perfect

New commits:

 ​e1b526c `trying to make derivative od piecewise work`

### comment:7 Changed 7 weeks ago by tscrim

What would you say is missing from making it perfect?

### comment:8 Changed 7 weeks ago by chapoton

derivative wrt y is not working, giving the same result as wrt x...

### comment:9 Changed 7 weeks ago by tscrim

Could we add a short explanation and doctest showing this behavior (and perhaps with the desired output)?

### comment:10 Changed 7 weeks ago by git

• Commit changed from e1b526c6be9cfc1bcb879fadbe63fb2d56b66010 to 2f0c8282bee61453e962f57cdc2a16be746ba097

Branch pushed to git repo; I updated commit sha1. New commits:

 ​028cc8a `Merge branch 'u/chapoton/28207' in 9.5.b4` ​2f0c828 `describe known bugs in derivative of piecewise`

### comment:11 Changed 7 weeks ago by chapoton

This is still very ugly. One should try to fix that, but experts are lacking..

### comment:12 Changed 7 weeks ago by tscrim

I am not sure these should actually count as bugs as the behavior is consistent with what other symbolic functions do:

```sage: y = SR.var('y')
sage: f(x) = x*y + x + y
sage: type(f)
<class 'sage.symbolic.expression.Expression'>
sage: f
x |--> x*y + x + y

sage: f.derivative(x)
x |--> y + 1
sage: f.derivative(y)
x |--> x + 1
```

What would you expect the output to be?

### comment:13 Changed 7 weeks ago by chapoton

I have written the expected output in the doctests. The actual behaviour, with the branch, is to raise an Error.

### comment:14 Changed 7 weeks ago by tscrim

• Reviewers set to Travis Scrimshaw
• Status changed from needs_review to positive_review

Ah, sorry, I misunderstood. Thank you. LGTM.

### comment:15 Changed 7 weeks ago by chapoton

I would have hoped that someone step in to fix that..

Here is the traceback:

```sage: y = SR.var('y')
sage: h = piecewise([((-1,1),x**2*y)])
sage: h.derivative(x)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-6-efc8c30bd882> in <module>
----> 1 h.derivative(x)

~/sage/local/lib/python3.8/site-packages/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.derivative (build/cythonized/sage/symbolic/expression.cpp:54561)()
4574             ValueError: No differentiation variable specified.
4575         """
-> 4576         return multi_derivative(self, args)
4577
4578     diff = differentiate = derivative

~/sage/local/lib/python3.8/site-packages/sage/misc/derivative.pyx in sage.misc.derivative.multi_derivative (build/cythonized/sage/misc/derivative.c:3218)()
220
221     for arg in derivative_parse(args):
--> 222         F = F._derivative(arg)
223     return F
224

~/sage/local/lib/python3.8/site-packages/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression._derivative (build/cythonized/sage/symbolic/expression.cpp:55084)()
4646         sig_on()
4647         try:
-> 4648             x = self._gobj.diff(ex_to_symbol(symbol._gobj), deg)
4649         finally:
4650             sig_off()

~/sage/local/lib/python3.8/site-packages/sage/functions/piecewise.py in _tderivative_(self, parameters, variable, *args, **kwds)
312             piecewise(x|-->0 on (-oo, -1), x|-->-2*x*e^(1/(x^2 - 1))/(x^2 - 1)^2 on (-1, 1), x|-->0 on (1, +oo); x)
313         """
--> 314         return piecewise([(domain, func.derivative(*args))
315                           for domain, func in parameters],
316                          var=variable)

~/sage/local/lib/python3.8/site-packages/sage/functions/piecewise.py in <listcomp>(.0)
312             piecewise(x|-->0 on (-oo, -1), x|-->-2*x*e^(1/(x^2 - 1))/(x^2 - 1)^2 on (-1, 1), x|-->0 on (1, +oo); x)
313         """
--> 314         return piecewise([(domain, func.derivative(*args))
315                           for domain, func in parameters],
316                          var=variable)

~/sage/local/lib/python3.8/site-packages/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression.derivative (build/cythonized/sage/symbolic/expression.cpp:54561)()
4574             ValueError: No differentiation variable specified.
4575         """
-> 4576         return multi_derivative(self, args)
4577
4578     diff = differentiate = derivative

~/sage/local/lib/python3.8/site-packages/sage/misc/derivative.pyx in sage.misc.derivative.multi_derivative (build/cythonized/sage/misc/derivative.c:3114)()
217     if not args:
218         # fast version where no arguments supplied
--> 219         return F._derivative()
220
221     for arg in derivative_parse(args):

~/sage/local/lib/python3.8/site-packages/sage/symbolic/expression.pyx in sage.symbolic.expression.Expression._derivative (build/cythonized/sage/symbolic/expression.cpp:54909)()
4637             else:
-> 4638                 raise ValueError("No differentiation variable specified.")
4639         if not isinstance(deg, (int, long, sage.rings.integer.Integer)) \
4640                 or deg < 1:

ValueError: No differentiation variable specified.
```

### comment:16 Changed 7 weeks ago by tscrim

I will try to dig a little deeper soon.

### comment:17 Changed 6 weeks ago by vbraun

• Branch changed from u/chapoton/28207 to 2f0c8282bee61453e962f57cdc2a16be746ba097
• Resolution set to fixed
• Status changed from positive_review to closed
Note: See TracTickets for help on using tickets.