""" The Schur cone, as described in the "Critical angles..." papers by Iusem, Seeger, and Sossa. It defines the Schur ordering on `R^{n}`. """ from sage.all import * def schur_cone(n): r""" Return the Schur cone in ``n`` dimensions. INPUT: - ``n`` -- the dimension the ambient space. OUTPUT: A rational closed convex Schur cone of dimension ``n``. REFERENCES: .. [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, doi:10.1007/s10107-005-0626-z. .. [SeegerSossaI] Alberto Seeger and David Sossa. Critical angles between two convex cones I. General theory. TOP, 24(1):44-65, 2016, doi:10.1007/s11750-015-0375-y. SETUP:: sage: from mjo.cone.nonnegative_orthant import nonnegative_orthant sage: from mjo.cone.schur import schur_cone EXAMPLES: Verify the claim that the maximal angle between any two generators of the Schur cone and the nonnegative quintant is ``3*pi/4``:: sage: P = schur_cone(5) sage: Q = nonnegative_orthant(5) sage: G = ( g.change_ring(QQbar).normalized() for g in P ) sage: H = ( h.change_ring(QQbar).normalized() for h in Q ) sage: actual = max(arccos(u.inner_product(v)) for u in G for v in H) sage: expected = 3*pi/4 sage: abs(actual - expected).n() < 1e-12 True TESTS: We get the trivial cone when ``n`` is zero:: sage: schur_cone(0).is_trivial() True The Schur cone induces the majorization ordering:: 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)) ....: and sum(x) == sum(y)) sage: n = ZZ.random_element(10) sage: V = VectorSpace(QQ, n) sage: S = schur_cone(n) sage: majorized_by(V.zero(), S.random_element()) True sage: x = V.random_element() sage: y = V.random_element() sage: majorized_by(x,y) == ( (y-x) in S ) True """ def _f(i,j): if i == j: return 1 elif j - i == 1: return -1 else: return 0 # 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))