sagemath / sage

Main repository of SageMath
https://www.sagemath.org
Other
1.41k stars 475 forks source link

Containers for families of geometric objects #32170

Open mkoeppe opened 3 years ago

mkoeppe commented 3 years ago

We define APIs for static and dynamic containers storing finite families of geometric objects, extending Container, Set, MutableSet, Mapping, MutableMapping https://docs.python.org/3/library/collections.abc.html

The family must define a collection of "measurement maps" B_i, each sending an object to an InternalRealInterval.

The product of these intervals can be thought of as a "generalized bounding box".

Ideally the maps would be inclusion-preserving.

The implementation is provided by rtree/libspatialindex (#32000).

The Sage-specific class will take care of:

Geometric lookup operations to be supported:

Applications:

Depends on #34277

CC: @DRKWang

Component: geometry

Work Issues: Rebase on #34277

Author: Binshuai Wang

Branch/Commit: public/32170 @ 05ea99d

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

DRKWang commented 3 years ago
comment:48

For the rtree.intersection() function, we can make the return objects of it either a list of boxes with an rtree data structure or a set of boxes without any structure. we can build a flag, like rtree_rebuilt = true/false to indicate the intention of it. Concretely, the boxes with an rtree data structure will be rebuilt by the class of rtree that we defined.

DRKWang commented 3 years ago
comment:49

For the static construction, we may build the rtree by 3 ways, top-down, bottom-up or hybrid. Supposedly, there are $n$ boxes in $k$ dimension for construction.

The idea of top-down should be made by recursive operation, which means the parent tree will be built after their children's trees were built. My expectation will be something like an H tree (https://en.wikipedia.org/wiki/H_tree), which has a property of self-similar fractal, or like a $k-D tree$. Anyway, the similarity of the subsets of boxes can be displayed on the rtree. Concretely, one way to do this is as follows:

  1. Separate the whole boxes into 2 subsets, equivalently in terms of numbers, based on their X-coordinate. And take those 2 subsets as the materials for building the left sub-rtree and right sub-rtree.
  2. Cyclically switch the criteria from x-coordinate to y-coordinate, to z-coordinate with separating the subsets smaller and smaller until the number of subsets equal 1. For this case, the complexity of it will be $nlog(n)+2 n/2 log(n/2) + 4 n/2 log(n/4) + ... + n1 log(1) <= n log(n) log(n) $

For the bottom-up, we may use the greedy strategy to do the local optimization on each step. We can always merge two boxes based on some criteria, like merging the two boxes that have minimal 1-norm distance. And replace the 2 boxes with merged box, so that the size of the input will be decreased by 1, (now the number of boxes will be $n-1$). Thus, after $n-1$ steps, the rtree will be built completely.

The complexity will be at least n^2, since we will compute the distance at least.

For the hybrid one, we can build the rtree partially by top-down and partially by bottom-up in certain steps. But, how to combining them adaptively is still a hard problem for me. I would like to implement the first two before thinking about the third one.

DRKWang commented 2 years ago
comment:50

The following content in latex form can be checked in this link.(https://github.com/DRKWang/cutgeneratingfunctions_new/blob/main/logsfile/log48.ipynb)

To determine whether a given fan is a pointed fan or not, we may encode it into an linear optimization.

Observation:

If a fan is pointed, then there exists a containing-the-original-point hyperplane that could divide the space into 2 half-spaces, one containing the fan and the other not.

Analysis:

We may think about finding the normal vector of this hyperplane via optimzation. Let us encode it.

Supposing that the normal vector of this hyperplane is $x$ and 1-norm vectors of the generating rays of all cones in the fan are $r_i, i\in A $,

then we may have let the constraints be:

$x \cdot r_i \ge 0$

Since we do not hope to get $x = 0$, we may add an extra constraint, $x_1 = 1$, for getting one representing element.

If we can not find any solution for this system, then the fan is not pointed. If we can find one solution, then the fan is pointed.

In practice, in order to give a initial solution for simplex method, we may change the system into the following form:

max. : $x_1$

s.t.

$x \cdot r_i \ge 0$

$1\ge x_1 \ge 0$

As is desired, $x = 0$ always be the solution for this system.

A better hyperplane for generating better projection

Seemingly, we may have optional hyperplanes for the same system. The ideal hyperplane would be constraints are all $>$, instead of $\ge$. We may get rid of $x_1 = 1$ and add a little "balance" for each constraints to get it. i.e.

$x \cdot r_i - b_i\ge 0$

$b_i$ are all some given small positive numbers.

Similarly, in order to have a initial solution, we may change the system into the following form:

max. :$ b_0$

$x \cdot r_i - b_i\ge 0$

$b_i \ge b_0$

$1\ge b_0 \ge 0$

As is desired, $x = 0$ always be the solution for this system.

DRKWang commented 2 years ago
comment:51

Except for the above view, we may think differently from the view of the convex hull of the fan, but it will be much harder than the above one, in terms of implementation and theory.

Based on the following observation, we can have:

If the convex hull of the fan is the universal space, then it is not pointed; otherwise, it is pointed.

Thus, we can figure out the convex hull to determine whether it is pointed or not.

In the beginning, my imagination to compute the convex hull will be the "Graham scan method", a popular method for computing the convex hull in 2 dimensions. But when it comes to high dimensions, this algorithm will fail and be replaced by an algorithm called "Quickhull", (https://en.wikipedia.org/wiki/Quickhull), for computing the convex hull. This algorithm is a little randomized for initial selection and a little bit complicated understanding. And in terms of performance, although this algorithm may recursively get the convex hull, we still need to compute the normal vector for the hyperplane, onto which the fan will be projected, based on the above optimization.

DRKWang commented 2 years ago
comment:52

As is enlightened by your idea for considering the double descriptions of cones, facets, and generating rays, we may have a facets-based method to find the proper normal vector of the separating hyperplane for a pointed fan.

Observation:

For a cone, a ray is in the (interior or boundary) of its polar cone, if and only if, the ray can induce (an interior or a boundary) separating hyperplane, whose normal vector is the ray, for this cone.

Note that the polar cone of cone $C$ is defined by the negative dual cone of cone $C$, i.e.

the polar cone of cone $C$ = ${y | y\cdot x \le 0, \forall x \in C}$

Thus, to figure out the separating hyperplane for a fan, the polar cones of cones in this fan can provide help.

Observation:

For a fan, a ray is in the interior points of the common intersection of all polar cones of the fan, if and only if, the ray can induce an interior separating hyperplane for the fan.

Proof

A ray is in the interior points of the common intersection of all polar cones,

$\iff$ it must be in the interior points of each polar cone,

$\iff$ it must induce the same interior separating hyperplane for each cone in the fan,

$\iff$ it must induce an interior separating hyperplane for the fan.

Thus, we can have a better understanding of the location of the normal vector of separating hyperplane for a fan. Meanwhile, we can also use it to determine whether a fan is a pointed fan or not.

DRKWang commented 2 years ago
comment:53

Based on these testing records https://github.com/DRKWang/cutgeneratingfunctions_new/blob/main/test_for_facets_and_generating_rays_based_methods.ipynb, in terms of time, the generating-rays-based method has significantly outperformed the facets-based method. However, according to test 4 in the above records, the LP-solver may have some numerical issues and it may lead to some inaccurate determination.

In my two cents, since LP-solver only takes a little time and the solution for the linear programming can be easily verified, we may use the LP-solver first to try to get a solution, if it fails or it only gives zero solution, then we use the facets-based method instead; otherwise, if the solution is non-zero, we may verify its correctness, and if the solution is correct, then we are home and we do not need the facets-based method. This mixed-method is better than the pure facets-based method especially in the case that the fan is pointed because in that case, it is really difficult to compute common intersection for all cones with keeping in analytical status according to the testing records.

DRKWang commented 2 years ago
comment:54

Apart from the function contains(), I just realized that the class RationalPolyhedralFan also has another function support_contains(self,*args), which is used for checking if a point is contained in the support of the fan, and the support of a fan is the union of all cones of the fan. This function is pretty good for the usage of rtree, and based on the following test results, https://github.com/DRKWang/cutgeneratingfunctions_new/blob/main/fan_rtree_test.ipynb, it shows that the support of rtree gives better performance than the original one. The only disadvantage is that the construction of rtree in the initial part may take a little longer time. But based on the test results, it only takes extra at most 1/3 time compared with the original one, which is much smaller than saving time for using support_contains(self,*args).

7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 2 years ago

Changed commit from d160842 to ebe6d92

7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 2 years ago

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

c9b20a0fixed the rtree's checksum
078f823adding self.polar() for class ConvexRationalPolyhedralCone()
ebe6d92add subclass: RationalPolyhedralFan_rtree for function support_contains().
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 2 years ago

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

a2fa0baFixed bugs in docstring.
7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 2 years ago

Changed commit from ebe6d92 to a2fa0ba

mkoeppe commented 2 years ago

Author: Binshuai Wang

7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 2 years ago

Changed commit from a2fa0ba to 05ea99d

7ed8c4ca-6d56-4ae9-953a-41e42b4ed313 commented 2 years ago

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

05ea99dFixed the failed examples in Class.
mkoeppe commented 2 years ago
comment:60

Docbuild fails

OSError: /sage/local/var/lib/sage/venv-python3.10.2/lib/python3.10/site-packages/sage/geometry/cone.py:docstring of sage.geometry.cone.ConvexRationalPolyhedralCone.polar:6: WARNING: Bullet list ends without a blank line; unexpected unindent.
mkoeppe commented 2 years ago

Dependencies: #34277

mkoeppe commented 2 years ago

Work Issues: Rebase on #34277