Skip to main content

Cone Class

This class handles all computations relating to rational polyhedral cones, such cone duality and extremal ray computations. It is mainly used for the study of Kähler and Mori cones.

warning

This class is primarily tailored to pointed (i.e. strongly convex) cones. There are a few computations, such as finding extremal rays, that may produce some unexpected results when working with non-pointed cones. Additionally, cones that are not pointed, and whose dual is also not pointed, are not supported since they are uncommon and difficult to deal with.

Constructor

cytools.cone.Cone

Description: Constructs a Cone object. This is handled by the hidden __init__ function.

Arguments:

  • rays (array_like, optional): A list of rays that generates the cone. If it is not specified then the hyperplane normals must be specified.
  • hyperplanes (array_like, optional): A list of inward-pointing hyperplane normals that define the cone. If it is not specified then the generating rays must be specified.
  • check (bool, optional, default=True): Whether to check the input. Recommended if constructing a cone directly.
note

Exactly one of rays or hyperplanes must be specified. Otherwise an exception is raised.

Example

We construct a cone in two different ways. First from a list of rays then from a list of hyperplane normals. We verify that the two inputs result in the same cone.

from cytools import Cone
c1 = Cone([[0,1],[1,1]]) # Create a cone using rays. It can also be done with Cone(rays=[[0,1],[1,1]])
c2 = Cone(hyperplanes=[[1,0],[-1,1]]) # Create a cone using hyperplane normals.
c1 == c2 # We verify that the two cones are the same.
# True

Functions

ambient_dimension

Description: Returns the dimension of the ambient lattice.

Arguments: None.

Returns: (int) The dimension of the ambient lattice.

Aliases: ambient_dim.

Example

We construct a cone and find the dimension of the ambient lattice.

c = Cone([[0,1,0],[1,1,0]])
c.ambient_dimension()
# 3

clear_cache

Description: Clears the cached results of any previous computation.

Arguments: None.

Returns: Nothing.

Example

We construct a cone, compute its extremal rays, clear the cache and then compute them again.

c = Cone([[1,0],[1,1],[0,1]])
c.extremal_rays()
# array([[0, 1],
# [1, 0]])
c.clear_cache() # Clears the cached result
c.extremal_rays() # The extremal rays recomputed
# array([[0, 1],
# [1, 0]])

dimension

Description: Returns the dimension of the cone.

Arguments: None.

Returns: (int) The dimension of the cone.

Aliases: dim.

Example

We construct a cone and find its dimension.

c = Cone([[0,1,0],[1,1,0]])
c.dimension()
# 2

dual_cone

Description: Returns the dual cone.

Arguments: None.

Returns: (Cone) The dual cone.

Aliases: dual.

Example

We construct a cone and find its dual cone.

c = Cone([[0,1],[1,1]])
c.dual_cone()
# A rational polyhedral cone in RR^2 defined by 2 hyperplanes normals
c.dual_cone().rays()
# array([[ 1, 0],
# [-1, 1]])

extremal_rays

Description: Returns the extremal rays of the cone.

note

By default, this function will use as many CPU threads as there are available. To fix the number of threads, you can set the n_threads variable in the config submodule.

Arguments:

  • tol (float, optional, default=1e-4): Specifies the tolerance for deciding whether a ray is extremal or not.
  • verbose (bool, optional, default=False): When set to True it show the progress while finding the extremal rays.

Returns: (numpy.ndarray) The list of extremal rays of the cone.

Example

We construct a cone and find its extremal_rays.

c = Cone([[0,1],[1,1],[1,0]])
c.extremal_rays()
# array([[0, 1],
# [1, 0]])

find_grading_vector

Description: Finds a grading vector for the cone, i.e. a vector v\mathbf{v} such that any non-zero point in the cone p\mathbf{p} has a positive dot product vp>0\mathbf{v}\cdot\mathbf{p}>0. Thus, the grading vector must be strictly interior to the dual cone, so it is only defined for pointed cones. This function returns an integer grading vector.

Arguments:

  • backend (str, optional, default=None): String that specifies the optimizer to use. The options are the same as for the find_interior_point function.

Returns: (numpy.ndarray) A grading vector. If it could not be found then None is returned.

Example

We construct a cone and find a grading vector.

c = Cone([[3,2],[5,3]])
c.find_grading_vector()
# array([-1, 2])

find_interior_point

Description: Finds a point in the strict interior of the cone. If no point is found then None is returned.

Arguments:

  • c (float, optional, default=1): A real positive number specifying the stretching of the cone (i.e. the minimum distance to the defining hyperplanes).
  • backend (str, optional, default=None): String that specifies the optimizer to use. Options are "glop", "scip", "cpsat", "mosek", "osqp", and "cvxopt". If it is not specified then "glop" is used by default. For d50d\geq50 it uses "mosek" if it is activated.
  • integral (bool, optional, default=False): A flag that specifies whether the point should have integral coordinates.

Returns: (numpy.ndarray) A point in the strict interior of the cone. If no point is found then None is returned.

Example

We construct a cone and find some interior points.

c = Cone([[3,2],[5,3]])
c.find_interior_point()
# array([4. , 2.5])
c.find_interior_point(integral=True)
# array([8, 5])

hyperplanes

Description: Returns the inward-pointing normals to the hyperplanes that define the cone.

Arguments: None.

Returns: (numpy.ndarray) The list of inward-pointing normals to the hyperplanes that define the cone.

Example

We construct two cones and find their hyperplane normals.

c1 = Cone([[0,1],[1,1]])
c2 = Cone(hyperplanes=[[0,1],[1,1]])
c1.hyperplanes()
# array([[ 1, 0],
# [-1, 1]])
c2.hyperplanes()
# array([[0, 1],
# [1, 1]])

rays

Description: Returns the (not necessarily extremal) rays that generate the cone.

Arguments: None.

Returns: (numpy.ndarray) The list of rays that generate the cone.

Example

We construct two cones and find their generating rays.

c1 = Cone([[0,1],[1,1]])
c2 = Cone(hyperplanes=[[0,1],[1,1]])
c1.rays()
# array([[0, 1],
# [1, 1]])
c2.rays()
# array([[ 1, 0],
# [-1, 1]])

tip_of_stretched_cone

Description: Finds the tip of the stretched cone. The stretched cone is defined as the convex polyhedral region inside the cone that is at least a distance c from any of its defining hyperplanes. Its tip is defined as the point in this region with the smallest norm.

note

This is a problem that requires quadratic programming since the norm of a vector is being minimized. For dimensions up to around 50, this can easily be done with open-source solvers like OSQP or CVXOPT, however for higher dimensions this becomes a difficult task that only the Mosek optimizer is able to handle. However, Mosek is closed-source and requires a license. For this reason we preferentially use ORTools, which is open-source, to solve a linear problem and find a good approximation of the tip. Nevertheless, if Mosek is activated then it uses Mosek as it is faster and more accurate.

Arguments:

  • c (float): A real positive number specifying the stretching of the cone (i.e. the minimum distance to the defining hyperplanes).
  • backend (str, optional, default=None): String that specifies the optimizer to use. Options are "mosek", "osqp", "cvxopt", and "glop". If it is not specified then for d<50d<50 it uses "osqp" by default. For d50d\geq50 it uses "mosek" if it is activated, or "glop" otherwise.
  • check (bool, optional, default=True): Flag that specifies whether to check if the output of the optimizer is consistent and satisfies constraint_error_tol.
  • constraint_error_tol (float, optional, default=1e-2): Error tolerance for the linear constraints.

Returns: (numpy.ndarray) The vector specifying the location of the tip. If it could not be found then None is returned.

Example

We construct two cones and find the locations of the tips of the stretched cones.

c1 = Cone([[1,0],[0,1]])
c2 = Cone([[3,2],[5,3]])
c1.tip_of_stretched_cone(1)
# array([1., 1.])
c2.tip_of_stretched_cone(1)
# array([8., 5.])

Hidden Functions

__eq__

Description: Implements comparison of cones with ==.

note

The comparison of cones that are not pointed, and whose duals are also not pointed, is not supported.

Arguments:

  • other (Cone): The other cone that is being compared.

Returns: (bool) The truth value of the cones being equal.

Example

We construct two cones and compare them.

c1 = Cone([[0,1],[1,1]])
c2 = Cone(hyperplanes=[[1,0],[-1,1]])
c1 == c2
# True

__hash__

Description: Implements the ability to obtain hash values from cones.

note

Cones that are not pointed, and whose duals are also not pointed, are not supported.

Arguments: None.

Returns: (int) The hash value of the cone.

Example

We compute the hash value of a cone. Also, we construct a set and a dictionary with a cone, which make use of the hash function.

c = Cone([[0,1],[1,1]])
h = hash(c) # Obtain hash value
d = {c: 1} # Create dictionary with cone keys
s = {c} # Create a set of cones

__init__

Description: Initializes a Cone object.

Arguments:

  • rays (array_like, optional): A list of rays that generates the cone. If it is not specified then the hyperplane normals must be specified.
  • hyperplanes (array_like, optional): A list of inward-pointing hyperplane normals that define the cone. If it is not specified then the generating rays must be specified.
  • check (bool, optional, default=True): Whether to check the input. Recommended if constructing a cone directly.
  • copy (bool, optional, default=True): Whether to ensure we copy the input rays/hyperplanes. Recommended.
note

Exactly one of rays or hyperplanes must be specified. Otherwise, an exception is raised.

Returns: Nothing.

Example

This is the function that is called when creating a new Cone object. We construct a cone in two different ways. First from a list of rays then from a list of hyperplane normals. We verify that the two inputs result in the same cone.

from cytools import Cone
c1 = Cone([[0,1],[1,1]]) # Create a cone using rays. It can also be done with Cone(rays=[[0,1],[1,1]])
c2 = Cone(hyperplanes=[[1,0],[-1,1]]) # Create a cone using hyperplane normals.
c1 == c2 # We verify that the two cones are the same.
# True

__ne__

Description: Implements comparison of cones with !=.

note

The comparison of cones that are not pointed, and whose duals are also not pointed, is not supported.

Arguments:

  • other (Cone): The other cone that is being compared.

Returns: (bool) The truth value of the cones being different.

Example

We construct two cones and compare them.

c1 = Cone([[0,1],[1,1]])
c2 = Cone(hyperplanes=[[1,0],[-1,1]])
c1 != c2
# False

__repr__

Description: Returns a string describing the polytope.

Arguments: None.

Returns: (str) A string describing the polytope.

Example

This function can be used to convert the Cone to a string or to print information about the cone.

c = Cone([[1,0],[1,1],[0,1]])
cone_info = str(c) # Converts to string
print(c) # Prints cone info
# A 2-dimensional rational polyhedral cone in RR^2 generated by 3 rays