X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Fcone%2Fcone.py;h=60f9c34ec8bc271d65812859f51ca77636c8cbbc;hb=874e3ce831e0b1901b3c280a32ffe18e36f54959;hp=3f5a4fed4e1c49853f00eafcf6084744223ca296;hpb=3e6f51aa1f2d6f300cb22281701901add3631904;p=sage.d.git diff --git a/mjo/cone/cone.py b/mjo/cone/cone.py index 3f5a4fe..60f9c34 100644 --- a/mjo/cone/cone.py +++ b/mjo/cone/cone.py @@ -7,6 +7,56 @@ addsitedir(abspath('../../')) from sage.all import * +def project_span(K): + r""" + Project ``K`` into its own span. + + EXAMPLES:: + + sage: K = Cone([(1,)]) + sage: project_span(K) == K + True + + sage: K2 = Cone([(1,0)]) + sage: project_span(K2).rays() + N(1) + in 1-d lattice N + sage: K3 = Cone([(1,0,0)]) + sage: project_span(K3).rays() + N(1) + in 1-d lattice N + sage: project_span(K2) == project_span(K3) + True + + TESTS: + + The projected cone should always be solid:: + + sage: K = random_cone() + sage: K_S = project_span(K) + sage: K_S.is_solid() + True + + If we do this according to our paper, then the result is proper:: + + sage: K = random_cone() + sage: K_S = project_span(K) + sage: P = project_span(K_S.dual()).dual() + sage: P.is_proper() + True + + """ + F = K.lattice().base_field() + Q = K.lattice().quotient(K.sublattice_complement()) + vecs = [ vector(F, reversed(list(Q(r)))) for r in K.rays() ] + + L = None + if len(vecs) == 0: + L = ToricLattice(0) + + return Cone(vecs, lattice=L) + + def rename_lattice(L,s): r""" Change all names of the given lattice to ``s``. @@ -37,32 +87,6 @@ def span_iso(K): sage: phi(K).dim() == phi(K).lattice_dim() True - The isomorphism should be an inner product space isomorphism, and - thus it should preserve dual cones (and commute with the "dual" - operation). But beware the automatic renaming of the dual lattice. - OH AND YOU HAVE TO SORT THE CONES:: - - sage: K = random_cone(max_dim=10, strictly_convex=False, solid=True) - sage: L = K.lattice() - sage: rename_lattice(L, 'L') - sage: (phi, phi_inv) = span_iso(K) - sage: sorted(phi_inv( phi(K).dual() )) == sorted(K.dual()) - True - - We may need to isomorph twice to make sure we stop moving down to - smaller spaces. (Once you've done this on a cone and its dual, the - result should be proper.) OH AND YOU HAVE TO SORT THE CONES:: - - sage: K = random_cone(max_dim=10, strictly_convex=False, solid=False) - sage: L = K.lattice() - sage: rename_lattice(L, 'L') - sage: (phi, phi_inv) = span_iso(K) - sage: K_S = phi(K) - sage: (phi_dual, phi_dual_inv) = span_iso(K_S.dual()) - sage: J_T = phi_dual(K_S.dual()).dual() - sage: phi_inv(phi_dual_inv(J_T)) == K - True - """ phi_domain = K.sublattice().vector_space() phi_codo = VectorSpace(phi_domain.base_field(), phi_domain.dimension()) @@ -424,17 +448,77 @@ def lyapunov_rank(K): sage: K = random_cone(max_dim=15, solid=False, strictly_convex=False) sage: actual = lyapunov_rank(K) - sage: (phi1, phi1_inv) = span_iso(K) + sage: (phi1, _) = span_iso(K) + sage: K_S = phi1(K) + sage: (phi2, _) = span_iso(K_S.dual()) + sage: J_T = phi2(K_S.dual()).dual() + sage: l = K.linear_subspace().dimension() + sage: codim = K.lattice_dim() - K.dim() + sage: expected = lyapunov_rank(J_T) + K.dim()*(l + codim) + codim**2 + sage: actual == expected + True + + Repeat the previous test with different ``random_cone()`` params:: + + sage: K = random_cone(max_dim=15, solid=False, strictly_convex=True) + sage: actual = lyapunov_rank(K) + sage: (phi1, _) = span_iso(K) + sage: K_S = phi1(K) + sage: (phi2, _) = span_iso(K_S.dual()) + sage: J_T = phi2(K_S.dual()).dual() + sage: l = K.linear_subspace().dimension() + sage: codim = K.lattice_dim() - K.dim() + sage: expected = lyapunov_rank(J_T) + K.dim()*(l + codim) + codim**2 + sage: actual == expected + True + + sage: K = random_cone(max_dim=15, solid=True, strictly_convex=False) + sage: actual = lyapunov_rank(K) + sage: (phi1, _) = span_iso(K) + sage: K_S = phi1(K) + sage: (phi2, _) = span_iso(K_S.dual()) + sage: J_T = phi2(K_S.dual()).dual() + sage: l = K.linear_subspace().dimension() + sage: codim = K.lattice_dim() - K.dim() + sage: expected = lyapunov_rank(J_T) + K.dim()*(l + codim) + codim**2 + sage: actual == expected + True + + sage: K = random_cone(max_dim=15, solid=True, strictly_convex=True) + sage: actual = lyapunov_rank(K) + sage: (phi1, _) = span_iso(K) sage: K_S = phi1(K) - sage: (phi2, phi2_inv) = span_iso(K_S.dual()) + sage: (phi2, _) = span_iso(K_S.dual()) sage: J_T = phi2(K_S.dual()).dual() - sage: phi1_inv(phi2_inv(J_T)) == K + sage: l = K.linear_subspace().dimension() + sage: codim = K.lattice_dim() - K.dim() + sage: expected = lyapunov_rank(J_T) + K.dim()*(l + codim) + codim**2 + sage: actual == expected True + + sage: K = random_cone(max_dim=15) + sage: actual = lyapunov_rank(K) + sage: (phi1, _) = span_iso(K) + sage: K_S = phi1(K) + sage: (phi2, _) = span_iso(K_S.dual()) + sage: J_T = phi2(K_S.dual()).dual() sage: l = K.linear_subspace().dimension() sage: codim = K.lattice_dim() - K.dim() sage: expected = lyapunov_rank(J_T) + K.dim()*(l + codim) + codim**2 sage: actual == expected True + And test with the project_span function:: + + sage: K = random_cone(max_dim=15) + sage: actual = lyapunov_rank(K) + sage: K_S = project_span(K) + sage: P = project_span(K_S.dual()).dual() + sage: l = K.linear_subspace().dimension() + sage: codim = K.lattice_dim() - K.dim() + sage: expected = lyapunov_rank(P) + K.dim()*(l + codim) + codim**2 + sage: actual == expected + True + """ return len(LL(K))