Esempio n. 1
0
def average_consensus(G, fig_id, loc=100, scale=50, state=[]):
    n = len(G.nodes())

    # laplacian matrix
    L, eps = graph_util(G)
    # initial state
    if len(state) == 0:
        state = random_initialize(n, loc, scale)
    else:
        state = np.matrix(state).transpose()
    """
    generating a n*1 matrix with all elements being the average point
    for the later convergency check
    """
    avg = np.asmatrix(state.mean() * np.ones((n, 1)))
    """
    records: record all the state during the
    iterative process until convergency
    """
    records = state

    # update the state iteratively
    for k in range(MAX_ITERATIVE_LIMIT):
        state = (np.identity(n) - eps * L) * state
        # check convergency
        # if np.array_equal(state, state_tmp):
        if np.allclose(state, avg, rtol=0, atol=1e-2):
            break
        # concatenate the states vertically
        records = np.asmatrix(np.concatenate((records, state), axis=1))

    np.savetxt("../records/" + fig_id + ".csv", records, delimiter=",")
    return records
def dp_avg_consensus(G, fig_id, c, q, s, state=[]):
    n = len(G.nodes())
    '''
     calculate the k-th scales of the laplacian noise vector
     with each scale being c_i*q_i^k
     q_ = 0(one-shot) is also supported
    '''
    def gen_kth_scales(k, c, q):
        kth_scales = [c_i * (q[idx]**k) for idx, c_i in enumerate(c)]
        return np.array(kth_scales)

    # both the type of c, q are list
    def gen_kth_laplacian_noise(k, c, q, n):
        kth_scales = gen_kth_scales(k, c, q)
        return np.asmatrix(np.random.laplace(scale=kth_scales,
                                             size=n)).transpose()

    L, eps = graph_util(G)

    if len(state) == 0:
        state = random_initialize(n)
    else:
        state = np.matrix(state).transpose()

    records = state

    state_ = state  # tmp state for convergency check
    for k in range(MAX_ITERATIVE_LIMIT):
        # noise
        eta = gen_kth_laplacian_noise(k, c, q, n)
        # print(eta)
        message = state + eta
        state = state_ - eps * L * message + np.diag(s) * eta
        '''
        check convergency
        '''
        if np.allclose(state_, state, atol=0.5 * 1e-1, rtol=0):
            # print("convergency happens")
            break

        state_ = state
        # concatenate the states vertically
        records = np.asmatrix(np.concatenate((records, state), axis=1))
    # print(
    #     "true average:", np.mean(records[:, 0]), "convergency average:",
    #     np.mean(records[:, -1]), "privacy rate:",
    #     abs(np.mean(records[:, -1]) - np.mean(records[:, 0])) /
    #     np.mean(records[:, 0]), "convergency time:", np.size(records, 1))

    return records

# delta = 1.0
'''
  for all the experiments in this part,  q_i(for all i), and s_i(for all i) are equal
'''
q_ = 0  # one-shot adding
s_ = 1.0
eps_swp = [10**step for step in np.arange(-2, 2.1, 0.2)]

unique_id = str(datetime.datetime.now().strftime('%m%d-%H%M%S'))

for n in [50, 100, 150, 200]:
    # for n in [50]:

    state = random_initialize(n, 50, 100)

    fig = plt.figure()
    # set_xscale only supported in add_subplot
    ax = fig.add_subplot(111)

    x_cords = []
    y_cords = []
    var_cords = []

    for eps in eps_swp:
        # x_cord is filed with the same eps
        x_cord = []
        y_cord = []
        # optimal setting
        c_ = set_c(eps, q_, s_)
def cmp_netsz_iternumbers(unique_id, dp_eps_):
    fig = plt.figure()

    plt.rc('text', usetex=True)
    plt.rc('font', family='Times New Roman', weight='normal', size=14)
    plt.rcParams['mathtext.fontset'] = 'stix'

    # set_xscale only supported in add_subplot
    ax = fig.add_subplot(111)
    mean_cord = []
    for n in size_list:
        # for n in [5]:
        q = [q_ for _ in range(n)]
        s = [s_ for _ in range(n)]
        c = [c_ for _ in range(n)]
        state = random_initialize(n, 50, 100)
        G, fig_id = gen_draw_geograph(n, set_dis(n), unique_id)
        y_cord = []
        for _ in range(20):
            records = dp_avg_consensus(G,
                                       fig_id,
                                       c,
                                       q,
                                       s,
                                       state=np.matrix(state).transpose())
            y_cord.append(records.shape[1])
        ax.scatter([n for _ in range(20)],
                   y_cord,
                   marker='D',
                   s=160,
                   facecolors='none',
                   edgecolors='black')
        mean_cord.append(np.mean(y_cord))
    ax.scatter(size_list,
               mean_cord,
               marker='o',
               s=80,
               color='none',
               edgecolors='g',
               linewidth=3)

    ax.plot(size_list, mean_cord, c='b', lw=1)

    # custom legend
    legend_elements = [
        Line2D([0], [0],
               c='none',
               marker='D',
               markerfacecolor='none',
               markeredgecolor='black',
               label='Iterative Times of Each Run (PE-IDA)',
               markersize=9),
        Line2D([0], [0],
               c='none',
               marker='o',
               markerfacecolor='none',
               markeredgewidth=3,
               markeredgecolor='g',
               label='Iterative Times of IDA algorithm',
               markersize=9)
    ]
    ax.legend(handles=legend_elements, prop={'size': 15})

    plt.xticks([50, 100, 150, 200, 225, 250, 275, 300],
               fontsize=20,
               weight='bold')
    plt.yticks(fontsize=20, weight='bold')
    plt.xlabel(r"$|\mathcal{V}|$", fontsize=20)
    plt.ylabel(r"Iterative Times", fontsize=25, weight='bold')
    ax.grid(ls=':')

    ax.set_aspect(1.0 / ax.get_data_ratio() * 0.6)

    # plt.show()

    # plt.show()
    fig_id = unique_id + "_eps_" + str(dp_eps_).replace('.', '') + "_szitt"
    plt.savefig("../final_exp_publication/netsz_acc_itertnum/" + fig_id +
                '.pdf',
                bbox_inches="tight",
                pad_inches=0.01)
def cmp_netsz_accuracy(unique_id, dp_eps_):
    fig = plt.figure()
    plt.rc('text', usetex=True)
    plt.rc('font', family='Times New Roman', weight='normal', size=14)
    plt.rcParams['mathtext.fontset'] = 'stix'
    # set_xscale only supported in add_subplot
    ax = fig.add_subplot(111)
    mean_cord = []
    for n in size_list:
        # for n in [5]:

        state = random_initialize(n, 50, 100)
        G, _ = gen_draw_geograph(n, set_dis(n), unique_id)
        y_cord = []
        for _ in range(20):
            y_cord.append(direct_cal_diff(n, s_, c_))
        ax.scatter(
            [n for _ in range(20)],
            y_cord,
            marker='P',
            s=160,
            # color="#007dff",
            # linewidth=2,
            color='none',
            edgecolors='black')
        mean_cord.append(np.mean(y_cord))
    ax.scatter(size_list,
               mean_cord,
               marker='o',
               s=80,
               color='none',
               edgecolors='b',
               linewidth=3)
    ax.plot(size_list, mean_cord, c='b', lw=1)

    # custom legend
    legend_elements = [
        Line2D([0], [0],
               c='none',
               marker='P',
               markerfacecolor='none',
               markeredgecolor='black',
               label='Error of Each Run',
               markersize=9),
        Line2D([0], [0],
               c='none',
               marker='o',
               markerfacecolor='none',
               markeredgewidth=3,
               markeredgecolor='b',
               label='Empirical Mean',
               markersize=9)
    ]
    ax.legend(handles=legend_elements, prop={'size': 15})
    ax.grid(ls=':')

    plt.xticks([50, 100, 150, 200, 225, 250, 275, 300],
               fontsize=20,
               weight='bold')
    plt.yticks(fontsize=20, weight='bold')
    # plt.yticks([1, 2])
    plt.xlabel(r"$|\mathcal{V}|$", fontsize=20)
    plt.ylabel(r"$|x^{*} - \bar{\mathbf{x}}|$", fontsize=25)

    ax.set_aspect(1.0 / ax.get_data_ratio() * 0.6)

    # plt.show()
    fig_id = unique_id + "_eps_" + str(dp_eps_).replace('.', '') + "_szacc"
    plt.savefig("../final_exp_publication/netsz_acc_itertnum/" + fig_id +
                '.pdf',
                bbox_inches="tight",
                pad_inches=0.01)