Closed rwst closed 8 years ago
Branch: u/rws/17659
I have nothing invested in how symbolics and series interact, but I see some immediate problems that would arise from subclassing Expression for a Series type:
F = (1/(x+1))*y+sin(x)*y^2+O(y^3)
G = (y/(y^2-2)*x + cos(y)*x^2 +O(x^3)
F+G
Is the result a series? If so, in which variable(s)? One solution would be a SymbolicSeriesRing as a parent, which declares in what variables the series are. I suspect this would be nearly useless for whatever problem the current design tries to solve, though.
Nils, this is not about creating a ring but simple refactoring. No behaviour change.
http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html
Replying to @nbruin:
I have nothing invested in how symbolics and series interact, but I see some immediate problems that would arise from subclassing Expression for a Series type:
These problems already exist, so nothing is new.
Description changed:
---
+++
@@ -3,3 +3,4 @@
* allows upcoming fixes that don't clutter `Expression` methods with `if ex.is_a_series():`
* makes for better documentation via having a `Symbolic Series` ref man page
+In refactoring language this is "replace conditional with polymorphism".
Branch pushed to git repo; I updated commit sha1. New commits:
ed003f0 | 16203: make imports more specific to prevent import loops |
Description changed:
---
+++
@@ -4,3 +4,5 @@
* makes for better documentation via having a `Symbolic Series` ref man page
In refactoring language this is "replace conditional with polymorphism".
+
+#16302 and #17400 depend on this.
OK, I thought that f.is_series()
would do some non-trivial logic to see if f
can be used as a series, but it's just exposing a flag that is held internally somewhere. You could indeed expose that information in the type instead, but with ducktyping, subtyping and sage's parent infrastructure doing so might not be as convenient as it might be in systems that are really governed by explicit types. You'd need to think if this refactoring actually will help for further development.
Indeed, being a "series" seems a rather fickle property. It doesn't seem to be preserved under anything:
sage: var('x,y');
sage: f=cos(y).series(y,10)
sage: g=sin(x).series(x,10)
sage: var('x,y');
sage: f=cos(y).series(y,10)
sage: g=sin(x).series(x,10)
sage: f.is_series()
True
sage: (f+f).is_series()
False
sage: (-f).is_series()
False
sage: (f+g).series(x,10)
Order(1)
The last result probably follows from interpreting the Order(x^10)
term in g
as an order term in y
, and hence equivalent to Order(y^0)
.
Replying to @nbruin:
You'd need to think if this refactoring actually will help for further development.
It isolates the code and the documentation.
Indeed, being a "series" seems a rather fickle property. It doesn't seem to be preserved under anything:
There are functions in pynac-0.3.2/ginac/pseries.cpp
to compare, add, multiply (also with constant), power (to constant). My plan is to only provide conversion to and from PowerSeries
(#10846, #16203, #17402) and fix the worst bugs (#17400, #16213) and that's it. I'd rather improve PowerSeries
but symbolic is what people use.
Description changed:
---
+++
@@ -5,4 +5,4 @@
In refactoring language this is "replace conditional with polymorphism".
-#16302 and #17400 depend on this.
+#16203 and #17400 depend on this.
Changed branch from u/rws/17659 to public/17659
Branch pushed to git repo; I updated commit sha1. New commits:
3198603 | 17659: factor out SymbolicSeries from Expression |
Description changed:
---
+++
@@ -5,4 +5,4 @@
In refactoring language this is "replace conditional with polymorphism".
-#16203 and #17400 depend on this.
+#16203, #17400, and 17402 depend on this.
Branch pushed to git repo; I updated commit sha1. New commits:
a67d0ce | Merge branch 'develop' into t/17659/public/17659 |
There is a spurious unreprodcible doctest failure in the 6.6beta2 pachbot run.
This now uncovers a regression of #12255 which was not really fixed.
File "src/sage/symbolic/expression.pyx", line 5279, in sage.symbolic.expression.Expression.coefficients
Failed example:
f.coefficients(g)
Exception raised:
ValueError: The name "g(t)" is not a valid Python identifier.
I will now let this ticket (and with it its dependencies) lie in limbo because, as a posting on sage-devel showed, there is no interest in symbolic series.
Branch pushed to git repo; I updated commit sha1. New commits:
5e2a136 | 17659: complete doctest coverage |
Reviewer: Vincent Delecroix
Hello,
The ticket looks good.
include "sage/ext/interrupt.pxi"
include "sage/ext/stdsage.pxi"
include "sage/ext/cdefs.pxi"
include "sage/ext/python.pxi"
As far as I saw you are using none of them.
... about 0, about `1` ...
Either `0`
and `1`
or 0
and 1
.
In the example, instead of float(expr)
could you use numerical_approx(expr)
?
You should not put self
as an argument of a method (you did it in truncate
). Moreover, it is better to avoid self
in the documentation. Always prefer this expression
or this object
.
In coefficients
, the argument sparse
is not documented in the INPUT
section
In coefficients
, you should replace if sparse is True
by if sparse
.
Changed branch from public/17659 to u/rws/17659-1
Is the method is_series
really usefull?
Replying to @videlec:
Is the method
is_series
really usefull?
Series are still expressions. How would you know a symbol holding a specific expression holds a series?
Branch pushed to git repo; I updated commit sha1. New commits:
b87cc1a | 17659: make doctest clearer |
Branch pushed to git repo; I updated commit sha1. New commits:
b30cf0a | 17659: remove superfluous is_series() |
Indeed. Anything else?
Replying to @rwst:
Indeed. Anything else?
Yes: you are not allowed to remove a public function without (one year) deprecation with an error message that indicates the new procedure: http://doc.sagemath.org/html/en/developer/coding_in_python.html#deprecation
Isn't it dangerous to expose globally SymbolicSeries
? If people don't know about classes they do not want to see it. And if they do, they know how to import modules. You can just be explicit in the deprecation message
isinstance(my_expr, sage.symbolic.series.SymbolicSeries)
(I would also hide Expression
from the global namespace but this does not concern this ticket.)
Branch pushed to git repo; I updated commit sha1. New commits:
d5cc424 | 17659: address reviewers comments |
Good for me.
Description changed:
---
+++
@@ -5,4 +5,4 @@
In refactoring language this is "replace conditional with polymorphism".
-#16203, #17400, and 17402 depend on this.
+#16203, #17400, and #17402 depend on this.
sage -t --long src/sage/symbolic/series.pyx
**********************************************************************
File "src/sage/symbolic/series.pyx", line 71, in sage.symbolic.series
Failed example:
x*ex1
Expected:
(1*x + (-1/6)*x^3 + Order(x^4))*x
Got:
x*(1*x + (-1/6)*x^3 + Order(x^4))
**********************************************************************
1 item had failures:
1 of 23 in sage.symbolic.series
[42 tests, 1 failure, 0.04 s]
Making
Expression.series
createSymbolicSeries
(a subclass ofExpression
) and moving the series code into a separate fileseries.pyx
Expression
methods withif ex.is_a_series():
Symbolic Series
ref man pageIn refactoring language this is "replace conditional with polymorphism".
16203, #17400, and #17402 depend on this.
Depends on #19948
Component: symbolics
Author: Ralf Stephan
Branch/Commit:
1832f4a
Reviewer: Vincent Delecroix
Issue created by migration from https://trac.sagemath.org/ticket/17659