X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Fcone%2Fschur.py;h=edf282da30794fc33b246485e27d3b378817d03f;hb=8698debba196d8746c1a32d8e6866085b6cb2161;hp=dca7292807096997a18bf5a57ae7dc400f3be187;hpb=721da31ab4d241fc74962e446fb92e60099df962;p=sage.d.git diff --git a/mjo/cone/schur.py b/mjo/cone/schur.py index dca7292..edf282d 100644 --- a/mjo/cone/schur.py +++ b/mjo/cone/schur.py @@ -5,20 +5,34 @@ Iusem, Seeger, and Sossa. It defines the Schur ordering on `R^{n}`. from sage.all import * -def schur_cone(n): +def schur_cone(n, lattice=None): r""" - Return the Schur cone in ``n`` dimensions. + Return the Schur cone in ``n`` dimensions that induces the + majorization ordering. INPUT: - - ``n`` -- the dimension the ambient space. + - ``n`` -- the dimension the ambient space. + + - ``lattice`` -- (default: ``None``) an ambient lattice of rank ``n`` + to be passed to the :func:`Cone` constructor. OUTPUT: - A rational closed convex Schur cone of dimension ``n``. + A rational closed convex Schur cone of dimension ``n``. Each + generating ray will have the integer ring as its base ring. + + If a ``lattice`` was specified, then the resulting cone will live in + that lattice unless its rank is incompatible with the dimension + ``n`` (in which case a ``ValueError`` is raised). REFERENCES: + .. [GourionSeeger] Daniel Gourion and Alberto Seeger. + Critical angles in polyhedral convex cones: numerical and + statistical considerations. Mathematical Programming, 123:173-198, + 2010, doi:10.1007/s10107-009-0317-2. + .. [IusemSeegerOnPairs] Alfredo Iusem and Alberto Seeger. On pairs of vectors achieving the maximal angle of a convex cone. Mathematical Programming, 104(2-3):501-523, 2005, @@ -47,6 +61,17 @@ def schur_cone(n): sage: abs(actual - expected).n() < 1e-12 True + The dual of the Schur cone is the "downward monotonic cone" + [GourionSeeger]_, whose elements' entries are in non-increasing + order:: + + sage: set_random_seed() + sage: n = ZZ.random_element(10) + sage: K = schur_cone(n).dual() + sage: x = K.random_element() + sage: all( x[i] >= x[i+1] for i in range(n-1) ) + True + TESTS: We get the trivial cone when ``n`` is zero:: @@ -59,7 +84,7 @@ def schur_cone(n): sage: set_random_seed() sage: def majorized_by(x,y): ....: return (all(sum(x[0:i]) <= sum(y[0:i]) - ....: for i in xrange(x.degree()-1)) + ....: for i in range(x.degree()-1)) ....: and sum(x) == sum(y)) sage: n = ZZ.random_element(10) sage: V = VectorSpace(QQ, n) @@ -71,7 +96,28 @@ def schur_cone(n): sage: majorized_by(x,y) == ( (y-x) in S ) True + If a ``lattice`` was given, it is actually used:: + + sage: L = ToricLattice(3, 'M') + sage: schur_cone(3, lattice=L) + 2-d cone in 3-d lattice M + + Unless the rank of the lattice disagrees with ``n``:: + + sage: L = ToricLattice(1, 'M') + sage: schur_cone(3, lattice=L) + Traceback (most recent call last): + ... + ValueError: lattice rank=1 and dimension n=3 are incompatible + """ + if lattice is None: + lattice = ToricLattice(n) + + if lattice.rank() != n: + raise ValueError('lattice rank=%d and dimension n=%d are incompatible' + % + (lattice.rank(), n)) def _f(i,j): if i == j: @@ -84,5 +130,4 @@ def schur_cone(n): # The "max" below catches the trivial case where n == 0. S = matrix(ZZ, max(0,n-1), n, _f) - # Likewise, when n == 0, we need to specify the lattice. - return Cone(S.rows(), ToricLattice(n)) + return Cone(S.rows(), lattice)