summaryrefslogtreecommitdiff
path: root/matching/src/common_util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'matching/src/common_util.cpp')
-rw-r--r--matching/src/common_util.cpp243
1 files changed, 243 insertions, 0 deletions
diff --git a/matching/src/common_util.cpp b/matching/src/common_util.cpp
new file mode 100644
index 0000000..96c3388
--- /dev/null
+++ b/matching/src/common_util.cpp
@@ -0,0 +1,243 @@
+#include <vector>
+#include <utility>
+#include <cmath>
+#include <ostream>
+#include <limits>
+#include <algorithm>
+
+#include <common_util.h>
+
+#include "spdlog/spdlog.h"
+#include "spdlog/fmt/ostr.h"
+
+namespace md {
+
+
+ int gcd(int a, int b)
+ {
+ assert(a != 0 or b != 0);
+ // make b <= a
+ std::tie(b, a) = std::minmax({ abs(a), abs(b) });
+ if (b == 0)
+ return a;
+ while((a = a % b)) {
+ std::swap(a, b);
+ }
+ return b;
+ }
+
+ int signum(int a)
+ {
+ if (a < 0)
+ return -1;
+ else if (a > 0)
+ return 1;
+ else
+ return 0;
+ }
+
+ Rational reduce(Rational frac)
+ {
+ int d = gcd(frac.numerator, frac.denominator);
+ frac.numerator /= d;
+ frac.denominator /= d;
+ return frac;
+ }
+
+ void Rational::reduce() { *this = md::reduce(*this); }
+
+
+ Rational& Rational::operator*=(const md::Rational& rhs)
+ {
+ numerator *= rhs.numerator;
+ denominator *= rhs.denominator;
+ reduce();
+ return *this;
+ }
+
+ Rational& Rational::operator/=(const md::Rational& rhs)
+ {
+ numerator *= rhs.denominator;
+ denominator *= rhs.numerator;
+ reduce();
+ return *this;
+ }
+
+ Rational& Rational::operator+=(const md::Rational& rhs)
+ {
+ numerator = numerator * rhs.denominator + denominator * rhs.numerator;
+ denominator *= rhs.denominator;
+ reduce();
+ return *this;
+ }
+
+ Rational& Rational::operator-=(const md::Rational& rhs)
+ {
+ numerator = numerator * rhs.denominator - denominator * rhs.numerator;
+ denominator *= rhs.denominator;
+ reduce();
+ return *this;
+ }
+
+
+ Rational midpoint(Rational a, Rational b)
+ {
+ return reduce({a.numerator * b.denominator + a.denominator * b.numerator, 2 * a.denominator * b.denominator });
+ }
+
+ Rational operator+(Rational a, const Rational& b)
+ {
+ a += b;
+ return a;
+ }
+
+ Rational operator-(Rational a, const Rational& b)
+ {
+ a -= b;
+ return a;
+ }
+
+ Rational operator*(Rational a, const Rational& b)
+ {
+ a *= b;
+ return a;
+ }
+
+ Rational operator/(Rational a, const Rational& b)
+ {
+ a /= b;
+ return a;
+ }
+
+ bool is_less(Rational a, Rational b)
+ {
+ // compute a - b = a_1 / a_2 - b_1 / b_2
+ long numer = a.numerator * b.denominator - a.denominator * b.numerator;
+ long denom = a.denominator * b.denominator;
+ assert(denom != 0);
+ return signum(numer) * signum(denom) < 0;
+ }
+
+ bool operator==(const Rational& a, const Rational& b)
+ {
+ return std::tie(a.numerator, a.denominator) == std::tie(b.numerator, b.denominator);
+ }
+
+ bool operator<(const Rational& a, const Rational& b)
+ {
+ // do not remove signum - overflow
+ long numer = a.numerator * b.denominator - a.denominator * b.numerator;
+ long denom = a.denominator * b.denominator;
+ assert(denom != 0);
+// spdlog::debug("a = {}, b = {}, numer = {}, denom = {}, result = {}", a, b, numer, denom, signum(numer) * signum(denom) <= 0);
+ return signum(numer) * signum(denom) < 0;
+ }
+
+ bool is_leq(Rational a, Rational b)
+ {
+ // compute a - b = a_1 / a_2 - b_1 / b_2
+ long numer = a.numerator * b.denominator - a.denominator * b.numerator;
+ long denom = a.denominator * b.denominator;
+ assert(denom != 0);
+ return signum(numer) * signum(denom) <= 0;
+ }
+
+ bool is_greater(Rational a, Rational b)
+ {
+ return not is_leq(a, b);
+ }
+
+ bool is_geq(Rational a, Rational b)
+ {
+ return not is_less(a, b);
+ }
+
+ Point operator+(const Point& u, const Point& v)
+ {
+ return Point(u.x + v.x, u.y + v.y);
+ }
+
+ Point operator-(const Point& u, const Point& v)
+ {
+ return Point(u.x - v.x, u.y - v.y);
+ }
+
+ Point least_upper_bound(const Point& u, const Point& v)
+ {
+ return Point(std::max(u.x, v.x), std::max(u.y, v.y));
+ }
+
+ Point greatest_lower_bound(const Point& u, const Point& v)
+ {
+ return Point(std::min(u.x, v.x), std::min(u.y, v.y));
+ }
+
+ Point max_point()
+ {
+ return Point(std::numeric_limits<Real>::max(), std::numeric_limits<Real>::min());
+ }
+
+ Point min_point()
+ {
+ return Point(-std::numeric_limits<Real>::max(), -std::numeric_limits<Real>::min());
+ }
+
+ std::ostream& operator<<(std::ostream& ostr, const Point& vec)
+ {
+ ostr << "(" << vec.x << ", " << vec.y << ")";
+ return ostr;
+ }
+
+ Real l_infty_norm(const Point& v)
+ {
+ return std::max(std::abs(v.x), std::abs(v.y));
+ }
+
+ Real l_2_norm(const Point& v)
+ {
+ return v.norm();
+ }
+
+ Real l_2_dist(const Point& x, const Point& y)
+ {
+ return l_2_norm(x - y);
+ }
+
+ Real l_infty_dist(const Point& x, const Point& y)
+ {
+ return l_infty_norm(x - y);
+ }
+
+ void DiagramKeeper::add_point(int dim, md::Real birth, md::Real death)
+ {
+ data_[dim].emplace_back(birth, death);
+ }
+
+ DiagramKeeper::Diagram DiagramKeeper::get_diagram(int dim) const
+ {
+ if (data_.count(dim) == 1)
+ return data_.at(dim);
+ else
+ return DiagramKeeper::Diagram();
+ }
+
+ // return true, if line starts with #
+ // or contains only spaces
+ bool ignore_line(const std::string& s)
+ {
+ for(auto c : s) {
+ if (isspace(c))
+ continue;
+ return (c == '#');
+ }
+ return true;
+ }
+
+
+
+ std::ostream& operator<<(std::ostream& os, const Rational& a)
+ {
+ os << a.numerator << " / " << a.denominator;
+ return os;
+ }
+}