Added executable to compute Wasserstein distance.
Powering to 1/q is done in output. Maybe, should be changed in the
function itself?
--- 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;
+ }
+}