def test_modularity():
    """Test the values that go into the modularity calculation after randomly
    creating a graph"""
    # Given a partition with the correct labels of the input graph, verify that
    # the modularity returns 1

    # We need to measure the degree within/between modules
    nnods = 120, 240, 360
    nmods = 2, 3, 4
    av_degrees = 8, 10, 16

    for nnod in nnods:
        for nmod in nmods:
            for av_degree in av_degrees:
                g = mod.random_modular_graph(nnod, nmod, av_degree)
                #Compute the of nodes per module
                nnod_mod = nnod/nmod
                #Make a "correct" partition for the graph
                part = mod.perfect_partition(nmod,nnod_mod)
                #Make a graphpartition object
                graph_partition = mod.GraphPartition(g,part)
                #call modularity
                mod_meas = graph_partition.modularity()
                mod_true = 1.0 - 1.0/nmod
                npt.assert_almost_equal(mod_meas, mod_true, 2)
Exemple #2
0
def test_modularity():
    """Test the values that go into the modularity calculation after randomly
    creating a graph"""
    # Given a partition with the correct labels of the input graph, verify that
    # the modularity returns 1

    # We need to measure the degree within/between modules
    nnods = 120, 240, 360
    nmods = 2, 3, 4
    av_degrees = 8, 10, 16

    for nnod in nnods:
        for nmod in nmods:
            for av_degree in av_degrees:
                g = mod.random_modular_graph(nnod, nmod, av_degree)
                #Compute the of nodes per module
                nnod_mod = nnod / nmod
                #Make a "correct" partition for the graph
                part = mod.perfect_partition(nmod, nnod_mod)
                #Make a graphpartition object
                graph_partition = mod.GraphPartition(g, part)
                #call modularity
                mod_meas = graph_partition.modularity()
                mod_true = 1.0 - 1.0 / nmod
                npt.assert_almost_equal(mod_meas, mod_true, 2)
Exemple #3
0
def test_mutual_information():
    """ Test the function which returns the mutual information in two
    partitions

    XXX - This test is currently incomplete - it only checks the most basic
    case of MI(x, x)==1, but doesn't do any non-trivial checks.
    """

    # nnod_mod, av_degrees, nmods
    networks = [ [4, [2, 3], [2, 4, 6]],
                 [8, [4, 6], [4, 6, 8]],
                 [40, [20], [2]] ]

    for nnod_mod, av_degrees, nmods in networks:
        for nmod in nmods:
            nnod = nnod_mod*nmod
            for av_degree in av_degrees:
                #make a graph object
                g = mod.random_modular_graph(nnod, nmod, av_degree)

                #Compute the of nodes per module
                nnod_mod = nnod/nmod
                #Make a "correct" partition for the graph
                ppart = mod.perfect_partition(nmod,nnod_mod)

                #graph_out, mod_array =mod.simulated_annealing(g, temperature =
                #temperature,temp_scaling = temp_scaling, tmin=tmin)

                #test the perfect case for now: two of the same partition
                #returns 1
                mi_orig  = mod.mutual_information(ppart,ppart)
                yield npt.assert_equal(mi_orig,1)

                #move one node and test that mutual_information comes out
                #correctly
                graph_partition = mod.GraphPartition(g,ppart)
                graph_partition.node_update(0,0,1)

                mi = mod.mutual_information(ppart,graph_partition.index)
                yield npt.assert_array_less(mi, mi_orig)
                ## NOTE: CORRECTNESS NOT TESTED YET

                #merge modules and check that mutual information comes out
                #correctly/lower
                graph_partition2 = mod.GraphPartition(g,ppart)
                merged_module, e_new, a_new, d,t,m1,m2,x = graph_partition2.compute_module_merge(0,1)
                graph_partition2.apply_module_merge(m1,m2,merged_module,e_new,a_new)
                mi2 = mod.mutual_information(ppart,graph_partition2.index)
                yield npt.assert_array_less(mi2,mi_orig)
                ## NOTE: CORRECTNESS NOT TESTED YET

                #split modules and check that mutual information comes out
                #correclty/lower
                graph_partition3 = mod.GraphPartition(g,ppart)
                n1 = list(graph_partition3.index[0])[::2]
                n2 = list(graph_partition3.index[0])[1::2]
                split_modules,e_new,a_new,d,t,m,n1,n2 = graph_partition3.compute_module_split(0,n1,n2)
                graph_partition3.apply_module_split(m,n1,n2,split_modules,e_new,a_new)
                mi3 = mod.mutual_information(ppart,graph_partition3.index)
                yield npt.assert_array_less(mi3,mi_orig)
Exemple #4
0
def SA():
    """ Test the simulated annealing script"""
    #nnod_mod, av_degrees, nmods
    #networks = [ [4, [2, 3], [2, 4, 6]]]#,
    #networks =  [ [8, [4, 6], [4, 6, 8]]]
    #networks = [[40, [20], [2]]]
    networks = [[32, [16], [4]]]
    #networks = [[64, [12], [6]]]
    btwn_fracs = [0]
    temperature = 10
    temp_scaling = 0.9995
    tmin = 1e-4
    nochange_ratio_min = 0.01

    #keep time

    for nnod_mod, av_degrees, nmods in networks:
        for nmod in nmods:
            nnod = nnod_mod * nmod
            for av_degree in av_degrees:
                for btwn_frac in btwn_fracs:
                    t1 = time.clock()
                    g = mod.random_modular_graph(nnod, nmod, av_degree,
                                                 btwn_frac)
                    #Compute the # of nodes per module
                    nnod_mod = nnod / nmod
                    #Make a "correct" partition for the graph
                    ppart = mod.perfect_partition(nmod, nnod_mod)

                    graph_out, energy_array, rej_array, temp_array = mod.simulated_annealing(
                        g,
                        temperature=temperature,
                        temp_scaling=temp_scaling,
                        tmin=tmin,
                        nochange_ratio_min=nochange_ratio_min)

                    print "perfect partition", ppart
                    print "SA partition", graph_out.index

                    t2 = time.clock()
                    print 'Elapsed time: ', float(t2 - t1) / 60, 'minutes'
                    print 'partition similarity: ', mod.mutual_information(
                        ppart, graph_out.index)
                    return graph_out, g, energy_array, rej_array, ppart, temp_array
Exemple #5
0
def SA():
    """ Test the simulated annealing script"""
    # nnod_mod, av_degrees, nmods
    # networks = [ [4, [2, 3], [2, 4, 6]]]#,
    # networks =  [ [8, [4, 6], [4, 6, 8]]]
    # networks = [[40, [20], [2]]]
    networks = [[32, [16], [4]]]
    # networks = [[64, [12], [6]]]
    btwn_fracs = [0]
    temperature = 10
    temp_scaling = 0.9995
    tmin = 1e-4
    nochange_ratio_min = 0.01

    # keep time

    for nnod_mod, av_degrees, nmods in networks:
        for nmod in nmods:
            nnod = nnod_mod * nmod
            for av_degree in av_degrees:
                for btwn_frac in btwn_fracs:
                    t1 = time.clock()
                    g = mod.random_modular_graph(nnod, nmod, av_degree, btwn_frac)
                    # Compute the # of nodes per module
                    nnod_mod = nnod / nmod
                    # Make a "correct" partition for the graph
                    ppart = mod.perfect_partition(nmod, nnod_mod)

                    graph_out, energy_array, rej_array, temp_array = mod.simulated_annealing(
                        g,
                        temperature=temperature,
                        temp_scaling=temp_scaling,
                        tmin=tmin,
                        nochange_ratio_min=nochange_ratio_min,
                    )

                    print "perfect partition", ppart
                    print "SA partition", graph_out.index

                    t2 = time.clock()
                    print "Elapsed time: ", float(t2 - t1) / 60, "minutes"
                    print "partition similarity: ", mod.mutual_information(ppart, graph_out.index)
                    return graph_out, g, energy_array, rej_array, ppart, temp_array
Exemple #6
0
def test_sim_anneal_simple():
    """Very simple simulated_annealing test with a small network"""

    #
    nnod, nmod, av_degree, btwn_frac = 24, 3, 4, 0
    g = mod.random_modular_graph(nnod, nmod, av_degree, btwn_frac)

    #Compute the # of nodes per module
    nnod_mod = nnod/nmod
    #Make a "correct" partition for the graph
    ppart = mod.perfect_partition(nmod,nnod_mod)

    temperature = 10
    temp_scaling = 0.95
    tmin=1

    graph_out, graph_dict = mod.simulated_annealing(g,
               temperature = temperature, temp_scaling = temp_scaling,
               tmin=tmin, extra_info = True, debug=True)

    # Ensure that there are no empty modules
    util.assert_no_empty_modules(graph_out.index)

    mi = mod.mutual_information(ppart, graph_out.index)
def danon_benchmark():
    """This test comes from Danon et al 2005. It will create the line plot of
    Mututal Information vs. betweenness fraction to assess the performance of
    the simulated annealing algorithm."""
    networks = [[32, [16], [6]]]
    btwn_fracs = [float(i)/100 for i in range(0,80,3)]

    temperature = 0.1
    temp_scaling = 0.9995
    tmin=1e-4

    num_reps = range(1)
    mi_arr=np.empty((len(btwn_fracs),len(num_reps)))

    #keep time
    for rep in num_reps:
        t1 = time.clock()
        for nnod_mod, av_degrees, nmods in networks:
            for nmod in nmods:
                nnod = nnod_mod*nmod
                for av_degree in av_degrees:
                    x_mod = []
                    for ix,btwn_frac in enumerate(btwn_fracs):
                        print 'btwn_frac: ',btwn_frac
                        g = mod.random_modular_graph(nnod, nmod, av_degree,btwn_frac)
                        #Compute the # of nodes per module
                        nnod_mod = nnod/nmod
                        #Make a "correct" partition for the graph
                        ppart = mod.perfect_partition(nmod,nnod_mod)

                        graph_out, graph_dict =mod.simulated_annealing(g,
                        temperature = temperature,temp_scaling = temp_scaling,
                        tmin=tmin, extra_info = True)

                        #print "SA partition",graph_out.index
                        mi = mod.mutual_information(ppart,graph_out.index)
                        t2 = time.clock()
                        print 'Elapsed time: ', (float(t2-t1)/60), ' minutes'
                        print 'partition similarity: ',mi
                        mi_arr[ix,rep] = mi
                        ## plot_partition(g,graph_out.index,'mi: '+ str(mi),'danon_test_6mod'+str(btwn_frac)+'_graph.png')
                        x_mod.append(betweenness_to_modularity(g,ppart))


                    ## mi_arr_avg = np.mean(mi_arr,1)
                    ## plt.figure()
                    ## plt.plot(btwn_fracs,mi_arr_avg)
                    ## plt.xlabel('Betweenness fraction')
                    ## plt.ylabel('Mutual information')
                    ## plt.savefig('danon_test_6mod/danontest_btwn.png')

                    ## plt.figure()
                    ## plt.plot(x_mod,mi_arr_avg)
                    ## plt.xlabel('Modularity')
                    ## plt.ylabel('Mutual information')
                    ## plt.savefig('danon_test_6mod/danontest_mod.png')

    #plt.figure()
    #plt.plot(graph_dict['energy'], label = 'energy')
    #plt.plot(graph_dict['temperature'], label = 'temperature')
    #plt.xlabel('Iteration')

    return mi_arr
def test_apply_module_merge():
    """Test the GraphPartition operation that merges modules so that it returns
    a change in modularity that reflects the difference between the modularity
    of the new and old parititions"""

    # nnod_mod, av_degrees, nmods
    networks = [ [3, [2], [3, 4]],
                 [4, [2, 3], [2, 4, 6]],
                 [8, [4, 6], [4, 6, 8]] ]

    for nnod_mod, av_degrees, nmods in networks:
        for nmod in nmods:
            nnod = nnod_mod*nmod
            for av_degree in av_degrees:

                g = mod.random_modular_graph(nnod, nmod, av_degree)

                #Make a "correct" partition for the graph
                part = mod.perfect_partition(nmod,nnod/nmod)

                #Make a random partition for the graph
                part_rand = dict()
                while len(part_rand) <= 1: #check if there is only one module
                    part_rand = mod.rand_partition(g)

                #List of modules in the partition
                r_mod=range(len(part))

                #Loop through pairs of modules
                for i in range(1): # DB: why is this necessary?
                    #select two modules to merge
                    mod_per = np.random.permutation(r_mod)
                    m1 = mod_per[0]; m2 = mod_per[1]

                    #make a graph partition object
                    graph_partition = mod.GraphPartition(g,part)

                    #index of nodes within the original module (before merge)
                    n1_init = list(graph_partition.index[m1])
                    n2_init = list(graph_partition.index[m2])
                    n_all_init = n1_init+n2_init

                    #calculate modularity before merging
                    mod_init = graph_partition.modularity()

                    #merge modules
                    merge_module,e1,a1,delta_energy_meas,type,m1,m2,m2 = \
                                  graph_partition.compute_module_merge(m1,m2)

                    graph_part2 = copy.deepcopy(graph_partition)
                    graph_part2.apply_module_merge(m1,m2,merge_module,e1,a1)
                    #index of nodes within the modules after merging
                    n_all = list(graph_part2.index[min(m1,m2)])

                    # recalculate modularity after splitting
                    mod_new = graph_part2.modularity()

                    # difference between new and old modularity
                    delta_energy_true = -(mod_new - mod_init)

                    # Test the measured difference in energy against the
                    # function that calculates the difference in energy
                    npt.assert_almost_equal(delta_energy_meas,
                                                  delta_energy_true)
                    # Check that the list of nodes in the two original modules
                    # is equal to the list of nodes in the merged module
                    n_all_init.sort()
                    n_all.sort()
                    npt.assert_equal(n_all_init, n_all)

                    # Test that the keys are equivalent after merging modules
                    npt.assert_equal(r_mod[:-1],
                                           sorted(graph_part2.index.keys()))

                    # Test that the values in the mod_e and mod_a matrices for
                    # the merged module are correct.
                    npt.assert_equal(graph_part2.mod_e[min(m1,m2)],e1)
                    npt.assert_equal(graph_part2.mod_a[min(m1,m2)],a1)
Exemple #9
0
def test_apply_module_split():
    """Test the GraphPartition operation that splits modules so that it returns
    a change in modularity that reflects the difference between the modularity
    of the new and old parititions.
    Also test that the module that was split now contains the correct nodes,
    the correct modularity update, the correct energy,and that no empty modules
    result from it."""

    # nnod_mod, av_degrees, nmods
    networks = [ [3, [2], [2, 3, 4]],
                 [4, [2, 3], [2, 4, 6]],
                 [8, [4, 6], [4, 6, 8]] ]

    for nnod_mod, av_degrees, nmods in networks:
        for nmod in nmods:
            nnod = nnod_mod*nmod
            for av_degree in av_degrees:

                g = mod.random_modular_graph(nnod, nmod, av_degree)

                #Make a "correct" partition for the graph
                part = mod.perfect_partition(nmod,nnod/nmod)

                #Make a random partition for the graph
                part_rand = mod.rand_partition(g, nnod/2)

                #List of modules in the partition that have two or more nodes
                r_mod = []
                for m, nodes in part_rand.iteritems():
                    if len(nodes)>2:
                        r_mod.append(m)

                # Note: The above can be written in this more compact, if
                # slightly less intuitively clear, list comprehension:
                # r_mod = [ m for m, nodes in part_rand.iteritems() if
                #          len(nodes)>2 ]

                #Module that we are splitting
                for m in r_mod:

                    graph_partition = mod.GraphPartition(g,part_rand)

                    #index of nodes within the original module (before split)
                    n_init = list(graph_partition.index[m])

                    #calculate modularity before splitting
                    mod_init = graph_partition.modularity()

                    # assign nodes to two groups
                    n1_orig,n2_orig = graph_partition.determine_node_split(m)

                    # make sure neither of these is empty
                    yield nt.assert_true(len(n1_orig)>= 1)
                    yield nt.assert_true(len(n2_orig)>= 1)

                    #make sure that there are no common nodes between the two
                    node_intersection = set.intersection(n1_orig,n2_orig)
                    yield nt.assert_equal(node_intersection,set([]))

                    #make sure that sum of the two node sets equals the
                    #original set
                    node_union = set.union(n1_orig,n2_orig)
                    yield npt.assert_equal(np.sort(list(node_union)),np.sort(n_init))

                    # split modules
                    split_modules,e1,a1,delta_energy_meas,type,m,n1,n2 = \
                               graph_partition.compute_module_split(m,n1_orig,n2_orig)

                    #note: n1 and n2 are output from this function (as well as
                    #inputs) because the function is called from within another
                    #(rand_mod) def but then output to the simulated script, so
                    #the node split needs to be passed along.

                    #as a simple confirmation, can make sure they match
                    yield npt.assert_equal(n1_orig,n1)
                    yield npt.assert_equal(n2_orig,n2)

                    #split_moduels should be a dictionary with two modules
                    #(0,1) that contain the node sets n1 and n2 respectively.
                    #test this.
                    yield npt.assert_equal(split_modules[0],n1)
                    yield npt.assert_equal(split_modules[1],n2)

                    #make a new graph partition equal to the old one and apply
                    #the module split to it (graph_part2)
                    graph_part2 = copy.deepcopy(graph_partition)
                    graph_part2.apply_module_split(m,n1,n2,split_modules,e1,a1)

                    #make a third graph partition using only the original graph
                    #and the partition from graph_part2
                    graph_part3 = mod.GraphPartition(g,graph_part2.index)

                    #index of nodes within the modules after splitting
                    n1_new = list(graph_part2.index[m])
                    n2_new = list(graph_part2.index[len(graph_part2)-1])
                    n_all = n1_new + n2_new

                    # recalculate modularity after splitting
                    mod_new = graph_part2.modularity()
                    mod_new_3 = graph_part3.modularity()

                    # difference between new and old modularity
                    delta_energy_true = -(mod_new - mod_init)

                    # Test that the measured change in energy by splitting a
                    # module is equal to the function output from module_split
                    yield npt.assert_almost_equal(delta_energy_meas,
                                                  delta_energy_true)

                    # Test that the nodes in the split modules are equal to the
                    # original nodes of the module
                    yield npt.assert_equal(np.sort(list(n1)), n1_new)
                    yield npt.assert_equal(np.sort(list(n2)), n2_new)

                    n_init.sort()
                    n_all.sort()
                    # Test that the initial list of nodes in the module are
                    # equal to the nodes in m1 and m2 (split modules)
                    yield npt.assert_equal(n_init,n_all)

                    # Test that the computed modularity found when
                    # apply_module_split is used is equal to the modularity you
                    # would find if using that partition and that graph
                    yield npt.assert_almost_equal(mod_new,mod_new_3)

                    # Check that there are no empty modules in the final
                    # partition
                    for m in graph_part2.index:
                        yield nt.assert_true(len(graph_part2.index[m]) > 0)
Exemple #10
0
def test_mutual_information():
    """ Test the function which returns the mutual information in two
    partitions

    XXX - This test is currently incomplete - it only checks the most basic
    case of MI(x, x)==1, but doesn't do any non-trivial checks.
    """

    # nnod_mod, av_degrees, nmods
    networks = [[4, [2, 3], [2, 4, 6]], [8, [4, 6], [4, 6, 8]],
                [40, [20], [2]]]

    for nnod_mod, av_degrees, nmods in networks:
        for nmod in nmods:
            nnod = nnod_mod * nmod
            for av_degree in av_degrees:
                #make a graph object
                g = mod.random_modular_graph(nnod, nmod, av_degree)

                #Compute the of nodes per module
                nnod_mod = nnod / nmod
                #Make a "correct" partition for the graph
                ppart = mod.perfect_partition(nmod, nnod_mod)

                #graph_out, mod_array =mod.simulated_annealing(g, temperature =
                #temperature,temp_scaling = temp_scaling, tmin=tmin)

                #test the perfect case for now: two of the same partition
                #returns 1
                mi_orig = mod.mutual_information(ppart, ppart)
                npt.assert_equal(mi_orig, 1)

                #move one node and test that mutual_information comes out
                #correctly
                graph_partition = mod.GraphPartition(g, ppart)
                graph_partition.node_update(0, 0, 1)

                mi = mod.mutual_information(ppart, graph_partition.index)
                npt.assert_array_less(mi, mi_orig)
                ## NOTE: CORRECTNESS NOT TESTED YET

                #merge modules and check that mutual information comes out
                #correctly/lower
                graph_partition2 = mod.GraphPartition(g, ppart)
                merged_module, e_new, a_new, d, t, m1, m2, x = graph_partition2.compute_module_merge(
                    0, 1)
                graph_partition2.apply_module_merge(m1, m2, merged_module,
                                                    e_new, a_new)
                mi2 = mod.mutual_information(ppart, graph_partition2.index)
                npt.assert_array_less(mi2, mi_orig)
                ## NOTE: CORRECTNESS NOT TESTED YET

                #split modules and check that mutual information comes out
                #correclty/lower
                graph_partition3 = mod.GraphPartition(g, ppart)
                n1 = set(list(graph_partition3.index[0])[::2])
                n2 = set(list(graph_partition3.index[0])[1::2])

                split_modules, e_new, a_new, d, t, m, n1, n2 = graph_partition3.compute_module_split(
                    0, n1, n2)
                graph_partition3.apply_module_split(m, n1, n2, split_modules,
                                                    e_new, a_new)
                mi3 = mod.mutual_information(ppart, graph_partition3.index)
                npt.assert_array_less(mi3, mi_orig)
Exemple #11
0
def danon_benchmark():
    """This test comes from Danon et al 2005. It will create the line plot of
    Mututal Information vs. betweenness fraction to assess the performance of
    the simulated annealing algorithm."""
    networks = [[32, [16], [6]]]
    btwn_fracs = [float(i) / 100 for i in range(0, 80, 3)]

    temperature = 0.1
    temp_scaling = 0.9995
    tmin = 1e-4

    num_reps = range(1)
    mi_arr = np.empty((len(btwn_fracs), len(num_reps)))

    #keep time
    for rep in num_reps:
        t1 = time.clock()
        for nnod_mod, av_degrees, nmods in networks:
            for nmod in nmods:
                nnod = nnod_mod * nmod
                for av_degree in av_degrees:
                    x_mod = []
                    for ix, btwn_frac in enumerate(btwn_fracs):
                        print 'btwn_frac: ', btwn_frac
                        g = mod.random_modular_graph(nnod, nmod, av_degree,
                                                     btwn_frac)
                        #Compute the # of nodes per module
                        nnod_mod = nnod / nmod
                        #Make a "correct" partition for the graph
                        ppart = mod.perfect_partition(nmod, nnod_mod)

                        graph_out, graph_dict = mod.simulated_annealing(
                            g,
                            temperature=temperature,
                            temp_scaling=temp_scaling,
                            tmin=tmin,
                            extra_info=True)

                        #print "SA partition",graph_out.index
                        mi = mod.mutual_information(ppart, graph_out.index)
                        t2 = time.clock()
                        print 'Elapsed time: ', (float(t2 - t1) /
                                                 60), ' minutes'
                        print 'partition similarity: ', mi
                        mi_arr[ix, rep] = mi
                        ## plot_partition(g,graph_out.index,'mi: '+ str(mi),'danon_test_6mod'+str(btwn_frac)+'_graph.png')
                        x_mod.append(betweenness_to_modularity(g, ppart))

                    ## mi_arr_avg = np.mean(mi_arr,1)
                    ## plt.figure()
                    ## plt.plot(btwn_fracs,mi_arr_avg)
                    ## plt.xlabel('Betweenness fraction')
                    ## plt.ylabel('Mutual information')
                    ## plt.savefig('danon_test_6mod/danontest_btwn.png')

                    ## plt.figure()
                    ## plt.plot(x_mod,mi_arr_avg)
                    ## plt.xlabel('Modularity')
                    ## plt.ylabel('Mutual information')
                    ## plt.savefig('danon_test_6mod/danontest_mod.png')

    #plt.figure()
    #plt.plot(graph_dict['energy'], label = 'energy')
    #plt.plot(graph_dict['temperature'], label = 'temperature')
    #plt.xlabel('Iteration')

    return mi_arr
Exemple #12
0
def test_apply_module_merge():
    """Test the GraphPartition operation that merges modules so that it returns
    a change in modularity that reflects the difference between the modularity
    of the new and old parititions"""

    # nnod_mod, av_degrees, nmods
    networks = [[3, [2], [3, 4]], [4, [2, 3], [2, 4, 6]],
                [8, [4, 6], [4, 6, 8]]]

    for nnod_mod, av_degrees, nmods in networks:
        for nmod in nmods:
            nnod = nnod_mod * nmod
            for av_degree in av_degrees:

                g = mod.random_modular_graph(nnod, nmod, av_degree)

                #Make a "correct" partition for the graph
                part = mod.perfect_partition(nmod, nnod / nmod)

                #Make a random partition for the graph
                part_rand = dict()
                while len(part_rand) <= 1:  #check if there is only one module
                    part_rand = mod.rand_partition(g)

                #List of modules in the partition
                r_mod = range(len(part))

                #Loop through pairs of modules
                for i in range(1):  # DB: why is this necessary?
                    #select two modules to merge
                    mod_per = np.random.permutation(r_mod)
                    m1 = mod_per[0]
                    m2 = mod_per[1]

                    #make a graph partition object
                    graph_partition = mod.GraphPartition(g, part)

                    #index of nodes within the original module (before merge)
                    n1_init = list(graph_partition.index[m1])
                    n2_init = list(graph_partition.index[m2])
                    n_all_init = n1_init + n2_init

                    #calculate modularity before merging
                    mod_init = graph_partition.modularity()

                    #merge modules
                    merge_module,e1,a1,delta_energy_meas,type,m1,m2,m2 = \
                                  graph_partition.compute_module_merge(m1,m2)

                    graph_part2 = copy.deepcopy(graph_partition)
                    graph_part2.apply_module_merge(m1, m2, merge_module, e1,
                                                   a1)
                    #index of nodes within the modules after merging
                    n_all = list(graph_part2.index[min(m1, m2)])

                    # recalculate modularity after splitting
                    mod_new = graph_part2.modularity()

                    # difference between new and old modularity
                    delta_energy_true = -(mod_new - mod_init)

                    # Test the measured difference in energy against the
                    # function that calculates the difference in energy
                    npt.assert_almost_equal(delta_energy_meas,
                                            delta_energy_true)
                    # Check that the list of nodes in the two original modules
                    # is equal to the list of nodes in the merged module
                    n_all_init.sort()
                    n_all.sort()
                    npt.assert_equal(n_all_init, n_all)

                    # Test that the keys are equivalent after merging modules
                    npt.assert_equal(r_mod[:-1],
                                     sorted(graph_part2.index.keys()))

                    # Test that the values in the mod_e and mod_a matrices for
                    # the merged module are correct.
                    npt.assert_equal(graph_part2.mod_e[min(m1, m2)], e1)
                    npt.assert_equal(graph_part2.mod_a[min(m1, m2)], a1)