# Ticket #8922: trac_8922-reviewer.patch

File trac_8922-reviewer.patch, 31.5 KB (added by mvngu, 11 years ago)
• ## sage/graphs/base/c_graph.pxd

# HG changeset patch
# User Minh Van Nguyen <nguyenminh2@gmail.com>
# Date 1275581569 25200
# Parent  34e31a8c91d4dba1960a1012750538d18479a904
#8922: reviewer patch: induced subgraph search; unit tests for cdef functions and methods

diff --git a/sage/graphs/base/c_graph.pxd b/sage/graphs/base/c_graph.pxd
 a cpdef add_arc(self, int u, int v) cpdef bint has_arc(self, int u, int v) cpdef del_all_arcs(self, int u, int v) cdef int *adjacency_sequence(self, int n, int *vertices, int v) cpdef list all_arcs(self, int u, int v) cpdef list in_neighbors(self, int v) cpdef list out_neighbors(self, int u)
• ## sage/graphs/base/c_graph.pyx

diff --git a/sage/graphs/base/c_graph.pyx b/sage/graphs/base/c_graph.pyx
 a """ raise NotImplementedError() cdef int *adjacency_sequence(self, int n, int *vertices, int v): r""" Returns the adjacency sequence corresponding to a list of vertices and a vertex. See the function _test_adjacency_sequence() of dense_graph.pyx and sparse_graph.pyx for unit tests. INPUT: - n -- nonnegative integer; the maximum index in vertices up to which we want to consider. If n = 0, we only want to know if v is adjacent to vertices. If n = 1, we want to know if v is adjacent to both vertices and vertices. Let k be the length of vertices. If 0 <= n < k, then we want to know if v is adjacent to each of vertices, vertices, ..., vertices[n]. Where n = k - 1, then we consider all elements in the list vertices. - vertices -- list of vertices. - v -- a vertex. OUTPUT: Returns a list of n integers, whose i-th element is set to 1 iff v is adjacent to vertices[i]. """ cdef int i = 0 cdef int *seq = sage_malloc(n * sizeof(int)) for 0 <= i < n: seq[i] = 1 if self.has_arc_unsafe(v, vertices[i]) else 0 return seq cpdef list all_arcs(self, int u, int v): """ Return the labels of all arcs from u to v.
• ## sage/graphs/base/dense_graph.pxd

diff --git a/sage/graphs/base/dense_graph.pxd b/sage/graphs/base/dense_graph.pxd
 a cdef int radix_mod_mask cdef int num_longs cdef unsigned long *edges cdef int * adjacency_sequence(self, int n, int * vertices, int vertex) # Method declarations inherited from CGraph: # cdef int add_arc_unsafe(self, int, int)
• ## sage/graphs/base/dense_graph.pyx

diff --git a/sage/graphs/base/dense_graph.pyx b/sage/graphs/base/dense_graph.pyx
 a self.check_vertex(u) self.check_vertex(v) self.del_arc_unsafe(u,v) cdef int * adjacency_sequence(self, int n, int * vertices, int vertex): r""" Returns the adjacency sequence corresponding to a list of vertices, and a vertex INPUT: - n -- number of elements in vertices - vertices -- list of vertices - vertex OUTPUT: Returns a list of n integers, whose i th element is set to 1 iif vertex is adjacent to vertices[i] """ cdef int i = 0 cdef int * line line = sage_malloc(n*sizeof(int)) for 0 <= i < n: line[i] = 1 if self.has_arc_unsafe(vertices[i],vertex) else 0 return line ################################### # Neighbor functions sage_free(neighbors) return output ############################## # Further tests. Unit tests for methods, functions, classes defined with cdef. ############################## def random_stress(): """ if Gnew.in_degrees[i] != Gold.in_degree(i): raise RuntimeError( "NO" ) def _test_adjacency_sequence(): """ Randomly test the method DenseGraph.adjacency_sequence(). No output indicates that no errors were found. TESTS:: sage: from sage.graphs.base.dense_graph import _test_adjacency_sequence sage: _test_adjacency_sequence()  # long time """ from sage.graphs.digraph import DiGraph from sage.graphs.graph_generators import GraphGenerators from sage.misc.prandom import randint, random low = 0 high = 500 randg = DiGraph(GraphGenerators().RandomGNP(randint(low, high), random())) n = randg.order() cdef DenseGraph g = DenseGraph(n, verts=randg.vertices(), arcs=randg.edges(labels=False)) assert g._num_verts() == randg.order(), ( "Graph order mismatch: %s vs. %s" % (g._num_verts(), randg.order())) assert g._num_arcs() == randg.size(), ( "Graph size mismatch: %s vs. %s" % (g._num_arcs(), randg.size())) M = randg.adjacency_matrix() cdef int *V = sage_malloc(n * sizeof(int)) cdef int i = 0 for v in randg.vertex_iterator(): V[i] = v i += 1 cdef int *seq for 0 <= i < randint(50, 101): u = randint(low, n - 1) seq = g.adjacency_sequence(n, V, u) A = [seq[k] for k in range(n)] try: assert A == list(M[u]) except AssertionError: sage_free(V) sage_free(seq) raise AssertionError("Graph adjacency mismatch") sage_free(seq) sage_free(V) ########################################### # Dense Graph Backend ########################################### NotImplementedError: Dense graphs do not support edge labels. """ raise NotImplementedError("Dense graphs do not support edge labels.")
• ## sage/graphs/base/sparse_graph.pyx

diff --git a/sage/graphs/base/sparse_graph.pyx b/sage/graphs/base/sparse_graph.pyx
 a raise RuntimeError("Label (%d) must be a nonnegative integer."%l) return self.has_arc_label_unsafe(u,v,l) == 1 ############################## # Further tests. Unit tests for methods, functions, classes defined with cdef. ############################## def random_stress(): """ Randomly search for mistakes in the code. if Gnew.has_arc_unsafe(i,j) != Gold.has_edge(i,j): raise RuntimeError( "NO" ) def _test_adjacency_sequence(): """ Randomly test the method SparseGraph.adjacency_sequence(). No output indicates that no errors were found. TESTS:: sage: from sage.graphs.base.sparse_graph import _test_adjacency_sequence sage: _test_adjacency_sequence()  # long time """ from sage.graphs.digraph import DiGraph from sage.graphs.graph_generators import GraphGenerators from sage.misc.prandom import randint, random low = 0 high = 1000 randg = DiGraph(GraphGenerators().RandomGNP(randint(low, high), random())) n = randg.order() # set all labels to 0 E = [(u, v, 0) for u, v in randg.edges(labels=False)] cdef SparseGraph g = SparseGraph(n, verts=randg.vertices(), arcs=E) assert g._num_verts() == randg.order(), ( "Graph order mismatch: %s vs. %s" % (g._num_verts(), randg.order())) assert g._num_arcs() == randg.size(), ( "Graph size mismatch: %s vs. %s" % (g._num_arcs(), randg.size())) M = randg.adjacency_matrix() cdef int *V = sage_malloc(n * sizeof(int)) cdef int i = 0 for v in randg.vertex_iterator(): V[i] = v i += 1 cdef int *seq for 0 <= i < randint(50, 101): u = randint(low, n - 1) seq = g.adjacency_sequence(n, V, u) A = [seq[k] for k in range(n)] try: assert A == list(M[u]) except AssertionError: sage_free(V) sage_free(seq) raise AssertionError("Graph adjacency mismatch") sage_free(seq) sage_free(V) ########################################### # Sparse Graph Backend ########################################### self._cg.del_arc_label(v_int, u_int, ll_int) self._cg.add_arc_label(u_int, v_int, l_int) self._cg.add_arc_label(v_int, u_int, l_int)
• ## sage/graphs/generic_graph.py

diff --git a/sage/graphs/generic_graph.py b/sage/graphs/generic_graph.py
 a if not inplace: return G def induced_subgraph_search(self, G): r""" Returns an induced copy of G in self. INPUT: - G -- the graph whose copy we are looking for in self def subgraph_search(self, G, induced=False): r""" Returns a copy of G in self. INPUT: - G -- the graph whose copy we are looking for in self. - induced -- boolean (default: False). Whether or not to search for an induced copy of G in self. OUTPUT: - If induced=False, return a copy of G in this graph. Otherwise, return an induced copy of G in self. If G is the empty graph, return the empty graph since it is a subgraph of every graph. Now suppose G is not the empty graph. If there is no copy (induced or otherwise) of G in self, we return None. ALGORITHM: Brute-force EXAMPLES: A Petersen Graph contains a P_5 :: Brute-force search. EXAMPLES: The Petersen graph contains the path graph P_5:: sage: g = graphs.PetersenGraph() sage: h1 = g.induced_subgraph_search(graphs.PathGraph(5)) sage: h1 sage: h1 = g.subgraph_search(graphs.PathGraph(5)); h1 Subgraph of (Petersen graph): Graph on 5 vertices sage: h1.vertices() [0, 1, 2, 3, 4] sage: I1 = g.subgraph_search(graphs.PathGraph(5), induced=True); I1 Subgraph of (Petersen graph): Graph on 5 vertices sage: I1.vertices() [0, 1, 2, 3, 8] It also contains a Claw (K_{1,3}):: sage: h2 = g.induced_subgraph_search(graphs.ClawGraph()) sage: h2 It also contains the claw K_{1,3}:: sage: h2 = g.subgraph_search(graphs.ClawGraph()); h2 Subgraph of (Petersen graph): Graph on 4 vertices sage: h2.vertices() [0, 1, 4, 5] Of course both copies are isomorphic to the graphs we were looking for :: sage: h1.is_isomorphic(graphs.PathGraph(5)) sage: I2 = g.subgraph_search(graphs.ClawGraph(), induced=True); I2 Subgraph of (Petersen graph): Graph on 4 vertices sage: I2.vertices() [0, 1, 4, 5] Of course the induced copies are isomorphic to the graphs we were looking for:: sage: I1.is_isomorphic(graphs.PathGraph(5)) True sage: h2.is_isomorphic(graphs.ClawGraph()) sage: I2.is_isomorphic(graphs.ClawGraph()) True However, as it contains no induced subgraphs isomorphic to P_6, an exception is raised in this case :: sage: g.induced_subgraph_search(graphs.PathGraph(6)) Traceback (most recent call last): ... ValueError: No induced copy of the graph exists However, the Petersen graph does not contain a subgraph isomorphic to K_3:: sage: g.subgraph_search(graphs.CompleteGraph(3)) is None True Nor does it contain a nonempty induced subgraph isomorphic to P_6:: sage: g.subgraph_search(graphs.PathGraph(6), induced=True) is None True The empty graph is a subgraph of every graph:: sage: g.subgraph_search(graphs.EmptyGraph()) Graph on 0 vertices sage: g.subgraph_search(graphs.EmptyGraph(), induced=True) Graph on 0 vertices """ from sage.graphs.generic_graph_pyx import subgraph_search H = subgraph_search(self, G, induced = True) from sage.graphs.graph_generators import GraphGenerators if G.order() == 0: return GraphGenerators().EmptyGraph() H = subgraph_search(self, G, induced=induced) if H == []: raise ValueError('No induced copy of the graph exists') return self.subgraph(H) def subgraph_search(self, G): r""" Returns an of G included in self. INPUT: - G -- the graph whose copy we are looking for in self ALGORITHM: Brute-force EXAMPLES: A Petersen Graph contains a P_5 :: sage: g = graphs.PetersenGraph() sage: h1 = g.subgraph_search(graphs.PathGraph(5)) sage: h1 Subgraph of (Petersen graph): Graph on 5 vertices sage: h1.vertices() [0, 1, 2, 3, 4] It also contains a Claw (K_{1,3}):: sage: h2 = g.subgraph_search(graphs.ClawGraph()) sage: h2 Subgraph of (Petersen graph): Graph on 4 vertices sage: h2.vertices() [0, 1, 4, 5] However, as it contains no subgraph isomorphic to K_3, an exception is raised in this case :: sage: g.subgraph_search(graphs.CompleteGraph(3)) Traceback (most recent call last): ... ValueError: No copy of the graph exists """ from sage.graphs.generic_graph_pyx import subgraph_search H = subgraph_search(self, G) if H == []: raise ValueError('No copy of the graph exists') return None return self.subgraph(H) def random_subgraph(self, p, inplace=False):
• ## sage/graphs/generic_graph_pyx.pxd

diff --git a/sage/graphs/generic_graph_pyx.pxd b/sage/graphs/generic_graph_pyx.pxd
 a cdef class GenericGraph_pyx(SageObject): pass cdef inline bint vectors_equal(int n, int *a, int *b) cdef inline bint vectors_inferior(int n, int *a, int *b)
• ## sage/graphs/generic_graph_pyx.pyx

diff --git a/sage/graphs/generic_graph_pyx.pyx b/sage/graphs/generic_graph_pyx.pyx
 a include '../ext/cdefs.pxi' include '../ext/stdsage.pxi' # import from Python standard library from random import random # import from third-party library from sage.graphs.base.dense_graph cimport DenseGraph from random import random cdef extern from *: double sqrt(double) # Exhaustive search in graphs cpdef subgraph_search(G,H, induced = False): cpdef list subgraph_search(G, H, bint induced=False): r""" Returns a set of vertices in G representing a copy of H Returns a set of vertices in G representing a copy of H. ALGORITHM: This algorithm is a brute-force search. Let V(H)=\{h_1,\dots,h_k\}.  It first tries Let V(H) = \{h_1,\dots,h_k\}.  It first tries to find in G a possible representant of h_1, then a representant of h_2 compatible with h_1, then a representant of h_3 compatible with the first two, etc ... two, etc. This way, most of the times we need to test far less than \binom k!{|V(G)|}{k} subsets, and hope this brute-force This way, most of the time we need to test far less than k! \binom{|V(G)|}{k} subsets, and hope this brute-force technique can sometimes be useful. INPUT: - G, H -- graphs - G, H -- two graphs such that H is a subgraph of G. - induced (boolean) -- whether to require that the subgraph is an induced subgraph - induced -- boolean (default: False); whether to require that the subgraph is an induced subgraph. OUTPUT: A list of vertices inducing a copy of H. If none is found, A list of vertices inducing a copy of H in G. If none is found, an empty list is returned. EXAMPLE: EXAMPLES: A Petersen Graph contains an induced P_5 :: A Petersen graph contains an induced path graph P_5:: sage: from sage.graphs.generic_graph_pyx import subgraph_search sage: g = graphs.PetersenGraph() sage: subgraph_search(g, graphs.PathGraph(5), induced = True) sage: subgraph_search(g, graphs.PathGraph(5), induced=True) [0, 1, 2, 3, 8] It also contains a Claw (K_{1,3}):: It also contains a the claw K_{1,3}:: sage: subgraph_search(g, graphs.ClawGraph()) [0, 1, 4, 5] Though it contains no induced P_6 :: Though it contains no induced P_6:: sage: subgraph_search(g, graphs.PathGraph(6), induced = True) sage: subgraph_search(g, graphs.PathGraph(6), induced=True) [] TESTS: Let G and H be graphs having orders m and n, respectively. If m < n, then there are no copies of H in G:: sage: from sage.graphs.generic_graph_pyx import subgraph_search sage: m = randint(100, 200) sage: n = randint(m + 1, 300) sage: G = graphs.RandomGNP(m, random()) sage: H = graphs.RandomGNP(n, random()) sage: G.order() < H.order() True sage: subgraph_search(G, H) [] """ # TODO: This is a brute-force search and can be very inefficient. Write # a more efficient subgraph search implementation. cdef int ng = G.order() cdef int nh = H.order() if ng < nh: return [] cdef int i, j, k cdef int * tmp_array cdef (int) (*is_admissible) (int, int *, int *) cdef int *tmp_array cdef (bint) (*is_admissible) (int, int *, int *) if induced: is_admissible = vectors_equal else: is_admissible = vectors_inferior # Static copies of the two graphs for # more efficient operations # static copies of the two graphs for more efficient operations cdef DenseGraph g = DenseGraph(ng) cdef DenseGraph h = DenseGraph(nh) # Copying the matrices # copying the adjacency relations in both G and H i = 0 for l in G.adjacency_matrix(): for row in G.adjacency_matrix(): j = 0 for k in l: for k in row: if k: g.add_arc(i,j) j=j+1 i=i+1 g.add_arc(i, j) j += 1 i += 1 i = 0 for l in H.adjacency_matrix(): for row in H.adjacency_matrix(): j = 0 for k in l: for k in row: if k: h.add_arc(i,j) j=j+1 i=i+1 # A vertex is said to be busy if it is already part # of the partial copy of H in G cdef int * busy busy = sage_malloc(ng*sizeof(int)) memset(busy, 0, ng*sizeof(int)) # 0 is the first vertex we use, so it is at first # busy h.add_arc(i, j) j += 1 i += 1 # A vertex is said to be busy if it is already part of the partial copy # of H in G. cdef int *busy = sage_malloc(ng * sizeof(int)) memset(busy, 0, ng * sizeof(int)) # 0 is the first vertex we use, so it is at first busy busy = 1 # stack # stack -- list of the vertices which are part of the partial copy of H # in G. # # List of the vertices which are part of the # partial copy of H in G # # stack[i] is the integer corresponding # to the vertex of G representing # the i th vertex of H # stack[i] -- the integer corresponding to the vertex of G representing # the i-th vertex of H. # # stack[i] = -1 means that i is not represented # ... yet ! cdef int * stack stack = sage_malloc(nh*sizeof(int)) # ... yet! cdef int *stack = sage_malloc(nh * sizeof(int)) stack = 0 stack = -1 # number of representants we have already # found # set to 1 as vertex 0 is already part of the partial # copy of H ... # Number of representants we have already found. Set to 1 as vertex 0 # is already part of the partial copy of H in G. cdef int active = 1 # vertices is equal to range(nh), as an int * variable cdef int * vertices vertices = sage_malloc(nh*sizeof(int)) for 0<= i < nh: # vertices is equal to range(nh), as an int *variable cdef int *vertices = sage_malloc(nh * sizeof(int)) for 0 <= i < nh: vertices[i] = i # line_h[i] represents the adjacency sequence of vertex i # in h relatively to vertices 0...i-1 cdef int ** line_h line_h = sage_malloc(nh * sizeof(int *)) for 0<= i < nh: line_h[i] = h.adjacency_sequence( i, vertices, i) # in h relative to vertices 0, 1, ..., i-1 cdef int **line_h = sage_malloc(nh * sizeof(int *)) for 0 <= i < nh: line_h[i] = h.adjacency_sequence(i, vertices, i) # the sequence of vertices to be returned value = [] cdef list value = [] _sig_on # as long as there is a non-void partial copy of H in G while active: # If we are here and found nothing yet # we try the next possible vertex # as a representant of the active th # vertex of H i = stack[active] +1 # Looking for a vertex which is not busy # and compatible with the partial copy we have of H # If we are here and found nothing yet, we try the next possible # vertex as a representant of the active i-th vertex of H. i = stack[active] + 1 # Looking for a vertex that is not busy and compatible with the # partial copy we have of H. while i < ng: if busy[i] == 1: i = i + 1 if busy[i]: i += 1 else: tmp_array =  g.adjacency_sequence(active, stack, i) tmp_array = g.adjacency_sequence(active, stack, i) if is_admissible(active, tmp_array, line_h[active]): free(tmp_array) sage_free(tmp_array) break else: free(tmp_array) i = i + 1 # if we found none, it means that we can not extend the current copy of H # so we update the status of stack[active] # and prepare to change the previous vertex sage_free(tmp_array) i += 1 # If we found none, it means that we cannot extend the current copy # of H so we update the status of stack[active] and prepare to change # the previous vertex. if i >= ng: if stack[active] != -1: busy[stack[active]] = 0 stack[active] = -1 active=active-1 # If we have found a good representant of H's i^{th} vertex in G active -= 1 # If we have found a good representant of H's i-th vertex in G else: if stack[active] != -1: busy[stack[active]]=0 busy[stack[active]] = 0 stack[active] = i busy[stack[active]]=1 active = active + 1 # We have found our copy !!! busy[stack[active]] = 1 active += 1 # We have found our copy!!! if active == nh: g_vertices = G.vertices() value = [g_vertices[stack[i]] for i in xrange(nh)] break else: # we begin the search of the next vertex at 0 stack[active] = -1 sage_free(busy) sage_free(stack) sage_free(vertices) for 0<= i < nh: for 0 <= i < nh: sage_free(line_h[i]) sage_free(line_h) return value cdef int vectors_equal(int n, int * a, int * b): cdef inline bint vectors_equal(int n, int *a, int *b): r""" Tests whether two vectors given in argument are equal Tests whether the two given vectors are equal. Two integer vectors a = (a_1, a_2, \dots, a_n) and b = (b_1, b_2, \dots, b_n) are equal iff a_i = b_i for all i = 1, 2, \dots, n. See the function _test_vectors_equal_inferior() for unit tests. INPUT: - n -- length of the vectors - a,b -- the two vectors - n -- positive integer; length of the vectors. - a, b -- two vectors of integers. OUTPUT: - True if a and b are the same vector; False otherwise. """ cdef int i =0 for 0<= i < n: cdef int i = 0 for 0 <= i < n: if a[i] != b[i]: return False return True cdef int vectors_inferior(int n, int * a, int * b): cdef inline bint vectors_inferior(int n, int *a, int *b): r""" Tests whether the second vector of integer is larger than the first Tests whether the second vector of integers is inferior to the first. Let u = (u_1, u_2, \dots, u_k) and v = (v_1, v_2, \dots, v_k) be two integer vectors of equal length. Then u is said to be less than (or inferior to) v if u_i \leq v_i for all i = 1, 2, \dots, k. See the function _test_vectors_equal_inferior() for unit tests. Given two equal integer vectors u and v, u is inferior to v and vice versa. We could also define two vectors a and b to be equal if a is inferior to b and b is inferior to a. INPUT: - n -- length of the vectors - a,b -- the two vectors - n -- positive integer; length of the vectors. - a, b -- two vectors of integers. OUTPUT: - True if b is inferior to (or less than) a; False otherwise. """ cdef int i =0 for 0<= i < n: cdef int i = 0 for 0 <= i < n: if a[i] < b[i]: return False return True ############################## # Further tests. Unit tests for methods, functions, classes defined with cdef. ############################## def _test_vectors_equal_inferior(): """ Unit testing the function vectors_equal(). No output means that no errors were found in the random tests. TESTS:: sage: from sage.graphs.generic_graph_pyx import _test_vectors_equal_inferior sage: _test_vectors_equal_inferior() """ from sage.misc.prandom import randint n = randint(500, 10**3) cdef int *u = sage_malloc(n * sizeof(int)) cdef int *v = sage_malloc(n * sizeof(int)) cdef int i # equal vectors: u = v for 0 <= i < n: u[i] = randint(-10**6, 10**6) v[i] = u[i] try: assert vectors_equal(n, u, v) assert vectors_equal(n, v, u) # Since u and v are equal vectors, then u is inferior to v and v is # inferior to u. One could also define u and v as being equal if # u is inferior to v and vice versa. assert vectors_inferior(n, u, v) assert vectors_inferior(n, v, u) except AssertionError: sage_free(u) sage_free(v) raise AssertionError("Vectors u and v should be equal.") # Different vectors: u != v because we have u_j > v_j for some j. Thus, # u_i = v_i for 0 <= i < j and u_j > v_j. For j < k < n - 2, we could have: # (1) u_k = v_k, # (2) u_k < v_k, or # (3) u_k > v_k. # And finally, u_{n-1} < v_{n-1}. cdef int j = randint(1, n//2) cdef int k for 0 <= i < j: u[i] = randint(-10**6, 10**6) v[i] = u[i] u[j] = randint(-10**6, 10**6) v[j] = u[j] - randint(1, 10**6) for j < k < n: u[k] = randint(-10**6, 10**6) v[k] = randint(-10**6, 10**6) u[n - 1] = v[n - 1] - randint(1, 10**6) try: assert not vectors_equal(n, u, v) assert not vectors_equal(n, v, u) # u is not inferior to v because at least u_j > v_j assert u[j] > v[j] assert not vectors_inferior(n, v, u) # v is not inferior to u because at least v_{n-1} > u_{n-1} assert v[n - 1] > u[n - 1] assert not vectors_inferior(n, u, v) except AssertionError: sage_free(u) sage_free(v) raise AssertionError("".join([ "Vectors u and v should not be equal. ", "u should not be inferior to v, and vice versa."])) # Different vectors: u != v because we have u_j < v_j for some j. Thus, # u_i = v_i for 0 <= i < j and u_j < v_j. For j < k < n - 2, we could have: # (1) u_k = v_k, # (2) u_k < v_k, or # (3) u_k > v_k. # And finally, u_{n-1} > v_{n-1}. j = randint(1, n//2) for 0 <= i < j: u[i] = randint(-10**6, 10**6) v[i] = u[i] u[j] = randint(-10**6, 10**6) v[j] = u[j] + randint(1, 10**6) for j < k < n: u[k] = randint(-10**6, 10**6) v[k] = randint(-10**6, 10**6) u[n - 1] = v[n - 1] + randint(1, 10**6) try: assert not vectors_equal(n, u, v) assert not vectors_equal(n, v, u) # u is not inferior to v because at least u_{n-1} > v_{n-1} assert u[n - 1] > v[n - 1] assert not vectors_inferior(n, v, u) # v is not inferior to u because at least u_j < v_j assert u[j] < v[j] assert not vectors_inferior(n, u, v) except AssertionError: sage_free(u) sage_free(v) raise AssertionError("".join([ "Vectors u and v should not be equal. ", "u should not be inferior to v, and vice versa."])) # different vectors u != v # What's the probability of two random vectors being equal? for 0 <= i < n: u[i] = randint(-10**6, 10**6) v[i] = randint(-10**6, 10**6) try: assert not vectors_equal(n, u, v) assert not vectors_equal(n, v, u) except AssertionError: sage_free(u) sage_free(v) raise AssertionError("Vectors u and v should not be equal.") # u is inferior to v, but v is not inferior to u for 0 <= i < n: v[i] = randint(-10**6, 10**6) u[i] = randint(-10**6, 10**6) while u[i] > v[i]: u[i] = randint(-10**6, 10**6) try: assert not vectors_equal(n, u, v) assert not vectors_equal(n, v, u) assert vectors_inferior(n, v, u) assert not vectors_inferior(n, u, v) except AssertionError: raise AssertionError( "u should be inferior to v, but v is not inferior to u.") finally: sage_free(u) sage_free(v)