[GiNaC-devel] Fwd: Add method ex::symbols for obtaining all symbols appearing in an expression

Richard B. Kreckel kreckel at ginac.de
Tue Aug 14 09:54:17 CEST 2012


On 08/13/2012 10:31 AM, Timo Kluck wrote:
> On ma, aug 13, 2012 at 9:02 , Richard B. Kreckel<kreckel at ginac.de>  wrote:
>> Wouldn't it be better to go one step further and cache those variables when
>> the variables() function is first used? This avoids quite a lot of overhead in
>> space and time! And then, variables() wouldn't have to be a member
>> function, right?
>
> That is probably best, especially in the light of the (x+y) - y
> example that Alexei mentioned.
>
> I could easily do that in Sage, but I think it wouldn't help in my
> case because I'm constructing so many expressions.
>
> However, I'm thinking it may make sense to do that in GiNaC, because
> from what I've seen it has some sort of a copy-on-right mechanism for
> subexpressions? As in:
>
> f = sin(x+y)
> g = f * cos(x-y)
> h = f * tan(z)
>
> will make g and h share the instance (and therefore the cache!) for f?

Yes, that is right.

> Please correct me if I've misunderstood that. But if it has, this is
> abstracted away in Sage, so caching the variables() function in Sage
> would have much less benefit than caching it in GiNaC.
>
> I'm not sure whether this will actually give me any speed benefit in
> practice, because even though I'm using very similar subexpressions
> over and over again, I'm not sure if I could construct them as the
> same object without writing really awkward code. I'm interested in
> your opinions, though.

Hmm, note that even if you cannot construct them as one object they 
might end up as one object after a while (c.f. the private ex::share(ex) 
method). Whether that helps or doesn't help in your case depends on the 
actual use pattern.

There remains Alexei's worry that this is likely to substantially slow 
down all applications.

Optimization is full of surprises. In any case, you should experiment 
with different strategies and carefully observe their impact!

> So my next question is: would you accept a patch implementing a
> recursive, cached version of symbols(), for Sage to call directly, and
> then have responsibility for optimizing / caching that going to the
> level of GiNaC?

Well, any patch would have to go into Pynac, in order to be of advantage 
in Sage. Pynac is a fork of GiNaC. (In the past, we've repeatedly fixed 
Sage bugs in GiNaC and suggested patches for Pynac and vice-versa, but 
that doesn't mean that changes in GiNaC propagate automatically into 
Sage. At least I'm not aware of that.)

> I would normally think that it would be a method of ex (and basic).
> Where would you say the cache lives if it where a global function?

It should be possible to equip that global function with a static 
hashmap ex -> symbols. Of course, that opens a memory leak because the 
map is never cleaned up. So, as an alternative, one could maintain that 
map only while it can really speed up things: store it in an object and 
delete it when that object is destructed.

Cheers
   -richy.
-- 
Richard B. Kreckel
<http://www.ginac.de/~kreckel/>


More information about the GiNaC-devel mailing list