from sage.all import *
+def drop_dependent(vs):
+ r"""
+ Return the largest linearly-independent subset of ``vs``.
+ """
+ if len(vs) == 0:
+ # ...for lazy enough definitions of linearly-independent
+ return vs
+
+ result = []
+ old_V = VectorSpace(vs[0].parent().base_field(), 0)
+
+ for v in vs:
+ new_V = span(result + [v])
+ if new_V.dimension() > old_V.dimension():
+ result.append(v)
+ old_V = new_V
+
+ return result
+
+
def basically_the_same(K1,K2):
r"""
``True`` if ``K1`` and ``K2`` are basically the same, and ``False``
# Create the space W \times W^{\perp} isomorphic to V.
# First we get an orthogonal (but not normal) basis...
M = matrix(V.base_field(), K.rays())
- W_basis,_ = M.gram_schmidt()
+ W_basis = drop_dependent(K.rays())
W = V.subspace_with_basis(W_basis)
W_perp = W.complement()
return (phi,phi_inv)
-
-def unrestrict_span(K, K2=None):
- if K2 is None:
- K2 = K
-
- _,phi_inv = ips_iso(K2)
- V_iso = iso_space(K2)
- (W, W_perp) = V_iso.cartesian_factors()
-
- rays = []
- for r in K.rays():
- w = sum([ r[idx]*W.basis()[idx] for idx in range(0,len(r)) ])
- pair = V_iso( (w, W_perp.zero()) )
- rays.append( phi_inv(pair) )
-
- L = ToricLattice(W.dimension() + W_perp.dimension())
-
- return Cone(rays, lattice=L)
-
-
-
-def restrict_span(K, K2=None):
+def rho(K, K2=None):
r"""
Restrict ``K`` into its own span, or the span of another cone.
sage: K_S.lattice_dim() == K.dual().dim()
True
- This function has ``unrestrict_span()`` as its inverse::
-
- sage: set_random_seed()
- sage: K = random_cone(max_dim = 8, solid=True)
- sage: J = restrict_span(K)
- sage: K == unrestrict_span(J,K)
- True
-
This function should not affect the dimension of a cone::
sage: set_random_seed()
return K.linear_subspace().dimension()
-def codim(K):
- r"""
- Compute the codimension of this cone.
-
- The codimension of a cone is the dimension of the space of all
- elements perpendicular to every element of the cone. In other words,
- the codimension is the difference between the dimension of the
- ambient space and the dimension of the cone itself.
-
- OUTPUT:
-
- A nonnegative integer representing the dimension of the space of all
- elements perpendicular to this cone.
-
- .. seealso::
-
- :meth:`dim`, :meth:`lattice_dim`
-
- EXAMPLES:
-
- The codimension of the nonnegative orthant is zero, since the span of
- its generators equals the entire ambient space::
-
- sage: K = Cone([(1,0,0), (0,1,0), (0,0,1)])
- sage: codim(K)
- 0
-
- However, if we remove a ray so that the entire cone is contained
- within the `x-y`-plane, then the resulting cone will have
- codimension one, because the `z`-axis is perpendicular to every
- element of the cone::
-
- sage: K = Cone([(1,0,0), (0,1,0)])
- sage: codim(K)
- 1
-
- If our cone is all of `\mathbb{R}^{2}`, then its codimension is zero::
-
- sage: K = Cone([(1,0), (-1,0), (0,1), (0,-1)])
- sage: codim(K)
- 0
-
- And if the cone is trivial in any space, then its codimension is
- equal to the dimension of the ambient space::
-
- sage: K = Cone([], lattice=ToricLattice(0))
- sage: K.lattice_dim()
- 0
- sage: codim(K)
- 0
-
- sage: K = Cone([(0,)])
- sage: K.lattice_dim()
- 1
- sage: codim(K)
- 1
-
- sage: K = Cone([(0,0)])
- sage: K.lattice_dim()
- 2
- sage: codim(K)
- 2
-
- TESTS:
-
- The codimension of a cone should be an integer between zero and
- the dimension of the ambient space, inclusive::
-
- sage: set_random_seed()
- sage: K = random_cone(max_dim = 8)
- sage: c = codim(K)
- sage: c in ZZ
- True
- sage: (0 <= c) and (c <= K.lattice_dim())
- True
-
- A solid cone should have codimension zero::
-
- sage: set_random_seed()
- sage: K = random_cone(max_dim = 8, solid = True)
- sage: codim(K)
- 0
-
- The codimension of a cone is equal to the lineality of its dual::
-
- sage: set_random_seed()
- sage: K = random_cone(max_dim = 8, solid = True)
- sage: codim(K) == lineality(K.dual())
- True
-
- """
- return (K.lattice_dim() - K.dim())
-
-
def discrete_complementarity_set(K):
r"""
Compute the discrete complementarity set of this cone.