Ask Your Question
0

Use of LazyLaurentSeriesRing.

asked 2025-12-08 20:26:08 +0100

Peter Luschny gravatar image

I would like to better understand the use of 'LazyLaurentSeriesRing' in Sage.

The expansion of the function 'Omega', as defined below, sometimes works, sometimes not.

More precisely, it works in the cases m = 0, 1, 2, 4, and does not work for m = 3, 5, 6.

What's the trick?

def Omega(m, z) :
    if m == 0: return z**0
    if m == 1: return exp(z)
    if m == 2: return cosh(z)
    if m == 3: return (exp(z) + 2 * exp(-z / 2) * cos(z * 3 ** (1 / 2) / 2)) / 3
    if m == 4: return (cosh(z) + cos(z)) / 2
    if m == 5: return (exp(z)
            + 2 * exp(-cos(pi / 5) * z) * cos(sin(pi / 5) * z)
            + 2 * exp(cos((2 * pi) / 5) * z) * cos(sin((2 * pi) / 5) * z) ) / 5
    if m == 6: return (cosh(z) + 2 * cos(z * sqrt(3) / 2) * cosh(z / 2)) / 3
    return 0

Test:

L = LazyLaurentSeriesRing(QQ, 'z')
for m in [0, 1, 2, 4]:
    f = Omega(m, L.gen())
    print(f"m={m}: {[factorial(n)*f.coefficient(n) for n in range(24)]}")
edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2025-12-08 21:30:10 +0100

Max Alekseyev gravatar image

updated 2025-12-08 21:30:52 +0100

The problem is that you are mixing up symbolic values, like 3 ** (1 / 2), cos(pi / 5), etc., that do not exist in QQ and L.

A possible solution is to extend the base ring from QQ to AA to include radicals like sqrt(3), sqrt(5). However, explicit conversion of those expression into AA is needed:

def Omega(m, z) :
    if m == 0: return z**0
    if m == 1: return exp(z)
    if m == 2: return cosh(z)
    if m == 3: return (exp(z) + 2 * exp(-z / 2) * cos(z * sqrt(AA(3)) / 2)) / 3
    if m == 4: return (cosh(z) + cos(z)) / 2
    if m == 5: return (exp(z)
            + 2 * exp(-AA(cos(pi / 5)) * z) * cos(AA(sin(pi / 5)) * z)
            + 2 * exp(AA(cos((2 * pi) / 5)) * z) * cos(AA(sin((2 * pi) / 5)) * z) ) / 5
    if m == 6: return (cosh(z) + 2 * cos(z * sqrt(AA(3)) / 2) * cosh(z / 2)) / 3
    return 0

L = LazyLaurentSeriesRing(AA, 'z')
for m in (0..6):
    f = Omega(m, L.gen())
    print(f"m={m}: {[factorial(n)*f.coefficient(n).radical_expression() for n in range(24)]}")
edit flag offensive delete link more

Comments

Excellent! Thank you so much!

Peter Luschny gravatar imagePeter Luschny ( 2025-12-08 22:17:32 +0100 )edit

However, (1) the execution time is considerable, and (2) I would like to write a general function that doesn't require any special pre-processing of the input function. Perhaps 'LazyLaurentSeriesRing' simply isn't the right ring for this. Are there any better solutions?

Peter Luschny gravatar imagePeter Luschny ( 2025-12-08 22:18:28 +0100 )edit

To address (1), you may consider working in a smaller field such as K.<r3,r5> = NumberField([x^2-3,x^2-5]) that contains all your constants. I do not quite follow your question (2) - what do you call "pre-processing"? Again, the issue was that if you define your series over the rational field QQ, all coefficients must come from that field, and so you cannot have symbolic constants like sqrt(3). If you want to work with those, you need to define your series over a larger field and embed all constants into it.

Max Alekseyev gravatar imageMax Alekseyev ( 2025-12-09 02:08:14 +0100 )edit

Btw, as an alternative to exact fields, you may consider defining L over the symbolic ring SR (just change QQ to SR in your original code), although I'd expect even worse running time here.

Max Alekseyev gravatar imageMax Alekseyev ( 2025-12-09 02:13:51 +0100 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2025-12-08 20:26:08 +0100

Seen: 9 times

Last updated: 5 hours ago