On Friday, August 19, 2016 at 1:43:30 PM UTC-7, Joseph Hundley wrote:
>
> There are two reasons I was planning to have AbstractAlgebraicGroup be 
> UniqueRepresentation
> (1) The passage in this tutorial 
> <http://sporadic.stanford.edu/thematic_tutorials/coercion_and_categories.html>
>  which 
> reads
>
 
<snip>

It really depends on what you need to do to construct the parent. In most 
cases, you just end up storing some of the construction parameters. Reusing 
parents that were already constructed can save some memory, but the usual 
pattern is that you construct only a few parents, which get naturally 
passed around anyway. Reusing a parent that is handed to you is obviously 
much more efficient than reusing a parent by trying to get a hold of it via 
its construction parameters.So if you need UniqueRepresentation to limit 
the number of parents in memory, it's probably a good idea to think of ways 
of restructuring your computation (there may be cases where you can't, 
though).

Using UniqueRepresentation does force a upfront cost, though: construction 
parameters need to be processed so that they can be used for lookup in a 
global dictionary to see if equivalent parameters have already been used to 
construct such an object, and then this lookup needs to happen. In many 
scenarios this search will come up empty, in which case you've just 
incurred a cost without a direct gain. So whether UniqueRepresentation is a 
performance gainer really depends on the scenario. Most of the time it is 
not, so I'd say the rationale given in the tutorial is misleading.

 UniqueRepresentation is needed in the coercion framework: If two different 
sources produce polynomials in Q[x,y], the user would expect to be able to 
combine them because they look indistinguishable to the user. In the 
coercion framework it turned out to be much more efficient if the parents 
of those two polynomials ARE indeed equal. The construction parameters in 
this case are indeed easy to compare because it's just (Q,('x','y')), where 
Q is a UniqueRepresentation itself, so you can recognize it by identity 
itself.

As a consequence, if you're implementing a ring type that itself is likely 
to be used as a base ring for a polynomial ring (or matrices etc.), you 
should probably try to make it UniqueRepresentation. But otherwise it's not 
immediately clear you'll be getting a benefit from it.

(2) It seems to me to make sense mathematically, since, mathematically 
> speaking, the split connected reductive algebraic group with based root 
> datum B is a unique mathematical object. 
>

Yes, but in what category? and is it unique up to unique isomorphism?
 

> I admit I don't understand the "cost" of "non-locality"? Can you point me 
> somewhere I could read up on relevant issues? Are there rules of thumb for 
> when parents should and should not be UniqueRepresentation?
>

A possible example of the risks you run:
 Suppose

K=NumberField(<something large>)
K.compute_classgroup( method="heuristic and conditional") #[*]

<do stuff, delete K. Suppose K is not yet garbage collected>

L=NumberField(<same thing>) #this will now get you K back!!!
L.classgroup() #suppose this gets you the class group cached on L, i.e., 
the one computed at [*]
 
alternatively, if K had been garbage collected already

L=NumberField(<same thing>) #this is now a fresh version
L.classgroup() #no classgroup info cached, you trigger (unconditional) 
computation.

The fact that your result is now dependent on what happened to be in memory 
is of course very bad. It makes your system unreliable. That means that 
this pattern of "implement a computation routine that can use several 
heuristics" combined with "use by default whatever is cached" cannot be 
applied to UniqueRepresentation objects, because obviously, caching 
heuristic computation results modifies the state of your object in a 
noticeable way. UniqueRepresentation object need to take their immutability 
quite seriously.

In a different direction: is there a good place to read about how to make 
> something be hashable or implement _cache_key()?
>

Hashing in mathematics in general is hard, because you need a==b implies 
hash(a)==hash(b), and at the same time you need that a!=b usually implies 
hash(a)!=hash(b).

Due to coercion we can't actually do that:

http://www.sagemath.org/git-developer-guide/coding_in_python.html#the-hash-special-method

and it depends on what you want "a==b" to mean in your category whether 
it's easy to decide and whether you can find a function Category -> [-2^63 
.. 2^63-1] that's not too constant and respects the "==" equivalence.
There are categories in which we know that "a==b" in general is 
undecidable. It may be easy for BasedRootDatum (it certainly is in your 
reference implementation :-)).

-- 
You received this message because you are subscribed to the Google Groups 
"sage-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sage-devel+unsubscr...@googlegroups.com.
To post to this group, send email to sage-devel@googlegroups.com.
Visit this group at https://groups.google.com/group/sage-devel.
For more options, visit https://groups.google.com/d/optout.

Reply via email to