Skip to content

Remove Iv core Op in favor of Ive and add rewrite rule for log of it #1092

@ricardoV94

Description

@ricardoV94
Member

Description

Similarly to how we approached Kv/Kve in #1081, we only need one core Op: Ive.

We should include the equivalent log(iv(x)) rewrite for stability, where iv is the expression based on ive returned by the helper.

The goal is to have one canonical form and reduce the number of Ops we need to test/support.

Activity

AdvH039

AdvH039 commented on Dec 7, 2024

@AdvH039
Contributor

Hey @ricardoV94, for this issue I followed the PR for kv and I expressed iv in the form of a ive helper as iv(v,z) = ive(v,z) * exp(z), but it overflows for iv(v,z) when z>100 for v=4.5 that is around 1e36 which I don't think should be happening.
Please let me know where I'm going wrong. Thanks!

ricardoV94

ricardoV94 commented on Jan 23, 2025

@ricardoV94
MemberAuthor

Sorry for missing this thread. How long after does iv itself start overflowing? It's not completely surprising that the multiplication will be a bit less precise.

It might or not be a deal breaker.

The rewrite for the log will probably still make things more stable via the ive route

ricardoV94

ricardoV94 commented on Jan 31, 2025

@ricardoV94
MemberAuthor

I'm not seeing a very early overflow?

import numpy as np
from scipy.special import iv, ive
print(
    iv(4.5, 500),
    ive(4.5, 500) * np.exp(500)
) # 2.4545477241973476e+215 2.4545477241973484e+215

It overflows a tiny bit before iv:

import numpy as np
from scipy.special import iv, ive

v = 4.5
for z in [709, 710, 711, 712, 713, 714, 715]:
    print(z, iv(v, z), ive(v, z) * np.exp(z))

709 1.2140731682798808e+306 1.2140731682798845e+306
710 3.2979337389547726e+306 inf
711 8.958584547932482e+306 inf
712 2.433533186526627e+307 inf
713 6.610518938992669e+307 inf
714 1.7957018810395855e+308 inf
715 inf inf

For now I think it's fine trade-off for simpler codebase. We can revisit later. Most applications will probably want to work on log-scale anyway, where the ive approach should win clearly

import numpy as np
from scipy.special import iv, ive

v = 4.5
for z in [709, 710, 711, 712, 713, 714, 715]:
    print(z, np.log(iv(v, z)), np.log(ive(v, z)) + z)
# 709 704.7850194174108 704.7850194174108
# 710 705.7843345888324 705.7843345888324
# 711 706.7836506961244 706.7836506961244
# 712 707.7829677367349 707.7829677367349
# 713 708.7822857081223 708.7822857081223
# 714 709.7816046077556 709.7816046077554
# 715 inf 710.7809244331132
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @ricardoV94@AdvH039

        Issue actions

          Remove `Iv` core `Op` in favor of `Ive` and add rewrite rule for log of it · Issue #1092 · pymc-devs/pytensor