I'm kind of late jumping into this thread, but I have some concerns. Unless the factorization is known completely (or gcd's are taken on the unknown part), I still think this can lead to combinatorial explosion fairly quickly. For example,
sage: from sage.rings.fraction_field_cache import FractionField_cache sage: from sage.rings.fraction_field import FractionField_generic sage: R.<x,y,z>=QQ[] sage: T = [ZZ.random_element()*x + ZZ.random_element()*y + ZZ.random_element()*z for _ in range(10)]; sage: S = [prod(random_sublist(T, .2)) for _ in range(50)] sage: Q=FractionField_cache(R,auto_reduce=False) sage: time f = sum([~Q(s) for s in S]) CPU times: user 6.41 s, sys: 0.01 s, total: 6.42 s Wall time: 6.45 sage: len(str(f)) 2011614 sage: time f.reduce() ^C ### Got really tired of waiting after 10 min.... sage: sage: time f(2,3,4) CPU times: user 9.68 s, sys: 0.03 s, total: 9.71 s Wall time: 10.08 244271/26730 sage: sage: Q=FractionField_generic(R) sage: time f = sum([~Q(s) for s in S]) CPU times: user 0.15 s, sys: 0.00 s, total: 0.15 s Wall time: 0.15 sage: len(str(f)) 5430 sage: time f.reduce() # it's already reduced, but it doesn't know that CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 0.00 sage: time f(2,3,4) CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s Wall time: 0.00 244271/26730 That being said, I think it could maybe have its use, as could a general factored element ring (though I too can't think of any uses off the top of my head). - Robert On May 27, 2007, at 10:03 AM, Michel wrote: > Hi, > > The current implementation of fraction fields is slow. This is very > apparent for rings with a slow gcd algorithm. But even if this is not > the > case then constantly taking gcd's eventually becomes a major > bottleneck. > See the example below which uses the new libSingular. > > It was pointed out on this list that not taking gcd's at every step > quickly leads to combinatorial explosion when evaluating polynomials > with > a large number of terms. > > I think I have found a solution for this last problem. The trick is to > cache partial partial factorizations of denominators. I.e. for example > if we performa an addition a/b+c/d=(ad+cb)/ad then we remember that > the denominator > ad is really a*d. If next time we have to add (ad+cb)/ad+(c/d)^2 we > can > take as new denominator ad^2 instead of ad^3. > > I have created a new FractionField_cache implementation which uses > this idea. > See > http://emis.uhasselt.be/sage_patches/fraction_field_cache. > The specific patch is here > http://emis.uhasselt.be/sage_patches/fraction_field_cache/ > factor_cacheing.patch > It depends on the one_element patch by William. It creates three new > files > > factor_cache.pyx > fraction_field_cache.py > fraction_field_element_cache.py > > and modifies setup.py (to build the extension factor_cache). To use > the > new implementation do > > from sage.rings.fraction_field_cache import FractionField_cache > > Example (using the new libSingular) > > sage: from sage.rings.fraction_field_cache import FractionField_cache > sage: R.<x,y,z>=QQ[] > sage: Q=FractionField_cache(R,auto_reduce=False) > sage: def t():((x+y+z)**20)(Q(1,x+y),y,y**100).reduce() > .... > sage: time t() > CPU times: user 2.11 s, sys: 0.02 s, total: 2.13 s > Wall time: 2.27 <== compare this > > sage: from sage.rings.fraction_field import FractionField_generic > sage: Q=FractionField_generic(R) > sage: def t():((x+y+z)**20)(Q(1,x+y),y,y**100) > ... > sage: time t() > CPU times: user 12.49 s, sys: 0.06 s, total: 12.54 s > Wall time: 14.36 <== to this > > > For more benchmarks see > http://emis.uhasselt.be/sage_patches/fraction_field_cache/summary.log > http://emis.uhasselt.be/sage_patches/fraction_field_cache/ > benchmark.log > > Yet more benchmarks can be created with the following program > http://emis.uhasselt.be/sage_patches/fraction_field_cache/benchmark.py > > Notes: > (1) When testing, please be careful to use the constructor > Q(num,denom) to create > fractions. A FractionField_cache constructed using __init__ is of > course not globally unique. So fractions of the form num/denom will > live in a FractionField_generic and not in Q. > (2) I did not look at coercions although if there are problems they > should > be trivial to fix. > (3) The actual cacheing of partial factorizations of denominators > is done in the extension "factor_cache". Please read the docstring > there > for the implementation. > (4) I hope to write an implementation of the subresultant algorithm > for > poly_dicts (if someone else does not do it). Then every polynomial > ring will have a fallback gcd algorithm (if the base ring has one). > Although I think I can optimize it quite a bit this algorithm will > of course be slower than more specialized ones. For this I would > like the FractionField implementation to be more optimized. > > Question: What should I do now? I think the implementation of > FractionField_cache > improves upon the implementation of FractionField_generic. Please > give some feedback. > > Michel > > PS. I has been discussed to perform the final reduce only for example > if a fraction > is printed. I have not done this yet since it makes benchmarking > somewhat more > tricky. But I can do this if people think this is a better solution. > > > --~--~---------~--~----~------------~-------~--~----~ To post to this group, send email to sage-devel@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sage-devel URLs: http://sage.scipy.org/sage/ and http://modular.math.washington.edu/sage/ -~----------~----~----~----~------~----~------~--~---