]>
gitweb.michael.orlitzky.com - sage.d.git/blob - mjo/cone/cone.py
be05f5e3a41b7edaf2fb9cb6c84817d0f08e9379
3 def is_cross_positive(L
,K
):
5 Determine whether or not ``L`` is cross-positive on ``K``.
7 We say that ``L`` is cross-positive on ``K`` if `\left\langle
8 L\left\lparenx\right\rparen,s\right\rangle >= 0` for all pairs
9 `\left\langle x,s \right\rangle` in the complementarity set of
10 ``K``. It is known that this property need only be
11 checked for generators of ``K`` and its dual.
15 - ``L`` -- A linear transformation or matrix.
17 - ``K`` -- A polyhedral closed convex cone.
21 ``True`` if it can be proven that ``L`` is cross-positive on ``K``,
22 and ``False`` otherwise.
26 If this function returns ``True``, then ``L`` is cross-positive
27 on ``K``. However, if ``False`` is returned, that could mean one
28 of two things. The first is that ``L`` is definitely not
29 cross-positive on ``K``. The second is more of an "I don't know"
30 answer, returned (for example) if we cannot prove that an inner
31 product is nonnegative.
35 The identity is always cross-positive in a nontrivial space::
37 sage: set_random_seed()
38 sage: K = random_cone(min_ambient_dim=1, max_ambient_dim=8)
39 sage: L = identity_matrix(K.lattice_dim())
40 sage: is_cross_positive(L,K)
43 As is the "zero" transformation::
45 sage: K = random_cone(min_ambient_dim=1, max_ambient_dim=8)
46 sage: R = K.lattice().vector_space().base_ring()
47 sage: L = zero_matrix(R, K.lattice_dim())
48 sage: is_cross_positive(L,K)
51 Everything in ``K.cross_positive_operator_gens()`` should be
52 cross-positive on ``K``::
54 sage: K = random_cone(min_ambient_dim=1, max_ambient_dim=6)
55 sage: all([ is_cross_positive(L,K)
56 ....: for L in K.cross_positive_operator_gens() ])
60 if L
.base_ring().is_exact() or L
.base_ring() is SR
:
61 return all([ s
*(L
*x
) >= 0
62 for (x
,s
) in K
.discrete_complementarity_set() ])
64 # The only inexact ring that we're willing to work with is SR,
65 # since it can still be exact when working with symbolic
66 # constants like pi and e.
67 raise ValueError('base ring of operator L is neither SR nor exact')
70 def is_lyapunov_like(L
,K
):
72 Determine whether or not ``L`` is Lyapunov-like on ``K``.
74 We say that ``L`` is Lyapunov-like on ``K`` if `\left\langle
75 L\left\lparenx\right\rparen,s\right\rangle = 0` for all pairs
76 `\left\langle x,s \right\rangle` in the complementarity set of
77 ``K``. It is known [Orlitzky]_ that this property need only be
78 checked for generators of ``K`` and its dual.
80 There are faster ways of checking this property. For example, we
81 could compute a `lyapunov_like_basis` of the cone, and then test
82 whether or not the given matrix is contained in the span of that
83 basis. The value of this function is that it works on symbolic
88 - ``L`` -- A linear transformation or matrix.
90 - ``K`` -- A polyhedral closed convex cone.
94 ``True`` if it can be proven that ``L`` is Lyapunov-like on ``K``,
95 and ``False`` otherwise.
99 If this function returns ``True``, then ``L`` is Lyapunov-like
100 on ``K``. However, if ``False`` is returned, that could mean one
101 of two things. The first is that ``L`` is definitely not
102 Lyapunov-like on ``K``. The second is more of an "I don't know"
103 answer, returned (for example) if we cannot prove that an inner
108 M. Orlitzky. The Lyapunov rank of an improper cone.
109 http://www.optimization-online.org/DB_HTML/2015/10/5135.html
113 The identity is always Lyapunov-like in a nontrivial space::
115 sage: set_random_seed()
116 sage: K = random_cone(min_ambient_dim=1, max_ambient_dim=8)
117 sage: L = identity_matrix(K.lattice_dim())
118 sage: is_lyapunov_like(L,K)
121 As is the "zero" transformation::
123 sage: K = random_cone(min_ambient_dim=1, max_ambient_dim=8)
124 sage: R = K.lattice().vector_space().base_ring()
125 sage: L = zero_matrix(R, K.lattice_dim())
126 sage: is_lyapunov_like(L,K)
129 Everything in ``K.lyapunov_like_basis()`` should be Lyapunov-like
132 sage: K = random_cone(min_ambient_dim=1, max_ambient_dim=6)
133 sage: all([ is_lyapunov_like(L,K) for L in K.lyapunov_like_basis() ])
137 if L
.base_ring().is_exact() or L
.base_ring() is SR
:
138 V
= VectorSpace(K
.lattice().base_field(), K
.lattice_dim()**2)
139 LL_of_K
= V
.span([ V(m
.list()) for m
in K
.lyapunov_like_basis() ])
140 return V(L
.list()) in LL_of_K
142 # The only inexact ring that we're willing to work with is SR,
143 # since it can still be exact when working with symbolic
144 # constants like pi and e.
145 raise ValueError('base ring of operator L is neither SR nor exact')
148 gens
= K
.lyapunov_like_basis()
149 L
= ToricLattice(K
.lattice_dim()**2)
150 return Cone([ g
.list() for g
in gens
], lattice
=L
, check
=False)
153 gens
= K
.cross_positive_operator_gens()
154 L
= ToricLattice(K
.lattice_dim()**2)
155 return Cone([ g
.list() for g
in gens
], lattice
=L
, check
=False)
158 gens
= K
.Z_operator_gens()
159 L
= ToricLattice(K
.lattice_dim()**2)
160 return Cone([ g
.list() for g
in gens
], lattice
=L
, check
=False)
162 def pi_cone(K1
, K2
=None):
165 gens
= K1
.positive_operator_gens(K2
)
166 L
= ToricLattice(K1
.lattice_dim()*K2
.lattice_dim())
167 return Cone([ g
.list() for g
in gens
], lattice
=L
, check
=False)