def approx_count(g, M1, M2):
    if (random_graphs.num_edges(g) == len(g) - 1):
        return 1
    # pick first edge of g
    #u = next(iter(g.keys()))
    #v = g[u][0] # possible because g connected
    # get random edge
    u, v = random_graphs.get_random_edge(g)

    # draw M1 samples to decide which case
    sampler = st_sampler.STSampler(g)
    has_e = 0

    for i in range(M1):
        sample = sampler.sample()
        if v in sample[u]:
            has_e += 1

    print(f'has_e = {has_e}')
    # decide if proportion of has_e > 0.5
    if (2 * has_e > M1):
        both_nbrs = set(g[v]).intersection(set(
            g[u]))  # a vertex is a double if it is in this set
        # contract g
        random_graphs.contract(g, (u, v))

        # we need to do some extra estimation, because st of the contracted g can be expanded in many ways
        sampler = st_sampler.STSampler(g)
        counter = collections.Counter()  # counts freq of doubles
        for i in range(M2):
            sample = sampler.sample()
            num_doubles = len(set(
                sample[u]).intersection(both_nbrs))  # u is now the node (u+v)
            counter[num_doubles] += 1
        exp = get_expansion_factor(counter)
        print(f'exp factor = {exp}')

        nst = mtt.MTT(g)
        rec = approx_count(g, M1, M2)
        est = rec
        error = abs(est - nst) / nst * 100
        print(f'actual = {nst}, estimated = {est}, error = {error}')

        return rec * exp * M1 / has_e
    else:
        # delete e and recurse
        g[u].remove(v)
        g[v].remove(u)
        nst = mtt.MTT(g)
        rec = approx_count(g, M1, M2)
        est = rec
        error = abs(est - nst) / nst * 100
        print(f'actual = {nst}, estimated = {est}, error = {error}')

        return rec * M1 / (M1 - has_e)
Ejemplo n.º 2
0
def make_row(n, density, num_samples):
    g = random_graphs.get_random_connected_graph(n, density)

    t0 = time.time()
    est = approx_count_log(g, num_samples)
    t1 = time.time()

    act = mtt.MTT(g, log=True)
    error = mult_error_log(float(est), act)
    print(f'actual = {act}, est = {est}, error = {error}')

    row = [n, density, act, float(est), error, t1 - t0]
    return row
def unit_test_2():
    n = 30
    p = 0.3
    seed = 1
    g = random_graphs.get_random_connected_graph(n, p)  # todo: add seed

    sampler = st_sampler.STSampler(
        {})  # empty sampler, it will be initialized within fn later
    num_edges_each_time_fn_1 = lambda x, y: 1  # one edge each time
    num_samples_fn_1 = lambda x, y: 200  # 100 samples each time
    num_edges_each_time_fn_2 = lambda x, y: 3  # 3 edges each time
    num_samples_fn_2 = lambda x, y: 100 + 30 * y  # 100 samples as base, and for every edge, add 10 samples
    use_log = False

    nst = approx_count_st_generic(g, sampler, num_samples_fn_2,
                                  num_edges_each_time_fn_2, use_log)
    actual = mtt.MTT(g)
    print('error =', abs(nst - actual) / actual)
def test_for_uniform_dist(g, sampler):
    st_counter = random_graphs.ST_counter(
    )  # for counting the number of spanning trees. Inefficient, so mtt(g) must be reasonably small, like < 100

    nst = mtt.MTT(g)
    print(f"nst = {nst}")
    for i in range(
            100 * nst
    ):  # if distr is uniform, we will have about 100 of each spanning tree
        tree = sampler.sample()
        st_counter.add_tree(tree)

    print("observed counts:", st_counter.counts)
    t = ss.chisquare(st_counter.counts)
    print(f"Test result: chi statistic = {t[0]}, p-value = {t[1]}")
    if (t[1] < 0.05):
        print("Distribution is probably not uniform")
    else:
        print("Distribution is probably uniform")
Ejemplo n.º 5
0
rr_time = array(rr_results[:,0])
rr_s = array(rr_results[:,2])
rr_p = array(rr_results[:,3])

fig,axes = plt.subplots(nrows, ncols, sharex='col', sharey='row', figsize=(15,8))

axes[0][0].set_title('Lumped Kinetics')
axes[0][0].plot(rr_time, rr_s, color='C1', linewidth=2, label='S (lumped)', linestyle='--')
axes[0][0].plot(rr_time, rr_p, color='C2', linewidth=2, label='P (lumped)', linestyle='--')
# axes[0][0].set_xlabel('time (a.u.)')
axes[0][0].set_ylabel('conc. (a.u.)')

for k,default_margin in enumerate([0.01, 0.1, 1., 10., 100.,],1):
    print('default_margin =',default_margin)
    wiring = mtt.Wiring.fromFile2(sbfile, {}, default_margin)
    model = mtt.MTT(wiring)
    model.reset()

    if default_margin > 10.:
        rr_model.reset()
        rr_results = rr_model.simulate(t_start,t_stop,10000)
        rr_time = array(rr_results[:,0])
        rr_s = array(rr_results[:,2])
        rr_p = array(rr_results[:,3])
    r = model.simulate(t_start,t_stop,1000 if default_margin <= 10. else 10000)

    mtt_time = array(r[:,0])
    mtt_s = array(r[:,2])
    mtt_p = array(r[:,4])

    rms = sqrt(mean([
def test():
    g = random_graphs.get_random_connected_graph(20, 0.6)
    nst = mtt.MTT(g)
    est = approx_count_iter(g, 300, 300)
    error = abs(est - nst) / nst * 100
    print(f'Final: actual = {nst}, estimated = {est}, error = {error}')
# densities_list = [0.3, 0.5, 0.7]
# graph_number_list = list(range(1, 6))

try:
    os.mkdir(subdir)
    print("Directory ", subdir, " Created ")
except FileExistsError:
    print("Directory ", subdir, " already exists")

for n in num_vertices_list:
    for p in densities_list:
        for i in graph_number_list:  # i gonna make 10 graphs of the same type (num_vertices and density)
            filename = 'g{}_{}_{}.json'.format(i, n, int(100 * p))
            path = os.path.join(subdir, filename)

            g1 = random_graphs.get_random_connected_graph(n, p)
            u, v = get_random_edge(g1)

            g2 = copy.deepcopy(g1)
            g2[u].remove(
                v
            )  # remove (u,v) from g2. there is a small chance that this disconnects the graph
            g2[v].remove(u)

            NST1 = mtt.MTT(g1)
            NST2 = mtt.MTT(g2)

            data = [g1, NST1, g2, NST2, [u, v]]

            db.save_data(data, path)