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

Great speedup in polytopes construction with generic backend #18241

Closed
videlec opened this issue Apr 17, 2015 · 32 comments
Closed

Great speedup in polytopes construction with generic backend #18241

videlec opened this issue Apr 17, 2015 · 32 comments

Comments

@videlec
Copy link
Contributor

videlec commented Apr 17, 2015

Construction of polytopes with number field coordinates are very slow. There are several reasons for that:

After applying the branch the speedup is really cool. Using polyhedron_test.py I got

Before

sage: %runfile polyhedron_test.py
sage: %time gr = great_rhombicuboctahedron()
CPU times: user 4.66 s, sys: 24 ms, total: 4.68 s
Wall time: 4.66 s

After

sage: %runfile polyhedron_test.py
sage: %time gr = great_rhombicuboctahedron()
CPU times: user 292 ms, sys: 28 ms, total: 320 ms
Wall time: 306 ms

(But I am still not able to build the 600-cell)

Modifications with the branch:

  1. In the double description file

    • use itertools instead of whatever sage/combinat/*
    • use base_ring.zero() and base_ring.one() instead of the Python integer 0 and 1. That prevents many coercions.
    • make the method add_inequality so that the object is changed inplace instead of returning a new instance. I had to change the type of the attribute from tuples to lists.
    • add a cache for matrix spaces (see constructing matrices is very slow #18231). These are the methods _matrix_space and _matrix
    • implement a cache for the method .zero_set (note that this was needed because the object is no more immutable, self.A will grow in add_inequality)
  2. Start with a trivial case in NumberField.__cmp__.

Depends on #18215

CC: @vbraun @nathanncohen

Component: geometry

Author: Vincent Delecroix

Branch/Commit: c5b15bf

Reviewer: Nathann Cohen

Issue created by migration from https://trac.sagemath.org/ticket/18241

@videlec videlec added this to the sage-6.7 milestone Apr 17, 2015
@videlec
Copy link
Contributor Author

videlec commented Apr 17, 2015

Branch: u/vdelecroix/18241

@videlec
Copy link
Contributor Author

videlec commented Apr 17, 2015

New commits:

3ec20b4Trac 18215: Faster hash for quadratic number fields
562d81aTrac 18241: better double description (Hrep2Vrep, Vrep2Hrep)
e28fdffTrac 18241: tiny modifs in constructor/parent
99c6708Trac 18241: trivial case in NumberField.__cmp__

@videlec

This comment has been minimized.

@videlec
Copy link
Contributor Author

videlec commented Apr 17, 2015

Commit: 99c6708

@videlec
Copy link
Contributor Author

videlec commented Apr 17, 2015

Author: Vincent Delecroix

@videlec
Copy link
Contributor Author

videlec commented Apr 17, 2015

comment:2

Attachment: polyhedron_test.py.gz

@videlec

This comment has been minimized.

@nathanncohen
Copy link
Mannequin

nathanncohen mannequin commented Apr 18, 2015

comment:3

Could you say in the ticket's description what the branch does?

Every single thing that you do without explanation, the reviewer has to figure out from the diff file.

@videlec
Copy link
Contributor Author

videlec commented Apr 18, 2015

comment:4

Replying to @nathanncohen:

Could you say in the ticket's description what the branch does?

Every single thing that you do without explanation, the reviewer has to figure out from the diff file.

done!

@videlec

This comment has been minimized.

@nathanncohen
Copy link
Mannequin

nathanncohen mannequin commented Apr 18, 2015

comment:5

Looks like your mutable object is also hashable

sage: DD.__hash__()
1042963791458606606
sage: DD.add_inequality(vector([1,0,0]))
sage: DD.__hash__()
-1000165618804906370

@videlec
Copy link
Contributor Author

videlec commented Apr 18, 2015

comment:6

Replying to @nathanncohen:

Looks like your mutable object is also hashable

sage: DD.__hash__()
1042963791458606606
sage: DD.add_inequality(vector([1,0,0]))
sage: DD.__hash__()
-1000165618804906370

F!!!** Sage objects!

cdef class SageObject:
...
    def __hash__(self):
        return hash(self.__repr__())

@nathanncohen
Copy link
Mannequin

nathanncohen mannequin commented Apr 18, 2015

comment:7

Unless all SageObject must be immutable, I guess that it should be removed (in another ticket that will become another war)

@nathanncohen
Copy link
Mannequin

nathanncohen mannequin commented Apr 18, 2015

comment:8

Actually, no...

sage: class A:
....:     pass
sage: hash(A())
-9223363253024015589

We should probably make SageObject.__hash__ raise a NotImplementedError

@videlec
Copy link
Contributor Author

videlec commented Apr 18, 2015

comment:9

Replying to @nathanncohen:

Actually, no...

sage: class A:
....:     pass
sage: hash(A())
-9223363253024015589

We should probably make SageObject.__hash__ raise a NotImplementedError

Or

class A:
    __hash__ = None

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Apr 18, 2015

Branch pushed to git repo; I updated commit sha1. New commits:

3c573aeTrac 18241: simpler import + remove SageObject inheritance

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Apr 18, 2015

Changed commit from 99c6708 to 3c573ae

@nathanncohen
Copy link
Mannequin

nathanncohen mannequin commented Apr 18, 2015

comment:12

About this branch:

  • zero_set: why don't you just call DD.zero_set.clear_cache() instead of rewriting the caching mechanism? If you do want to keep this self.cache please make the name more specific.

  • A_matrix : returns a pointer toward a mutable internal object.

  • Err

    Add an inequality to the double description with the inequality ``a``
    added.
    
  • I do not like this '_matrix' function very much. Its name is not very clear (matrix_from_cached_vector_space?) but what about just doing this 'if' twice (it is called twice)?

Nathann

@videlec
Copy link
Contributor Author

videlec commented Apr 18, 2015

comment:13

Replying to @nathanncohen:

About this branch:

  • zero_set: why don't you just call DD.zero_set.clear_cache() instead of rewriting the caching mechanism? If you do want to keep this self.cache please make the name more specific.

Nope. If you call the function with the same ray argument you do not want to recompute it from scratch.

  • I do not like this '_matrix' function very much. Its name is not very clear (matrix_from_cached_vector_space?) but what about just doing this 'if' twice (it is called twice)?

Me neither. That's why I opened #18231. The function just constructs a matrix, why the name is badly chosen? You will get the very same answer as calling matrix(self.problem.base_ring(), data). Except that it is faster. What about .build_matrix and .build_matrix_space?

I do not understand you remark about the if.

@nathanncohen
Copy link
Mannequin

nathanncohen mannequin commented Apr 18, 2015

comment:14

Hello,

Nope. If you call the function with the same ray argument you do not want to recompute it from scratch.

Oh, okay. Then change the cache's name please

  • I do not like this '_matrix' function very much. Its name is not very clear (matrix_from_cached_vector_space?) but what about just doing this 'if' twice (it is called twice)?

Me neither. That's why I opened #18231.

Then should it be really fixed inside of this class? Or do we keep this code as it is and try to solve the #18231 instead.

The function just constructs a matrix, why the name is badly chosen? You will get the very same answer as calling matrix(self.problem.base_ring(), data). Except that it is faster.

Precisely because the name does not reflect the difference. matrix_from_cached_vector_space does.

What about .build_matrix and .build_matrix_space?

I hate this class already.

I do not understand you remark about the if.

Oh. Well, because all that 'matrix' does is a if. If it is not a function of its own, you just have to copy this 'if' around.

Nathann

@nathanncohen nathanncohen mannequin removed the s: needs review label Apr 18, 2015
@nathanncohen nathanncohen mannequin added the s: needs work label Apr 18, 2015
@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Apr 18, 2015

Branch pushed to git repo; I updated commit sha1. New commits:

770ad60Trac 18241: move code in double_description.py

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Apr 18, 2015

Changed commit from 3c573ae to 770ad60

@videlec
Copy link
Contributor Author

videlec commented Apr 18, 2015

comment:17
  • I get rid of def _matrix and move Problem._matrix_space -> DoubleDescription.matrix_space.
  • I changed .cache -> .zero_set_cache
  • I modified the output of zero_set to return Python sets instead of tuple (since the most important operation on them is the intersection)

Needs review again.

@nathanncohen
Copy link
Mannequin

nathanncohen mannequin commented Apr 18, 2015

comment:18

Yoooooooooooooo !

Looks good, almost good to go. Just two things:

  • This sentence repeats itself

    Add an inequality to the double description with the inequality ``a``
    added.
    
  • What is the difference between those two lines?

    lines = self._linear_subspace.matrix().rows()
    lines = self._linear_subspace.basis_matrix().rows()
    

Nathann

@videlec
Copy link
Contributor Author

videlec commented Apr 18, 2015

comment:20

Hello,

Replying to @nathanncohen:

  • What is the difference between those two lines?

    lines = self._linear_subspace.matrix().rows()
    lines = self._linear_subspace.basis_matrix().rows()
    

linear_subspace.matrix calls linear_subspace.basis_matrix. Having aliases is cool, but avoiding using them is cooler ;-)

Vincent

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Apr 18, 2015

Changed commit from 770ad60 to c5b15bf

@sagetrac-git
Copy link
Mannequin

sagetrac-git mannequin commented Apr 18, 2015

Branch pushed to git repo; I updated commit sha1. New commits:

2fba20cTrac 18241: avoid a repetition in the doc
bee81efTrac 18215: fix a failing doctest
c5b15bfTrac 18241: merge failing doctest from #18215

@nathanncohen
Copy link
Mannequin

nathanncohen mannequin commented Apr 18, 2015

comment:23

Okayyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy

@videlec
Copy link
Contributor Author

videlec commented Apr 18, 2015

comment:24

Replying to @nathanncohen:

Okayyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy

Great! Thanks. It becomes reasonable to start using the generic backend.

Next step: avoid the recomputation of vertices! The algorithm is currently

INPUT: vertices
OUTPUT: (vertices, hyperplanes)
ALGO:
  1. compute hyperplanes from vertices (with no redundancy)
  2. recompute vertices from hyperplanes (with no redundancy)
  3. return (vertices, hyperplanes)

And it is precisely step 2 which takes an infinite amount of time for the 600-cell!

@vbraun
Copy link
Member

vbraun commented Apr 18, 2015

comment:25

reviewer name

@nathanncohen
Copy link
Mannequin

nathanncohen mannequin commented Apr 19, 2015

Reviewer: Nathann Cohen

@vbraun
Copy link
Member

vbraun commented Apr 19, 2015

Changed branch from u/vdelecroix/18241 to c5b15bf

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

No branches or pull requests

2 participants