Opened 5 years ago

Closed 5 years ago

# make Expression.series return an element of SR[[]]

Reported by: Owned by: rws major sage-duplicate/invalid/wontfix calculus bhackl N/A

Instead of duplicating power series functionality (existing in `rings/`) in Pynac, where there is momentarily only a skeleton implementation that does not even play nice with the rest of symbolics, the `series` method of `Expression` should return an element of `PowerSeriesRing(SR)`.

It does not necessarily mean everything will be implemented in Python, Pynac could still compute the series as Python object.

### comment:1 Changed 5 years ago by rws

• Description modified (diff)

### comment:2 follow-up: ↓ 3 Changed 5 years ago by nbruin

• What's the variable of `SR[[]]`? Does it support multivariate power series?
• How does `f=(x^2+y^2+1)` coerce into `SR[['x']]`? Note that `f` is already an element of `SR`, so by default it would be a "constant" in `SR[['x']]`.

### comment:3 in reply to: ↑ 2 ; follow-up: ↓ 4 Changed 5 years ago by rws

• What's the variable of `SR[[]]`?

A symbolic variable is given as argument of `series`. The ring variable will have the same name and thus override it on new input from the user.

Does it support multivariate power series?

At the moment `series` takes one symbol.

• How does `f=(x^2+y^2+1)` coerce into `SR[['x']]`? Note that `f` is already an element of `SR`, so by default it would be a "constant" in `SR[['x']]`.

As above the `series` argument determines the name of the series variable, so it also determines what is being done with the expression. Already now:

```sage: (1+x+y).series(x,5)
(y + 1) + 1*x
```

(However, the `coefficient` functions don't work with "exact" series atm)

### comment:4 in reply to: ↑ 3 ; follow-up: ↓ 5 Changed 5 years ago by nbruin

• How does `f=(x^2+y^2+1)` coerce into `SR[['x']]`? Note that `f` is already an element of `SR`, so by default it would be a "constant" in `SR[['x']]`.

As above the `series` argument determines the name of the series variable, so it also determines what is being done with the expression. Already now:

That's ambiguous and not what happens by default in our current coercion:

```sage: R=PowerSeriesRing(SR,name='x',default_prec=10)
sage: F=1/(1-R.0)
sage: F-x
-x + 1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + O(x^10)
sage: F-R.0
1 + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + O(x^10)
```

You see that SR('x') doesn't coerce to R.0 in R. You'd have to override that somehow and that will be extremely messy: where does `sin(x)` coerce?

### comment:5 in reply to: ↑ 4 ; follow-up: ↓ 6 Changed 5 years ago by rws

That's ambiguous and not what happens by default in our current coercion:

```sage: R=PowerSeriesRing(SR,name='x',default_prec=10)
sage: F=1/(1-R.0)
sage: F-x
-x + 1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + O(x^10)
sage: F-R.0
1 + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + O(x^10)
```

You see that SR('x') doesn't coerce to R.0 in R. You'd have to override that somehow and that will be extremely messy: where does `sin(x)` coerce?

To `sin(R.0)`, where is the problem? Of course it would expand to

```x - 1/6*x^3 + 1/120*x^5 - 1/5040*x^7 + 1/362880*x^9 - 1/39916800*x^11 + 1/6227020800*x^13 - 1/1307674368000*x^15 + 1/355687428096000*x^17 - 1/121645100408832000*x^19 + Order(x^20)
```

### comment:6 in reply to: ↑ 5 ; follow-up: ↓ 7 Changed 5 years ago by nbruin

where does `sin(x)` coerce? To `sin(R.0)`, where is the problem? Of course it would expand to

```x - 1/6*x^3 + 1/120*x^5 - 1/5040*x^7 + 1/362880*x^9 - 1/39916800*x^11 + 1/6227020800*x^13 - 1/1307674368000*x^15 + 1/355687428096000*x^17 - 1/121645100408832000*x^19 + Order(x^20)
```

That will be quite a bit of work to arrange, but that's not what I meant: What are the results of

```SR[['x']]( sin(SR('x')) )
SR[['x']]( sin(SR('y')) )
```

(the main part: how are you going to arrive at those results? I'm not saying it's impossible to come up with something satisfactory. Just that there's some non-trivial work to be done)

### comment:7 in reply to: ↑ 6 Changed 5 years ago by rws

...how are you going to arrive at those results? I'm not saying it's impossible to come up with something satisfactory. Just that there's some non-trivial work to be done)

It's just another expression converter, isn't it? BTW, `exp(x)` already does the desired thing. Though it's not dependent the work would also benefit from #17759 which itself depends on #18255.

### comment:8 Changed 5 years ago by rws

Ah I see, `sin(x)` needs a second order DE. But Pari is able to do `sin` easily so there must be an algorithm.

### comment:9 Changed 5 years ago by rws

Power series via Pari would be #15601, but actually Pynac is more complete here. It just needs the conversion to `PowerSeries`.

Last edited 5 years ago by rws (previous) (diff)

### comment:10 follow-up: ↓ 12 Changed 5 years ago by rws

• Milestone changed from sage-6.7 to sage-duplicate/invalid/wontfix
• Status changed from new to needs_review

I think my new posting in sage-devel (https://groups.google.com/forum/?hl=en#!topic/sage-devel/XhOhwjjeLTM) makes this ticket obsolete. Maybe we just need to change Pynac so that, if an expression contains a `pseries` it will be reexpanded (making the new order the min of all orders). What do you think?

Surprise.

### comment:11 Changed 5 years ago by rws

I think there is also a satisfying solution to the discussed interface problem. Instead of automatically creating a `PowerSeriesRing`, with all the problems of duplicate generators, the user will do this part and give the chosen generator as argument to `series` or simply use it as part of the expression.

### comment:12 in reply to: ↑ 10 ; follow-up: ↓ 13 Changed 5 years ago by mmezzarobba

• Status changed from needs_review to positive_review

I think my new posting in sage-devel (https://groups.google.com/forum/?hl=en#!topic/sage-devel/XhOhwjjeLTM) makes this ticket obsolete. Maybe we just need to change Pynac so that, if an expression contains a `pseries` it will be reexpanded (making the new order the min of all orders). What do you think?

I'm not too convinced: calling `series()` is a bit like calling `expand()` or `normal()`, with symbolic expressions, you don't necessarily want that to happen automatically. And (FWIW) that's also what Maple does:

```#-->s := series(sin(x),x);
s := series(1*x-1/6*x^3+1/120*x^5+O(x^7),x,7)
#-->t := series(exp(x),x);
t := series(1+1*x+1/2*x^2+1/6*x^3+1/24*x^4+1/120*x^5+O(x^6),x,6)
#-->s*t;
(series(1*x-1/6*x^3+1/120*x^5+O(x^7),x,7))*(series(1+1*x+1/2*x^2+1/6*x^3+1/24*x^4+1/120*x^5+O(x^6),x,6))
#-->series(s*t,x);
series(1*x+1*x^2+1/3*x^3-1/30*x^5+O(x^6),x,6)
```

But perhaps I misunderstood the question?

In any case, I agree that this ticket can be closed.

### comment:13 in reply to: ↑ 12 ; follow-up: ↓ 14 Changed 5 years ago by rws

...And (FWIW) that's also what Maple does:

```#-->s := series(sin(x),x);
s := series(1*x-1/6*x^3+1/120*x^5+O(x^7),x,7)
#-->t := series(exp(x),x);
t := series(1+1*x+1/2*x^2+1/6*x^3+1/24*x^4+1/120*x^5+O(x^6),x,6)
#-->s*t;
(series(1*x-1/6*x^3+1/120*x^5+O(x^7),x,7))*(series(1+1*x+1/2*x^2+1/6*x^3+1/24*x^4+1/120*x^5+O(x^6),x,6))
#-->series(s*t,x);
series(1*x+1*x^2+1/3*x^3-1/30*x^5+O(x^6),x,6)
```

But perhaps I misunderstood the question?

Interesting. But that can be considered a bug and see the sage-devel link for a bug report. I mean, what else do you expect as result when dealing with a series? But I'll open a new ticket for that.

### comment:14 in reply to: ↑ 13 ; follow-up: ↓ 15 Changed 5 years ago by nbruin

Interesting. But that can be considered a bug and see the sage-devel link for a bug report. I mean, what else do you expect as result when dealing with a series? But I'll open a new ticket for that.

The problem is: there are SR allows expressions of such generality that series expansions aren't always possible. Consider:

```sage: function('f')
sage: s=series(sin(x))
sage: f(cos(x))+g
```

Should that be considered a series in x?

And then there are of course the cases with well-defined functions as ingredients where you really can't make a series expansion:

```sage: s=series(sin(x))
sage: exp(1/x)+s
```

The general problem is: an element of SR (and the fundamental data type in maple) is just an expression tree. Mathematical meaning is only obtained by *what* you do with the element (it's like an untyped programming language). That means you can do algebra with objects in SR that represent a series in such a way that you get another object that can't possibly be interpreted as a series. maple (and apparently pynac by default) solves that problem by not even trying: they leave it to the user to do that, trusting that he/she will take care to only do that in situations where it is possible to interpret the result as a series.

### comment:15 in reply to: ↑ 14 Changed 5 years ago by mmezzarobba

The problem is: there are SR allows expressions of such generality that series expansions aren't always possible. Consider:

```sage: function('f')
sage: s=series(sin(x))
sage: f(cos(x))+g
```

(I guess `g` should be `s`?)

Should that be considered a series in x?

Here Maple does (when one explicitly asks for a series expansion, of course):

```#-->series(f(cos(x)) + sin(x), x);
series(f(1)+1*x+(-1/2*D(f)(1))*x^2-1/6*x^3+(1/24*D(f)(1)+1/8*`@@`(D,2)(f)(1))*x^4+1/120*x^5+O(x^6),x,6)
```

and I found that convenient on many occasions. But I seem to rememer that ginac can do something similar.

### comment:16 Changed 5 years ago by rws

Followup tickets: #18499, #18500

### comment:17 Changed 5 years ago by vbraun

• Resolution set to fixed
• Status changed from positive_review to closed
Note: See TracTickets for help on using tickets.