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