From 6a865d4925c036465d9bf402fb6c8558718e1c79 Mon Sep 17 00:00:00 2001 From: Manos Katsomallos Date: Wed, 6 Oct 2021 18:12:10 +0200 Subject: [PATCH] code: Comparing Wasserstein and Euclidean distance --- code/expt/lmdk_sel_cmp.py | 10 ++++++---- code/lib/lmdk_sel.py | 10 +++++++++- rslt/lmdk_sel_cmp/lmdk_sel_cmp-emd.pdf | Bin 0 -> 14362 bytes ...lmdk_sel_cmp.pdf => lmdk_sel_cmp-norm.pdf} | Bin 15240 -> 14805 bytes 4 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 rslt/lmdk_sel_cmp/lmdk_sel_cmp-emd.pdf rename rslt/lmdk_sel_cmp/{lmdk_sel_cmp.pdf => lmdk_sel_cmp-norm.pdf} (77%) diff --git a/code/expt/lmdk_sel_cmp.py b/code/expt/lmdk_sel_cmp.py index cf9c878..b50a600 100644 --- a/code/expt/lmdk_sel_cmp.py +++ b/code/expt/lmdk_sel_cmp.py @@ -32,7 +32,8 @@ def main(args): plt.xlabel('Landmarks (%)') # Set x axis label. plt.xlim(x_i.min() - x_margin, x_i.max() + x_margin) # The y axis - plt.ylabel('Mean absolute error') # Set y axis label. + # plt.yscale('log') + plt.ylabel('Euclidean distance') # Set y axis label. # Bar offset x_offset = -(bar_width/2)*(len(dist_type) - 1) for d_i, d in enumerate(dist_type): @@ -50,8 +51,9 @@ def main(args): hist, h = lmdk_lib.get_hist(seq, lmdks) opts = lmdk_sel.get_opts_from_top_h(seq, lmdks) delta = 1.0 - res, _ = exp_mech.exponential_pareto(hist, opts, exp_mech.score, delta, epsilon) - mae[n_i] += lmdk_lib.get_norm(hist, res)/args.reps + res, _ = exp_mech.exponential(hist, opts, exp_mech.score, delta, epsilon) + mae[n_i] += lmdk_lib.get_norm(hist, res)/args.reps # Euclidean + # mae[n_i] += lmdk_lib.get_emd(hist, res)/args.reps # Wasserstein print('[OK]', flush=True) # Plot bar for current distribution plt.bar( @@ -63,7 +65,7 @@ def main(args): ) # Change offset for next bar x_offset += bar_width - path = str('../../rslt/lmdk_sel_cmp-pareto/' + 'lmdk_sel_cmp') + path = str('../../rslt/lmdk_sel_cmp/' + 'lmdk_sel_cmp-norm') # Plot legend lmdk_lib.plot_legend() # Show plot diff --git a/code/lib/lmdk_sel.py b/code/lib/lmdk_sel.py index 91638f4..b45a79d 100644 --- a/code/lib/lmdk_sel.py +++ b/code/lib/lmdk_sel.py @@ -6,6 +6,7 @@ import exp_mech import numpy as np import random import time +from scipy.spatial.distance import cdist ''' @@ -174,7 +175,8 @@ def get_opts_from_top_h(seq, lmdks): hist_tmp = np.copy(hist_cur) hist_tmp[i] += 1 # Find difference from original - diff_cur = get_norm(hist, hist_tmp) + diff_cur = get_norm(hist, hist_tmp) # Euclidean + # diff_cur = get_emd(hist, hist_tmp) # Wasserstein # Remember if it is the best that you've seen if diff_cur < diff_min: diff_min = diff_cur @@ -331,6 +333,12 @@ def find_lmdks(seq, lmdks, epsilon): return lmdks_new, epsilon - eps_sel def test(): + + A = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) + B = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + print(get_norm(A, B)) + exit() + # Start and end points of the sequence # # Nonrandom # start = 1 diff --git a/rslt/lmdk_sel_cmp/lmdk_sel_cmp-emd.pdf b/rslt/lmdk_sel_cmp/lmdk_sel_cmp-emd.pdf new file mode 100644 index 0000000000000000000000000000000000000000..27efa2be98b558c9416cd53399b6d391fabbc4ef GIT binary patch literal 14362 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 delta 3433 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