Ticket #11046: trac_11046.patch

File trac_11046.patch, 10.2 KB (added by ncohen, 10 years ago)
  • sage/graphs/base/sparse_graph.pyx

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1301158401 -3600
    # Node ID dac000bf6a5fdfedba7876d52171958e3b3e1405
    # Parent  c149091735389012583604eed9897d1ab49b2151
    trac 11046 - Some comments in the code of SparseGraph
    
    diff -r c14909173538 -r dac000bf6a5f sage/graphs/base/sparse_graph.pyx
    a b  
    302302            i = i << 1
    303303        self.hash_length = i
    304304        self.hash_mask = i - 1
     305
     306        # Allocating memory
    305307        self.vertices = <SparseGraphBTNode **> \
    306308          sage_malloc(nverts * self.hash_length * sizeof(SparseGraphBTNode *))
    307309        self.in_degrees = <int *> sage_malloc(nverts * sizeof(int))
    308310        self.out_degrees = <int *> sage_malloc(nverts * sizeof(int))
     311
     312        # Checking the memory was actually allocated
    309313        if not self.vertices or not self.in_degrees or not self.out_degrees:
    310314            if self.vertices: sage_free(self.vertices)
    311315            if self.in_degrees: sage_free(self.in_degrees)
    312316            if self.out_degrees: sage_free(self.out_degrees)
    313317            raise RuntimeError("Failure allocating memory.")
    314         for i from 0 <= i < nverts * self.hash_length:
    315             self.vertices[i] = NULL
    316         for i from 0 <= i < nverts:
    317             self.in_degrees[i] = 0
    318             self.out_degrees[i] = 0
     318
     319        # Initializing variables:
     320        #
     321        # self.vertices[i] = 0
     322        memset(self.vertices, <int> NULL, nverts * self.hash_length * sizeof(SparseGraphBTNode *))
     323
     324        # self.in_degrees[i] = 0
     325        memset(self.in_degrees, 0, nverts * sizeof(int))
     326
     327        # self.out_degrees[i] = 0
     328        memset(self.out_degrees, 0, nverts * sizeof(int))
     329
    319330        bitset_init(self.active_vertices, self.num_verts + extra_vertices)
    320331        bitset_set_first_n(self.active_vertices, self.num_verts)
    321332
     
    333344        cdef SparseGraphBTNode **temp
    334345        cdef SparseGraphLLNode *label_temp
    335346        cdef int i
     347
     348        # Freeing the list of arcs attached to each vertex
    336349        for i from 0 <= i < self.active_vertices.size * self.hash_length:
    337350            temp = &(self.vertices[i])
     351
     352            # While temp[0]=self.vertices[i] is not NULL, find a leaf in the
     353            # tree rooted at temp[0] and free it. Then go back to temp[0] and do
     354            # it again. When self.vertices[i] is NULL, go for self.vertices[i+1]
    338355            while temp[0] != NULL:
    339356                if temp[0].left != NULL:
    340357                    temp = &(temp[0].left)
     
    349366                    sage_free(temp[0])
    350367                    temp[0] = NULL
    351368                    temp = &(self.vertices[i])
     369
    352370        sage_free(self.vertices)
    353371        sage_free(self.in_degrees)
    354372        sage_free(self.out_degrees)
     
    440458                bitset_free(bits)
    441459                return -1
    442460            bitset_free(bits)
     461
    443462        self.vertices = <SparseGraphBTNode **> sage_realloc(self.vertices, total * self.hash_length * sizeof(SparseGraphBTNode *))
    444463        self.in_degrees = <int *> sage_realloc(self.in_degrees, total * sizeof(int))
    445464        self.out_degrees = <int *> sage_realloc(self.out_degrees, total * sizeof(int))
    446         cdef int i
    447         for i from self.active_vertices.size*self.hash_length <= i < total*self.hash_length:
    448             # empty unless there are new vertices
    449             self.vertices[i] = NULL
    450         for i from self.active_vertices.size <= i < total:
    451             self.in_degrees[i] = 0
    452             self.out_degrees[i] = 0
     465
     466        cdef int new_vertices = total - self.active_vertices.size
     467
     468        # Initializing the entries corresponding to new vertices if any
     469        if new_vertices>0:
     470
     471            # self.vertices
     472            memset(self.vertices+self.active_vertices.size *  self.hash_length,
     473                   <int> NULL,
     474                   new_vertices * self.hash_length * sizeof(SparseGraphBTNode *))
     475
     476            # self.int_degrees
     477            memset(self.in_degrees+self.active_vertices.size, 0, new_vertices * sizeof(int))
     478
     479            # self.out_degrees
     480            memset(self.out_degrees+self.active_vertices.size, 0, new_vertices * sizeof(int))
     481
     482        # self.active_vertices
    453483        bitset_realloc(self.active_vertices, total)
    454484
    455485    ###################################
     
    579609        cdef SparseGraphBTNode *temp, **left_child, **right_child
    580610        cdef SparseGraphBTNode **parent = &self.vertices[i]
    581611        cdef SparseGraphLLNode *labels
     612
     613        # Assigning to parent the SparseGraphBTNode corresponding to arc (u,v)
    582614        while parent[0] != NULL:
    583615            compared = compare(parent[0].vertex, v)
    584616            if compared > 0:
     
    587619                parent = &(parent[0].right)
    588620            else:# if parent[0].vertex == v:
    589621                break
     622
     623        # If not found, there is no arc to delete !
    590624        if parent[0] == NULL:
    591             return 1 # indicate there is no arc to delete
     625            return 1
     626
    592627        # now parent[0] points to the BT node corresponding to (u,v)
    593628        labels = parent[0].labels
    594629        i = parent[0].number
    595630        self.in_degrees[v] -= i
    596631        self.out_degrees[u] -= i
    597632        self.num_arcs -= i
     633
     634        # Freeing the labels
    598635        while labels != NULL:
    599636            i = labels.number
    600637            parent[0].labels = parent[0].labels.next
     
    603640            self.in_degrees[v] -= i
    604641            self.out_degrees[u] -= i
    605642            self.num_arcs -= i
     643
     644        # Now, if the SparseGraphBTNode element is to be removed, it has to be
     645        # replaced in the binary tree by one of its children.
     646
     647        # If there is no left child
    606648        if parent[0].left == NULL:
    607649            temp = parent[0]
    608650            parent[0] = parent[0].right
    609651            sage_free(temp)
    610652            return 0
     653
     654        # If there is no right child
    611655        elif parent[0].right == NULL:
    612656            temp = parent[0]
    613657            parent[0] = parent[0].left
    614658            sage_free(temp)
    615659            return 0
     660
     661        # Both children
    616662        else:
    617663            left_len = 0
    618664            right_len = 0
    619665            left_child = &(parent[0].left)
     666            right_child = &(parent[0].right)
     667
     668            # left_len is equal to the maximum length of a path LR...R. The
     669            # last element of this path is the value of left_child
     670
    620671            while left_child[0].right != NULL:
    621672                left_len += 1
    622673                left_child = &(left_child[0].right)
    623             right_child = &(parent[0].right)
     674            # right_len is equal to the maximum length of a path RL...L. The
     675            # last element of this path is the value of right_child
     676
    624677            while right_child[0].left != NULL:
    625678                right_len += 1
    626679                right_child = &(right_child[0].left)
     680
     681            # According to the respective lengths, replace parent by the left or
     682            # right child and place the other child at its expected place.
    627683            if left_len > right_len:
    628684                left_child[0].right = parent[0].right
    629685                temp = parent[0]
     
    703759            pointers[num_nbrs] = self.vertices[i]
    704760            neighbors[num_nbrs] = self.vertices[i].vertex
    705761            num_nbrs += 1
     762
     763            # While all the neighbors have not been added to the list, explore
     764            # element pointers[current_nbr] and append its children to the end
     765            # of pointers if necessary, the increment current_nbr.
    706766            while current_nbr < num_nbrs:
    707767                if pointers[current_nbr].left != NULL:
    708768                    if num_nbrs == size:
     
    769829            -1 -- indicates that the array has been filled with neighbors, but
    770830        there were more
    771831
     832        NOTE: Due to the implementation of SparseGraph, this method is much more
     833        expensive than out_neighbors_unsafe.
     834
    772835        """
    773836        cdef int i, num_nbrs = 0
    774837        if self.in_degrees[v] == 0:
     
    801864            sage: G.in_neighbors(3)
    802865            [1]
    803866
     867        NOTE: Due to the implementation of SparseGraph, this method is much more
     868        expensive than neighbors_unsafe.
    804869        """
    805870        cdef int i, num_nbrs
    806871        self.check_vertex(v)
  • sage/graphs/graph.py

    diff -r c14909173538 -r dac000bf6a5f sage/graphs/graph.py
    a b  
    12271227                    if m[k] == '1':
    12281228                        self.add_edge(i, j)
    12291229                    k += 1
     1230
    12301231        elif format == 'sparse6':
    12311232            for i,j in edges:
    12321233                self.add_edge(i,j)
     1234
    12331235        elif format == 'adjacency_matrix':
    12341236            e = []
    12351237            if weighted:
     
    12451247                    if i <= j:
    12461248                        e.append((i,j))
    12471249            self.add_edges(e)
     1250
    12481251        elif format == 'incidence_matrix':
    12491252            self.add_edges(positions)
     1253
    12501254        elif format == 'Graph':
    12511255            self.name(data.name())
     1256
    12521257        elif format == 'rule':
    12531258            verts = list(verts)
    12541259            for u in xrange(num_verts):
     
    12561261                    uu,vv = verts[u], verts[v]
    12571262                    if f(uu,vv):
    12581263                        self.add_edge(uu,vv)
     1264
    12591265        elif format == 'dict_of_dicts':
    12601266            for u in data:
    12611267                for v in data[u]:
     
    12641270                            self.add_edges([(u,v,l) for l in data[u][v]])
    12651271                        else:
    12661272                            self.add_edge((u,v,data[u][v]))
     1273
    12671274        elif format == 'dict_of_lists':
    12681275            for u in data:
    12691276                for v in data[u]:
    12701277                    if multiedges or hash(u) <= hash(v) or \
    12711278                       v not in data or u not in data[v]:
    12721279                        self.add_edge(u,v)
     1280
    12731281        elif format == 'elliptic_curve_congruence':
    12741282            from sage.rings.arith import lcm, prime_divisors
    12751283            from sage.rings.fast_arith import prime_range
     
    12961304                        self.add_edge(E.cremona_label(), F.cremona_label(), str(p_edges)[1:-1])
    12971305        else:
    12981306            assert format == 'int'
     1307
    12991308        self._pos = pos
    13001309        self._boundary = boundary
    13011310        name = kwds.get('name', None)