Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memoization of SymPy function calls does not recognize identical arguments #30

Closed
jlbosse opened this issue Jul 25, 2023 · 3 comments
Closed

Comments

@jlbosse
Copy link

jlbosse commented Jul 25, 2023

Memoization of SymPy functions in a Dict does not work as expected. When integrate() is called with equal, but not identical arguments it computes integrate() again and grows the cache.

See the following MWE

using SymPy
using Memoization

function integrate_wrapper(args...; kwargs...)
    # memoize the call in Dict, not IdDict
    out = @memoize Dict integrate(args...; kwargs...)
    return out
end

t, a = symbols("t, a")
f = sin(a * t)
integrate_wrapper(f, (t, 0, t))
g = sin(a * t)
integrate_wrapper(g, (t, 0, t))

f == g    # true
f === g   # false

Memoization.get_caches()[SymPy.integrate]

# output
Dict{Any, Any} with 2 entries:
  ((sin(a*t), (t, 0, t)), NamedTuple()) => Piecewise((-cos(a*t)/a + 1/a, (a > -
  ((sin(a*t), (t, 0, t)), NamedTuple()) => Piecewise((-cos(a*t)/a + 1/a, (a > -

If I call integrate_wrapper() again with (f, (t, 0, t) the cache does not grow. But if I create f = sin(a * t) again and then call integrate_wrapper(f, (t, 0, t)) again the cache does grow. Exactly the same behavious is observed when using @memoize integrate(args...; kwargs...) or @memoize LRU(maxcache=5) integrate(args...; kwargs...).

The same is true for many other SymPy functions.

@jlbosse jlbosse changed the title Memoization of SymPy function calls does recognize identical arguments Memoization of SymPy function calls does not recognize identical arguments Jul 25, 2023
@jlbosse
Copy link
Author

jlbosse commented Sep 18, 2023

I have done some more digging and it appears that Tuples containing SymPy.Syms don't work properly as keys in julia's standard Dicts. See the following MWE:

julia> using SymPy

julia> t = symbols("t");

julia> d = Dict();

julia> get!(d, (sin(t),), 0)
0

julia> get!(d, (sin(t),), 1)
1

julia> s = sin(t);

julia> get!(d, (s,), 2)
2

julia> get!(d, (s,), 3)
2

julia> (sin(t), ) in keys(d)
true

julia> haskey(d, (sin(t),))
false

julia> haskey(d, (s,))
true

@jlbosse
Copy link
Author

jlbosse commented Dec 27, 2023

This wasn't a Memoization.jl issue and got fixed with JuliaPy/SymPy.jl#520

@jlbosse jlbosse closed this as completed Dec 27, 2023
@marius311
Copy link
Owner

Thanks for following up on this, sorry for forgetting about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants