First, I'll mention that I prefer LazyPowerSeriesRing to PowerSeriesRing. Here is an example of using it.

```
sage: P.<t> = LazyPowerSeriesRing(QQ) # Creates the power series ring QQ[[t]]
sage: f = (t + (1/2)*t^2).exponential # In latex, $f = e^{t + \frac{t^2}{2}}$
sage: f[20]*factorial(20) # f[20] is the coefficient of t^20
23758664096
```

It's an unfortunate fact the interface here is a little bit flaky. For example, using

```
sage: f = (t + t^2/2).exponential()
```

gives an error. Even worse is that I only know to define f=1/(1-t) with the following sequence of commands.

```
sage: f = P() # Prepare to define f by a functional equation
sage: f.define(1 + t*f) # This defines f by the functional equation f = 1 + t*f
sage: f[20] # Coefficient of t^20
1
```

However, this does has a facility for dealing with infinite products. For example, the generating functions for partitions is the infinite product \prod_{i \ge 1} 1/(1-t^i). We can do this in sage as follows. First we define a function that will return any given factor.

```
sage: def factor(i):
f = P()
f.define(1+t^i*f) # f = 1/(1-t^i)
return f
```

Now we define a generator that represents the infinite product without needing to compute it.

```
sage: def gen():
i = 1 # product starts here
while True: # product continues forever
yield factor(i) # return the i^th factor
i += 1
```

Now we can define what we want.

```
sage: g = P.product_generator(gen())
sage: g.compute_coefficients(8) # Compute the first 8 coefficients
sage: g
1 + t + 2*t^2 + 3*t^3 + 5*t^4 + 7*t^5 + 11*t^6 + 15*t^7 + 22*t^8 + O(x^9)
sage: g[20]
627
sage: number_of_partitions(20)
627
```

As I said, there are definitely problems with the interface here, but the structure is quite powerful. Please ask for more specific help if this answer isn't enough for you to solve your problem.