diff options
author | Nicolas Courty <ncourty@irisa.fr> | 2017-09-13 10:12:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-09-13 10:12:36 +0200 |
commit | c86cc4feb4003e90c7c3dddba237190b360fc514 (patch) | |
tree | f11601b6b1d7ef821a0ae3233960f6f29a1ac0f7 /test | |
parent | 7e5df4cc25e6500ec6f3e85f1c80a7db94863ace (diff) | |
parent | a53ede95f916a11e2150ab7917820d813c0034bc (diff) |
Merge branch 'master' into gromov
Diffstat (limited to 'test')
-rw-r--r-- | test/test_da.py | 326 | ||||
-rw-r--r-- | test/test_ot.py | 114 |
2 files changed, 292 insertions, 148 deletions
diff --git a/test/test_da.py b/test/test_da.py index 104a798..593dc53 100644 --- a/test/test_da.py +++ b/test/test_da.py @@ -22,60 +22,68 @@ def test_sinkhorn_lpl1_transport_class(): Xs, ys = get_data_classif('3gauss', ns) Xt, yt = get_data_classif('3gauss2', nt) - clf = ot.da.SinkhornLpl1Transport() + otda = ot.da.SinkhornLpl1Transport() # test its computed - clf.fit(Xs=Xs, ys=ys, Xt=Xt) - assert hasattr(clf, "cost_") - assert hasattr(clf, "coupling_") + otda.fit(Xs=Xs, ys=ys, Xt=Xt) + assert hasattr(otda, "cost_") + assert hasattr(otda, "coupling_") # test dimensions of coupling - assert_equal(clf.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) - assert_equal(clf.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) + assert_equal(otda.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) + assert_equal(otda.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) # test margin constraints mu_s = unif(ns) mu_t = unif(nt) - assert_allclose(np.sum(clf.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) - assert_allclose(np.sum(clf.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) # test transform - transp_Xs = clf.transform(Xs=Xs) + transp_Xs = otda.transform(Xs=Xs) assert_equal(transp_Xs.shape, Xs.shape) Xs_new, _ = get_data_classif('3gauss', ns + 1) - transp_Xs_new = clf.transform(Xs_new) + transp_Xs_new = otda.transform(Xs_new) # check that the oos method is working assert_equal(transp_Xs_new.shape, Xs_new.shape) # test inverse transform - transp_Xt = clf.inverse_transform(Xt=Xt) + transp_Xt = otda.inverse_transform(Xt=Xt) assert_equal(transp_Xt.shape, Xt.shape) Xt_new, _ = get_data_classif('3gauss2', nt + 1) - transp_Xt_new = clf.inverse_transform(Xt=Xt_new) + transp_Xt_new = otda.inverse_transform(Xt=Xt_new) # check that the oos method is working assert_equal(transp_Xt_new.shape, Xt_new.shape) # test fit_transform - transp_Xs = clf.fit_transform(Xs=Xs, ys=ys, Xt=Xt) + transp_Xs = otda.fit_transform(Xs=Xs, ys=ys, Xt=Xt) assert_equal(transp_Xs.shape, Xs.shape) - # test semi supervised mode - clf = ot.da.SinkhornLpl1Transport() - clf.fit(Xs=Xs, ys=ys, Xt=Xt) - n_unsup = np.sum(clf.cost_) + # test unsupervised vs semi-supervised mode + otda_unsup = ot.da.SinkhornLpl1Transport() + otda_unsup.fit(Xs=Xs, ys=ys, Xt=Xt) + n_unsup = np.sum(otda_unsup.cost_) - # test semi supervised mode - clf = ot.da.SinkhornLpl1Transport() - clf.fit(Xs=Xs, ys=ys, Xt=Xt, yt=yt) - assert_equal(clf.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) - n_semisup = np.sum(clf.cost_) + otda_semi = ot.da.SinkhornLpl1Transport() + otda_semi.fit(Xs=Xs, ys=ys, Xt=Xt, yt=yt) + assert_equal(otda_semi.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) + n_semisup = np.sum(otda_semi.cost_) + # check that the cost matrix norms are indeed different assert n_unsup != n_semisup, "semisupervised mode not working" + # check that the coupling forbids mass transport between labeled source + # and labeled target samples + mass_semi = np.sum( + otda_semi.coupling_[otda_semi.cost_ == otda_semi.limit_max]) + assert mass_semi == 0, "semisupervised mode not working" + def test_sinkhorn_l1l2_transport_class(): """test_sinkhorn_transport @@ -87,65 +95,75 @@ def test_sinkhorn_l1l2_transport_class(): Xs, ys = get_data_classif('3gauss', ns) Xt, yt = get_data_classif('3gauss2', nt) - clf = ot.da.SinkhornL1l2Transport() + otda = ot.da.SinkhornL1l2Transport() # test its computed - clf.fit(Xs=Xs, ys=ys, Xt=Xt) - assert hasattr(clf, "cost_") - assert hasattr(clf, "coupling_") - assert hasattr(clf, "log_") + otda.fit(Xs=Xs, ys=ys, Xt=Xt) + assert hasattr(otda, "cost_") + assert hasattr(otda, "coupling_") + assert hasattr(otda, "log_") # test dimensions of coupling - assert_equal(clf.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) - assert_equal(clf.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) + assert_equal(otda.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) + assert_equal(otda.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) # test margin constraints mu_s = unif(ns) mu_t = unif(nt) - assert_allclose(np.sum(clf.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) - assert_allclose(np.sum(clf.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) # test transform - transp_Xs = clf.transform(Xs=Xs) + transp_Xs = otda.transform(Xs=Xs) assert_equal(transp_Xs.shape, Xs.shape) Xs_new, _ = get_data_classif('3gauss', ns + 1) - transp_Xs_new = clf.transform(Xs_new) + transp_Xs_new = otda.transform(Xs_new) # check that the oos method is working assert_equal(transp_Xs_new.shape, Xs_new.shape) # test inverse transform - transp_Xt = clf.inverse_transform(Xt=Xt) + transp_Xt = otda.inverse_transform(Xt=Xt) assert_equal(transp_Xt.shape, Xt.shape) Xt_new, _ = get_data_classif('3gauss2', nt + 1) - transp_Xt_new = clf.inverse_transform(Xt=Xt_new) + transp_Xt_new = otda.inverse_transform(Xt=Xt_new) # check that the oos method is working assert_equal(transp_Xt_new.shape, Xt_new.shape) # test fit_transform - transp_Xs = clf.fit_transform(Xs=Xs, ys=ys, Xt=Xt) + transp_Xs = otda.fit_transform(Xs=Xs, ys=ys, Xt=Xt) assert_equal(transp_Xs.shape, Xs.shape) - # test semi supervised mode - clf = ot.da.SinkhornL1l2Transport() - clf.fit(Xs=Xs, ys=ys, Xt=Xt) - n_unsup = np.sum(clf.cost_) + # test unsupervised vs semi-supervised mode + otda_unsup = ot.da.SinkhornL1l2Transport() + otda_unsup.fit(Xs=Xs, ys=ys, Xt=Xt) + n_unsup = np.sum(otda_unsup.cost_) - # test semi supervised mode - clf = ot.da.SinkhornL1l2Transport() - clf.fit(Xs=Xs, ys=ys, Xt=Xt, yt=yt) - assert_equal(clf.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) - n_semisup = np.sum(clf.cost_) + otda_semi = ot.da.SinkhornL1l2Transport() + otda_semi.fit(Xs=Xs, ys=ys, Xt=Xt, yt=yt) + assert_equal(otda_semi.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) + n_semisup = np.sum(otda_semi.cost_) + # check that the cost matrix norms are indeed different assert n_unsup != n_semisup, "semisupervised mode not working" + # check that the coupling forbids mass transport between labeled source + # and labeled target samples + mass_semi = np.sum( + otda_semi.coupling_[otda_semi.cost_ == otda_semi.limit_max]) + mass_semi = otda_semi.coupling_[otda_semi.cost_ == otda_semi.limit_max] + assert_allclose(mass_semi, np.zeros_like(mass_semi), + rtol=1e-9, atol=1e-9) + # check everything runs well with log=True - clf = ot.da.SinkhornL1l2Transport(log=True) - clf.fit(Xs=Xs, ys=ys, Xt=Xt) - assert len(clf.log_.keys()) != 0 + otda = ot.da.SinkhornL1l2Transport(log=True) + otda.fit(Xs=Xs, ys=ys, Xt=Xt) + assert len(otda.log_.keys()) != 0 def test_sinkhorn_transport_class(): @@ -158,65 +176,73 @@ def test_sinkhorn_transport_class(): Xs, ys = get_data_classif('3gauss', ns) Xt, yt = get_data_classif('3gauss2', nt) - clf = ot.da.SinkhornTransport() + otda = ot.da.SinkhornTransport() # test its computed - clf.fit(Xs=Xs, Xt=Xt) - assert hasattr(clf, "cost_") - assert hasattr(clf, "coupling_") - assert hasattr(clf, "log_") + otda.fit(Xs=Xs, Xt=Xt) + assert hasattr(otda, "cost_") + assert hasattr(otda, "coupling_") + assert hasattr(otda, "log_") # test dimensions of coupling - assert_equal(clf.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) - assert_equal(clf.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) + assert_equal(otda.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) + assert_equal(otda.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) # test margin constraints mu_s = unif(ns) mu_t = unif(nt) - assert_allclose(np.sum(clf.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) - assert_allclose(np.sum(clf.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) # test transform - transp_Xs = clf.transform(Xs=Xs) + transp_Xs = otda.transform(Xs=Xs) assert_equal(transp_Xs.shape, Xs.shape) Xs_new, _ = get_data_classif('3gauss', ns + 1) - transp_Xs_new = clf.transform(Xs_new) + transp_Xs_new = otda.transform(Xs_new) # check that the oos method is working assert_equal(transp_Xs_new.shape, Xs_new.shape) # test inverse transform - transp_Xt = clf.inverse_transform(Xt=Xt) + transp_Xt = otda.inverse_transform(Xt=Xt) assert_equal(transp_Xt.shape, Xt.shape) Xt_new, _ = get_data_classif('3gauss2', nt + 1) - transp_Xt_new = clf.inverse_transform(Xt=Xt_new) + transp_Xt_new = otda.inverse_transform(Xt=Xt_new) # check that the oos method is working assert_equal(transp_Xt_new.shape, Xt_new.shape) # test fit_transform - transp_Xs = clf.fit_transform(Xs=Xs, Xt=Xt) + transp_Xs = otda.fit_transform(Xs=Xs, Xt=Xt) assert_equal(transp_Xs.shape, Xs.shape) - # test semi supervised mode - clf = ot.da.SinkhornTransport() - clf.fit(Xs=Xs, Xt=Xt) - n_unsup = np.sum(clf.cost_) + # test unsupervised vs semi-supervised mode + otda_unsup = ot.da.SinkhornTransport() + otda_unsup.fit(Xs=Xs, Xt=Xt) + n_unsup = np.sum(otda_unsup.cost_) - # test semi supervised mode - clf = ot.da.SinkhornTransport() - clf.fit(Xs=Xs, ys=ys, Xt=Xt, yt=yt) - assert_equal(clf.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) - n_semisup = np.sum(clf.cost_) + otda_semi = ot.da.SinkhornTransport() + otda_semi.fit(Xs=Xs, ys=ys, Xt=Xt, yt=yt) + assert_equal(otda_semi.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) + n_semisup = np.sum(otda_semi.cost_) + # check that the cost matrix norms are indeed different assert n_unsup != n_semisup, "semisupervised mode not working" + # check that the coupling forbids mass transport between labeled source + # and labeled target samples + mass_semi = np.sum( + otda_semi.coupling_[otda_semi.cost_ == otda_semi.limit_max]) + assert mass_semi == 0, "semisupervised mode not working" + # check everything runs well with log=True - clf = ot.da.SinkhornTransport(log=True) - clf.fit(Xs=Xs, ys=ys, Xt=Xt) - assert len(clf.log_.keys()) != 0 + otda = ot.da.SinkhornTransport(log=True) + otda.fit(Xs=Xs, ys=ys, Xt=Xt) + assert len(otda.log_.keys()) != 0 def test_emd_transport_class(): @@ -229,60 +255,72 @@ def test_emd_transport_class(): Xs, ys = get_data_classif('3gauss', ns) Xt, yt = get_data_classif('3gauss2', nt) - clf = ot.da.EMDTransport() + otda = ot.da.EMDTransport() # test its computed - clf.fit(Xs=Xs, Xt=Xt) - assert hasattr(clf, "cost_") - assert hasattr(clf, "coupling_") + otda.fit(Xs=Xs, Xt=Xt) + assert hasattr(otda, "cost_") + assert hasattr(otda, "coupling_") # test dimensions of coupling - assert_equal(clf.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) - assert_equal(clf.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) + assert_equal(otda.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) + assert_equal(otda.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) # test margin constraints mu_s = unif(ns) mu_t = unif(nt) - assert_allclose(np.sum(clf.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) - assert_allclose(np.sum(clf.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) # test transform - transp_Xs = clf.transform(Xs=Xs) + transp_Xs = otda.transform(Xs=Xs) assert_equal(transp_Xs.shape, Xs.shape) Xs_new, _ = get_data_classif('3gauss', ns + 1) - transp_Xs_new = clf.transform(Xs_new) + transp_Xs_new = otda.transform(Xs_new) # check that the oos method is working assert_equal(transp_Xs_new.shape, Xs_new.shape) # test inverse transform - transp_Xt = clf.inverse_transform(Xt=Xt) + transp_Xt = otda.inverse_transform(Xt=Xt) assert_equal(transp_Xt.shape, Xt.shape) Xt_new, _ = get_data_classif('3gauss2', nt + 1) - transp_Xt_new = clf.inverse_transform(Xt=Xt_new) + transp_Xt_new = otda.inverse_transform(Xt=Xt_new) # check that the oos method is working assert_equal(transp_Xt_new.shape, Xt_new.shape) # test fit_transform - transp_Xs = clf.fit_transform(Xs=Xs, Xt=Xt) + transp_Xs = otda.fit_transform(Xs=Xs, Xt=Xt) assert_equal(transp_Xs.shape, Xs.shape) - # test semi supervised mode - clf = ot.da.EMDTransport() - clf.fit(Xs=Xs, Xt=Xt) - n_unsup = np.sum(clf.cost_) + # test unsupervised vs semi-supervised mode + otda_unsup = ot.da.EMDTransport() + otda_unsup.fit(Xs=Xs, ys=ys, Xt=Xt) + n_unsup = np.sum(otda_unsup.cost_) - # test semi supervised mode - clf = ot.da.EMDTransport() - clf.fit(Xs=Xs, ys=ys, Xt=Xt, yt=yt) - assert_equal(clf.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) - n_semisup = np.sum(clf.cost_) + otda_semi = ot.da.EMDTransport() + otda_semi.fit(Xs=Xs, ys=ys, Xt=Xt, yt=yt) + assert_equal(otda_semi.cost_.shape, ((Xs.shape[0], Xt.shape[0]))) + n_semisup = np.sum(otda_semi.cost_) + # check that the cost matrix norms are indeed different assert n_unsup != n_semisup, "semisupervised mode not working" + # check that the coupling forbids mass transport between labeled source + # and labeled target samples + mass_semi = np.sum( + otda_semi.coupling_[otda_semi.cost_ == otda_semi.limit_max]) + mass_semi = otda_semi.coupling_[otda_semi.cost_ == otda_semi.limit_max] + + # we need to use a small tolerance here, otherwise the test breaks + assert_allclose(mass_semi, np.zeros_like(mass_semi), + rtol=1e-2, atol=1e-2) + def test_mapping_transport_class(): """test_mapping_transport @@ -300,47 +338,51 @@ def test_mapping_transport_class(): ########################################################################## # check computation and dimensions if bias == False - clf = ot.da.MappingTransport(kernel="linear", bias=False) - clf.fit(Xs=Xs, Xt=Xt) - assert hasattr(clf, "coupling_") - assert hasattr(clf, "mapping_") - assert hasattr(clf, "log_") + otda = ot.da.MappingTransport(kernel="linear", bias=False) + otda.fit(Xs=Xs, Xt=Xt) + assert hasattr(otda, "coupling_") + assert hasattr(otda, "mapping_") + assert hasattr(otda, "log_") - assert_equal(clf.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) - assert_equal(clf.mapping_.shape, ((Xs.shape[1], Xt.shape[1]))) + assert_equal(otda.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) + assert_equal(otda.mapping_.shape, ((Xs.shape[1], Xt.shape[1]))) # test margin constraints mu_s = unif(ns) mu_t = unif(nt) - assert_allclose(np.sum(clf.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) - assert_allclose(np.sum(clf.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) # test transform - transp_Xs = clf.transform(Xs=Xs) + transp_Xs = otda.transform(Xs=Xs) assert_equal(transp_Xs.shape, Xs.shape) - transp_Xs_new = clf.transform(Xs_new) + transp_Xs_new = otda.transform(Xs_new) # check that the oos method is working assert_equal(transp_Xs_new.shape, Xs_new.shape) # check computation and dimensions if bias == True - clf = ot.da.MappingTransport(kernel="linear", bias=True) - clf.fit(Xs=Xs, Xt=Xt) - assert_equal(clf.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) - assert_equal(clf.mapping_.shape, ((Xs.shape[1] + 1, Xt.shape[1]))) + otda = ot.da.MappingTransport(kernel="linear", bias=True) + otda.fit(Xs=Xs, Xt=Xt) + assert_equal(otda.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) + assert_equal(otda.mapping_.shape, ((Xs.shape[1] + 1, Xt.shape[1]))) # test margin constraints mu_s = unif(ns) mu_t = unif(nt) - assert_allclose(np.sum(clf.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) - assert_allclose(np.sum(clf.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) # test transform - transp_Xs = clf.transform(Xs=Xs) + transp_Xs = otda.transform(Xs=Xs) assert_equal(transp_Xs.shape, Xs.shape) - transp_Xs_new = clf.transform(Xs_new) + transp_Xs_new = otda.transform(Xs_new) # check that the oos method is working assert_equal(transp_Xs_new.shape, Xs_new.shape) @@ -350,52 +392,56 @@ def test_mapping_transport_class(): ########################################################################## # check computation and dimensions if bias == False - clf = ot.da.MappingTransport(kernel="gaussian", bias=False) - clf.fit(Xs=Xs, Xt=Xt) + otda = ot.da.MappingTransport(kernel="gaussian", bias=False) + otda.fit(Xs=Xs, Xt=Xt) - assert_equal(clf.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) - assert_equal(clf.mapping_.shape, ((Xs.shape[0], Xt.shape[1]))) + assert_equal(otda.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) + assert_equal(otda.mapping_.shape, ((Xs.shape[0], Xt.shape[1]))) # test margin constraints mu_s = unif(ns) mu_t = unif(nt) - assert_allclose(np.sum(clf.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) - assert_allclose(np.sum(clf.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) # test transform - transp_Xs = clf.transform(Xs=Xs) + transp_Xs = otda.transform(Xs=Xs) assert_equal(transp_Xs.shape, Xs.shape) - transp_Xs_new = clf.transform(Xs_new) + transp_Xs_new = otda.transform(Xs_new) # check that the oos method is working assert_equal(transp_Xs_new.shape, Xs_new.shape) # check computation and dimensions if bias == True - clf = ot.da.MappingTransport(kernel="gaussian", bias=True) - clf.fit(Xs=Xs, Xt=Xt) - assert_equal(clf.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) - assert_equal(clf.mapping_.shape, ((Xs.shape[0] + 1, Xt.shape[1]))) + otda = ot.da.MappingTransport(kernel="gaussian", bias=True) + otda.fit(Xs=Xs, Xt=Xt) + assert_equal(otda.coupling_.shape, ((Xs.shape[0], Xt.shape[0]))) + assert_equal(otda.mapping_.shape, ((Xs.shape[0] + 1, Xt.shape[1]))) # test margin constraints mu_s = unif(ns) mu_t = unif(nt) - assert_allclose(np.sum(clf.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) - assert_allclose(np.sum(clf.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=0), mu_t, rtol=1e-3, atol=1e-3) + assert_allclose( + np.sum(otda.coupling_, axis=1), mu_s, rtol=1e-3, atol=1e-3) # test transform - transp_Xs = clf.transform(Xs=Xs) + transp_Xs = otda.transform(Xs=Xs) assert_equal(transp_Xs.shape, Xs.shape) - transp_Xs_new = clf.transform(Xs_new) + transp_Xs_new = otda.transform(Xs_new) # check that the oos method is working assert_equal(transp_Xs_new.shape, Xs_new.shape) # check everything runs well with log=True - clf = ot.da.MappingTransport(kernel="gaussian", log=True) - clf.fit(Xs=Xs, Xt=Xt) - assert len(clf.log_.keys()) != 0 + otda = ot.da.MappingTransport(kernel="gaussian", log=True) + otda.fit(Xs=Xs, Xt=Xt) + assert len(otda.log_.keys()) != 0 def test_otda(): @@ -424,7 +470,8 @@ def test_otda(): da_entrop.interp() da_entrop.predict(xs) - np.testing.assert_allclose(a, np.sum(da_entrop.G, 1), rtol=1e-3, atol=1e-3) + np.testing.assert_allclose( + a, np.sum(da_entrop.G, 1), rtol=1e-3, atol=1e-3) np.testing.assert_allclose(b, np.sum(da_entrop.G, 0), rtol=1e-3, atol=1e-3) # non-convex Group lasso regularization @@ -458,12 +505,3 @@ def test_otda(): da_emd = ot.da.OTDA_mapping_kernel() # init class da_emd.fit(xs, xt, numItermax=10) # fit distributions da_emd.predict(xs) # interpolation of source samples - - -# if __name__ == "__main__": - -# test_sinkhorn_transport_class() -# test_emd_transport_class() -# test_sinkhorn_l1l2_transport_class() -# test_sinkhorn_lpl1_transport_class() -# test_mapping_transport_class() diff --git a/test/test_ot.py b/test/test_ot.py index acd8718..ea6d9dc 100644 --- a/test/test_ot.py +++ b/test/test_ot.py @@ -4,12 +4,15 @@ # # License: MIT License +import warnings + import numpy as np + import ot +from ot.datasets import get_1D_gauss as gauss def test_doctest(): - import doctest # test lp solver @@ -66,9 +69,6 @@ def test_emd_empty(): def test_emd2_multi(): - - from ot.datasets import get_1D_gauss as gauss - n = 1000 # nb bins # bin positions @@ -100,3 +100,109 @@ def test_emd2_multi(): ot.toc('multi proc : {} s') np.testing.assert_allclose(emd1, emdn) + + # emd loss multipro proc with log + ot.tic() + emdn = ot.emd2(a, b, M, log=True, return_matrix=True) + ot.toc('multi proc : {} s') + + for i in range(len(emdn)): + emd = emdn[i] + log = emd[1] + cost = emd[0] + check_duality_gap(a, b[:, i], M, log['G'], log['u'], log['v'], cost) + emdn[i] = cost + + emdn = np.array(emdn) + np.testing.assert_allclose(emd1, emdn) + + +def test_warnings(): + n = 100 # nb bins + m = 100 # nb bins + + mean1 = 30 + mean2 = 50 + + # bin positions + x = np.arange(n, dtype=np.float64) + y = np.arange(m, dtype=np.float64) + + # Gaussian distributions + a = gauss(n, m=mean1, s=5) # m= mean, s= std + + b = gauss(m, m=mean2, s=10) + + # loss matrix + M = ot.dist(x.reshape((-1, 1)), y.reshape((-1, 1))) ** (1. / 2) + + print('Computing {} EMD '.format(1)) + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + print('Computing {} EMD '.format(1)) + ot.emd(a, b, M, numItermax=1) + assert "numItermax" in str(w[-1].message) + assert len(w) == 1 + a[0] = 100 + print('Computing {} EMD '.format(2)) + ot.emd(a, b, M) + assert "infeasible" in str(w[-1].message) + assert len(w) == 2 + a[0] = -1 + print('Computing {} EMD '.format(2)) + ot.emd(a, b, M) + assert "infeasible" in str(w[-1].message) + assert len(w) == 3 + + +def test_dual_variables(): + n = 5000 # nb bins + m = 6000 # nb bins + + mean1 = 1000 + mean2 = 1100 + + # bin positions + x = np.arange(n, dtype=np.float64) + y = np.arange(m, dtype=np.float64) + + # Gaussian distributions + a = gauss(n, m=mean1, s=5) # m= mean, s= std + + b = gauss(m, m=mean2, s=10) + + # loss matrix + M = ot.dist(x.reshape((-1, 1)), y.reshape((-1, 1))) ** (1. / 2) + + print('Computing {} EMD '.format(1)) + + # emd loss 1 proc + ot.tic() + G, log = ot.emd(a, b, M, log=True) + ot.toc('1 proc : {} s') + + ot.tic() + G2 = ot.emd(b, a, np.ascontiguousarray(M.T)) + ot.toc('1 proc : {} s') + + cost1 = (G * M).sum() + # Check symmetry + np.testing.assert_array_almost_equal(cost1, (M * G2.T).sum()) + # Check with closed-form solution for gaussians + np.testing.assert_almost_equal(cost1, np.abs(mean1 - mean2)) + + # Check that both cost computations are equivalent + np.testing.assert_almost_equal(cost1, log['cost']) + check_duality_gap(a, b, M, G, log['u'], log['v'], log['cost']) + + +def check_duality_gap(a, b, M, G, u, v, cost): + cost_dual = np.vdot(a, u) + np.vdot(b, v) + # Check that dual and primal cost are equal + np.testing.assert_almost_equal(cost_dual, cost) + + [ind1, ind2] = np.nonzero(G) + + # Check that reduced cost is zero on transport arcs + np.testing.assert_array_almost_equal((M - u.reshape(-1, 1) - v.reshape(1, -1))[ind1, ind2], + np.zeros(ind1.size)) |