1 | initial version |

The code in the question can be simplified in several ways.

Let us first provide simple code to plot the desired function, and then take the opportunity of this question to review the code in the question and offer some advice.

Here `omega`

is renamed `w`

and a few more names are changed
for brevity and readability.

```
sage: R.<s> = CC[]
sage: w = polygen(CC, 'w')
sage: I = CC.0
sage: d = [0.902488008823108, 2.31898630138664, 3.15237117897600, 2.14081977623463, 1.0]
sage: s21 = 0.894292331092066/R(d)
sage: w21 = s21(I*w)
sage: w21_diff = w21.derivative()
sage: arg = w21_diff/w21
sage: f = lambda z: -arg(z).imag()
sage: plot(f, (-1.5, 1.5))
```

VoilĂ !

The essential point is to avoid Sage's symbolic ring if at all possible.

What made the original code so slow was that `imag(arg2)`

returned
an expression living in Sage's symbolic ring, which is best avoided.

Since `arg2`

is just a more complicated expression of `arg`

, it is not needed.

But let me still say how I would have reformatted its definition for readability.

After defining `num`

, `den`

, `den_conj`

, one could define `num2`

and `den2`

as:

```
sage: num2 = (num*den_conj).map_coefficients(lambda z:
....: 0 if abs(z.real()) < 1e-10 and abs(z.imag()) < 1e-10 else
....: z.imag()*I if abs(z.real()) < 1e-10 and abs(z.imag()) >= 1e-10 else
....: z.real() if abs(z.real()) >= 1e-10 and abs(z.imag()) < 1e-10 else z)
sage: den2 = (den*den_conj).map_coefficients(lambda z:
....: 0 if abs(z.real()) < 1e-10 and abs(z.imag()) < 1e-10 else
....: z.imag()*I if abs(z.real()) < 1e-10 and abs(z.imag()) >= 1e-10 else
....: z.real() if abs(z.real()) >= 1e-10 and abs(z.imag()) < 1e-10 else z)
```

from there it appears that the goal is to suppress any real part or imaginary
part that less than `1e-10`

, which can be made more readable as follows:

```
sage: epsilon = 1e-10
sage: truncate_x = lambda x: 0 if abs(x) < epsilon else x
sage: truncate_z = lambda z: (truncate_x(z[0]), truncate_x(z[1]))
sage: num2 = (num*den_conj).map_coefficients(truncate_z)
sage: den2 = (den*den_conj).map_coefficients(truncate_z)
```

This alternative formulation makes it a lot easier to change the
truncation threshold; in case `1e-10`

has to be changed to `1e-8`

or `1e-12`

, it's better if it can be changed in only one place!

Copyright Sage, 2010. Some rights reserved under creative commons license. Content on this site is licensed under a Creative Commons Attribution Share Alike 3.0 license.