示例#1
0
    def symmetrized_matrix(self):
        """
        Return the symmetrized matrix of ``self`` if symmetrizable.

        EXAMPLES::

            sage: cm = CartanMatrix(['B',4,1])
            sage: cm.symmetrized_matrix()
            [ 4  0 -2  0  0]
            [ 0  4 -2  0  0]
            [-2 -2  4 -2  0]
            [ 0  0 -2  4 -2]
            [ 0  0  0 -2  2]
        """
        M = matrix.diagonal(list(self.symmetrizer())) * self
        M.set_immutable()
        return M
示例#2
0
    def symmetrized_matrix(self):
        """
        Return the symmetrized matrix of ``self`` if symmetrizable.

        EXAMPLES::

            sage: cm = CartanMatrix(['B',4,1])
            sage: cm.symmetrized_matrix()
            [ 4  0 -2  0  0]
            [ 0  4 -2  0  0]
            [-2 -2  4 -2  0]
            [ 0  0 -2  4 -2]
            [ 0  0  0 -2  2]
        """
        M = matrix.diagonal(list(self.symmetrizer())) * self
        M.set_immutable()
        return M
示例#3
0
    def next_step(indices, prev, T):
        for pos,i in enumerate(indices):
            U = prev * T
            mu = U * phi[i]
            mu = mu.stack(matrix.diagonal([B[i]]).dense_matrix())
            row_syzygy = matrix(S, syz(mu.transpose())).matrix_from_columns(range(r))
            Y = less_generators(row_syzygy)
            if not Y.is_square():
                continue

            if len(indices) == 1:
                return [prev, Y]

            I = list(indices)
            I.pop(pos)
            ret = next_step(I, Y, U)
            if ret is not None:
                return [prev] + ret
        return None                
        def _symmetric_form_matrix(self):
            r"""
            Return the matrix for the symmetric form `( | )` in
            the weight lattice basis.

            Let `A` be a symmetrizable Cartan matrix with symmetrizer `D`,.
            This returns the matrix `M^t DA M`, where `M` is dependent upon
            the type given below.

            In finite types, `M` is the inverse of the Cartan matrix.

            In affine types, `M` takes the basis
            `(\Lambda_0, \Lambda_1, \ldots, \Lambda_r, \delta)` to
            `(\alpha_0, \ldots, \alpha_r, \Lambda_0)` where `r` is the
            rank of ``self``.

            This is used in computing the symmetric form for affine
            root systems.

            EXAMPLES::

                sage: P = RootSystem(['C',2]).weight_lattice()
                sage: P._symmetric_form_matrix
                [1 1]
                [1 2]

                sage: P = RootSystem(['C',2,1]).weight_lattice()
                sage: P._symmetric_form_matrix
                [0 0 0 1]
                [0 1 1 1]
                [0 1 2 1]
                [1 1 1 0]

                sage: P = RootSystem(['A',4,2]).weight_lattice()
                sage: P._symmetric_form_matrix
                [  0   0   0 1/2]
                [  0   2   2   1]
                [  0   2   4   1]
                [1/2   1   1   0]
            """
            from sage.matrix.constructor import matrix
            ct = self.cartan_type()
            cm = ct.cartan_matrix()
            if cm.det() != 0:
                cm_inv = cm.inverse()
                diag = cm.is_symmetrizable(True)
                return cm_inv.transpose() * matrix.diagonal(diag)

            if not ct.is_affine():
                raise ValueError("only implemented for affine types when the"
                                 " Cartan matrix is singular")

            r = ct.rank()
            a = ct.a()
            # Determine the change of basis matrix
            # La[0], ..., La[r], delta -> al[0], ..., al[r], La[0]
            M = cm.stack( matrix([1] + [0]*(r-1)) )
            M = matrix.block([[ M, matrix([[1]] + [[0]]*r) ]])
            M = M.inverse()

            if a[0] != 1:
                from sage.rings.all import QQ
                S = matrix([~a[0]]+[0]*(r-1))
                A = cm.symmetrized_matrix().change_ring(QQ).stack(S)
            else:
                A = cm.symmetrized_matrix().stack(matrix([1]+[0]*(r-1)))
            A = matrix.block([[A, matrix([[~a[0]]] + [[0]]*r)]])
            return M.transpose() * A * M
示例#5
0
        def _symmetric_form_matrix(self):
            r"""
            Return the matrix for the symmetric form `( | )` in
            the weight lattice basis.

            Let `A` be a symmetrizable Cartan matrix with symmetrizer `D`,.
            This returns the matrix `M^t DA M`, where `M` is dependent upon
            the type given below.

            In finite types, `M` is the inverse of the Cartan matrix.

            In affine types, `M` takes the basis
            `(\Lambda_0, \Lambda_1, \ldots, \Lambda_r, \delta)` to
            `(\alpha_0, \ldots, \alpha_r, \Lambda_0)` where `r` is the
            rank of ``self``.

            This is used in computing the symmetric form for affine
            root systems.

            EXAMPLES::

                sage: P = RootSystem(['C',2]).weight_lattice()
                sage: P._symmetric_form_matrix
                [1 1]
                [1 2]

                sage: P = RootSystem(['C',2,1]).weight_lattice()
                sage: P._symmetric_form_matrix
                [0 0 0 1]
                [0 1 1 1]
                [0 1 2 1]
                [1 1 1 0]

                sage: P = RootSystem(['A',4,2]).weight_lattice()
                sage: P._symmetric_form_matrix
                [  0   0   0 1/2]
                [  0   2   2   1]
                [  0   2   4   1]
                [1/2   1   1   0]
            """
            from sage.matrix.constructor import matrix
            ct = self.cartan_type()
            cm = ct.cartan_matrix()
            if cm.det() != 0:
                cm_inv = cm.inverse()
                diag = cm.is_symmetrizable(True)
                return cm_inv.transpose() * matrix.diagonal(diag)

            if not ct.is_affine():
                raise ValueError("only implemented for affine types when the"
                                 " Cartan matrix is singular")

            r = ct.rank()
            a = ct.a()
            # Determine the change of basis matrix
            # La[0], ..., La[r], delta -> al[0], ..., al[r], La[0]
            M = cm.stack(matrix([1] + [0] * (r - 1)))
            M = matrix.block([[M, matrix([[1]] + [[0]] * r)]])
            M = M.inverse()

            if a[0] != 1:
                from sage.rings.all import QQ
                S = matrix([~a[0]] + [0] * (r - 1))
                A = cm.symmetrized_matrix().change_ring(QQ).stack(S)
            else:
                A = cm.symmetrized_matrix().stack(matrix([1] + [0] * (r - 1)))
            A = matrix.block([[A, matrix([[~a[0]]] + [[0]] * r)]])
            return M.transpose() * A * M
示例#6
0
def construct_free_chain(A):
    """
    Construct the free chain for the hyperplanes ``A``.

    ALGORITHM:

    We follow Algorithm 6.5 in [BC2012]_.

    INPUT:

    - ``A`` -- a hyperplane arrangement

    EXAMPLES::

        sage: from sage.geometry.hyperplane_arrangement.check_freeness import construct_free_chain
        sage: H.<x,y,z> = HyperplaneArrangements(QQ)
        sage: A = H(z, y+z, x+y+z)
        sage: construct_free_chain(A)
        [
        [1 0 0]  [ 1  0  0]  [    0     1     0]
        [0 1 0]  [ 0  z -1]  [y + z     0    -1]
        [0 0 z], [ 0  y  1], [    x     0     1]
        ]
    """
    AL = list(A)
    if not AL:  # Empty arrangement
        return []

    S = A.parent().ambient_space().symmetric_space()
    # Compute the morphisms \phi_{H_j} : S^{1xR} \to S / <b_j>
    B = [H.to_symmetric_space() for H in AL]
    phi = [matrix(S, [[beta.derivative(x)] for x in S.gens()]) for beta in B]

    # Setup variables
    syz = fun_fact.ff.syz
    G = S.gens()
    r = len(G)
    indices = list(range(len(B)))
    X = []

    # Helper function
    def next_step(indices, prev, T):
        for pos, i in enumerate(indices):
            U = prev * T
            mu = U * phi[i]
            mu = mu.stack(matrix.diagonal([B[i]]).dense_matrix())
            row_syzygy = matrix(S, syz(mu.transpose())).matrix_from_columns(
                range(r))
            Y = less_generators(row_syzygy)
            if not Y.is_square():
                continue

            if len(indices) == 1:
                return [prev, Y]

            I = list(indices)
            I.pop(pos)
            ret = next_step(I, Y, U)
            if ret is not None:
                return [prev] + ret
        return None

    T = matrix.identity(S, r)
    for i in indices:
        mu = phi[i].stack(matrix.diagonal([B[i]]).dense_matrix())
        row_syzygy = matrix(S,
                            syz(mu.transpose())).matrix_from_columns(range(r))
        Y = less_generators(row_syzygy)
        if not Y.is_square():
            continue

        if len(indices) == 1:
            return [Y]

        I = list(indices)
        I.pop(i)
        ret = next_step(I, Y, T)
        if ret is not None:
            return ret
    return None
示例#7
0
def construct_free_chain(A):
    """
    Construct the free chain for the hyperplanes ``A``.

    ALGORITHM:

    We follow Algorithm 6.5 in [BC2012]_.

    INPUT:

    - ``A`` -- a hyperplane arrangement

    EXAMPLES::

        sage: from sage.geometry.hyperplane_arrangement.check_freeness import construct_free_chain
        sage: H.<x,y,z> = HyperplaneArrangements(QQ)
        sage: A = H(z, y+z, x+y+z)
        sage: construct_free_chain(A)
        [
        [1 0 0]  [ 1  0  0]  [    0     1     0]
        [0 1 0]  [ 0  z -1]  [y + z     0    -1]
        [0 0 z], [ 0  y  1], [    x     0     1]
        ]
    """
    AL = list(A)
    if not AL: # Empty arrangement
        return []

    S = A.parent().ambient_space().symmetric_space()
    # Compute the morphisms \phi_{H_j} : S^{1xR} \to S / <b_j>
    B = [H.to_symmetric_space() for H in AL]
    phi = [matrix(S, [[beta.derivative(x)] for x in S.gens()]) for beta in B]

    # Setup variables
    syz = fun_fact.ff.syz
    G = S.gens()
    r = len(G)
    indices = list(range(len(B)))

    # Helper function
    def next_step(indices, prev, T):
        for pos,i in enumerate(indices):
            U = prev * T
            mu = U * phi[i]
            mu = mu.stack(matrix.diagonal([B[i]]).dense_matrix())
            row_syzygy = matrix(S, syz(mu.transpose())).matrix_from_columns(range(r))
            Y = less_generators(row_syzygy)
            if not Y.is_square():
                continue

            if len(indices) == 1:
                return [prev, Y]

            I = list(indices)
            I.pop(pos)
            ret = next_step(I, Y, U)
            if ret is not None:
                return [prev] + ret
        return None                

    T = matrix.identity(S, r)
    for i in indices:
        mu = phi[i].stack(matrix.diagonal([B[i]]).dense_matrix())
        row_syzygy = matrix(S, syz(mu.transpose())).matrix_from_columns(range(r))
        Y = less_generators(row_syzygy)
        if not Y.is_square():
            continue

        if len(indices) == 1:
            return [Y]

        I = list(indices)
        I.pop(i)
        ret = next_step(I, Y, T)
        if ret is not None:
            return ret
    return None