X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Fcone%2Fcone.py;h=ff7d195d134c15943dbb75c1f26b741bb4a0afba;hb=10142e85f34c47fa35df002f519d1d58a79a74f4;hp=a4e327248fd47bf700dd698b63e426f16f47037c;hpb=41ce22703a7948acd99917ce655e321025836858;p=sage.d.git diff --git a/mjo/cone/cone.py b/mjo/cone/cone.py index a4e3272..ff7d195 100644 --- a/mjo/cone/cone.py +++ b/mjo/cone/cone.py @@ -119,7 +119,7 @@ def lineality(K): sage: (0 <= l) and (l <= K.lattice_dim()) True - A strictly cone should have lineality zero:: + A strictly convex cone should have lineality zero:: sage: K = random_cone(max_dim = 10, strictly_convex = True) sage: lineality(K) @@ -129,6 +129,91 @@ def lineality(K): 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: codim(K) + 0 + + sage: K = Cone([(0,)]) + sage: codim(K) + 1 + + sage: K = Cone([(0,0)]) + 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: K = random_cone(max_dim = 10) + 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: K = random_cone(max_dim = 10, solid = True) + sage: codim(K) + 0 + + The codimension of a cone is equal to the lineality of its dual:: + + sage: K = random_cone(max_dim = 10, 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. @@ -418,7 +503,7 @@ def lyapunov_rank(K): sage: K = Cone([e1, neg_e1, e2, neg_e2, zero, zero, zero]) sage: lyapunov_rank(K) 19 - sage: K.lattice_dim()**2 - K.dim()*(K.lattice_dim() - K.dim()) + sage: K.lattice_dim()**2 - K.dim()*codim(K) 19 The Lyapunov rank should be additive on a product of proper cones @@ -494,8 +579,8 @@ def lyapunov_rank(K): sage: K_S = project_span(K) sage: P = project_span(K_S.dual()).dual() sage: l = lineality(K) - sage: codim = K.lattice_dim() - K.dim() - sage: expected = lyapunov_rank(P) + K.dim()*(l + codim) + codim**2 + sage: c = codim(K) + sage: expected = lyapunov_rank(P) + K.dim()*(l + c) + c**2 sage: actual == expected True