예제 #1
0
def basis_of_short_vectors(self, show_lengths=False, safe_flag=True):
    """
    Return a basis for `ZZ^n` made of vectors with minimal lengths Q(`v`).

    The safe_flag allows us to select whether we want a copy of the
    output, or the original output.  By default safe_flag = True, so
    we return a copy of the cached information.  If this is set to
    False, then the routine is much faster but the return values are
    vulnerable to being corrupted by the user.

    OUTPUT:
        a list of vectors, and optionally a list of values for each vector.

    EXAMPLES::

        sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7])
        sage: Q.basis_of_short_vectors()
        [(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)]
        sage: Q.basis_of_short_vectors(True)
        ([(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)], [1, 3, 5, 7])

    """
    ## Try to use the cached results
    try:
        ## Return the appropriate result
        if show_lengths:
            if safe_flag:
                return deep_copy(self.__basis_of_short_vectors), deepcopy(self.__basis_of_short_vectors_lengths)
            else:
                return self.__basis_of_short_vectors, self.__basis_of_short_vectors_lengths
        else:
            if safe_flag:
                return deepcopy(self.__basis_of_short_vectors)
            else:
                return deepcopy(self.__basis_of_short_vectors)
    except Exception:
        pass

    ## Set an upper bound for the number of vectors to consider
    Max_number_of_vectors = 10000

    ## Generate a PARI matrix string for the associated Hessian matrix
    M_str = str(gp(self.matrix()))

    ## Run through all possible minimal lengths to find a spanning set of vectors
    n = self.dim()
    # MS = MatrixSpace(QQ, n)
    M1 = Matrix([[0]])
    vec_len = 0
    while M1.rank() < n:

        ## DIAGONSTIC
        # print
        # print "Starting with vec_len = ", vec_len
        # print "M_str = ", M_str

        vec_len += 1
        gp_mat = gp.qfminim(M_str, vec_len, Max_number_of_vectors)[3].mattranspose()
        number_of_vecs = ZZ(gp_mat.matsize()[1])
        vector_list = []
        for i in range(number_of_vecs):
            # print "List at", i, ":", list(gp_mat[i+1,])
            new_vec = vector([ZZ(x) for x in list(gp_mat[i + 1,])])
            vector_list.append(new_vec)

        ## DIAGNOSTIC
        # print "number_of_vecs = ", number_of_vecs
        # print "vector_list = ", vector_list

        ## Make a matrix from the short vectors
        if len(vector_list) > 0:
            M1 = Matrix(vector_list)

        ## DIAGNOSTIC
        # print "matrix of vectors = \n", M1
        # print "rank of the matrix = ", M1.rank()

    # print " vec_len = ", vec_len
    # print M1

    ## Organize these vectors by length (and also introduce their negatives)
    max_len = vec_len / 2
    vector_list_by_length = [[] for _ in range(max_len + 1)]
    for v in vector_list:
        l = self(v)
        vector_list_by_length[l].append(v)
        vector_list_by_length[l].append(vector([-x for x in v]))

    ## Make a matrix from the column vectors (in order of ascending length).
    sorted_list = []
    for i in range(len(vector_list_by_length)):
        for v in vector_list_by_length[i]:
            sorted_list.append(v)
    sorted_matrix = Matrix(sorted_list).transpose()

    ## Determine a basis of vectors of minimal length
    pivots = sorted_matrix.pivots()
    basis = [sorted_matrix.column(i) for i in pivots]
    pivot_lengths = [self(v) for v in basis]

    ## DIAGNOSTIC
    # print "basis = ", basis
    # print "pivot_lengths = ", pivot_lengths

    ## Cache the result
    self.__basis_of_short_vectors = basis
    self.__basis_of_short_vectors_lenghts = pivot_lengths

    ## Return the appropriate result
    if show_lengths:
        return basis, pivot_lengths
    else:
        return basis
def basis_of_short_vectors(self, show_lengths=False, safe_flag=True):
    """
    Return a basis for `ZZ^n` made of vectors with minimal lengths Q(`v`).

    The safe_flag allows us to select whether we want a copy of the
    output, or the original output.  By default safe_flag = True, so
    we return a copy of the cached information.  If this is set to
    False, then the routine is much faster but the return values are
    vulnerable to being corrupted by the user.

    OUTPUT:
        a list of vectors, and optionally a list of values for each vector.

    EXAMPLES::

        sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7])
        sage: Q.basis_of_short_vectors()
        [(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)]
        sage: Q.basis_of_short_vectors(True)
        ([(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)], [1, 3, 5, 7])

    """
    ## Try to use the cached results
    try:
        ## Return the appropriate result
        if show_lengths:
            if safe_flag:
                return deep_copy(self.__basis_of_short_vectors), deepcopy(self.__basis_of_short_vectors_lengths)
            else:
                return self.__basis_of_short_vectors, self.__basis_of_short_vectors_lengths
        else:
            if safe_flag:
                return deepcopy(self.__basis_of_short_vectors)
            else:
                return deepcopy(self.__basis_of_short_vectors)
    except Exception:
        pass


    ## Set an upper bound for the number of vectors to consider
    Max_number_of_vectors = 10000

    ## Generate a PARI matrix string for the associated Hessian matrix
    M_str = str(gp(self.matrix()))


    ## Run through all possible minimal lengths to find a spanning set of vectors
    n = self.dim()
    #MS = MatrixSpace(QQ, n)
    M1 = Matrix([[0]])
    vec_len = 0
    while M1.rank() < n:

        ## DIAGONSTIC
        #print
        #print "Starting with vec_len = ", vec_len
        #print "M_str = ", M_str

        vec_len += 1
        gp_mat = gp.qfminim(M_str, vec_len, Max_number_of_vectors)[3].mattranspose()
        number_of_vecs = ZZ(gp_mat.matsize()[1])
        vector_list = []
        for i in range(number_of_vecs):
            #print "List at", i, ":", list(gp_mat[i+1,])
            new_vec = vector([ZZ(x)  for x in list(gp_mat[i+1,])])
            vector_list.append(new_vec)


        ## DIAGNOSTIC
        #print "number_of_vecs = ", number_of_vecs
        #print "vector_list = ", vector_list


        ## Make a matrix from the short vectors
        if len(vector_list) > 0:
            M1 = Matrix(vector_list)


        ## DIAGNOSTIC
        #print "matrix of vectors = \n", M1
        #print "rank of the matrix = ", M1.rank()



    #print " vec_len = ", vec_len
    #print M1


    ## Organize these vectors by length (and also introduce their negatives)
    max_len = vec_len // 2
    vector_list_by_length = [[]  for _ in range(max_len + 1)]
    for v in vector_list:
        l = self(v)
        vector_list_by_length[l].append(v)
        vector_list_by_length[l].append(vector([-x  for x in v]))


    ## Make a matrix from the column vectors (in order of ascending length).
    sorted_list = []
    for i in range(len(vector_list_by_length)):
        for v in vector_list_by_length[i]:
            sorted_list.append(v)
    sorted_matrix = Matrix(sorted_list).transpose()


    ## Determine a basis of vectors of minimal length
    pivots = sorted_matrix.pivots()
    basis = [sorted_matrix.column(i) for i in pivots]
    pivot_lengths = [self(v)  for v in basis]


    ## DIAGNOSTIC
    #print "basis = ", basis
    #print "pivot_lengths = ", pivot_lengths


    ## Cache the result
    self.__basis_of_short_vectors = basis
    self.__basis_of_short_vectors_lenghts = pivot_lengths


    ## Return the appropriate result
    if show_lengths:
        return basis, pivot_lengths
    else:
        return basis
예제 #3
0
def short_vector_list_up_to_length(self, len_bound, up_to_sign_flag=False):
    """
    Return a list of lists of short vectors `v`, sorted by length, with
    Q(`v`) < len_bound.  The list in output `[i]` indexes all vectors of
    length `i`.  If the up_to_sign_flag is set to True, then only one of
    the vectors of the pair `[v, -v]` is listed.

    Note:  This processes the PARI/GP output to always give elements of type `ZZ`.

    OUTPUT:
        a list of lists of vectors.

    EXAMPLES::

        sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7])
        sage: Q.short_vector_list_up_to_length(3)
        [[(0, 0, 0, 0)], [(1, 0, 0, 0), (-1, 0, 0, 0)], []]
        sage: Q.short_vector_list_up_to_length(4)
        [[(0, 0, 0, 0)],
         [(1, 0, 0, 0), (-1, 0, 0, 0)],
         [],
         [(0, 1, 0, 0), (0, -1, 0, 0)]]
        sage: Q.short_vector_list_up_to_length(5)
        [[(0, 0, 0, 0)],
         [(1, 0, 0, 0), (-1, 0, 0, 0)],
         [],
         [(0, 1, 0, 0), (0, -1, 0, 0)],
         [(1, 1, 0, 0),
         (-1, -1, 0, 0),
         (-1, 1, 0, 0),
         (1, -1, 0, 0),
         (2, 0, 0, 0),
         (-2, 0, 0, 0)]]
        sage: Q.short_vector_list_up_to_length(5, True)
        [[(0, 0, 0, 0)],
         [(1, 0, 0, 0)],
         [],
         [(0, 1, 0, 0)],
         [(1, 1, 0, 0), (-1, 1, 0, 0), (2, 0, 0, 0)]]
        sage: Q = QuadraticForm(matrix(6, [2, 1, 1, 1, -1, -1, 1, 2, 1, 1, -1, -1, 1, 1, 2, 0, -1, -1, 1, 1, 0, 2, 0, -1, -1, -1, -1, 0, 2, 1, -1, -1, -1, -1, 1, 2]))
        sage: vs = Q.short_vector_list_up_to_length(40)     #long time

    The cases of ``len_bound < 2`` led to exception or infinite runtime before.

    ::

        sage: Q.short_vector_list_up_to_length(0)
        []
        sage: Q.short_vector_list_up_to_length(1)
        [[(0, 0, 0, 0, 0, 0)]]

    In the case of quadratic forms that are not positive definite an error is raised.

    ::

        sage: QuadraticForm(matrix(2, [2, 0, 0, -2])).short_vector_list_up_to_length(3)
        Traceback (most recent call last):
        ...
        ValueError: Quadratic form must be positive definite in order to enumerate short vectors

    Sometimes, Pari does not compute short vectors correctly.  It returns too long vectors.

    ::

        sage: mat = matrix(2, [72, 12, 12, 120])                         #long time
        sage: len_bound = 22953421                                       #long time
        sage: gp_mat = gp.qfminim(str(gp(mat)), 2 * len_bound - 2)[3]    #long time
        sage: rows = [ map(ZZ, str(gp_mat[i,])[1:-1].split(',')) for i in range(1, gp_mat.matsize()[1] + 1) ]   #long time
        sage: vec_list = map(vector, zip(*rows))                         #long time
        sage: eval_v_cython = cython_lambda( ", ".join( "int a{0}".format(i) for i in range(2) ), " + ".join( "{coeff} * a{i} * a{j}".format(coeff = mat[i,j], i = i, j = j) for i in range(2) for j in range(2) ) )   #long time
        sage: any( eval_v_cython(*v) == 2 * 22955664 for v in vec_list ) # 22955664 > 22953421 = len_bound   #long time
        True
    """
    if not self.is_positive_definite():
        raise ValueError(
            "Quadratic form must be positive definite in order to enumerate short vectors"
        )

    ## Generate a PARI matrix string for the associated Hessian matrix
    M_str = str(gp(self.matrix()))

    if len_bound <= 0:
        return list()
    elif len_bound == 1:
        return [[(vector([ZZ(0) for _ in range(self.dim())]))]]

    ## Generate the short vectors
    gp_mat = gp.qfminim(M_str, 2 * len_bound - 2)[3]

    ## We read all n-th entries at once so that not too many sage[...] variables are
    ## used.  This is important when to many vectors are returned.
    rows = [
        map(ZZ,
            str(gp_mat[i, ])[1:-1].split(','))
        for i in range(1,
                       gp_mat.matsize()[1] + 1)
    ]
    vec_list = map(vector, zip(*rows))

    if len(vec_list) > 500:
        eval_v_cython = cython_lambda(
            ", ".join("int a{0}".format(i) for i in range(self.dim())),
            " + ".join(
                "{coeff} * a{i} * a{j}".format(coeff=self[i, j], i=i, j=j)
                for i in range(self.dim()) for j in range(i, self.dim())))
        eval_v = lambda v: eval_v_cython(*v)
    else:
        eval_v = self

    ## Sort the vectors into lists by their length
    vec_sorted_list = [list() for i in range(len_bound)]
    for v in vec_list:
        v_evaluated = eval_v(v)
        try:
            vec_sorted_list[v_evaluated].append(v)
            if not up_to_sign_flag:
                vec_sorted_list[v_evaluated].append(-v)
        except IndexError:
            ## We deal with a Pari but, that returns longer vectors that requested.
            ## E.g. : self.matrix() == matrix(2, [72, 12, 12, 120])
            ##        len_bound = 22953421
            ## gives maximal length 22955664
            pass

    ## Add the zero vector by hand
    zero_vec = vector([ZZ(0) for _ in range(self.dim())])
    vec_sorted_list[0].append(zero_vec)

    ## Return the sorted list
    return vec_sorted_list
예제 #4
0
def short_vector_list_up_to_length(self, len_bound, up_to_sign_flag=False):
    """
    Return a list of lists of short vectors `v`, sorted by length, with
    Q(`v`) < len_bound.  The list in output `[i]` indexes all vectors of
    length `i`.  If the up_to_sign_flag is set to True, then only one of
    the vectors of the pair `[v, -v]` is listed.

    Note:  This processes the PARI/GP output to always give elements of type `ZZ`.

    OUTPUT:
        a list of lists of vectors.

    EXAMPLES::

        sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7])
        sage: Q.short_vector_list_up_to_length(3)
        [[(0, 0, 0, 0)], [(1, 0, 0, 0), (-1, 0, 0, 0)], []]
        sage: Q.short_vector_list_up_to_length(4)
        [[(0, 0, 0, 0)],
         [(1, 0, 0, 0), (-1, 0, 0, 0)],
         [],
         [(0, 1, 0, 0), (0, -1, 0, 0)]]
        sage: Q.short_vector_list_up_to_length(5)
        [[(0, 0, 0, 0)],
         [(1, 0, 0, 0), (-1, 0, 0, 0)],
         [],
         [(0, 1, 0, 0), (0, -1, 0, 0)],
         [(1, 1, 0, 0),
         (-1, -1, 0, 0),
         (-1, 1, 0, 0),
         (1, -1, 0, 0),
         (2, 0, 0, 0),
         (-2, 0, 0, 0)]]
        sage: Q.short_vector_list_up_to_length(5, True)
        [[(0, 0, 0, 0)],
         [(1, 0, 0, 0)],
         [],
         [(0, 1, 0, 0)],
         [(1, 1, 0, 0), (-1, 1, 0, 0), (2, 0, 0, 0)]]
        sage: Q = QuadraticForm(matrix(6, [2, 1, 1, 1, -1, -1, 1, 2, 1, 1, -1, -1, 1, 1, 2, 0, -1, -1, 1, 1, 0, 2, 0, -1, -1, -1, -1, 0, 2, 1, -1, -1, -1, -1, 1, 2]))
        sage: vs = Q.short_vector_list_up_to_length(40)     #long time

    The cases of ``len_bound < 2`` led to exception or infinite runtime before.

    ::

        sage: Q.short_vector_list_up_to_length(0)
        []
        sage: Q.short_vector_list_up_to_length(1)
        [[(0, 0, 0, 0, 0, 0)]]

    In the case of quadratic forms that are not positive definite an error is raised.

    ::

        sage: QuadraticForm(matrix(2, [2, 0, 0, -2])).short_vector_list_up_to_length(3)
        Traceback (most recent call last):
        ...
        ValueError: Quadratic form must be positive definite in order to enumerate short vectors

    Sometimes, Pari does not compute short vectors correctly.  It returns too long vectors.

    ::

        sage: mat = matrix(2, [72, 12, 12, 120])                         #long time
        sage: len_bound = 22953421                                       #long time
        sage: gp_mat = gp.qfminim(str(gp(mat)), 2 * len_bound - 2)[3]    #long time
        sage: rows = [ map(ZZ, str(gp_mat[i,])[1:-1].split(',')) for i in range(1, gp_mat.matsize()[1] + 1) ]   #long time
        sage: vec_list = map(vector, zip(*rows))                         #long time
        sage: eval_v_cython = cython_lambda( ", ".join( "int a{0}".format(i) for i in range(2) ), " + ".join( "{coeff} * a{i} * a{j}".format(coeff = mat[i,j], i = i, j = j) for i in range(2) for j in range(2) ) )   #long time
        sage: any( eval_v_cython(*v) == 2 * 22955664 for v in vec_list ) # 22955664 > 22953421 = len_bound   #long time
        True
    """
    if not self.is_positive_definite() :
        raise ValueError( "Quadratic form must be positive definite in order to enumerate short vectors" )

    ## Generate a PARI matrix string for the associated Hessian matrix
    M_str = str(gp(self.matrix()))

    if len_bound <= 0 :
        return list()
    elif len_bound == 1 :
        return [ [(vector([ZZ(0) for _ in range(self.dim())]))] ]

    ## Generate the short vectors
    gp_mat = gp.qfminim(M_str, 2*len_bound - 2)[3]

    ## We read all n-th entries at once so that not too many sage[...] variables are
    ## used.  This is important when to many vectors are returned.
    rows = [ map(ZZ, str(gp_mat[i,])[1:-1].split(','))
             for i in range(1, gp_mat.matsize()[1] + 1) ]
    vec_list = map(vector, zip(*rows))

    if len(vec_list) > 500 :
        eval_v_cython = cython_lambda( ", ".join( "int a{0}".format(i) for i in range(self.dim()) ),
                                       " + ".join( "{coeff} * a{i} * a{j}".format(coeff = self[i,j], i = i, j = j)
                                                   for i in range(self.dim()) for j in range(i, self.dim()) ) )
        eval_v = lambda v: eval_v_cython(*v)
    else :
        eval_v = self

    ## Sort the vectors into lists by their length
    vec_sorted_list = [list() for i in range(len_bound)]
    for v in vec_list:
        v_evaluated = eval_v(v)
        try :
            vec_sorted_list[v_evaluated].append(v)
            if not up_to_sign_flag :
                vec_sorted_list[v_evaluated].append(-v)
        except IndexError :
            ## We deal with a Pari but, that returns longer vectors that requested.
            ## E.g. : self.matrix() == matrix(2, [72, 12, 12, 120])
            ##        len_bound = 22953421
            ## gives maximal length 22955664
            pass

    ## Add the zero vector by hand
    zero_vec = vector([ZZ(0)  for _ in range(self.dim())])
    vec_sorted_list[0].append(zero_vec)

    ## Return the sorted list
    return vec_sorted_list
def short_vector_list_up_to_length(self, len_bound, up_to_sign_flag=False):
    """
    Return a list of lists of short vectors `v`, sorted by length, with
    Q(`v`) < len_bound.  The list in output `[i]` indexes all vectors of
    length `i`.  If the up_to_sign_flag is set to True, then only one of
    the vectors of the pair `[v, -v]` is listed.

    Note:  This processes the PARI/GP output to always give elements of type `ZZ`.

    OUTPUT:
        a list of lists of vectors.

    EXAMPLES::
    
        sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7])
        sage: Q.short_vector_list_up_to_length(3)
        [[(0, 0, 0, 0)], [(1, 0, 0, 0), [-1, 0, 0, 0]], []]
        sage: Q.short_vector_list_up_to_length(4)
        [[(0, 0, 0, 0)],
         [(1, 0, 0, 0), [-1, 0, 0, 0]],
         [],
         [(0, 1, 0, 0), [0, -1, 0, 0]]]
        sage: Q.short_vector_list_up_to_length(5)
        [[(0, 0, 0, 0)],
         [(1, 0, 0, 0), [-1, 0, 0, 0]],
         [],
         [(0, 1, 0, 0), [0, -1, 0, 0]],
         [(1, 1, 0, 0),
         [-1, -1, 0, 0],
         (-1, 1, 0, 0),
         [1, -1, 0, 0],
         (2, 0, 0, 0),
         [-2, 0, 0, 0]]]
        sage: Q.short_vector_list_up_to_length(5, True)
        [[(0, 0, 0, 0)],
         [(1, 0, 0, 0)],
         [],
         [(0, 1, 0, 0)],
         [(1, 1, 0, 0), (-1, 1, 0, 0), (2, 0, 0, 0)]]
         
    """
    ## Set an upper bound for the number of vectors to consider
    Max_number_of_vectors = 10000

    ## Generate a PARI matrix string for the associated Hessian matrix
    M_str = str(gp(self.matrix()))

    ## Generate the short vectors
    gp_mat = gp.qfminim(M_str, 2 * len_bound - 2,
                        Max_number_of_vectors)[3].mattranspose()
    number_of_rows = gp_mat.matsize()[1]
    gp_mat_vector_list = [
        vector([ZZ(x) for x in gp_mat[i + 1, ]]) for i in range(number_of_rows)
    ]

    ## Sort the vectors into lists by their length
    vec_list = [[] for i in range(len_bound)]
    for v in gp_mat_vector_list:
        vec_list[self(v)].append(v)
        if up_to_sign_flag == False:
            vec_list[self(v)].append([-x for x in v])

    ## Add the zero vector by hand
    zero_vec = vector([ZZ(0) for _ in range(self.dim())])
    vec_list[0].append(zero_vec)

    ## Return the sorted list
    return vec_list
def short_vector_list_up_to_length(self, len_bound, up_to_sign_flag=False):
    """
    Return a list of lists of short vectors `v`, sorted by length, with
    Q(`v`) < len_bound.  The list in output `[i]` indexes all vectors of
    length `i`.  If the up_to_sign_flag is set to True, then only one of
    the vectors of the pair `[v, -v]` is listed.

    Note:  This processes the PARI/GP output to always give elements of type `ZZ`.

    OUTPUT:
        a list of lists of vectors.

    EXAMPLES::
    
        sage: Q = DiagonalQuadraticForm(ZZ, [1,3,5,7])
        sage: Q.short_vector_list_up_to_length(3)
        [[(0, 0, 0, 0)], [(1, 0, 0, 0), [-1, 0, 0, 0]], []]
        sage: Q.short_vector_list_up_to_length(4)
        [[(0, 0, 0, 0)],
         [(1, 0, 0, 0), [-1, 0, 0, 0]],
         [],
         [(0, 1, 0, 0), [0, -1, 0, 0]]]
        sage: Q.short_vector_list_up_to_length(5)
        [[(0, 0, 0, 0)],
         [(1, 0, 0, 0), [-1, 0, 0, 0]],
         [],
         [(0, 1, 0, 0), [0, -1, 0, 0]],
         [(1, 1, 0, 0),
         [-1, -1, 0, 0],
         (-1, 1, 0, 0),
         [1, -1, 0, 0],
         (2, 0, 0, 0),
         [-2, 0, 0, 0]]]
        sage: Q.short_vector_list_up_to_length(5, True)
        [[(0, 0, 0, 0)],
         [(1, 0, 0, 0)],
         [],
         [(0, 1, 0, 0)],
         [(1, 1, 0, 0), (-1, 1, 0, 0), (2, 0, 0, 0)]]
         
    """
    ## Set an upper bound for the number of vectors to consider
    Max_number_of_vectors = 10000

    ## Generate a PARI matrix string for the associated Hessian matrix
    M_str = str(gp(self.matrix()))

    ## Generate the short vectors
    gp_mat = gp.qfminim(M_str, 2*len_bound-2, Max_number_of_vectors)[3].mattranspose()
    number_of_rows = gp_mat.matsize()[1]
    gp_mat_vector_list = [vector([ZZ(x)  for x in gp_mat[i+1,]])  for i in range(number_of_rows)]

    ## Sort the vectors into lists by their length
    vec_list = [[]  for i in range(len_bound)]
    for v in gp_mat_vector_list:
        vec_list[self(v)].append(v)
        if up_to_sign_flag == False:
            vec_list[self(v)].append([-x  for x in v])

    ## Add the zero vector by hand
    zero_vec = vector([ZZ(0)  for _ in range(self.dim())])
    vec_list[0].append(zero_vec)  

    ## Return the sorted list
    return vec_list