Fréchet View  1.6.0
A Tool for Exploring Fréchet Distance Algorithms
cli.cpp
Go to the documentation of this file.
1 
3 #include <concurrency.h>
4 #include <fs_path.h>
5 
6 using namespace frechet;
7 using namespace poly;
8 using namespace k;
9 using namespace reach;
10 using namespace app;
11 
12 void FrechetViewApplication::cli_setup(QString inputFile, Algorithm algo)
13 {
14 #ifdef QT_DEBUG
15  std::cout << ">>> Debug Build (don't use for serious benchmarks)." << std::endl;
16 #endif
17 
18  // read input file
19  QFileInfo file(inputFile);
20  reader.readAll(file.absoluteFilePath());
21  if (!reader.errorMessage().isEmpty()) {
22  std::string message = reader.errorMessage().toStdString();
23  throw std::runtime_error(message);
24  }
25  if (reader.getResults().size() < 2)
26  throw std::runtime_error("Input file with two curves expected.");
27 
28  P = reader.getResults()[0].toCurve();
29  Q = reader.getResults()[1].toCurve();
30 
31  auto fstring = inputFile.toLocal8Bit();
32  std::cout << " Input: " << fstring.data() << std::endl
33  << " Data: P=" << P.size() << " vertices. Q=" << Q.size() << " vertices. " << std::endl;
34 }
35 
36 
37 
38 int FrechetViewApplication::cli_decideKFrechet(double epsilon)
39 {
40  freeSpace = frechet::FreeSpace::ptr(new frechet::FreeSpace(P,Q));
41  kAlgorithm.reset(new frechet::k::kAlgorithm(freeSpace));
42 
43  freeSpace->calculateFreeSpace(epsilon);
44  freeSpace->calculateBounds(epsilon);
45  freeSpace->components().calculateComponents(*freeSpace);
46 
48  /* The results of the Greedy algorithm
49  * serve as lower and upper bounds for the Brute Force algorithm
50  * */
51  //bf.k_min = greedy.lowerBound();
52  //bf.k_max = greedy.upperBound();
53 
54  if (kAlgorithm->optimalResult().k_max == kAlgorithm::NO_SOLUTION)
55  return kAlgorithm::NO_SOLUTION;
56 
57  if (kAlgorithm->optimalResult().k_optimal != kAlgorithm::UNKNOWN)
58  // the Greedy result is already optimal. Fine.
60 
61  std::cout << " Greedy Result: "
63  <<std::endl;
64 
65  return kAlgorithm->runBruteForce();
66 }
67 
68 int FrechetViewApplication::commandLineInterface(QString inputFile,
69  Algorithm algo, bool topo,
70  double accuracy, double epsilon) throw(std::exception)
71 {
72 
73  cli_setup(inputFile, algo);
74 
75  bool yes;
76  double d_F;
77 
78  pushTimer();
79  FSPath::ptr noPath;
80 
81  switch(algo)
82  {
83  case ALGORITHM_CURVE:
84  std::cout << " Algorithm: Fréchet Distance for Curves. " <<std::endl;
85 
86  polyAlgorithm = newPolyAlgorithm(topo);
87  polyAlgorithm->setup(P,Q,true);
88 
89  if (accuracy==0.0) {
90  std::cout << " "<<"Optimisation variant. "<<std::endl;
91  d_F = polyAlgorithm->optimiseCurve(0.0);
92  }
93  else if (accuracy > 0.0) {
94  std::cout << " "<<"Approximation to "<<accuracy<<std::endl;
95  d_F = polyAlgorithm->optimiseCurve(accuracy);
96  }
97  else if (std::isnan(accuracy)) {
98  std::cout << " "<<"Decision variant. Is d_F <= "<<epsilon<<" ?"<<std::endl;
99  freeSpace = frechet::FreeSpace::ptr(new frechet::FreeSpace(P,Q));
100  freeSpace->calculateFreeSpace(epsilon);
101  yes = (bool)polyAlgorithm->decideCurve(freeSpace,noPath,NAN,true);
102  }
103  else
104  throw std::runtime_error("unexpected accuracy");
105  break;
106 
107  case ALGORITHM_POLYGON:
108 
109  std::cout << " Algorithm: Fréchet Distance for Simple Polygons. "<<std::endl;
110  if (accuracy == 0.0)
111  std::cout << " "<<"Optimisation variant." << std::endl;
112  else if (accuracy > 0.0)
113  std::cout << " "<<"Approximation to " << accuracy << std::endl;
114  else if (std::isnan(accuracy))
115  std::cout << " "<<"Decision variant. Is d_F <= " << epsilon << " ?" << std::endl;
116 
117  setupCurves(topo); // also instantiates PolyAlgorithm and triangulates, etc.
118  printTimer("Setup Curves");
119 
120  if (sizeof(accurate_float) > sizeof(double)) {
121  std::cout << " Info: Using extended floating point arithmetic "
122  <<"("<< std::numeric_limits<accurate_float>::digits <<" digits mantissa) for intermediate results."
123  << std::endl;
124  }
125 
126  switch(polyAlgorithm->status())
127  {
129  break;
130  default:
131  throw std::runtime_error("unexpected status "+polyAlgorithm->status());
132  // die Kurven müssen mind. 2 Punkte enthalten
135  throw std::runtime_error("Polygons must not be empty.");
136  // beide Kurven müssen geschlossen sein
139  throw std::runtime_error("Polygons must be closed. Use -curve instead.");
140  // beide Kurven müssen einfache Polygone seine
143  throw std::runtime_error("Polygons are not simple. Use -curve instead.");
144  // beide Polygone müssen gegen den Uhrzeigersinn orientiert sein
147  throw std::runtime_error("Polygons are not counter-clockwise. This is a bug !");
148  // für konvexe Polygone könenn wir einen einfacheren Algorithmus verwenden
151  throw std::runtime_error("One of the polyons is convex. Use -curve instead.");
152  }
153 
154  if (accuracy==0.0) {
155  d_F = polyAlgorithm->optimisePolygon(noPath);
156  }
157  else if (accuracy > 0.0) {
158  d_F = polyAlgorithm->optimisePolygon(noPath,accuracy);
159  }
160  else if (std::isnan(accuracy)) {
161  freeSpace = frechet::FreeSpace::ptr(new frechet::FreeSpace(P,Q));
162  freeSpace->calculateFreeSpace(epsilon);
163  yes = (bool)polyAlgorithm->decidePolygon(freeSpace,noPath,epsilon,true);
164  }
165  else
166  throw std::runtime_error("Unexpected accuracy");
167  break;
168 
169  case ALGORITHM_K_FRECHET:
170  if (!std::isnan(accuracy))
171  throw std::runtime_error("Optimisation variant not implemented for k-Fréchet algorithm.");
172 
173  std::cout << " Algorithm: k-Fréchet Distance."<<std::endl
174  << " Calculate k for epsilon="<<epsilon << std::endl;
175 
176  int k = cli_decideKFrechet(epsilon);
177  std::cout << " Result: ";
178  if (k >= 0)
179  std::cout <<"k = "<<k<<std::endl;
180  else
181  std::cout <<"no solution."<<std::endl;
182  break;
183  }
184 
185  Clock::time_point t2 = Clock::now();
186 
187  if (algo != ALGORITHM_K_FRECHET)
188  {
189  std::cout << std::fixed << std::setprecision(std::numeric_limits<double>::digits10);
190  if (!std::isnan(accuracy)) {
191  std::cout << " Result: d_F = " << d_F << std::endl;
192  }
193  else if (yes) {
194  std::cout << " Decision: YES. d_F <= " << epsilon << std::endl;
195  }
196  else {
197  std::cout << " Decision: NO. d_F > " << epsilon << std::endl;
198  }
199  }
200 
201  popTimer("Elapsed time");
202  return 0;
203 }
input data are faulty. Q is not a closed curve.
Definition: algorithm.h:100
The k-Frechet algorithm.
Definition: kalgorithm.h:113
time_point printTimer(std::string label, bool do_print=true)
clock benchmark
const struct BruteForce & optimalResult() const
Definition: kalgorithm.h:289
const fs::Components & components
connected components of the free-space diagram
Definition: kalgorithm.h:147
input data have been successfully processed, the algorithm is now ready to execute
Definition: algorithm.h:92
int k_optimal
optimal value so far
Definition: kalgorithm.h:271
global definitions for all algorithms.
input data are faulty. P is convex.
Definition: algorithm.h:110
Algorithm::ptr newPolyAlgorithm(bool topo)
factory method for creating a new algorithm object. Choose the appropriate implementation based on av...
Definition: parallel.cpp:11
Clock::time_point time_point
timestamp with high resolution
Definition: concurrency.h:136
input data are faulty. P is not a oriented counter-clockwise.
Definition: algorithm.h:106
input data are faulty. Q is not a simple polygon.
Definition: algorithm.h:104
input data are faulty. P is not a simple polygon.
Definition: algorithm.h:102
Algorithm
we have three Fréchet Distance algorithms
int runBruteForce(volatile bool *cancelFlag=0)
run the brute force algorithm. The greedy algorithm must have been run before!
Definition: kalgorithm.cpp:267
int runGreedy()
run the greedy algorithm
Definition: kalgorithm.cpp:78
long double accurate_float
Definition: numeric.h:42
time_point popTimer(std::string label, bool do_print=true)
clock benchmark and remove from stack
boost::shared_ptr< FSPath > ptr
smart pointer to an FSPath object
Definition: fs_path.h:65
void calculateComponents(FreeSpace &fs)
calculate connected components
Definition: components.cpp:56
int k_max
upper bound derived from greedy results. k_max = min{greedy.k_xy,greedy.k_yx}
Definition: kalgorithm.h:265
input data are faulty. Q is an empty curve.
Definition: algorithm.h:96
The FreeSpace class models the Free-Space Diagram calculated from two curves.
Definition: freespace.h:83
input data are faulty. Q is not a oriented counter-clockwise.
Definition: algorithm.h:108
input data are faulty. P is an empty curve.
Definition: algorithm.h:94
int k_min
lower bound derived from greedy results. k_min = max{greedy.k_x,greedy.k_y}
Definition: kalgorithm.h:263
input data are faulty. P is not a closed curve.
Definition: algorithm.h:98
input data are faulty. Q is convex.
Definition: algorithm.h:112
boost::shared_ptr< FreeSpace > ptr
smart pointer to FreeSpace object
Definition: freespace.h:92
void pushTimer()
start a new benchmark timer and push it to stack