Opened 11 years ago
Closed 5 months ago
#12070 closed defect (invalid)
Unavoidable DeprecationWarnings when calling piecewise functions
Reported by: | mjo | Owned by: | burcin |
---|---|---|---|
Priority: | minor | Milestone: | sage-duplicate/invalid/wontfix |
Component: | symbolics | Keywords: | |
Cc: | kcrisman | Merged in: | |
Authors: | Reviewers: | Michael Orlitzky, Samuel Lelièvre | |
Report Upstream: | N/A | Work issues: | |
Branch: | Commit: | ||
Dependencies: | Stopgaps: |
Description
When using piecewise functions across modules, you can find yourself unable to avoid the DeprecationWarning? resulting from positional arguments, e.g. f(0).
A small example:
some_library.py
from sage.all import * def make_f(): x = SR.symbol('x', domain='real') f = piecewise([[(-1,1), x**2]]) return f
some_script.py
from some_library import * my_f = make_f() my_f(0)
There is no obvious (or un-obvious, as far as I know) way to avoid the warning here.
The output, for reference:
$ sage some_script.py some_script.py:4: DeprecationWarning: Substitution using function-call syntax and unnamed arguments is deprecated and will be removed from a future release of Sage; you can use named arguments instead, like EXPR(x=..., y=...) my_f(0)
Change History (18)
comment:1 Changed 11 years ago by
comment:2 Changed 11 years ago by
Well, in a sage prompt there's an easy workaround: write f(x) = piecewise(...) instead of just f = ...
That doesn't work outside of a prompt, though, and the preprocessor breaks some imports if you try to rename the *.py files to *.sage.
comment:3 Changed 11 years ago by
Actually that doesn't work - I get a TypeError
with no message, which is pretty strange. I also saw this same TypeError
when trying to coerce a PiecewisePolynomial
into SR
(the Symbolic Ring) so that I could write .function(x)
inside your definition of make_f
, which I originally thought should be the correct way to do this.
comment:4 Changed 11 years ago by
Oh, sorry. This is how to make it work in the prompt:
sage: f1(x) = 2*x sage: f = piecewise([[(-1,1), f1]])
I was planning an "easy" patch for this too, but it turns out to be harder than it looks. You can supply a variable to piecewise() to fix my simple example, but that causes other problems by turning everything into a callable expression.
comment:5 Changed 10 years ago by
- Cc kcrisman added
comment:6 Changed 9 years ago by
- Milestone changed from sage-5.11 to sage-5.12
comment:7 Changed 8 years ago by
- Milestone changed from sage-6.1 to sage-6.2
comment:8 Changed 8 years ago by
- Milestone changed from sage-6.2 to sage-6.3
comment:9 Changed 8 years ago by
- Milestone changed from sage-6.3 to sage-6.4
comment:10 follow-up: ↓ 13 Changed 6 years ago by
The example in this ticket is just misuse. piecewise
takes functions, not expressions. Oneliner solution is
f = piecewise([[(-1,1), (x**2).function(x)]])
It's essential to be explicit about the variable name. See:
var('foo,bar') f = piecewise([[(-1,1), (foo+bar).function(foo)]])
Close as invalid or resolve by updating documentation?
comment:11 Changed 6 years ago by
I vote to update the documentation. Maybe we also need a thematic tutorial about piecewise-defined functions. Questions about them are quite frequent in the various help channels.
comment:12 Changed 6 years ago by
Or to use Volker's new piecewise functions, #14801. But there are some things that no longer work with those, I guess (the oooold stuff about fourier or whatever) and there are some other roadblocks. But probably in the long run that might be better unless we can somehow integrate piecewise.mac in Maxima, but I'm not even sure those are well-debugged.
comment:13 in reply to: ↑ 10 Changed 6 years ago by
Replying to nbruin:
The example in this ticket is just misuse.
piecewise
takes functions, not expressions.
Ok, but the existing doctests and examples (mis)use that same format (I never knew I could/should change an expression into a function). The ones that don't, rely on the preparsing of f(x) = ...
that isn't helpful to people using piecewise()
in python code. What do we do with f(x) = 1
, change it to f = SR(1).function(x)
?
I think f = SR(1).function(x)
is stupid, but having examples that only work when preparsed isn't great either. How about we just fix this for symbolic expressions of one variable?
if is_Expression(f): if len(f.variables()) == 1: f = f.function(f.variables()[0]) # We know what you meant bro. else: raise Whatever()
If there's a good reason not to do that, then the examples illustrating e.g. (x**2).function(x)
should at least be prominent.
comment:14 Changed 6 years ago by
About f(x) = 1
vs f = SR(1).function(x)
, maybe we could
introduce constant_function
and use f = constant_function(1)
.
comment:15 Changed 5 months ago by
- Milestone changed from sage-6.4 to sage-duplicate/invalid/wontfix
This got fixed somewhere along the way:
sage: f = piecewise([[(-1,1), SR(1)]]) sage: f(0) 1
comment:16 Changed 5 months ago by
- Status changed from new to needs_review
comment:17 Changed 5 months ago by
- Reviewers set to Michael Orlitzky, Samuel Lelièvre
- Status changed from needs_review to positive_review
Tried it in Sage 9.5.beta9, seems indeed fixed.
comment:18 Changed 5 months ago by
- Resolution set to invalid
- Status changed from positive_review to closed
This produces the same output in the Sage console (directly after starting it) so I doubt it has anything to do with modules or
.py
/.sage
files in particular.Indeed something is screwed up here, though.