-
-
Notifications
You must be signed in to change notification settings - Fork 677
Description
This patch adds support for a PointCollection class, which is not yet used for anything, but I propose switching cones and fans to it and plan to extensively use it in the rewrite of lattice polytopes.
Module level documentation explains the benefits, basically, it is an "enhanced but still fast tuple" which will allow uniform treatment of things like ray generators, lattice points, and normals. Instead of writing
sage: cone.rays()
sage: cone.ray_matrix()
sage: cone.ray_set()
sage: cone.lines()
sage: cone.line_matrix()
sage: cone.line_set()
which requires 6 different methods (and more for facet normals and vertices/points of polytopes), one will be able to use
sage: cone.rays()
sage: cone.rays().matrix()
sage: cone.rays().set()
sage: cone.lines()
sage: cone.lines().matrix()
sage: cone.lines().set()
which uses only special methods for cones (plus 2 for point collections).
Another good point will be elimination of IntegralRayCollection class which is currently the common base of cones and fans, which seemed to be convenient, but is definitely a bit weird.
To make sure that the transition is painless, this ticket will only add the new class, while transition will be done in a consecutive one, with all the proper deprecations etc. The doctests show how cone.rays() will eventually behave.
Regarding speed: there is Sequence class which does a similar thing, "Sagifying" lists and tuples. But it is very slow in construction (1000 times with checks on, 20 times with checks off compared to tuples, my class is only 2 times slower) and two times slower than tuples in access (mine is as fast as tuples):
sage: from sage.geometry.point_collection import PointCollection
sage: f = toric_varieties.dP6xdP6().fan()
sage: timeit("PointCollection(f.rays())", number=1000, repeat=100)
1000 loops, best of 100: 3.59 µs per loop
sage: timeit("tuple(f.rays())", number=1000, repeat=100)
1000 loops, best of 100: 1.62 µs per loop
sage: timeit("seq(f.rays())", number=100, repeat=10)
100 loops, best of 10: 1.49 ms per loop
sage: timeit("seq(f.rays(), f.lattice(), check=False)", number=1000, repeat=100)
1000 loops, best of 100: 39.3 µs per loop
sage: pc = PointCollection(f.rays())
sage: timeit("pc[5]", number=1000, repeat=100)
1000 loops, best of 100: 561 ns per loop
sage: pct = tuple(f.rays())
sage: timeit("pct[5]", number=1000, repeat=100)
1000 loops, best of 100: 547 ns per loop
sage: pcs = seq(f.rays(), f.lattice(), check=False)
sage: timeit("pcs[5]", number=1000, repeat=100)
1000 loops, best of 100: 1.16 µs per loop
While plain tuples are still the fastest, I think that benefits of the proposed class worth the associated penalty (which is not the case for sequences). In fact, I think that overall speed will improve due to better cache sharing.
Component: geometry
Author: Andrey Novoseltsev
Reviewer: Volker Braun
Merged: sage-5.0.beta6
Issue created by migration from https://trac.sagemath.org/ticket/11400