Added executable to compute Wasserstein distance. dev
author"Arnur Nigmetov <a.nigmetov@gmail.com>"
Mon, 02 Mar 2015 13:20:51 +0100
branchdev
changeset 281 6e883f004ebe
parent 280 668bf4bf1bfb
child 282 c54290544583
Added executable to compute Wasserstein distance. Powering to 1/q is done in output. Maybe, should be changed in the function itself?
examples/bottleneck-distance.cpp
tools/matching/CMakeLists.txt
tools/matching/bottleneck.cpp
tools/matching/wasserstein.cpp
--- a/examples/bottleneck-distance.cpp	Fri Dec 06 19:09:12 2013 -0800
+++ b/examples/bottleneck-distance.cpp	Mon Mar 02 13:20:51 2015 +0100
@@ -60,8 +60,9 @@
     PDgm dgm1, dgm2;
     read_diagram(dgm1, filename1);
     read_diagram(dgm2, filename2);
-    std::cout << "Size dgm1: " << dgm1.size() << std::endl;
-    std::cout << "Size dgm2: " << dgm2.size() << std::endl;
+    //std::cout << "Size dgm1: " << dgm1.size() << std::endl;
+    //std::cout << "Size dgm2: " << dgm2.size() << std::endl;
 
-    std::cout << "Distance: " << bottleneck_distance(dgm1, dgm2) << std::endl;
+    //std::cout << "Distance: " << bottleneck_distance(dgm1, dgm2) << std::endl;
+    std::cout << "L2-Distance: " << wasserstein_distance(dgm1, dgm2, 2) << std::endl;
 }
--- a/tools/matching/CMakeLists.txt	Fri Dec 06 19:09:12 2013 -0800
+++ b/tools/matching/CMakeLists.txt	Mon Mar 02 13:20:51 2015 +0100
@@ -4,3 +4,6 @@
 # Build compare-diagrams
 add_executable                  (bottleneck                     bottleneck.cpp)
 target_link_libraries           (bottleneck                     ${libraries})
+
+add_executable                  (wasserstein                     wasserstein.cpp)
+target_link_libraries           (wasserstein                     ${libraries})
--- a/tools/matching/bottleneck.cpp	Fri Dec 06 19:09:12 2013 -0800
+++ b/tools/matching/bottleneck.cpp	Mon Mar 02 13:20:51 2015 +0100
@@ -23,7 +23,7 @@
     read_diagram(filename1, dgm1);
     read_diagram(filename2, dgm2);
 
-    std::cout << "Distance: " << bottleneck_distance(dgm1, dgm2) << std::endl;
+    std::cout << bottleneck_distance(dgm1, dgm2) << std::endl;
 }
 
 
@@ -34,6 +34,7 @@
     while(in)
     {
         in >> birth >> death;
+        //std::cout << "birth: " << birth << ", death: " << death << std::endl;
         if (in)
             dgm.push_back(Point(birth, death));
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/matching/wasserstein.cpp	Mon Mar 02 13:20:51 2015 +0100
@@ -0,0 +1,74 @@
+#include <iostream>
+#include <fstream>
+
+#include <topology/persistence-diagram.h>
+
+#include <boost/program_options.hpp>
+namespace po = boost::program_options;
+
+typedef PersistenceDiagram<>                    PDgm;
+typedef PDgm::Point                             Point;
+
+
+void    read_diagram(const std::string& filename, PDgm& dgm);
+void    process_program_options(int argc, char* argv[], std::string& filename1, std::string& filename2, double& wasserPower);
+
+
+int main(int argc, char* argv[])
+{
+    std::string     filename1, filename2;
+    double wasserPower;
+    process_program_options(argc, argv, filename1, filename2, wasserPower);
+
+    PDgm dgm1, dgm2;
+    read_diagram(filename1, dgm1);
+    read_diagram(filename2, dgm2);
+
+    std::cout << pow(wasserstein_distance(dgm1, dgm2, wasserPower), 1.0 / wasserPower) << std::endl;
+}
+
+
+void    read_diagram(const std::string& filename, PDgm& dgm)
+{
+    std::ifstream in(filename.c_str());
+    double birth, death;
+    while(in)
+    {
+        in >> birth >> death;
+        //std::cout << "birth: " << birth << ", death: " << death << std::endl;
+        if (in)
+            dgm.push_back(Point(birth, death));
+    }
+}
+
+void    process_program_options(int     argc, char* argv[], std::string& filename1, std::string& filename2, double& wasserPower)
+{
+    po::options_description hidden("Hidden options");
+    hidden.add_options()
+        ("input-file1",  po::value<std::string>(&filename1), "The first collection of persistence diagrams")
+        ("input-file2",  po::value<std::string>(&filename2), "The second collection of persistence diagrams")
+        ("wasser-power",  po::value<double>(&wasserPower), "The power of Wasserstein distance");
+
+    po::positional_options_description p;
+    p.add("input-file1", 1);
+    p.add("input-file2", 1);
+    p.add("wasser-power", 1);
+    
+    po::options_description all; all.add(hidden);
+
+    po::variables_map vm;
+    po::store(po::command_line_parser(argc, argv).
+                  options(all).positional(p).run(), vm);
+    po::notify(vm);
+
+    if (!vm.count("input-file1") || !vm.count("input-file2"))
+    { 
+        std::cout << "Usage: " << argv[0] << " input-file1 input-file2" << std::endl;
+        std::abort();
+    }
+    if (!vm.count("wasser-power")) 
+    {
+        // use L2 by default
+        wasserPower = 2;
+    }
+}