]> gitweb.michael.orlitzky.com - sage.d.git/blob - mjo/cone/tests.py
Remove lyapunov_rank() for inclusion in Sage.
[sage.d.git] / mjo / cone / tests.py
1 """
2 Additional tests for the mjo.cone.cone module. These are extra
3 properties that we'd like to check, but which are overkill for inclusion
4 into Sage.
5 """
6
7 # Sage doesn't load ~/.sage/init.sage during testing (sage -t), so we
8 # have to explicitly mangle our sitedir here so that "mjo.cone"
9 # resolves.
10 from os.path import abspath
11 from site import addsitedir
12 addsitedir(abspath('../../'))
13
14 from sage.all import *
15
16 # The double-import is needed to get the underscore methods.
17 from mjo.cone.cone import *
18
19 #
20 # Tests for _restrict_to_space.
21 #
22 def _look_isomorphic(K1, K2):
23 r"""
24 Test whether or not ``K1`` and ``K2`` look linearly isomorphic.
25
26 This is a hack to get around the fact that it's difficult to tell
27 when two cones are linearly isomorphic. Instead, we check a list of
28 properties that should be preserved under linear isomorphism.
29
30 OUTPUT:
31
32 ``True`` if ``K1`` and ``K2`` look isomorphic, or ``False``
33 if we can prove that they are not isomorphic.
34
35 EXAMPLES:
36
37 Any proper cone with three generators in `\mathbb{R}^{3}` is
38 isomorphic to the nonnegative orthant::
39
40 sage: K1 = Cone([(1,0,0), (0,1,0), (0,0,1)])
41 sage: K2 = Cone([(1,2,3), (3, 18, 4), (66, 51, 0)])
42 sage: _look_isomorphic(K1, K2)
43 True
44
45 Negating a cone gives you an isomorphic cone::
46
47 sage: K = Cone([(0,2,-5), (-6, 2, 4), (0, 51, 0)])
48 sage: _look_isomorphic(K, -K)
49 True
50
51 TESTS:
52
53 Any cone is isomorphic to itself::
54
55 sage: K = random_cone(max_ambient_dim = 8)
56 sage: _look_isomorphic(K, K)
57 True
58
59 After applying an invertible matrix to the rows of a cone, the
60 result should is isomorphic to the cone we started with::
61
62 sage: K1 = random_cone(max_ambient_dim = 8)
63 sage: A = random_matrix(QQ, K1.lattice_dim(), algorithm='unimodular')
64 sage: K2 = Cone( [ A*r for r in K1.rays() ], lattice=K1.lattice())
65 sage: _look_isomorphic(K1, K2)
66 True
67
68 """
69 if K1.lattice_dim() != K2.lattice_dim():
70 return False
71
72 if K1.nrays() != K2.nrays():
73 return False
74
75 if K1.dim() != K2.dim():
76 return False
77
78 if K1.lineality() != K2.lineality():
79 return False
80
81 if K1.is_solid() != K2.is_solid():
82 return False
83
84 if K1.is_strictly_convex() != K2.is_strictly_convex():
85 return False
86
87 if len(K1.lyapunov_like_basis()) != len(K2.lyapunov_like_basis()):
88 return False
89
90 C_of_K1 = K1.discrete_complementarity_set()
91 C_of_K2 = K2.discrete_complementarity_set()
92 if len(C_of_K1) != len(C_of_K2):
93 return False
94
95 if len(K1.facets()) != len(K2.facets()):
96 return False
97
98 return True
99
100
101 """
102 Apply _restrict_to_space according to our paper (to obtain our main
103 result). Test all four parameter combinations::
104
105 sage: set_random_seed()
106 sage: K = random_cone(max_ambient_dim = 8,
107 ....: strictly_convex=False,
108 ....: solid=False)
109 sage: K_S = K._restrict_to_space(K.span())
110 sage: K_SP = K_S.dual()._restrict_to_space(K_S.dual().span()).dual()
111 sage: K_SP.is_proper()
112 True
113 sage: K_SP = K_S._restrict_to_space(K_S.dual().span())
114 sage: K_SP.is_proper()
115 True
116
117 ::
118
119 sage: set_random_seed()
120 sage: K = random_cone(max_ambient_dim = 8,
121 ....: strictly_convex=True,
122 ....: solid=False)
123 sage: K_S = K._restrict_to_space(K.span())
124 sage: K_SP = K_S.dual()._restrict_to_space(K_S.dual().span()).dual()
125 sage: K_SP.is_proper()
126 True
127 sage: K_SP = K_S._restrict_to_space(K_S.dual().span())
128 sage: K_SP.is_proper()
129 True
130
131 ::
132
133 sage: set_random_seed()
134 sage: K = random_cone(max_ambient_dim = 8,
135 ....: strictly_convex=False,
136 ....: solid=True)
137 sage: K_S = K._restrict_to_space(K.span())
138 sage: K_SP = K_S.dual()._restrict_to_space(K_S.dual().span()).dual()
139 sage: K_SP.is_proper()
140 True
141 sage: K_SP = K_S._restrict_to_space(K_S.dual().span())
142 sage: K_SP.is_proper()
143 True
144
145 ::
146
147 sage: set_random_seed()
148 sage: K = random_cone(max_ambient_dim = 8,
149 ....: strictly_convex=True,
150 ....: solid=True)
151 sage: K_S = K._restrict_to_space(K.span())
152 sage: K_SP = K_S.dual()._restrict_to_space(K_S.dual().span()).dual()
153 sage: K_SP.is_proper()
154 True
155 sage: K_SP = K_S._restrict_to_space(K_S.dual().span())
156 sage: K_SP.is_proper()
157 True
158
159 Test the proposition in our paper concerning the duals and
160 restrictions. Generate a random cone, then create a subcone of
161 it. The operation of dual-taking should then commute with rho. Test
162 all parameter combinations::
163
164
165 sage: set_random_seed()
166 sage: J = random_cone(max_ambient_dim = 8,
167 ....: solid=False,
168 ....: strictly_convex=False)
169 sage: K = Cone(random_sublist(J.rays(), 0.5), lattice=J.lattice())
170 sage: K_W_star = K._restrict_to_space(J.span()).dual()
171 sage: K_star_W = K.dual()._restrict_to_space(J.span())
172 sage: _look_isomorphic(K_W_star, K_star_W)
173 True
174
175 ::
176
177 sage: set_random_seed()
178 sage: J = random_cone(max_ambient_dim = 8,
179 ....: solid=True,
180 ....: strictly_convex=False)
181 sage: K = Cone(random_sublist(J.rays(), 0.5), lattice=J.lattice())
182 sage: K_W_star = K._restrict_to_space(J.span()).dual()
183 sage: K_star_W = K.dual()._restrict_to_space(J.span())
184 sage: _look_isomorphic(K_W_star, K_star_W)
185 True
186
187 ::
188
189 sage: set_random_seed()
190 sage: J = random_cone(max_ambient_dim = 8,
191 ....: solid=False,
192 ....: strictly_convex=True)
193 sage: K = Cone(random_sublist(J.rays(), 0.5), lattice=J.lattice())
194 sage: K_W_star = K._restrict_to_space(J.span()).dual()
195 sage: K_star_W = K.dual()._restrict_to_space(J.span())
196 sage: _look_isomorphic(K_W_star, K_star_W)
197 True
198
199 ::
200
201 sage: set_random_seed()
202 sage: J = random_cone(max_ambient_dim = 8,
203 ....: solid=True,
204 ....: strictly_convex=True)
205 sage: K = Cone(random_sublist(J.rays(), 0.5), lattice=J.lattice())
206 sage: K_W_star = K._restrict_to_space(J.span()).dual()
207 sage: K_star_W = K.dual()._restrict_to_space(J.span())
208 sage: _look_isomorphic(K_W_star, K_star_W)
209 True
210
211 """
212
213
214 #
215 # Lyapunov rank tests
216 #
217 """
218
219 The Lyapunov rank is invariant under a linear isomorphism. Check all
220 combinations of parameters::
221
222 sage: K1 = random_cone(max_ambient_dim=8,
223 ....: strictly_convex=True,
224 ....: solid=True)
225 sage: A = random_matrix(QQ, K1.lattice_dim(), algorithm='unimodular')
226 sage: K2 = Cone( [ A*r for r in K1.rays() ], lattice=K1.lattice())
227 sage: K1.lyapunov_rank() == K2.lyapunov_rank()
228 True
229
230 ::
231
232 sage: K1 = random_cone(max_ambient_dim=8,
233 ....: strictly_convex=True,
234 ....: solid=False)
235 sage: A = random_matrix(QQ, K1.lattice_dim(), algorithm='unimodular')
236 sage: K2 = Cone( [ A*r for r in K1.rays() ], lattice=K1.lattice())
237 sage: K1.lyapunov_rank() == K2.lyapunov_rank()
238 True
239
240 ::
241
242 sage: K1 = random_cone(max_ambient_dim=8,
243 ....: strictly_convex=False,
244 ....: solid=True)
245 sage: A = random_matrix(QQ, K1.lattice_dim(), algorithm='unimodular')
246 sage: K2 = Cone( [ A*r for r in K1.rays() ], lattice=K1.lattice())
247 sage: K1.lyapunov_rank() == K2.lyapunov_rank()
248 True
249
250 ::
251
252 sage: K1 = random_cone(max_ambient_dim=8,
253 ....: strictly_convex=False,
254 ....: solid=False)
255 sage: A = random_matrix(QQ, K1.lattice_dim(), algorithm='unimodular')
256 sage: K2 = Cone( [ A*r for r in K1.rays() ], lattice=K1.lattice())
257 sage: K1.lyapunov_rank() == K2.lyapunov_rank()
258 True
259
260 The Lyapunov rank of a dual cone should be the same as the original
261 cone. Check all combinations of parameters::
262
263 sage: set_random_seed()
264 sage: K = random_cone(max_ambient_dim=8,
265 ....: strictly_convex=False,
266 ....: solid=False)
267 sage: K.lyapunov_rank() == K.dual().lyapunov_rank()
268 True
269
270 ::
271
272 sage: set_random_seed()
273 sage: K = random_cone(max_ambient_dim=8,
274 ....: strictly_convex=False,
275 ....: solid=True)
276 sage: K.lyapunov_rank() == K.dual().lyapunov_rank()
277 True
278
279 ::
280
281 sage: set_random_seed()
282 sage: K = random_cone(max_ambient_dim=8,
283 ....: strictly_convex=True,
284 ....: solid=False)
285 sage: K.lyapunov_rank() == K.dual().lyapunov_rank()
286 True
287
288 ::
289
290 sage: set_random_seed()
291 sage: K = random_cone(max_ambient_dim=8,
292 ....: strictly_convex=True,
293 ....: solid=True)
294 sage: K.lyapunov_rank() == K.dual().lyapunov_rank()
295 True
296
297 The Lyapunov rank of a cone ``K`` is the dimension of
298 ``K.lyapunov_like_basis()``. Check all combinations of parameters::
299
300 sage: set_random_seed()
301 sage: K = random_cone(max_ambient_dim=8,
302 ....: strictly_convex=True,
303 ....: solid=True)
304 sage: K.lyapunov_rank() == len(K.lyapunov_like_basis())
305 True
306
307 ::
308
309 sage: set_random_seed()
310 sage: K = random_cone(max_ambient_dim=8,
311 ....: strictly_convex=True,
312 ....: solid=False)
313 sage: K.lyapunov_rank() == len(K.lyapunov_like_basis())
314 True
315
316 ::
317
318 sage: set_random_seed()
319 sage: K = random_cone(max_ambient_dim=8,
320 ....: strictly_convex=False,
321 ....: solid=True)
322 sage: K.lyapunov_rank() == len(K.lyapunov_like_basis())
323 True
324
325 ::
326
327 sage: set_random_seed()
328 sage: K = random_cone(max_ambient_dim=8,
329 ....: strictly_convex=False,
330 ....: solid=False)
331 sage: K.lyapunov_rank() == len(K.lyapunov_like_basis())
332 True
333
334 """