Skip to content

Commit

Permalink
fix in approximate simplification
Browse files Browse the repository at this point in the history
Dennis Rohde committed Jan 26, 2023
1 parent 71d916e commit c7151a7
Showing 3 changed files with 23 additions and 17 deletions.
16 changes: 10 additions & 6 deletions include/simplification.hpp
Original file line number Diff line number Diff line change
@@ -17,11 +17,15 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
#include <algorithm>
#include <cmath>

#include <pybind11/pybind11.h>

#include "config.hpp"
#include "types.hpp"
#include "curve.hpp"
#include "frechet.hpp"

namespace py = pybind11;

namespace Simplification {

class Subcurve_Shortcut_Graph {
@@ -32,15 +36,15 @@ class Subcurve_Shortcut_Graph {
public:

Subcurve_Shortcut_Graph(Curve &curve) : curve{curve}, edges{std::vector<Distances>(curve.complexity(), Distances(curve.complexity(), std::numeric_limits<distance_t>::infinity()))} {
if (Config::verbosity > 1) std::cout << "SIMPL: computing shortcut graph" << std::endl;
if (Config::verbosity > 1) py::print("SIMPL: computing shortcut graph");
const curve_size_t complexity = curve.complexity();
Curve segment(2, curve.front().dimensions());
auto distance = Frechet::Continuous::Distance();

for (curve_size_t i = 0; i < complexity - 1; ++i) {
for (curve_size_t j = i + 1; j < complexity; ++j) {

if (Config::verbosity > 1) std::cout << "SIMPL: computing shortcut distance from vertex " << i << " to vertex " << j << std::endl;
if (Config::verbosity > 1) py::print("SIMPL: computing shortcut distance from vertex ", i, " to vertex ", j);

curve.set_subcurve(i, j);

@@ -57,7 +61,7 @@ class Subcurve_Shortcut_Graph {
}

Curve minimum_error_simplification(const curve_size_t ll) const {
if (Config::verbosity > 1) std::cout << "SIMPL: computing exact minimum error simplification using shortcut graph" << std::endl;
if (Config::verbosity > 1) py::print("SIMPL: computing exact minimum error simplification using shortcut graph");
if (ll >= curve.complexity()) return curve;

const curve_size_t l = ll - 1;
@@ -78,15 +82,15 @@ class Subcurve_Shortcut_Graph {
for (curve_size_t i = 0; i < l; ++i) {

if (i == 0) {
if (Config::verbosity > 1) std::cout << "SIMPL: initializing arrays" << std::endl;
if (Config::verbosity > 1) py::print("SIMPL: initializing arrays");
#pragma omp parallel for
for (curve_size_t j = 1; j < curve.complexity(); ++j) {
distances[j][0] = edges[0][j];
predecessors[j][0] = 0;
}
} else {
for (curve_size_t j = 1; j < curve.complexity(); ++j) {
if (Config::verbosity > 1) std::cout << "SIMPL: computing shortcut using " << i << " jumps" << std::endl;
if (Config::verbosity > 1) py::print("SIMPL: computing shortcut using ", i, " jumps");
others.resize(j);
#pragma omp parallel for
for (curve_size_t k = 0; k < j; ++k) {
@@ -101,7 +105,7 @@ class Subcurve_Shortcut_Graph {
}
}

if (Config::verbosity > 1) std::cout << "SIMPL: backwards constructing simplification" << std::endl;
if (Config::verbosity > 1) py::print("SIMPL: backwards constructing simplification");

curve_size_t ell = l - 1;

2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -80,7 +80,7 @@ def build_extension(self, ext):

setup(
name='Fred-Frechet',
version='1.10.4',
version='1.10.5',
author='Dennis Rohde',
author_email='dennis.rohde@tu-dortmund.de',
description='A fast, scalable and light-weight C++ Fréchet distance library, exposed to python and focused on (k,l)-clustering of polygonal curves.',
22 changes: 12 additions & 10 deletions src/simplification.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright 2020-2021 Dennis Rohde
Copyright 2020-2023 Dennis Rohde
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
@@ -11,7 +11,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
#include "simplification.hpp"

Curve Simplification::approximate_minimum_link_simplification(const Curve &pcurve, const distance_t epsilon) {
if (Config::verbosity > 1) std::cout << "ASIMPL: computing approximate minimum link simplification" << std::endl;
if (Config::verbosity > 1) py::print("ASIMPL: computing approximate minimum link simplification");
Curve &curve = const_cast<Curve&>(pcurve);
const curve_size_t complexity = curve.complexity();

@@ -26,10 +26,12 @@ Curve Simplification::approximate_minimum_link_simplification(const Curve &pcurv

segment[0] = curve[i];
j = 0;
distance = 0;

if (Config::verbosity > 1) std::cout << "ASIMPL: computing maximum shortcut starting at " << i << std::endl;
if (Config::verbosity > 1) py::print("ASIMPL: computing maximum shortcut starting at ", i);

if (Config::verbosity > 1) py::print("ASIMPL: exponential error search");

if (Config::verbosity > 1) std::cout << "ASIMPL: exponential error search" << std::endl;
while (distance <= epsilon) {
++j;

@@ -47,7 +49,7 @@ Curve Simplification::approximate_minimum_link_simplification(const Curve &pcurv
low = j == 1 ? 0 : std::pow(2, j - 1);
high = std::min(static_cast<curve_size_t>(std::pow(2, j)), complexity - i - 1);

if (Config::verbosity > 1) std::cout << "ASIMPL: binary error search" << std::endl;
if (Config::verbosity > 1) py::print("ASIMPL: binary error search");
while (low < high) {
mid = std::ceil((low + high) / 2.);

@@ -60,7 +62,7 @@ Curve Simplification::approximate_minimum_link_simplification(const Curve &pcurv
if (distance <= epsilon) low = mid;
else high = mid - 1;
}
if (Config::verbosity > 1) std::cout << "ASIMPL: shortcutting from " << i << " to " << i+low << std::endl;
if (Config::verbosity > 1) py::print("ASIMPL: shortcutting from ", i, " to ", i+low);
i += low;
curve.reset_subcurve();
simplification.push_back(curve[i]);
@@ -69,7 +71,7 @@ Curve Simplification::approximate_minimum_link_simplification(const Curve &pcurv
}

Curve Simplification::approximate_minimum_error_simplification(const Curve &curve, const curve_size_t ell) {
if (Config::verbosity > 1) std::cout << "ASIMPL: computing approximate minimum error simplification" << std::endl;
if (Config::verbosity > 1) py::print("ASIMPL: computing approximate minimum error simplification");
Curve simplification(curve.dimensions()), segment(2, curve.dimensions());

segment[0] = curve.front();
@@ -81,13 +83,13 @@ Curve Simplification::approximate_minimum_error_simplification(const Curve &curv

Curve new_simplification = Simplification::approximate_minimum_link_simplification(curve, max_distance);

if (Config::verbosity > 1) std::cout << "ASIMPL: computing upper bound for error by exponential search" << std::endl;
if (Config::verbosity > 1) py::print("ASIMPL: computing upper bound for error by exponential search");
while (new_simplification.complexity() > ell) {
max_distance *= 2.;
new_simplification = Simplification::approximate_minimum_link_simplification(curve, max_distance);
}

if (Config::verbosity > 1) std::cout << "ASIMPL: binary search using upper bound" << std::endl;
if (Config::verbosity > 1) py::print("ASIMPL: binary search using upper bound");
const distance_t epsilon = std::max(min_distance * Frechet::Continuous::error / 100, std::numeric_limits<distance_t>::epsilon());
while (max_distance - min_distance > epsilon) {
mid_distance = (min_distance + max_distance) / distance_t(2);
@@ -100,7 +102,7 @@ Curve Simplification::approximate_minimum_error_simplification(const Curve &curv
max_distance = mid_distance;
}
}
if (Config::verbosity > 1) std::cout << "ASIMPL: backwards construction of simplification" << std::endl;
if (Config::verbosity > 1) py::print("ASIMPL: backwards construction of simplification");
curve_size_t diff = ell - simplification.complexity();
while (diff > 0) {
simplification.push_back(simplification.back());

0 comments on commit c7151a7

Please sign in to comment.