From 082038fa9ff72b59852623d6fc5847936dbae5bd Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Thu, 23 Mar 2017 16:26:55 +0800 Subject: [PATCH 01/41] BigNum.h build --- src/include/math/BigNum.h | 55 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/src/include/math/BigNum.h b/src/include/math/BigNum.h index e69de29..6be9532 100644 --- a/src/include/math/BigNum.h +++ b/src/include/math/BigNum.h @@ -0,0 +1,55 @@ +#ifndef CUHKSZ_MATH_BIGNUM +#define CUHKSZ_MATH_BIGNUM + +namespace cuhksz { + +#include +#include + +class BigNum { +public: + BigNum(); + BigNum(char* input); + BigNum(long long input); + BigNum(const BigNum &other); + + ~BigNum(); + + friend BigNum& operator+(const BigNum& a, const BigNum& b); + friend BigNum& operator-(const BigNum& a, const BigNum& b); + friend BigNum& operator*(const BigNum& a, const BigNum& b); + friend BigNum& operator/(const BigNum& a, const BigNum& b); + + friend BigNum& operator+(const BigNum& a, const long long &b); + friend BigNum& operator-(const BigNum& a, const long long &b); + friend BigNum& operator*(const BigNum& a, const long long &b); + friend BigNum& operator/(const BigNum& a, const long long &b); + + friend BigNum& operator+(const long long &a, const BigNum& b); + friend BigNum& operator-(const long long &a, const BigNum& b); + friend BigNum& operator*(const long long &a, const BigNum& b); + friend BigNum& operator/(const long long &a, const BigNum& b); + + friend BigNum operator+=(BigNum& a, const BigNum& b); + friend BigNum operator-=(BigNum& a, const BigNum& b); + friend BigNum operator*=(BigNum& a, const BigNum& b); + friend BigNum operator/=(BigNum& a, const BigNum& b); + + friend BigNum operator+=(long long &a, const BigNum &b); + friend BigNum operator-=(long long &a, const BigNum &b); + friend BigNum operator*=(long long &a, const BigNum &b); + friend BigNum operator/=(long long &a, const BigNum &b); + + friend std::ostream operator<<(const ostream& os, const BigNum& output); + friend std::istream operator>>(const istream& is, BigNum& input); + + friend long long intval(); +private: + char* element; +}; + + +} // namespace cuhksz + + +#endif // CUHKSZ_MATH_BIGNUM From d0cc67d7134d3b2e29d7a744ed5daa36183b1073 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Thu, 23 Mar 2017 16:47:27 +0800 Subject: [PATCH 02/41] change data store way from char pointer to std::string for dynamic --- src/include/math/BigNum.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/include/math/BigNum.h b/src/include/math/BigNum.h index 6be9532..8c5e363 100644 --- a/src/include/math/BigNum.h +++ b/src/include/math/BigNum.h @@ -5,13 +5,13 @@ namespace cuhksz { #include #include +#include class BigNum { public: BigNum(); BigNum(char* input); BigNum(long long input); - BigNum(const BigNum &other); ~BigNum(); @@ -45,7 +45,7 @@ class BigNum { friend long long intval(); private: - char* element; + string element; }; From 6695e1d649cab09d03eaee8a27a12718a46e494b Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Fri, 7 Apr 2017 19:07:23 +0800 Subject: [PATCH 03/41] BigNum implement --- src/include/geometry/Point.h | 77 +++---- src/include/math_utils/BigNum.h | 349 ++++++++++++++++++++++++++++++++ 2 files changed, 392 insertions(+), 34 deletions(-) diff --git a/src/include/geometry/Point.h b/src/include/geometry/Point.h index 94f5d16..b82b7a7 100644 --- a/src/include/geometry/Point.h +++ b/src/include/geometry/Point.h @@ -13,55 +13,64 @@ template class Point { public: Point() { - memset(element, 0, N * sizeof(double)); + memset(elem, 0, N * sizeof(double)); } explicit Point(double const x) { - element[0] = x; + elem[0] = x; static_assert(N == 1, "X constructor only usable in 1D"); } Point(double const x, double const y) { - element[0] = x, element[1] = y; + elem[0] = x, elem[1] = y; static_assert(N == 2, "XY constructor only usable in 2D"); } Point(double const x, double const y, double const z) { - element[0] = x, element[1] = y, element[2] = z; + elem[0] = x, elem[1] = y, elem[2] = z; static_assert(N == 3, "XYZ constructor only usable in 3D"); } + Point(const Point& src) { + memcpy(elem, src.elem, N * sizeof(double)); + } + ~Point() { } - // element can be change directly + Point& operator=(const Point& src) { + Point ret = Point(src); + return ret; + } + + // elem can be change directly double& operator[](int const &index) const { - return element[index]; + return elem[index]; } - // TODO: what about init a null Point then assign to element[i] + other.element[i] + // TODO: what about init a null Point then assign to elem[i] + other.elem[i] Point& operator+(Point const &other) const { - Point ret(this); + Point ret; for (int i = 0; i < N; i ++) - ret.element[i] += other.element[i]; + ret.elem[i] = elem[i] + other.elem[i]; return ret; } Point& operator-(Point const &other) const { - Point ret(this); + Point ret; for (int i = 0; i < N; i ++) - ret.element[i] -= other.element[i]; + ret.elem[i] = elem[i] - other.elem[i]; return ret; } Point& operator+=(Point const &other) { for (int i = 0; i < N; i ++) - element[i] += other.element[i]; + elem[i] += other.elem[i]; return *this; } Point& operator-=(Point const &other) { for (int i = 0; i < N; i ++) - element[i] -= other.element[i]; + elem[i] -= other.elem[i]; return *this; } @@ -69,14 +78,14 @@ class Point { double operator*(Point const &other) const { double ret = 0.0; for (int i = 0; i < N; i ++) - ret += element[i] * other.element[i]; + ret += elem[i] * other.elem[i]; return ret; } Point& operator*(double const &constant) const { - Point ret(this); + Point ret; for (int i = 0; i < N; i ++) - ret.element[i] *= constant; + ret.elem[i] = elem[i] * constant; return ret; } @@ -86,26 +95,26 @@ class Point { Point& operator*=(double const &constant) { for (int i = 0; i < N; i ++) - element[i] *= constant; + elem[i] *= constant; return *this; } Point& operator/(double const &constant) const { - Point ret(this); + Point ret; for (int i = 0; i < N; i ++) - ret.element[i] /= constant; + ret.elem[i] = elem[i] / constant; return ret; } Point& operator/=(double const &constant) { for (int i = 0; i < N; i ++) - element[i] /= constant; + elem[i] /= constant; return *this; } bool operator==(Point const &other) const { for (int i = 0; i < N; i ++) - if (fabs(element[i] - other.element[i]) < EPS) + if (fabs(elem[i] - other.elem[i]) < EPS) return false; return true; } @@ -116,29 +125,29 @@ class Point { bool operator<(Point const &other) const { for (int i = 0; i < N; i ++) - if (element[i] != other.element[i]) - return element[i] < other.element[i]; + if (elem[i] != other.elem[i]) + return elem[i] < other.elem[i]; return false; } bool operator<=(Point const &other) const { for (int i = 0; i < N; i ++) - if (element[i] != other.element[i]) - return element[i] < other.element[i]; + if (elem[i] != other.elem[i]) + return elem[i] < other.elem[i]; return true; } bool operator>(Point const &other) const { for (int i = 0; i < N; i ++) - if (element[i] != other.element[i]) - return element[i] > other.element[i]; + if (elem[i] != other.elem[i]) + return elem[i] > other.elem[i]; return false; } bool operator>=(Point const &other) const { for (int i = 0; i < N; i ++) - if (element[i] != other.element[i]) - return element[i] > other.element[i]; + if (elem[i] != other.elem[i]) + return elem[i] > other.elem[i]; return true; } @@ -147,26 +156,26 @@ class Point { // cross product double operator^(Point const other) const { static_assert(N == 2, "cross product only apply to 2D"); - return element[0] * other.element[1] - element[1] * other.element[0]; + return elem[0] * other.elem[1] - elem[1] * other.elem[0]; } friend std::ostream& operator<<(std::ostream& os, Point const self) { - os << "(" << self.element[0]; + os << "(" << self.elem[0]; for (int i = 1; i < N; i ++) - os << ", " << self.element[i]; + os << ", " << self.elem[i]; return os << ")"; } double len() { double ret = 0.0; for (int i = 0; i < N; i ++) - ret += element[i] * element[i]; + ret += elem[i] * elem[i]; return sqrt(ret); } private: - double element[N]; // coordinates + double elem[N]; // coordinates }; } // namespace cuhksz diff --git a/src/include/math_utils/BigNum.h b/src/include/math_utils/BigNum.h index e69de29..964751b 100644 --- a/src/include/math_utils/BigNum.h +++ b/src/include/math_utils/BigNum.h @@ -0,0 +1,349 @@ +#ifndef CUHKSZ_MATH_BIGNUM +#define CUHKSZ_MATH_BIGNUM + +#include +#include +#include +#include + +namespace cuhksz { + +template +class BigNum { +public: + BigNum() { + memset(elem, 0, MAX_SIZE * sizeof(int)); + sign = 1; + len = 0; + } + + BigNum(const long long x) { + len = 0; + sign = x < 0 ? -1 : 1; + memset(elem, 0, MAX_SIZE * sizeof(int)); + for (long long i = std::abs(x); i; i /= BigNum::base) + elem[len ++] = i % BigNum::base; + } + + // TODO: use 短除法 + BigNum(const std::string & s) { + sign = s[0] == '-' ? -1 : 1; + len = 0; + memset(elem, 0, MAX_SIZE * sizeof(int)); + for (int i = s.size() - 1; i >= (s[0] == '-'); i --) + elem[len ++] = s[i]; + } + + BigNum(const BigNum &src) { + sign = src.sign; + len = src.len; + memcpy(elem, src.elem, len * sizeof(int)); + } + + ~BigNum() { } + + // allocation + BigNum& operator= (const BigNum& src) const { + sign = src.sign; + len = src.len; + memcpy(elem, src.elem, len * sizeof(int)); + return *this; + } + + // index + int& operator[] (const int index) const { + return elem[index]; + } + + // output + friend std::ostream& operator<< (std::ostream& os, const BigNum& src) { + os << src.toString(); + return os; + } + + // compare + bool operator< (const BigNum& other) const { + return cmp(*this, other) < 0; + } + + bool operator<= (const BigNum& other) const { + return cmp(*this, other) <= 0; + } + + bool operator> (const BigNum& other) const { + return cmp(*this, other) > 0; + } + + bool operator>= (const BigNum& other) const { + return cmp(*this, other) >= 0; + } + + bool operator== (const BigNum& other) const { + return cmp(*this, other) == 0; + } + + bool operator!= (const BigNum& other) const { + return cmp(*this, other) != 0; + } + + // addition + BigNum& operator+ (const BigNum& other) const { + BigNum ret; + if (sign == other.sign) { + ret = add(*this, other); + } else { + if (sign < 0) + ret = sub(other, *this); + else + ret = sub(*this, other); + } + return ret; + } + + BigNum& operator+ (const long long smallNum) const { + BigNum ret, other = BigNum(smallNum); + if (sign == other.sign) { + ret = add(*this, other); + } else { + if (sign < 0) + ret = sub(other, *this); + else + ret = sub(*this, other); + } + return ret; + } + + BigNum& operator+= (const BigNum& other) { + if (sign == other.sign) { + *this = add(*this, other); + } else { + if (sign < 0) + *this = sub(other, *this); + else + *this = sub(*this, other); + } + return *this; + } + + BigNum& operator+= (const long long smallNum) { + BigNum other = BigNum(smallNum); + if (sign == other.sign) { + *this = add(*this, other); + } else { + if (sign < 0) + *this = sub(other, *this); + else + *this = sub(*this, other); + } + return *this; + } + + // subtraction + BigNum& operator- (const BigNum& other) const { + BigNum ret; + if (sign == other.sign) { + if (sign < 0) + ret = sub(other, *this); + else + ret = sub(*this, other); + } + else { + ret = add(*this, other); + } + return ret; + } + + BigNum& operator- (const long long smallNum) const { + BigNum ret, other = BigNum(smallNum); + if (sign == other.sign) { + if (sign < 0) + ret = sub(other, *this); + else + ret = sub(*this, other); + } + else { + ret = add(*this, other); + } + return ret; + } + + BigNum& operator-= (const BigNum& other) { + if (sign == other.sign) { + if (sign < 0) + *this = sub(other, *this); + else + *this = sub(*this, other); + } + else { + *this = add(*this, other); + } + return *this; + } + + BigNum& operator-= (const long long smallNum) { + BigNum other = BigNum(smallNum); + if (sign == other.sign) { + if (sign < 0) + *this = sub(other, *this); + else + *this = sub(*this, other); + } + else { + *this = add(*this, other); + } + return *this; + } + + // multiplication + BigNum& operator* (const BigNum& other) const { + BigNum ret = mul(*this, other); + return ret; + } + + BigNum& operator* (const long long smallNum) const { + BigNum ret, other = BigNum(smallNum); + ret = mul(*this, other); + return ret; + } + + BigNum& operator*= (const BigNum& other) const { + *this = mul(*this, other); + return *this; + } + + BigNum& operator*= (const long long smallNum) { + BigNum other = BigNum(smallNum); + *this = mul(*this, other); + return *this; + } + + // other + BigNum& operator- () const { + BigNum ret = *this; + ret.sign = -ret.sign; + return ret; + } + + BigNum& operator++ () { // prefix ++ + *this += 1; + return *this; + } + + BigNum& operator++ (int) { // postfix ++ + BigNum ret = *this; + ++ (*this); + return ret; + } + + BigNum& operator-- () { + *this -= 1; + return *this; + } + + BigNum& operator-- (int) { + BigNum ret = *this; + -- (*this); + return ret; + } + + + friend int cmp(const BigNum& a, const BigNum& b, bool isAbs=false) { + if (!isAbs && a.sign != b.sign) return a.sign > b.sign ? 1 : -1; + if (a.len != b.len) return a.len > b.len ? a.sign : -a.sign; + for (int i = a.len - 1; i >= 0; i --) + if (a[i] != b[i]) + return a[i] > b[i] ? a.sign : -a.sign; + return 0; + } + + friend BigNum& add(const BigNum& a, const BigNum& b) { + BigNum ret; + ret.len = std::max(a.len, b.len); + for (int i = 0; i < ret.len; i ++) + ret[i] = a[i] + b[i]; + for (int i = 0; i < ret.len; i ++) + if (ret[i] >= BigNum::base) { + ret[i] -= BigNum::base; + ret[i + 1] ++; + } + if (ret[ret.len]) ret.len ++; + ret.sign = a.sign; + return ret; + } + + friend BigNum& sub(const BigNum& a, const BigNum& b) { + BigNum ret, *l, *s; + + if (cmp(a, b, true) < 0) { + l = &b, s = &a; + ret.sign = -1; + } else l = &a, s = &b; + + ret.len = l->len; + for (int i = 0; i < ret.len; i ++) + ret[i] = (*l)[i] - (*s)[i]; + for (int i = 0; i < ret.len; i ++) + if (ret[i] < 0) { + ret[i] += BigNum::base; + ret[i + 1] --; + } + while (ret.len > 0 && !ret[ret.len-1]) ret.len --; + return ret; + } + + friend BigNum& mul(const BigNum& a, const BigNum& b) { + BigNum ret; + if (a.len == 0 || b.len == 0) + return ret; + + ret.len = a.len + b.len - 1; + for (int i = 0; i < a.len; i ++) + for (int j = 0; j < b.len; j ++) { + ret[i + j] += a[i] * b[j]; + } + for (int i = 0; i < ret.len; i ++) { + ret[i + 1] += ret[i] / BigNum::base; + ret[i] %= BigNum::base; + } + if (ret[ret.len]) ret.len ++; + ret.sign = a.sign; + return ret; + } + + BigNum& abs() const { + sign = 1; + return *this; + } + + friend BigNum& abs(const BigNum& a) { + return a.abs(); + } + + std::string toString() const { + std::string s; + if (sign < 0) s += "-"; + for (int i = len - 1, j = 0; i >= 0; i --, j ++) + s[j] += std::to_string(elem[i]); + return s; + } + + friend std::string toString(const BigNum& src) { + return src.toString(); + } + + + +private: + int elem[MAX_SIZE]; + int len; + int sign; + static int base; +}; + +template +int BigNum::base = 10; + +} // namespace cuhksz + + +#endif // CUHKSZ_MATH_BIGNUM From f9735e87f5da65eb82d3edc5f67319c7526e0ea2 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Fri, 7 Apr 2017 19:32:00 +0800 Subject: [PATCH 04/41] update BigNum string constructor --- src/include/math_utils/BigNum.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/include/math_utils/BigNum.h b/src/include/math_utils/BigNum.h index 964751b..86505c2 100644 --- a/src/include/math_utils/BigNum.h +++ b/src/include/math_utils/BigNum.h @@ -25,13 +25,14 @@ class BigNum { elem[len ++] = i % BigNum::base; } - // TODO: use 短除法 BigNum(const std::string & s) { sign = s[0] == '-' ? -1 : 1; len = 0; memset(elem, 0, MAX_SIZE * sizeof(int)); - for (int i = s.size() - 1; i >= (s[0] == '-'); i --) - elem[len ++] = s[i]; + for (int i = s.size() - 1; i >= BigNum::order - 1 + (s[0] == '-'); i -= BigNum::order) + elem[len ++] = s.substr(i - BigNum::order + 1, BigNum::order); + if ((s.size() - (s[0] == '-')) % BigNum::order) + elem[len ++] = s.substr((s[0] == '-'), (s.size() - (s[0] == '-')) % BigNum::order); } BigNum(const BigNum &src) { @@ -338,11 +339,15 @@ class BigNum { int len; int sign; static int base; + static int order; }; template int BigNum::base = 10; +template +int BigNum::order = 1; + } // namespace cuhksz From 192acb51cc7564fbfd6af10c8815341b7520ab5c Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Fri, 7 Apr 2017 22:39:12 +0800 Subject: [PATCH 05/41] Matrix implement --- src/include/math_utils/Matrix.h | 186 ++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) diff --git a/src/include/math_utils/Matrix.h b/src/include/math_utils/Matrix.h index a7579b5..ac8994a 100644 --- a/src/include/math_utils/Matrix.h +++ b/src/include/math_utils/Matrix.h @@ -1,8 +1,194 @@ #ifndef CUHKSZ_MATH_MATRIX #define CUHKSZ_MATH_MATRIX +#include +#include +#include +#include +#include + namespace cuhksz { +#define EPS 1e-6 + +class Matrix { +public: + Matrix(int n) : row(n), col(n) { + elem = new double*[row]; + for (int i = 0; i < row; i ++) { + elem[i] = new double[col]; + memset(elem[i], 0, col * sizeof(double)); + } + } + + Matrix(int n, int m) : row(n), col(m) { + elem = new double*[row]; + for (int i = 0; i < row; i ++) { + elem[i] = new double[col]; + memset(elem[i], 0, col * sizeof(double)); + } + } + + Matrix(const Matrix& src) { + deepCopy(src); + } + + ~Matrix() { + clear(); + } + + // allocation + Matrix& operator= (const Matrix& src) { + if (this == &src) return *this; + clear(), deepCopy(src); + return *this; + } + + // index + double* operator[] (int i) const { + return elem[i]; + } + + friend std::ostream& operator<< (const std::ostream& os, const Matrix& src) { + os << src.toString(); + return os; + } + + Matrix& operator* (const Matrix& other) const { + assert(col == other.row); + Matrix* ret = new Matrix(row, other.col); + for (int i = 0; i < ret->row; i ++) + for (int j = 0; j < ret->col; j ++) + for (int k = 0; k < col; k ++) + (*ret)[i][j] += (*this)[i][k] * other[k][j]; + return *ret; + } + + Matrix& operator*= (const Matrix& other) { + assert(col == other.row); + Matrix* ret = new Matrix(row, other.col); + for (int i = 0; i < ret->row; i ++) + for (int j = 0; j < ret->col; j ++) + for (int k = 0; k < col; k ++) + (*ret)[i][j] += (*this)[i][k] * other[k][j]; + clear(); + *this = *ret; + return *this; + } + + Matrix& operator+ (const Matrix& other) const { + assert(row == other.row && col == other.col); + Matrix* ret = new Matrix(row, col); + for (int i = 0; i < row; i ++) + for (int j = 0; j < col; j ++) + (*ret)[i][j] = (*this)[i][j] + other[i][j]; + return *ret; + } + + Matrix& operator+= (const Matrix& other) { + assert(row == other.row && col == other.col); + for (int i = 0; i < row; i ++) + for (int j = 0; j < col; j ++) + (*this)[i][j] += other[i][j]; + return *this; + } + + Matrix& operator- (const Matrix& other) const { + assert(row == other.row && col == other.col); + Matrix* ret = new Matrix(row, col); + for (int i = 0; i < row; i ++) + for (int j = 0; j < col; j ++) + (*ret)[i][j] = (*this)[i][j] - other[i][j]; + return *ret; + } + + Matrix& operator-= (const Matrix& other) { + assert(row == other.row && col == other.col); + for (int i = 0; i < row; i ++) + for (int j = 0; j < col; j ++) + (*this)[i][j] -= other[i][j]; + return *this; + } + + void clear() { + for (int i = 0; i < row; i ++) + delete[] elem[i]; + delete[] elem; + } + + void deepCopy(const Matrix& src) { + row = src.row, col = src.col; + for (int i = 0; i < row; i ++) + memcpy((*this)[i], src[i], col * sizeof(double)); + } + + friend Matrix& idMat(int n) { + Matrix* ret = new Matrix(n); + for (int i = 0; i < n; i ++) + (*ret)[i][i] = 1; + return *ret; + } + + friend Matrix& pow(const Matrix& src, unsigned int n) { + if (n == 1) { + Matrix* ret = new Matrix(src); + return *ret; + } + + Matrix& ret = pow(src, n >> 1); + if (n & 1) ret *= src; + return ret; + } + + int reduce() { + Matrix& A = *this; + for (int i = 0, r = 0; i < row; i ++) { + int nonZeroRow; + while (r < col) { + nonZeroRow = -1; + for (int j = i; j < row; j ++) + if (std::fabs(A[j][r]) >= EPS) { + nonZeroRow = j; + break; + } + if (nonZeroRow < 0) + r ++; + else { + swap(A[nonZeroRow], A[i]); + break; + } + } + if (nonZeroRow < 0) return i; + for (int j = col - 1; j > r; j --) + A[i][j] /= A[i][r]; + A[i][r] = 1.0; + + for (int j = i + 1; j < row; j ++) { + for (int k = col - 1; k > r; k --) + A[j][k] -= A[i][k] * A[j][r]; + A[j][r] = 0.0; + } + } + return ; + } + + std::string toString() { + std::string s; + Matrix& A = *this; + for (int i = 0; i < row; i ++) { + s += std::to_string(A[i][0]); + for (int j = 1; j < col; j ++) + s += ", " + std::to_string(A[i][j]); + s += "\n"; + } + return s; + } + +private: + double** elem; + int row; + int col; +}; } // namespace cuhksz From 0413950ed0d1daee223ce596ec5536c4961decb8 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Fri, 7 Apr 2017 23:52:48 +0800 Subject: [PATCH 06/41] Circle implement --- src/include/geometry/Circle.h | 27 ++++++++++++++++++++++++++- src/include/geometry/Point.h | 2 ++ src/include/math_utils/Matrix.h | 13 +++++++------ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/include/geometry/Circle.h b/src/include/geometry/Circle.h index b67d48c..a8d03e3 100644 --- a/src/include/geometry/Circle.h +++ b/src/include/geometry/Circle.h @@ -1,11 +1,36 @@ #ifndef CUHKSZ_GEOMETRY_CIRCLE #define CUHKSZ_GEOMETRY_CIRCLE +#include "geometry/Point.h" +#include + namespace cuhksz { +#define PI 3.1415926 + class Circle { -private: +public: + Circle() : O(Point<2>(0, 0)), r(1.0) { } + Circle(double r) : O(Point<2>(0, 0)), r(r) { } + Circle(Point<2> O) : O(O), r(1.0) { } + Circle(Point<2> O, double r) : O(O), r(r) { } + ~Circle() { } + + double getArea() { + return PI * r * r; + } + double getPerimeter() { + return 2.0 * PI * r; + } + + Point<2> getPoint(double rad) { + return O + Vector<2>(r * std::cos(rad), r * std::sin(rad)); + } + +private: + Point<2> O; + double r; }; diff --git a/src/include/geometry/Point.h b/src/include/geometry/Point.h index b82b7a7..1c9a388 100644 --- a/src/include/geometry/Point.h +++ b/src/include/geometry/Point.h @@ -178,6 +178,8 @@ class Point { double elem[N]; // coordinates }; +#define Vector Point + } // namespace cuhksz diff --git a/src/include/math_utils/Matrix.h b/src/include/math_utils/Matrix.h index ac8994a..01febaa 100644 --- a/src/include/math_utils/Matrix.h +++ b/src/include/math_utils/Matrix.h @@ -6,6 +6,7 @@ #include #include #include +#include namespace cuhksz { @@ -49,7 +50,7 @@ class Matrix { return elem[i]; } - friend std::ostream& operator<< (const std::ostream& os, const Matrix& src) { + friend std::ostream& operator<< (std::ostream& os, const Matrix& src) { os << src.toString(); return os; } @@ -140,7 +141,7 @@ class Matrix { return ret; } - int reduce() { + void reduce() { Matrix& A = *this; for (int i = 0, r = 0; i < row; i ++) { int nonZeroRow; @@ -154,11 +155,11 @@ class Matrix { if (nonZeroRow < 0) r ++; else { - swap(A[nonZeroRow], A[i]); + std::swap(A.elem[nonZeroRow], A.elem[i]); break; } } - if (nonZeroRow < 0) return i; + if (nonZeroRow < 0) return ; for (int j = col - 1; j > r; j --) A[i][j] /= A[i][r]; A[i][r] = 1.0; @@ -172,9 +173,9 @@ class Matrix { return ; } - std::string toString() { + std::string toString() const { std::string s; - Matrix& A = *this; + const Matrix& A = *this; for (int i = 0; i < row; i ++) { s += std::to_string(A[i][0]); for (int j = 1; j < col; j ++) From 1fde045140888dd503d4f449090532ee576fe9dd Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Tue, 11 Apr 2017 23:31:54 +0800 Subject: [PATCH 07/41] graph/Edge implement --- src/graph/Edge.cpp | 43 +++++++++++++++++++++++++++++ src/graph/{Point.cpp => Vertex.cpp} | 2 +- src/include/graph/Edge.h | 40 +++++++++++++++++++++++++++ src/include/graph/Point.h | 14 ---------- src/include/graph/Vertex.h | 17 ++++++++++++ 5 files changed, 101 insertions(+), 15 deletions(-) create mode 100644 src/graph/Edge.cpp rename src/graph/{Point.cpp => Vertex.cpp} (63%) create mode 100644 src/include/graph/Edge.h delete mode 100644 src/include/graph/Point.h create mode 100644 src/include/graph/Vertex.h diff --git a/src/graph/Edge.cpp b/src/graph/Edge.cpp new file mode 100644 index 0000000..b45cb61 --- /dev/null +++ b/src/graph/Edge.cpp @@ -0,0 +1,43 @@ +#include "graph/Edge.h" + +namespace cuhksz { + +int Edge::nextEdgeID = 0; + +Edge::Edge(Vertex* from, Vertex* to) : from(from), to(to) { + val = 0; + use = true; + id = Edge::nextEdgeID ++; +} + +Edge::Edge(Vertex* from, Vertex* to, int val) : from(from), to(to), val(val) { + use = true; + id = Edge::nextEdgeID ++; +} + +Edge::Edge(const Edge& src) { + from = src.from; + to = src.to; + val = src.val; + use = src.use; + id = Edge::nextEdgeID ++; +} + +Edge::~Edge() { } + +Edge& Edge::operator= (const Edge & src) { + from = src.from; + to = src.to; + val = src.val; + use = src.use; +} + +bool Edge::operator== (const Edge& other) const { + return id == other.id; +} + +bool Edge::operator!= (const Edge& other) const { + return !(*this == other); +} + +} // namespace cuhksz diff --git a/src/graph/Point.cpp b/src/graph/Vertex.cpp similarity index 63% rename from src/graph/Point.cpp rename to src/graph/Vertex.cpp index 3a38ec2..683216c 100644 --- a/src/graph/Point.cpp +++ b/src/graph/Vertex.cpp @@ -1,4 +1,4 @@ -#include "graph/Point.h" +#include "graph/Vertex.h" namespace cuhksz { diff --git a/src/include/graph/Edge.h b/src/include/graph/Edge.h new file mode 100644 index 0000000..efafdb2 --- /dev/null +++ b/src/include/graph/Edge.h @@ -0,0 +1,40 @@ +#ifndef CUHKSZ_GRAPH_EDGE +#define CUHKSZ_GRAPH_EDGE + +#include "graph/Vertex.h" + +namespace cuhksz { + +class Edge { +public: + Edge(Vertex* from, Vertex* to); + Edge(Vertex* from, Vertex* to, int val); + Edge(const Edge & src); + ~Edge(); + + Vertex* getFrom() { return from; } + Vertex* getTo() { return to; } + int getVal() { return val; } + void setVal(int newVal) { val = newVal; } + bool isValid() { return use; } + void setValid() { use = true; } + void setInvalid() { use = false; } + int getID() { return id; } + + Edge& operator= (const Edge & src); + bool operator== (const Edge& other) const; + bool operator!= (const Edge& other) const; + +private: + Vertex* from; + Vertex* to; + int val; + bool use; + int id; + static int nextEdgeID; +}; + +} // namespace cuhksz + + +#endif // CUHKSZ_GRAPH_EDGE diff --git a/src/include/graph/Point.h b/src/include/graph/Point.h deleted file mode 100644 index fbbcd95..0000000 --- a/src/include/graph/Point.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef CUHKSZ_GRAPH_POINT -#define CUHKSZ_GRAPH_POINT - -namespace cuhksz { - -class Point { -private: - -}; - -} // namespace cuhksz - - -#endif // CUHKSZ_GRAPH_POINT diff --git a/src/include/graph/Vertex.h b/src/include/graph/Vertex.h new file mode 100644 index 0000000..3018b62 --- /dev/null +++ b/src/include/graph/Vertex.h @@ -0,0 +1,17 @@ +#ifndef CUHKSZ_GRAPH_VERTEX +#define CUHKSZ_GRAPH_VERTEX + +namespace cuhksz { + +class Edge; + +class Vertex { +private: + Edge* e; + int val; +}; + +} // namespace cuhksz + + +#endif // CUHKSZ_GRAPH_VERTEX From 481dfa70ab920fea0fd55976e7fa668fd03de791 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Tue, 11 Apr 2017 23:55:37 +0800 Subject: [PATCH 08/41] add operator< for sort() --- src/graph/Edge.cpp | 4 ++++ src/include/graph/Edge.h | 1 + 2 files changed, 5 insertions(+) diff --git a/src/graph/Edge.cpp b/src/graph/Edge.cpp index b45cb61..6f28cfd 100644 --- a/src/graph/Edge.cpp +++ b/src/graph/Edge.cpp @@ -40,4 +40,8 @@ bool Edge::operator!= (const Edge& other) const { return !(*this == other); } +bool Edge::operator< (const Edge& other) const { + return val < other.val; +} + } // namespace cuhksz diff --git a/src/include/graph/Edge.h b/src/include/graph/Edge.h index efafdb2..480155e 100644 --- a/src/include/graph/Edge.h +++ b/src/include/graph/Edge.h @@ -24,6 +24,7 @@ class Edge { Edge& operator= (const Edge & src); bool operator== (const Edge& other) const; bool operator!= (const Edge& other) const; + bool operator< (const Edge& other) const; private: Vertex* from; From f93f21f2ddde1f337748558805a6076a63499b7a Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Wed, 12 Apr 2017 00:50:34 +0800 Subject: [PATCH 09/41] graph/Vertex implement --- src/graph/Vertex.cpp | 56 ++++++++++++++++++++++++++++++++++++++ src/include/graph/Vertex.h | 28 ++++++++++++++++++- 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/graph/Vertex.cpp b/src/graph/Vertex.cpp index 683216c..f915cf5 100644 --- a/src/graph/Vertex.cpp +++ b/src/graph/Vertex.cpp @@ -2,6 +2,62 @@ namespace cuhksz { +int Vertex::nextVertexID = 0; + +Vertex::Vertex() { + val = 0; + use = true; + id = Vertex::nextVertexID ++; + inEdges.clear(); + outEdges.clear(); +} + +Vertex::Vertex(int val) : val(val) { + use = true; + id = Vertex::nextVertexID ++; + inEdges.clear(); + outEdges.clear(); +} + +Vertex::Vertex(const Vertex& src) { + val = src.val; + use = src.use; + id = Vertex::nextVertexID ++; + inEdges.clear(); + outEdges.clear(); + for (list::iterator it = src.inEdges.begin(); it != src.inEdges.end(); ++ it) + inEdges.push_back(*it); + for (list::iterator it = src.outEdges.begin(); it != src.outEdges.end(); ++ it) + outEdges.push_back(*it); +} + +Vertex::~Vertex() { + edges.clear(); + for (list::iterator it = inEdges.begin(); it != inEdges.end(); ++ it) + if (*it != NULL) + delete *it; +} + +Vertex& Vertex::operator= (const Vertex& src) { + val = src.val; + use = src.use; + inEdges.clear(); + outEdges.clear(); + for (list::iterator it = src.inEdges.begin(); it != src.inEdges.end(); ++ it) + inEdges.push_back(*it); + for (list::iterator it = src.outEdges.begin(); it != src.outEdges.end(); ++ it) + outEdges.push_back(*it); +} + +bool Vertex::operator< (const Vertex& src) const { + return val < src.val; +} + +void addEdge(Vertex& to, int val) { + Edge* e = new Edge(this, &to, val); + outEdges.push_back(e); + to.inEdges.push_back(e); +} diff --git a/src/include/graph/Vertex.h b/src/include/graph/Vertex.h index 3018b62..5d1ab7e 100644 --- a/src/include/graph/Vertex.h +++ b/src/include/graph/Vertex.h @@ -1,14 +1,40 @@ #ifndef CUHKSZ_GRAPH_VERTEX #define CUHKSZ_GRAPH_VERTEX +#include + namespace cuhksz { class Edge; class Vertex { +public: + Vertex(); + Vertex(int val); + Vertex(const Vertex& src); + ~Vertex(); + + int getVal() { return val; } + void setVal(int newVal) { val = newVal; } + bool isValid() { return use; } + void setValid() { use = true; } + void setInvalid() { use = false; } + int getID() { return id; } + + Vertex& operator= (const Vertex& src); + bool operator< (const Vertex& src) const; + + void addEdge(Vertex& to, int val=0); + int getDegree() { return inEdges.size() + outEdges.size(); } + + list inEdges; + list outEdges; + private: - Edge* e; int val; + bool use; + int id; + static int nextVertexID; }; } // namespace cuhksz From b0c55ce0a8ffaa8ad3019d536d4fdc1e7783f5c4 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Wed, 12 Apr 2017 00:56:51 +0800 Subject: [PATCH 10/41] update user interface --- src/graph/Edge.cpp | 6 ------ src/include/graph/Edge.h | 10 ++++++---- src/include/graph/Vertex.h | 6 ++++-- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/graph/Edge.cpp b/src/graph/Edge.cpp index 6f28cfd..fe16e63 100644 --- a/src/graph/Edge.cpp +++ b/src/graph/Edge.cpp @@ -4,12 +4,6 @@ namespace cuhksz { int Edge::nextEdgeID = 0; -Edge::Edge(Vertex* from, Vertex* to) : from(from), to(to) { - val = 0; - use = true; - id = Edge::nextEdgeID ++; -} - Edge::Edge(Vertex* from, Vertex* to, int val) : from(from), to(to), val(val) { use = true; id = Edge::nextEdgeID ++; diff --git a/src/include/graph/Edge.h b/src/include/graph/Edge.h index 480155e..3b13cd4 100644 --- a/src/include/graph/Edge.h +++ b/src/include/graph/Edge.h @@ -7,14 +7,16 @@ namespace cuhksz { class Edge { public: - Edge(Vertex* from, Vertex* to); - Edge(Vertex* from, Vertex* to, int val); + Edge(Vertex* from, Vertex* to, int val=0); Edge(const Edge & src); ~Edge(); Vertex* getFrom() { return from; } Vertex* getTo() { return to; } + Vertex* from() { return from; } + Vertex* to() { return to; } int getVal() { return val; } + int val() { return val; } void setVal(int newVal) { val = newVal; } bool isValid() { return use; } void setValid() { use = true; } @@ -22,9 +24,9 @@ class Edge { int getID() { return id; } Edge& operator= (const Edge & src); - bool operator== (const Edge& other) const; + bool operator== (const Edge& other) const; // for multipath bool operator!= (const Edge& other) const; - bool operator< (const Edge& other) const; + bool operator< (const Edge& other) const; // for sort private: Vertex* from; diff --git a/src/include/graph/Vertex.h b/src/include/graph/Vertex.h index 5d1ab7e..660114e 100644 --- a/src/include/graph/Vertex.h +++ b/src/include/graph/Vertex.h @@ -15,6 +15,7 @@ class Vertex { ~Vertex(); int getVal() { return val; } + int val() { return val; } void setVal(int newVal) { val = newVal; } bool isValid() { return use; } void setValid() { use = true; } @@ -22,10 +23,11 @@ class Vertex { int getID() { return id; } Vertex& operator= (const Vertex& src); - bool operator< (const Vertex& src) const; + bool operator< (const Vertex& src) const; // for sort void addEdge(Vertex& to, int val=0); - int getDegree() { return inEdges.size() + outEdges.size(); } + int getInDegree() { return inEdges.size(); } + int getOutDegree() { return outEdges.size(); } list inEdges; list outEdges; From b78c615682e75a99f77eccd3ccb4c8b6eae44f1e Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Wed, 12 Apr 2017 01:10:40 +0800 Subject: [PATCH 11/41] solve complie error --- src/graph/Vertex.cpp | 23 ++++++++++++++--------- src/include/graph/Edge.h | 3 --- src/include/graph/Vertex.h | 9 ++++----- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/graph/Vertex.cpp b/src/graph/Vertex.cpp index f915cf5..2d74f61 100644 --- a/src/graph/Vertex.cpp +++ b/src/graph/Vertex.cpp @@ -1,4 +1,5 @@ #include "graph/Vertex.h" +#include "graph/Edge.h" namespace cuhksz { @@ -19,33 +20,37 @@ Vertex::Vertex(int val) : val(val) { outEdges.clear(); } -Vertex::Vertex(const Vertex& src) { +Vertex::Vertex(Vertex& src) { val = src.val; use = src.use; id = Vertex::nextVertexID ++; inEdges.clear(); outEdges.clear(); - for (list::iterator it = src.inEdges.begin(); it != src.inEdges.end(); ++ it) + for (std::list::iterator it = src.inEdges.begin(); it != src.inEdges.end(); ++ it) inEdges.push_back(*it); - for (list::iterator it = src.outEdges.begin(); it != src.outEdges.end(); ++ it) + for (std::list::iterator it = src.outEdges.begin(); it != src.outEdges.end(); ++ it) outEdges.push_back(*it); } Vertex::~Vertex() { - edges.clear(); - for (list::iterator it = inEdges.begin(); it != inEdges.end(); ++ it) + for (std::list::iterator it = inEdges.begin(); it != inEdges.end(); ++ it) if (*it != NULL) delete *it; + for (std::list::iterator it = outEdges.begin(); it != outEdges.end(); ++ it) + if (*it != NULL) + delete *it; + inEdges.clear(); + outEdges.clear(); } -Vertex& Vertex::operator= (const Vertex& src) { +Vertex& Vertex::operator= (Vertex& src) { val = src.val; use = src.use; inEdges.clear(); outEdges.clear(); - for (list::iterator it = src.inEdges.begin(); it != src.inEdges.end(); ++ it) + for (std::list::iterator it = src.inEdges.begin(); it != src.inEdges.end(); ++ it) inEdges.push_back(*it); - for (list::iterator it = src.outEdges.begin(); it != src.outEdges.end(); ++ it) + for (std::list::iterator it = src.outEdges.begin(); it != src.outEdges.end(); ++ it) outEdges.push_back(*it); } @@ -53,7 +58,7 @@ bool Vertex::operator< (const Vertex& src) const { return val < src.val; } -void addEdge(Vertex& to, int val) { +void Vertex::addEdge(Vertex& to, int val) { Edge* e = new Edge(this, &to, val); outEdges.push_back(e); to.inEdges.push_back(e); diff --git a/src/include/graph/Edge.h b/src/include/graph/Edge.h index 3b13cd4..423972a 100644 --- a/src/include/graph/Edge.h +++ b/src/include/graph/Edge.h @@ -13,10 +13,7 @@ class Edge { Vertex* getFrom() { return from; } Vertex* getTo() { return to; } - Vertex* from() { return from; } - Vertex* to() { return to; } int getVal() { return val; } - int val() { return val; } void setVal(int newVal) { val = newVal; } bool isValid() { return use; } void setValid() { use = true; } diff --git a/src/include/graph/Vertex.h b/src/include/graph/Vertex.h index 660114e..65ce994 100644 --- a/src/include/graph/Vertex.h +++ b/src/include/graph/Vertex.h @@ -11,26 +11,25 @@ class Vertex { public: Vertex(); Vertex(int val); - Vertex(const Vertex& src); + Vertex(Vertex& src); ~Vertex(); int getVal() { return val; } - int val() { return val; } void setVal(int newVal) { val = newVal; } bool isValid() { return use; } void setValid() { use = true; } void setInvalid() { use = false; } int getID() { return id; } - Vertex& operator= (const Vertex& src); + Vertex& operator= (Vertex& src); bool operator< (const Vertex& src) const; // for sort void addEdge(Vertex& to, int val=0); int getInDegree() { return inEdges.size(); } int getOutDegree() { return outEdges.size(); } - list inEdges; - list outEdges; + std::list inEdges; + std::list outEdges; private: int val; From c0e0fe5a5f43273a7d5c01099499e92e8d5bb18e Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Thu, 13 Apr 2017 15:32:26 +0800 Subject: [PATCH 12/41] update iterator to const_iterator --- src/graph/Edge.cpp | 1 + src/graph/Vertex.cpp | 21 +++++++++++++++------ src/include/graph/Vertex.h | 6 ++++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/graph/Edge.cpp b/src/graph/Edge.cpp index fe16e63..7a575d1 100644 --- a/src/graph/Edge.cpp +++ b/src/graph/Edge.cpp @@ -24,6 +24,7 @@ Edge& Edge::operator= (const Edge & src) { to = src.to; val = src.val; use = src.use; + return *this; } bool Edge::operator== (const Edge& other) const { diff --git a/src/graph/Vertex.cpp b/src/graph/Vertex.cpp index 2d74f61..93c2149 100644 --- a/src/graph/Vertex.cpp +++ b/src/graph/Vertex.cpp @@ -20,15 +20,15 @@ Vertex::Vertex(int val) : val(val) { outEdges.clear(); } -Vertex::Vertex(Vertex& src) { +Vertex::Vertex(const Vertex& src) { val = src.val; use = src.use; id = Vertex::nextVertexID ++; inEdges.clear(); outEdges.clear(); - for (std::list::iterator it = src.inEdges.begin(); it != src.inEdges.end(); ++ it) + for (std::list::const_iterator it = src.inEdges.begin(); it != src.inEdges.end(); ++ it) inEdges.push_back(*it); - for (std::list::iterator it = src.outEdges.begin(); it != src.outEdges.end(); ++ it) + for (std::list::const_iterator it = src.outEdges.begin(); it != src.outEdges.end(); ++ it) outEdges.push_back(*it); } @@ -43,15 +43,24 @@ Vertex::~Vertex() { outEdges.clear(); } -Vertex& Vertex::operator= (Vertex& src) { +Vertex& Vertex::operator= (const Vertex& src) { val = src.val; use = src.use; inEdges.clear(); outEdges.clear(); - for (std::list::iterator it = src.inEdges.begin(); it != src.inEdges.end(); ++ it) + for (std::list::const_iterator it = src.inEdges.begin(); it != src.inEdges.end(); ++ it) inEdges.push_back(*it); - for (std::list::iterator it = src.outEdges.begin(); it != src.outEdges.end(); ++ it) + for (std::list::const_iterator it = src.outEdges.begin(); it != src.outEdges.end(); ++ it) outEdges.push_back(*it); + return *this; +} + +bool Vertex::operator== (const Vertex& src) const { + return id == src.id; +} + +bool Vertex::operator!= (const Vertex& src) const { + return !(*this == src); } bool Vertex::operator< (const Vertex& src) const { diff --git a/src/include/graph/Vertex.h b/src/include/graph/Vertex.h index 65ce994..b505207 100644 --- a/src/include/graph/Vertex.h +++ b/src/include/graph/Vertex.h @@ -11,7 +11,7 @@ class Vertex { public: Vertex(); Vertex(int val); - Vertex(Vertex& src); + Vertex(const Vertex& src); ~Vertex(); int getVal() { return val; } @@ -21,7 +21,9 @@ class Vertex { void setInvalid() { use = false; } int getID() { return id; } - Vertex& operator= (Vertex& src); + Vertex& operator= (const Vertex& src); + bool operator== (const Vertex& src) const; + bool operator!= (const Vertex& src) const; bool operator< (const Vertex& src) const; // for sort void addEdge(Vertex& to, int val=0); From 74504da0eb8e86305e3ac12a6ad6b3f53828fb02 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sat, 15 Apr 2017 13:39:22 +0800 Subject: [PATCH 13/41] geometry/Line implement --- src/geometry/Line.cpp | 30 ++++++++++++++++++++++++++++++ src/include/geometry/Line.h | 28 ++++++++++++++++++++++++++++ src/include/geometry/Point.h | 33 ++++++++++++++++++--------------- 3 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 src/geometry/Line.cpp create mode 100644 src/include/geometry/Line.h diff --git a/src/geometry/Line.cpp b/src/geometry/Line.cpp new file mode 100644 index 0000000..d6529ac --- /dev/null +++ b/src/geometry/Line.cpp @@ -0,0 +1,30 @@ +#include "geometry/Line.h" + +namespace cuhksz { + +Line::Line(Point<2> A, Vector<2> v) : A(A), v(v) { } + +// Line::Line(Point<2> A, Point<2> B) : A(A) { +// v = B - A; +// } + +Line::Line(const Line& src) { + A = src.A; + v = src.v; +} + +Line::~Line() { } + +Line& Line::operator= (const Line& src) { + A = src.A; + v = src.v; + return *this; +} + +Point<2> getIntersection(const Line& l1, const Line& l2) { + Vector<2> u = l1.A - l2.A; + double t = cross(l2.v, u) / cross(l1.v, l2.v); + return l1.A + l1.v * t; +} + +} diff --git a/src/include/geometry/Line.h b/src/include/geometry/Line.h new file mode 100644 index 0000000..d3fbd07 --- /dev/null +++ b/src/include/geometry/Line.h @@ -0,0 +1,28 @@ +#ifndef CUHKSZ_GEOMETRY_LINE +#define CUHKSZ_GEOMETRY_LINE + +#include "geometry/Point.h" + +namespace cuhksz { + +class Line { +public: + Line(Point<2> A, Vector<2> v); + // Line(Point<2> A, Point<2> B); + Line(const Line& src); + ~Line(); + + Line& operator= (const Line& src); + + double len() { return v.len(); } + + friend Point<2> getIntersection(const Line& l1, const Line& l2); + +private: + Point<2> A; + Vector<2> v; +}; + +} + +#endif // CUHKSZ_GEOMETRY_LINE diff --git a/src/include/geometry/Point.h b/src/include/geometry/Point.h index 1c9a388..03f1dd4 100644 --- a/src/include/geometry/Point.h +++ b/src/include/geometry/Point.h @@ -38,8 +38,8 @@ class Point { ~Point() { } Point& operator=(const Point& src) { - Point ret = Point(src); - return ret; + memcpy(elem, src.elem, N * sizeof(double)); + return *this; } // elem can be change directly @@ -49,14 +49,14 @@ class Point { // TODO: what about init a null Point then assign to elem[i] + other.elem[i] Point& operator+(Point const &other) const { - Point ret; + Point& ret = *(new Point); for (int i = 0; i < N; i ++) ret.elem[i] = elem[i] + other.elem[i]; return ret; } Point& operator-(Point const &other) const { - Point ret; + Point& ret = *(new Point); for (int i = 0; i < N; i ++) ret.elem[i] = elem[i] - other.elem[i]; return ret; @@ -83,7 +83,7 @@ class Point { } Point& operator*(double const &constant) const { - Point ret; + Point& ret = *(new Point); for (int i = 0; i < N; i ++) ret.elem[i] = elem[i] * constant; return ret; @@ -100,7 +100,7 @@ class Point { } Point& operator/(double const &constant) const { - Point ret; + Point& ret = *(new Point); for (int i = 0; i < N; i ++) ret.elem[i] = elem[i] / constant; return ret; @@ -151,15 +151,6 @@ class Point { return true; } - - - // cross product - double operator^(Point const other) const { - static_assert(N == 2, "cross product only apply to 2D"); - return elem[0] * other.elem[1] - elem[1] * other.elem[0]; - } - - friend std::ostream& operator<<(std::ostream& os, Point const self) { os << "(" << self.elem[0]; for (int i = 1; i < N; i ++) @@ -167,6 +158,12 @@ class Point { return os << ")"; } + // cross product + friend double cross(const Point& v, const Point& w) { + static_assert(N == 2, "cross product only apply to 2D"); + return v.elem[0] * w.elem[1] - v.elem[1] * w.elem[0]; + } + double len() { double ret = 0.0; for (int i = 0; i < N; i ++) @@ -174,6 +171,12 @@ class Point { return sqrt(ret); } + void normalize() { + double l = len(); + for (int i = 0; i < N; i ++) + elem[i] /= l; + } + private: double elem[N]; // coordinates }; From 20f99fb43b00572a11b32fc7a4a3400f1c934bfd Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sat, 15 Apr 2017 13:59:58 +0800 Subject: [PATCH 14/41] add disToLine func --- src/geometry/Line.cpp | 21 +++++++++++++++++++++ src/include/geometry/Line.h | 2 ++ src/include/geometry/Point.h | 2 ++ 3 files changed, 25 insertions(+) diff --git a/src/geometry/Line.cpp b/src/geometry/Line.cpp index d6529ac..687525a 100644 --- a/src/geometry/Line.cpp +++ b/src/geometry/Line.cpp @@ -1,7 +1,16 @@ +#include + #include "geometry/Line.h" namespace cuhksz { +#define EPS 1e-6 + +int dcmp(double x) { + if (std::fabs(x) < EPS) return 0; + return x > 0 ? 1 : -1; +} + Line::Line(Point<2> A, Vector<2> v) : A(A), v(v) { } // Line::Line(Point<2> A, Point<2> B) : A(A) { @@ -27,4 +36,16 @@ Point<2> getIntersection(const Line& l1, const Line& l2) { return l1.A + l1.v * t; } +double disToLine(Point<2> P, Line l) { + Vector<2> v1 = l.v, v2 = P - l.A; + return std::fabs(cross(v1, v2) / v1.len()); +} + +double disToSegment(Point<2> P, Line l) { + Vector<2> v1 = l.v, v2 = P - l.A, v3 = P - l.A - l.v; + if (dcmp(v1 * v2) < 0) return v2.len(); + else if (dcmp(v1 * v3) > 0) return v3.len(); + else return std::fabs(cross(v1, v2) / v1.len()); +} + } diff --git a/src/include/geometry/Line.h b/src/include/geometry/Line.h index d3fbd07..9dcef09 100644 --- a/src/include/geometry/Line.h +++ b/src/include/geometry/Line.h @@ -17,6 +17,8 @@ class Line { double len() { return v.len(); } friend Point<2> getIntersection(const Line& l1, const Line& l2); + friend double disToLine(Point<2> P, Line l); + friend double disToSegment(Point<2> P, Line l); private: Point<2> A; diff --git a/src/include/geometry/Point.h b/src/include/geometry/Point.h index 03f1dd4..59e24c1 100644 --- a/src/include/geometry/Point.h +++ b/src/include/geometry/Point.h @@ -183,6 +183,8 @@ class Point { #define Vector Point +#undef EPS + } // namespace cuhksz From e23f77231e641f01b86f925ef51fcf872099c631 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sat, 20 May 2017 17:40:11 +0800 Subject: [PATCH 15/41] complete DFS and Tree --- src/graph/Tree.cpp | 56 ++++++++++++++++++++++++++++++++++++++++ src/include/graph/DFS.h | 29 +++++++++++++++++++++ src/include/graph/Tree.h | 30 ++++++++++++++++++--- 3 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 src/graph/Tree.cpp create mode 100644 src/include/graph/DFS.h diff --git a/src/graph/Tree.cpp b/src/graph/Tree.cpp new file mode 100644 index 0000000..31f5c4a --- /dev/null +++ b/src/graph/Tree.cpp @@ -0,0 +1,56 @@ +#include "graph/Tree.h" + +namespace cuhksz { + +Node::Node(int id, int val) : id(id), val(val) { + fa = NULL; + son.clear(); +} + +Node::~Node() { } + +Node* Node::getAncestor(int level) { + Node* cur = this; + for (int i = 0; level <= (1 << i); i ++) + if (level & (1 << i)) + cur = cur->ancestor[i]; + + return cur; +} + +void Tree::setRoot(Node* newRoot) { + root = newRoot; + root->setFa(NULL); + root->setHeight(0); +} + +void Tree::addNode(Node* node, Node* fa) { + fa->addSon(node); + node->setFa(fa); + node->setHeight(fa->getHeight() + 1); + node->ancestor.push_back(fa); + for (int i = 0; ; i ++) { + Node* nextNode = node->ancestor[i]; + if ((int)nextNode->ancestor.size() <= i) break; + node->ancestor.push_back(nextNode->ancestor[i]); + } +} + +Node* Tree::LCA(Node* x, Node* y) { + int hx = x->getHeight(), hy = y->getHeight(); + if (hx < hy) x = x->getAncestor(hy - hx); + else y = y->getAncestor(hx - hy); + for (int i = x->ancestor.size() - 1; i >= 0; i --) { + if (x->ancestor[i] != y->ancestor[i]) { + x = x->ancestor[i], y = y->ancestor[i]; + } + } + return x->getFa(); +} + +int Tree::getDistance(Node* x, Node* y) { + return x->getHeight() + y->getHeight() - 2 * LCA(x, y)->getHeight(); +} + + +} diff --git a/src/include/graph/DFS.h b/src/include/graph/DFS.h new file mode 100644 index 0000000..a81090e --- /dev/null +++ b/src/include/graph/DFS.h @@ -0,0 +1,29 @@ +#ifndef CUHKSZ_GRAPH_DFS +#define CUHKSZ_GRAPH_DFS + +namespace cuhksz { + +#include +#include + +#include "graph/Vertex.h" + +class DFS : public std::unary_function { +public: + void operator() (Vertex& v) { + vis.insert(v); + for (Edge* e : v.outEdges) { + Vertex& next = *e.to; + if (vis.count(next) == 0) + this->operator(next); + } + } +private: + set vis; +}; + + +} + + +#endif // CUHKSZ_GRAPH_DFS diff --git a/src/include/graph/Tree.h b/src/include/graph/Tree.h index 359bf4c..cc2ea9a 100644 --- a/src/include/graph/Tree.h +++ b/src/include/graph/Tree.h @@ -7,19 +7,43 @@ namespace cuhksz { class Node { public: - Node(); + Node(int id) : Node(id, 0) {} + Node(int id, int val); + ~Node(); - void + int getVal() { return val; } + Node* getFa() { return fa; } + std::vector getSon() { return son; } + void setFa(Node* newFa) { fa = newFa; } + void addSon(Node* newSon) { son.push_back(newSon); } + int getHeight() { return height; } + void setHeight(int h) { height = h; } + Node* getAncestor(int level); + int getDegree() { return son.size(); } + int getID() { return id; } + + std::vector ancestor; // power 2 ancestor + private: Node* fa; std::vector son; - int val; int id; + int val; + int height; }; class Tree { +public: + void setRoot(Node* newRoot); + void addNode(Node* node, Node* fa); + Node* LCA(Node* x, Node* y); + int getDistance(Node* x, Node* y); + +private: + Node* root; + std::vector nodes; }; From 5a32b2a3c685692ccb8e01f2aceeb4adb6c327f7 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sat, 20 May 2017 20:16:34 +0800 Subject: [PATCH 16/41] complete BST --- src/graph/BST.cpp | 109 ++++++++++++++++++++++++++++++++++++++++ src/include/graph/BST.h | 35 +++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 src/graph/BST.cpp create mode 100644 src/include/graph/BST.h diff --git a/src/graph/BST.cpp b/src/graph/BST.cpp new file mode 100644 index 0000000..edbd93a --- /dev/null +++ b/src/graph/BST.cpp @@ -0,0 +1,109 @@ +#include "graph/BST.h" + +namespace cuhksz { + +void BST::rotate(BSTNode* x, int c) { + BSTNode* y = x->fa; + y->ch[!c] = y->ch[c]; + if (x->ch[0] != nullptr) x->ch[0]->fa = y; + x->fa = y->fa; + if (y->fa->ch[0] == y) y->fa->ch[0] = x; + else y->fa->ch[1] = x; + y->fa = x, x->ch[c] = y; + if (y == root) root = x; +} + +void BST::splay(BSTNode* x) { + while (x->fa != nullptr) { + if (x->fa->fa == nullptr) { + if (x->fa->ch[0] == x) rotate(x, 1); + else rotate(x, 0); + } else { + BSTNode* y = x->fa; + BSTNode* z = y->fa; + if (z->ch[0] == y) { + if (y->ch[0] == x) + rotate(y, 1), rotate(x, 1); + else rotate(x, 0), rotate(x, 1); + } else { + if (y->ch[1] == x) + rotate(y, 0), rotate(x, 0); + else rotate(x, 1), rotate(x, 0); + } + } + } +} + +BSTNode* BST::pre(BSTNode* x) { + BSTNode* cur = x->ch[0]; + if (cur == nullptr) return nullptr; + while(cur->ch[1] != nullptr) + cur = cur->ch[1]; + return cur; +} + +BSTNode* BST::suf(BSTNode* x) { + BSTNode* cur = x->ch[1]; + if (cur == nullptr) return nullptr; + while(cur->ch[0] != nullptr) + cur = cur->ch[0]; + return cur; +} + +void BST::insert(BSTNode* x) { + if (root == nullptr) { + root = x; + return; + } + + BSTNode* cur = root; + BSTNode* next; + while (true) { + if (x->rank < cur->rank) { + next = cur->ch[0]; + } else { + next = cur->ch[1]; + } + if (next == nullptr) break; + cur = next; + } + x->fa = cur; + cur->ch[x->rank >= cur->rank] = x; + splay(x); +} + +void BST::erase(BSTNode* x) { + splay(x); + if (x->ch[0] == nullptr && x->ch[1] == nullptr) { + root = nullptr; + } else if (x->ch[0] == nullptr && x->ch[1] != nullptr) { + root = x->ch[1]; + root->fa = nullptr; + } else if (x->ch[0] != nullptr && x->ch[1] == nullptr) { + root = x->ch[1]; + root->fa = nullptr; + } else { + root = pre(x); + if (root->fa->ch[0] == root) + root->fa->ch[0] = root->ch[0]; + else root->fa->ch[1] = root->ch[0]; + if (root->ch[0] != nullptr) root->ch[0]->fa = root->fa; + root->fa = nullptr; + root->ch[0] = x->ch[0]; + root->ch[1] = x->ch[1]; + } +} + +BSTNode* BST::find(int k) { + BSTNode* cur = root; + while (cur != nullptr) { + if (cur->rank == k) return cur; + if (cur->rank < k) cur = cur->ch[1]; + else cur = cur->ch[0]; + } + return nullptr; +} + + + +} diff --git a/src/include/graph/BST.h b/src/include/graph/BST.h new file mode 100644 index 0000000..579d71d --- /dev/null +++ b/src/include/graph/BST.h @@ -0,0 +1,35 @@ +#ifndef CUHKSZ_GRAPH_BST +#define CUHKSZ_GRAPH_BST + +namespace cuhksz { + +struct BSTNode { + BSTNode(int k, int v) : rank(k), val(v) { + ch[0] = ch[1] = fa = nullptr; + } + BSTNode* ch[2]; + BSTNode* fa; + int rank; + int val; +}; + +class BST { +public: + void insert(BSTNode* x); + void erase(BSTNode* x); + BSTNode* find(int k); + BSTNode* pre(BSTNode* x); + BSTNode* suf(BSTNode* x); + +private: + // c = 0 for left_rotate + void rotate(BSTNode* x, int c); + void splay(BSTNode* x); + + BSTNode* root; +}; + + +} + +#endif // CUHKSZ_GRAPH_DFS From db84dbbda0af966f92406f2362e6d38de27ce31b Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 00:28:25 +0800 Subject: [PATCH 17/41] complete SegmentTree.h --- src/include/graph/SegmentTree.h | 178 ++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 src/include/graph/SegmentTree.h diff --git a/src/include/graph/SegmentTree.h b/src/include/graph/SegmentTree.h new file mode 100644 index 0000000..f112ace --- /dev/null +++ b/src/include/graph/SegmentTree.h @@ -0,0 +1,178 @@ +#ifndef CHUKSZ_GRAPH_SEGMENT_TREE +#define CUHKSZ_GRAPH_SEGMENT_TREE + +#include +#include + +namespace cuhksz { + +template +class SegmentTree { +public: + SegmentTree(std::vector& v); + ~SegmentTree(); + + void init(std::vector& v, int l, int r, int o); + ValueType queryMax(int lv, int rv, int l = 0, int r = size - 1, int o = 1); + ValueType queryMin(int lv, int rv, int l = 0, int r = size - 1, int o = 1); + ValueType querySum(int lv, int rv, int l = 0, int r = size - 1, int o = 1); + void addInterval(int lv, int rv, ValueType x, int l = 0, int r = size - 1, int o = 1); + void mulInterval(int lv, int rv, ValueType x, int l = 0, int r = size - 1, int o = 1); + +private: + std::vector minVal; + std::vector maxVal; + std::vector sumVal; + std::vector addFlag; + std::vector mulFlag; + std::vector hasAddFlag; + std::vector hasMulFlag; + int size; + + void update(int o); +}; + +template +SegmentTree::SegmentTree(std::vector& v) { + size = v.size(); + for (int i = 0; i < size * 3; i ++) { + minVal.push_back(v[0]); + maxVal.push_back(v[0]); + sumVal.push_back(v[0]); + } + init(v, 0, size - 1, 1); +} + +template +void SegmentTree::init(std::vector& v, int l, int r, int o) { + if (l == r) { + minVal[o] = v[l]; + maxVal[o] = v[l]; + sumVal[o] = v[l]; + hasAddFlag[o] = hasMulFlag[o] = false; + return; + } + int mid = (l + r) >> 1; + int ls = o << 1, rs = (o << 1) | 1; + init(v, l, mid, ls); + init(v, mid + 1, r, rs); + minVal[o] = std::min(minVal[ls], minVal[rs]); + maxVal[o] = std::max(maxVal[ls], maxVal[rs]); + sumVal[o] = sumVal[ls] + sumVal[rs]; +} + +template +void SegmentTree::update(int o, int l, int r) { + int ls = o << 1, rs = (o << 1) | 1; + if (hasMulFlag[o]) { + hasMulFlag[o] = false; + minVal[o] *= mulFlag[o]; + maxVal[o] *= mulFlag[o]; + sumVal[o] *= mulFlag[o]; + if (hasMulFlag[ls]) + mulFlag[ls] *= mulFlag[o]; + else { + hasMulFlag[ls] = true; + mulFlag[ls] = mulFlag[o]; + } + if (hasAddFlag[ls]) + addFlag[ls] *= mulFlag[o]; + + if (hasMulFlag[rs]) + mulFlag[rs] *= mulFlag[o]; + else { + hasMulFlag[rs] = true; + mulFlag[rs] = mulFlag[o]; + } + if (hasAddFlag[rs]) + addFlag[rs] *= mulFlag[o]; + } + + if (hasAddFlag[o]) { + hasAddFlag[o] = false; + minVal[o] += addFlag[o]; + maxVal[o] += addFlag[o]; + sumVal[o] += addFlag[o] * (r - l + 1); + if (hasAddFlag[ls]) + addFlag[ls] += addFlag[o]; + else { + hasAddFlag[ls] = true; + addFlag[ls] = addFlag[o]; + } + if (hasAddFlag[rs]) + addFlag[rs] += addFlag[o]; + else { + hasAddFlag[rs] = true; + addFlag[rs] = addFlag[o]; + } + } + +} + +template +ValueType SegmentTree::queryMax(int lv, int rv, int l, int r, int o) { + update(o, l, r); + if (lv <= l && rv >= r) + return maxVal[o]; + int mid = (l + r) >> 1; + int ls = o << 1, rs = (o << 1) | 1; + if (rv <= mid) return queryMax(lv, rv, l, mid, ls); + if (lv > mid) return queryMax(lv, rv, mid + 1, r, rs); + return std::max(queryMax(lv, rv, l, mid, ls), queryMax(lv, rv, mid + 1, r, rs)); +} + +template +ValueType SegmentTree::queryMin(int lv, int rv, int l, int r, int o) { + update(o, l, r); + if (lv <= l && rv >= r) + return minVal[o]; + int mid = (l + r) >> 1; + int ls = o << 1, rs = (o << 1) | 1; + if (rv <= mid) return queryMin(lv, rv, l, mid, ls); + if (lv > mid) return queryMin(lv, rv, mid + 1, r, rs); + return std::max(queryMin(lv, rv, l, mid, ls), queryMin(lv, rv, mid + 1, r, rs)); +} + +template +ValueType SegmentTree::querySum(int lv, int rv, int l, int r, int o) { + update(o, l, r); + if (lv <= l && rv >= r) + return sumVal[o]; + int mid = (l + r) >> 1; + int ls = o << 1, rs = (o << 1) | 1; + if (rv <= mid) return querySum(lv, rv, l, mid, ls); + if (lv > mid) return querySum(lv, rv, mid + 1, r, rs); + return std::max(querySum(lv, rv, l, mid, ls), querySum(lv, rv, mid + 1, r, rs)); +} + +template +void SegmentTree::addInterval(int lv, int rv, ValueType x, int l, int r, int o) { + update(o, l, r); + if (lv <= l && rv >= r) { + addFlag[o] = x; + hasAddFlag[o] = true; + return; + } + int mid = (l + r) >> 1; + int ls = o << 1, rs = (o << 1) | 1; + if (lv <= mid) addInterval(lv, rv, x, l, mid, ls); + if (rv > mid) addInterval(lv, rv, x, mid + 1, r, rs); +} + +template +void SegmentTree::mulInterval(int lv, int rv, ValueType x, int l, int r, int o) { + update(o, l, r); + if (lv <= l && rv >= r) { + mulFlag[o] = x; + hasMulFlag[o] = true; + return; + } + int mid = (l + r) >> 1; + int ls = o << 1, rs = (o << 1) | 1; + if (lv <= mid) mulInterval(lv, rv, x, l, mid, ls); + if (rv > mid) mulInterval(lv, rv, x, mid + 1, r, rs); +} + +} + +#endif // CUHKSZ_GRAPH_SEGMENT_TREE From 71493d45339ded67dfe3f5923c38e486e030ad69 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 11:34:59 +0800 Subject: [PATCH 18/41] update gtest --- external/gtest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external/gtest b/external/gtest index aa148eb..59c795c 160000 --- a/external/gtest +++ b/external/gtest @@ -1 +1 @@ -Subproject commit aa148eb2b7f70ede0eb10de34b6254826bfb34f4 +Subproject commit 59c795ce08be0c8b225bc894f8da6c7954ea5c14 From dfcbf0d8250fce974c9250dfecce6f5ec2156e25 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 11:38:52 +0800 Subject: [PATCH 19/41] change NULL to nullptr --- src/graph/Tree.cpp | 4 ++-- src/graph/Vertex.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/graph/Tree.cpp b/src/graph/Tree.cpp index 31f5c4a..8ffe102 100644 --- a/src/graph/Tree.cpp +++ b/src/graph/Tree.cpp @@ -3,7 +3,7 @@ namespace cuhksz { Node::Node(int id, int val) : id(id), val(val) { - fa = NULL; + fa = nullptr; son.clear(); } @@ -20,7 +20,7 @@ Node* Node::getAncestor(int level) { void Tree::setRoot(Node* newRoot) { root = newRoot; - root->setFa(NULL); + root->setFa(nullptr); root->setHeight(0); } diff --git a/src/graph/Vertex.cpp b/src/graph/Vertex.cpp index 93c2149..5786bb1 100644 --- a/src/graph/Vertex.cpp +++ b/src/graph/Vertex.cpp @@ -34,10 +34,10 @@ Vertex::Vertex(const Vertex& src) { Vertex::~Vertex() { for (std::list::iterator it = inEdges.begin(); it != inEdges.end(); ++ it) - if (*it != NULL) + if (*it != nullptr) delete *it; for (std::list::iterator it = outEdges.begin(); it != outEdges.end(); ++ it) - if (*it != NULL) + if (*it != nullptr) delete *it; inEdges.clear(); outEdges.clear(); From 37fe7b0e288e38717209196243d3482a8a3194a8 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 11:40:04 +0800 Subject: [PATCH 20/41] add #undef EPS in Line.cpp && change dcmp into unnameed namespace --- src/geometry/Line.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/geometry/Line.cpp b/src/geometry/Line.cpp index 687525a..ecd4c1b 100644 --- a/src/geometry/Line.cpp +++ b/src/geometry/Line.cpp @@ -2,15 +2,19 @@ #include "geometry/Line.h" -namespace cuhksz { - -#define EPS 1e-6 +namespace { int dcmp(double x) { if (std::fabs(x) < EPS) return 0; return x > 0 ? 1 : -1; } +} + +namespace cuhksz { + +#define EPS 1e-6 + Line::Line(Point<2> A, Vector<2> v) : A(A), v(v) { } // Line::Line(Point<2> A, Point<2> B) : A(A) { @@ -48,4 +52,6 @@ double disToSegment(Point<2> P, Line l) { else return std::fabs(cross(v1, v2) / v1.len()); } +#undef EPS + } From 6959f71547c5c6c3325ef024c37a3e6f561b8ed2 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 11:46:52 +0800 Subject: [PATCH 21/41] change 'val' to 'value' --- src/graph/Vertex.cpp | 14 +++++++------- src/include/graph/Vertex.h | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/graph/Vertex.cpp b/src/graph/Vertex.cpp index 5786bb1..d18cbb8 100644 --- a/src/graph/Vertex.cpp +++ b/src/graph/Vertex.cpp @@ -6,14 +6,14 @@ namespace cuhksz { int Vertex::nextVertexID = 0; Vertex::Vertex() { - val = 0; + value = 0; use = true; id = Vertex::nextVertexID ++; inEdges.clear(); outEdges.clear(); } -Vertex::Vertex(int val) : val(val) { +Vertex::Vertex(int value) : value(value) { use = true; id = Vertex::nextVertexID ++; inEdges.clear(); @@ -21,7 +21,7 @@ Vertex::Vertex(int val) : val(val) { } Vertex::Vertex(const Vertex& src) { - val = src.val; + value = src.value; use = src.use; id = Vertex::nextVertexID ++; inEdges.clear(); @@ -44,7 +44,7 @@ Vertex::~Vertex() { } Vertex& Vertex::operator= (const Vertex& src) { - val = src.val; + value = src.value; use = src.use; inEdges.clear(); outEdges.clear(); @@ -64,11 +64,11 @@ bool Vertex::operator!= (const Vertex& src) const { } bool Vertex::operator< (const Vertex& src) const { - return val < src.val; + return value < src.value; } -void Vertex::addEdge(Vertex& to, int val) { - Edge* e = new Edge(this, &to, val); +void Vertex::addEdge(Vertex& to, int value) { + Edge* e = new Edge(this, &to, value); outEdges.push_back(e); to.inEdges.push_back(e); } diff --git a/src/include/graph/Vertex.h b/src/include/graph/Vertex.h index b505207..220cf2b 100644 --- a/src/include/graph/Vertex.h +++ b/src/include/graph/Vertex.h @@ -10,12 +10,12 @@ class Edge; class Vertex { public: Vertex(); - Vertex(int val); + Vertex(int value); Vertex(const Vertex& src); ~Vertex(); - int getVal() { return val; } - void setVal(int newVal) { val = newVal; } + int getVal() { return value; } + void setVal(int newVal) { value = newVal; } bool isValid() { return use; } void setValid() { use = true; } void setInvalid() { use = false; } @@ -26,7 +26,7 @@ class Vertex { bool operator!= (const Vertex& src) const; bool operator< (const Vertex& src) const; // for sort - void addEdge(Vertex& to, int val=0); + void addEdge(Vertex& to, int value=0); int getInDegree() { return inEdges.size(); } int getOutDegree() { return outEdges.size(); } @@ -34,7 +34,7 @@ class Vertex { std::list outEdges; private: - int val; + int value; bool use; int id; static int nextVertexID; From 6fafa96737af72ee2922dc1facbd040cd2a88c49 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 11:49:35 +0800 Subject: [PATCH 22/41] add free func declare in Line.h --- src/include/geometry/Line.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/include/geometry/Line.h b/src/include/geometry/Line.h index 9dcef09..b1d0fbd 100644 --- a/src/include/geometry/Line.h +++ b/src/include/geometry/Line.h @@ -25,6 +25,12 @@ class Line { Vector<2> v; }; +Point<2> getIntersection(const Line& l1, const Line& l2); + +double disToLine(Point<2> P, Line l); + +double disToSegment(Point<2> P, Line l); + } #endif // CUHKSZ_GEOMETRY_LINE From 3b4f0cf825c21d543d8dcb631c6330cfd66339b0 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 11:55:29 +0800 Subject: [PATCH 23/41] correct some unexpected --- src/include/geometry/Circle.h | 2 ++ src/include/graph/Vertex.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/include/geometry/Circle.h b/src/include/geometry/Circle.h index 2f3add2..db33561 100644 --- a/src/include/geometry/Circle.h +++ b/src/include/geometry/Circle.h @@ -33,6 +33,8 @@ class Circle { double r; }; +#undef PI + } // namespace cuhksz #endif // CUHKSZ_GEOMETRY_CIRCLE diff --git a/src/include/graph/Vertex.h b/src/include/graph/Vertex.h index 220cf2b..31b6297 100644 --- a/src/include/graph/Vertex.h +++ b/src/include/graph/Vertex.h @@ -3,6 +3,8 @@ #include +#include "graph/Edge.h" + namespace cuhksz { class Edge; From 2a85aab8903503da36c3c305f05f9c2e5f9fc241 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 11:59:30 +0800 Subject: [PATCH 24/41] change BSTNode to class, add private field and getter --- src/include/graph/BST.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/include/graph/BST.h b/src/include/graph/BST.h index 579d71d..ed1b352 100644 --- a/src/include/graph/BST.h +++ b/src/include/graph/BST.h @@ -3,10 +3,18 @@ namespace cuhksz { -struct BSTNode { +class BSTNode { +public: BSTNode(int k, int v) : rank(k), val(v) { ch[0] = ch[1] = fa = nullptr; } + + int getVal() { return val; } + int getRank() { return rank; } + void setVal(int newVal) { val = newVal; } + + friend class BST; +private: BSTNode* ch[2]; BSTNode* fa; int rank; From a3440baa86c9fc973c69a71fed1644e0355dc725 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 12:02:23 +0800 Subject: [PATCH 25/41] add -wd4458 to MSVC to prevent 'val' rename --- CMakeLists.txt | 2 +- src/graph/Vertex.cpp | 14 +++++++------- src/include/graph/Vertex.h | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 18d3f94..df8477b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ option(SAMPLES "Compile samples" ON) option(COVERAGE "Enable coverage test for codecov" OFF) if(MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W4 -wd4244 -wd4267 -wd4800 -wd4068 -WX -MP") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W4 -wd4244 -wd4267 -wd4800 -wd4068 -wd4458 -WX -MP") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Zi -Od") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ox") add_definitions(-DUNICODE -D_UNICODE) diff --git a/src/graph/Vertex.cpp b/src/graph/Vertex.cpp index d18cbb8..5786bb1 100644 --- a/src/graph/Vertex.cpp +++ b/src/graph/Vertex.cpp @@ -6,14 +6,14 @@ namespace cuhksz { int Vertex::nextVertexID = 0; Vertex::Vertex() { - value = 0; + val = 0; use = true; id = Vertex::nextVertexID ++; inEdges.clear(); outEdges.clear(); } -Vertex::Vertex(int value) : value(value) { +Vertex::Vertex(int val) : val(val) { use = true; id = Vertex::nextVertexID ++; inEdges.clear(); @@ -21,7 +21,7 @@ Vertex::Vertex(int value) : value(value) { } Vertex::Vertex(const Vertex& src) { - value = src.value; + val = src.val; use = src.use; id = Vertex::nextVertexID ++; inEdges.clear(); @@ -44,7 +44,7 @@ Vertex::~Vertex() { } Vertex& Vertex::operator= (const Vertex& src) { - value = src.value; + val = src.val; use = src.use; inEdges.clear(); outEdges.clear(); @@ -64,11 +64,11 @@ bool Vertex::operator!= (const Vertex& src) const { } bool Vertex::operator< (const Vertex& src) const { - return value < src.value; + return val < src.val; } -void Vertex::addEdge(Vertex& to, int value) { - Edge* e = new Edge(this, &to, value); +void Vertex::addEdge(Vertex& to, int val) { + Edge* e = new Edge(this, &to, val); outEdges.push_back(e); to.inEdges.push_back(e); } diff --git a/src/include/graph/Vertex.h b/src/include/graph/Vertex.h index 31b6297..26cdf2e 100644 --- a/src/include/graph/Vertex.h +++ b/src/include/graph/Vertex.h @@ -12,12 +12,12 @@ class Edge; class Vertex { public: Vertex(); - Vertex(int value); + Vertex(int val); Vertex(const Vertex& src); ~Vertex(); - int getVal() { return value; } - void setVal(int newVal) { value = newVal; } + int getVal() { return val; } + void setVal(int newVal) { val = newVal; } bool isValid() { return use; } void setValid() { use = true; } void setInvalid() { use = false; } @@ -28,7 +28,7 @@ class Vertex { bool operator!= (const Vertex& src) const; bool operator< (const Vertex& src) const; // for sort - void addEdge(Vertex& to, int value=0); + void addEdge(Vertex& to, int val=0); int getInDegree() { return inEdges.size(); } int getOutDegree() { return outEdges.size(); } @@ -36,7 +36,7 @@ class Vertex { std::list outEdges; private: - int value; + int val; bool use; int id; static int nextVertexID; From e77bea6d201b7a43d71cae9409aec2681e166c0e Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 12:06:25 +0800 Subject: [PATCH 26/41] change Vector to GVector && remove & in arithmetic operator in Point.h --- src/geometry/Line.cpp | 8 ++++---- src/include/geometry/Circle.h | 2 +- src/include/geometry/Line.h | 4 ++-- src/include/geometry/Point.h | 10 +++++----- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/geometry/Line.cpp b/src/geometry/Line.cpp index ecd4c1b..2fbd34f 100644 --- a/src/geometry/Line.cpp +++ b/src/geometry/Line.cpp @@ -15,7 +15,7 @@ namespace cuhksz { #define EPS 1e-6 -Line::Line(Point<2> A, Vector<2> v) : A(A), v(v) { } +Line::Line(Point<2> A, GVector<2> v) : A(A), v(v) { } // Line::Line(Point<2> A, Point<2> B) : A(A) { // v = B - A; @@ -35,18 +35,18 @@ Line& Line::operator= (const Line& src) { } Point<2> getIntersection(const Line& l1, const Line& l2) { - Vector<2> u = l1.A - l2.A; + GVector<2> u = l1.A - l2.A; double t = cross(l2.v, u) / cross(l1.v, l2.v); return l1.A + l1.v * t; } double disToLine(Point<2> P, Line l) { - Vector<2> v1 = l.v, v2 = P - l.A; + GVector<2> v1 = l.v, v2 = P - l.A; return std::fabs(cross(v1, v2) / v1.len()); } double disToSegment(Point<2> P, Line l) { - Vector<2> v1 = l.v, v2 = P - l.A, v3 = P - l.A - l.v; + GVector<2> v1 = l.v, v2 = P - l.A, v3 = P - l.A - l.v; if (dcmp(v1 * v2) < 0) return v2.len(); else if (dcmp(v1 * v3) > 0) return v3.len(); else return std::fabs(cross(v1, v2) / v1.len()); diff --git a/src/include/geometry/Circle.h b/src/include/geometry/Circle.h index db33561..7238dcd 100644 --- a/src/include/geometry/Circle.h +++ b/src/include/geometry/Circle.h @@ -25,7 +25,7 @@ class Circle { } Point<2> getPoint(double rad) { - return O + Vector<2>(r * std::cos(rad), r * std::sin(rad)); + return O + GVector<2>(r * std::cos(rad), r * std::sin(rad)); } private: diff --git a/src/include/geometry/Line.h b/src/include/geometry/Line.h index b1d0fbd..1a4e968 100644 --- a/src/include/geometry/Line.h +++ b/src/include/geometry/Line.h @@ -7,7 +7,7 @@ namespace cuhksz { class Line { public: - Line(Point<2> A, Vector<2> v); + Line(Point<2> A, GVector<2> v); // Line(Point<2> A, Point<2> B); Line(const Line& src); ~Line(); @@ -22,7 +22,7 @@ class Line { private: Point<2> A; - Vector<2> v; + GVector<2> v; }; Point<2> getIntersection(const Line& l1, const Line& l2); diff --git a/src/include/geometry/Point.h b/src/include/geometry/Point.h index a91238a..9af7ef3 100644 --- a/src/include/geometry/Point.h +++ b/src/include/geometry/Point.h @@ -48,14 +48,14 @@ class Point { } // TODO: what about init a null Point then assign to elem[i] + other.elem[i] - Point& operator+(Point const &other) const { + Point operator+(Point const &other) const { Point& ret = *(new Point); for (int i = 0; i < N; i ++) ret.elem[i] = elem[i] + other.elem[i]; return ret; } - Point& operator-(Point const &other) const { + Point operator-(Point const &other) const { Point& ret = *(new Point); for (int i = 0; i < N; i ++) ret.elem[i] = elem[i] - other.elem[i]; @@ -82,7 +82,7 @@ class Point { return ret; } - Point& operator*(double const &constant) const { + Point operator*(double const &constant) const { Point& ret = *(new Point); for (int i = 0; i < N; i ++) ret.elem[i] = elem[i] * constant; @@ -99,7 +99,7 @@ class Point { return *this; } - Point& operator/(double const &constant) const { + Point operator/(double const &constant) const { Point& ret = *(new Point); for (int i = 0; i < N; i ++) ret.elem[i] = elem[i] / constant; @@ -181,7 +181,7 @@ class Point { double elem[N]; // coordinates }; -#define Vector Point +#define GVector Point #undef EPS From 1e87ba20c5eb3eb29c705d246020af2bf650d8d4 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 12:26:03 +0800 Subject: [PATCH 27/41] do not include Edge.h in Vertex.h causing circle, fit EPS field --- src/geometry/Line.cpp | 8 ++++---- src/include/graph/Vertex.h | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/geometry/Line.cpp b/src/geometry/Line.cpp index 2fbd34f..32da1a7 100644 --- a/src/geometry/Line.cpp +++ b/src/geometry/Line.cpp @@ -2,6 +2,8 @@ #include "geometry/Line.h" +#define EPS 1e-6 + namespace { int dcmp(double x) { @@ -13,8 +15,6 @@ int dcmp(double x) { namespace cuhksz { -#define EPS 1e-6 - Line::Line(Point<2> A, GVector<2> v) : A(A), v(v) { } // Line::Line(Point<2> A, Point<2> B) : A(A) { @@ -52,6 +52,6 @@ double disToSegment(Point<2> P, Line l) { else return std::fabs(cross(v1, v2) / v1.len()); } -#undef EPS - } + +#undef EPS diff --git a/src/include/graph/Vertex.h b/src/include/graph/Vertex.h index 26cdf2e..b505207 100644 --- a/src/include/graph/Vertex.h +++ b/src/include/graph/Vertex.h @@ -3,8 +3,6 @@ #include -#include "graph/Edge.h" - namespace cuhksz { class Edge; From 4cd9d0aebe375805c4dfe4903e0a0b035015e63f Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 12:32:36 +0800 Subject: [PATCH 28/41] add std:: in memset and memcpy --- src/include/geometry/Point.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/include/geometry/Point.h b/src/include/geometry/Point.h index 9af7ef3..1302748 100644 --- a/src/include/geometry/Point.h +++ b/src/include/geometry/Point.h @@ -2,6 +2,7 @@ #define CUHKSZ_GEOMETRY_POINT #include +#include #include #include @@ -13,7 +14,7 @@ template class Point { public: Point() { - memset(elem, 0, N * sizeof(double)); + std::memset(elem, 0, N * sizeof(double)); } explicit Point(double const x) { @@ -32,13 +33,13 @@ class Point { } Point(const Point& src) { - memcpy(elem, src.elem, N * sizeof(double)); + std::memcpy(elem, src.elem, N * sizeof(double)); } ~Point() { } Point& operator=(const Point& src) { - memcpy(elem, src.elem, N * sizeof(double)); + std::memcpy(elem, src.elem, N * sizeof(double)); return *this; } From 72d2aaf4e6d702b957c470572efbd33b57ea4805 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 12:38:02 +0800 Subject: [PATCH 29/41] add explict to some needed place --- src/include/geometry/Circle.h | 4 ++-- src/include/graph/Tree.h | 2 +- src/include/graph/Vertex.h | 2 +- src/include/math_utils/Matrix.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/include/geometry/Circle.h b/src/include/geometry/Circle.h index 7238dcd..fa5641b 100644 --- a/src/include/geometry/Circle.h +++ b/src/include/geometry/Circle.h @@ -11,8 +11,8 @@ namespace cuhksz { class Circle { public: Circle() : O(Point<2>(0, 0)), r(1.0) { } - Circle(double r) : O(Point<2>(0, 0)), r(r) { } - Circle(Point<2> O) : O(O), r(1.0) { } + explicit Circle(double r) : O(Point<2>(0, 0)), r(r) { } + explicit Circle(Point<2> O) : O(O), r(1.0) { } Circle(Point<2> O, double r) : O(O), r(r) { } ~Circle() { } diff --git a/src/include/graph/Tree.h b/src/include/graph/Tree.h index cc2ea9a..c500e58 100644 --- a/src/include/graph/Tree.h +++ b/src/include/graph/Tree.h @@ -7,7 +7,7 @@ namespace cuhksz { class Node { public: - Node(int id) : Node(id, 0) {} + explicit Node(int id) : Node(id, 0) {} Node(int id, int val); ~Node(); diff --git a/src/include/graph/Vertex.h b/src/include/graph/Vertex.h index b505207..bca230a 100644 --- a/src/include/graph/Vertex.h +++ b/src/include/graph/Vertex.h @@ -10,7 +10,7 @@ class Edge; class Vertex { public: Vertex(); - Vertex(int val); + explicit Vertex(int val); Vertex(const Vertex& src); ~Vertex(); diff --git a/src/include/math_utils/Matrix.h b/src/include/math_utils/Matrix.h index 01febaa..8b1f32c 100644 --- a/src/include/math_utils/Matrix.h +++ b/src/include/math_utils/Matrix.h @@ -14,7 +14,7 @@ namespace cuhksz { class Matrix { public: - Matrix(int n) : row(n), col(n) { + explicit Matrix(int n) : row(n), col(n) { elem = new double*[row]; for (int i = 0; i < row; i ++) { elem[i] = new double[col]; From 927ca4611b3c16e0a2bad6e8d564d3dc077945e2 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 14:07:40 +0800 Subject: [PATCH 30/41] add MatrixTest && change to 'using' replace '#define' GVector --- src/include/geometry/Point.h | 4 +- src/include/math_utils/Matrix.h | 74 ++++++++++------ tests/math_utils/MatrixTest.cpp | 148 ++++++++++++++++++++++++++++++++ 3 files changed, 200 insertions(+), 26 deletions(-) create mode 100644 tests/math_utils/MatrixTest.cpp diff --git a/src/include/geometry/Point.h b/src/include/geometry/Point.h index 1302748..974ef3b 100644 --- a/src/include/geometry/Point.h +++ b/src/include/geometry/Point.h @@ -182,7 +182,9 @@ class Point { double elem[N]; // coordinates }; -#define GVector Point +// #define GVector Point +template +using GVector = Point; #undef EPS diff --git a/src/include/math_utils/Matrix.h b/src/include/math_utils/Matrix.h index 8b1f32c..ce529b4 100644 --- a/src/include/math_utils/Matrix.h +++ b/src/include/math_utils/Matrix.h @@ -7,26 +7,31 @@ #include #include #include +#include namespace cuhksz { -#define EPS 1e-6 - +template class Matrix { public: - explicit Matrix(int n) : row(n), col(n) { - elem = new double*[row]; + explicit Matrix(int n) : Matrix(n, n) { } + + Matrix(int n, int m) : row(n), col(m) { + elem = new ValueType*[row]; for (int i = 0; i < row; i ++) { - elem[i] = new double[col]; - memset(elem[i], 0, col * sizeof(double)); + elem[i] = new ValueType[col]; + std::memset(elem[i], 0, col * sizeof(ValueType)); } } - Matrix(int n, int m) : row(n), col(m) { - elem = new double*[row]; + Matrix(std::vector > ini) { + row = ini.size(); + col = ini[0].size(); + elem = new ValueType*[row]; for (int i = 0; i < row; i ++) { - elem[i] = new double[col]; - memset(elem[i], 0, col * sizeof(double)); + elem[i] = new ValueType[col]; + for (int j = 0; j < col; j ++) + elem[i][j] = ini[i][j]; } } @@ -41,12 +46,13 @@ class Matrix { // allocation Matrix& operator= (const Matrix& src) { if (this == &src) return *this; - clear(), deepCopy(src); + clear(); + deepCopy(src); return *this; } // index - double* operator[] (int i) const { + ValueType* operator[] (int i) const { return elem[i]; } @@ -55,7 +61,21 @@ class Matrix { return os; } - Matrix& operator* (const Matrix& other) const { + bool operator== (const Matrix& other) const { + if (row != other.row || col != other.col) + return false; + for (int i = 0; i < row; i ++) + for (int j = 0; j < col; j ++) + if ((*this)[i][j] != other[i][j]) + return false; + return true; + } + + bool operator!= (const Matrix& other) const { + return !this->operator==(other); + } + + Matrix operator* (const Matrix& other) const { assert(col == other.row); Matrix* ret = new Matrix(row, other.col); for (int i = 0; i < ret->row; i ++) @@ -77,13 +97,13 @@ class Matrix { return *this; } - Matrix& operator+ (const Matrix& other) const { + Matrix operator+ (const Matrix& other) const { assert(row == other.row && col == other.col); - Matrix* ret = new Matrix(row, col); + Matrix ret(row, col); for (int i = 0; i < row; i ++) for (int j = 0; j < col; j ++) - (*ret)[i][j] = (*this)[i][j] + other[i][j]; - return *ret; + ret[i][j] = (*this)[i][j] + other[i][j]; + return ret; } Matrix& operator+= (const Matrix& other) { @@ -94,13 +114,13 @@ class Matrix { return *this; } - Matrix& operator- (const Matrix& other) const { + Matrix operator- (const Matrix& other) const { assert(row == other.row && col == other.col); - Matrix* ret = new Matrix(row, col); + Matrix ret(row, col); for (int i = 0; i < row; i ++) for (int j = 0; j < col; j ++) - (*ret)[i][j] = (*this)[i][j] - other[i][j]; - return *ret; + ret[i][j] = (*this)[i][j] - other[i][j]; + return ret; } Matrix& operator-= (const Matrix& other) { @@ -119,8 +139,12 @@ class Matrix { void deepCopy(const Matrix& src) { row = src.row, col = src.col; - for (int i = 0; i < row; i ++) - memcpy((*this)[i], src[i], col * sizeof(double)); + elem = new ValueType*[row]; + for (int i = 0; i < row; i ++) { + elem[i] = new ValueType[col]; + for (int j = 0; j < col; j ++) + elem[i][j] = src[i][j]; + } } friend Matrix& idMat(int n) { @@ -148,7 +172,7 @@ class Matrix { while (r < col) { nonZeroRow = -1; for (int j = i; j < row; j ++) - if (std::fabs(A[j][r]) >= EPS) { + if (A[j][r] != 0) { nonZeroRow = j; break; } @@ -186,7 +210,7 @@ class Matrix { } private: - double** elem; + ValueType** elem; int row; int col; }; diff --git a/tests/math_utils/MatrixTest.cpp b/tests/math_utils/MatrixTest.cpp new file mode 100644 index 0000000..a65ac50 --- /dev/null +++ b/tests/math_utils/MatrixTest.cpp @@ -0,0 +1,148 @@ +#include "math_utils/Matrix.h" + +#include "gtest/gtest.h" + +TEST(Matrix, initialize) { + std::vector > a; + a.clear(); + + std::vector tmp; + tmp.clear(); + tmp.push_back(1), tmp.push_back(2), tmp.push_back(1); + a.push_back(tmp); + tmp.clear(); + tmp.push_back(2), tmp.push_back(-1), tmp.push_back(3); + a.push_back(tmp); + tmp.clear(); + tmp.push_back(-1), tmp.push_back(0), tmp.push_back(1); + a.push_back(tmp); + + cuhksz::Matrix A(a), B(3, 3); + + EXPECT_EQ(A[0][0], 1); + EXPECT_EQ(A[0][2], 1); + EXPECT_EQ(A[2][1], 0); + + B = A; + EXPECT_TRUE(A == B); +} + +TEST(Matrix, addition) { + std::vector > a, b, c; + a.clear(), b.clear(), c.clear(); + + std::vector tmp; + tmp.clear(); + tmp.push_back(1), tmp.push_back(2), tmp.push_back(1); + a.push_back(tmp); + tmp.clear(); + tmp.push_back(2), tmp.push_back(-1), tmp.push_back(3); + a.push_back(tmp); + tmp.clear(); + tmp.push_back(-1), tmp.push_back(0), tmp.push_back(1); + a.push_back(tmp); + + tmp.clear(); + tmp.push_back(-2), tmp.push_back(3), tmp.push_back(4); + b.push_back(tmp); + tmp.clear(); + tmp.push_back(9), tmp.push_back(-5), tmp.push_back(5); + b.push_back(tmp); + tmp.clear(); + tmp.push_back(10), tmp.push_back(33), tmp.push_back(34); + b.push_back(tmp); + + tmp.clear(); + tmp.push_back(-1), tmp.push_back(5), tmp.push_back(5); + c.push_back(tmp); + tmp.clear(); + tmp.push_back(11), tmp.push_back(-6), tmp.push_back(8); + c.push_back(tmp); + tmp.clear(); + tmp.push_back(9), tmp.push_back(33), tmp.push_back(35); + c.push_back(tmp); + + cuhksz::Matrix A(a), B(b), C(c), D(3, 3); + D = A + B; + EXPECT_TRUE(C == D); +} + +TEST(Matrix, subtraction) { + std::vector > a, b, c; + a.clear(), b.clear(), c.clear(); + + std::vector tmp; + tmp.clear(); + tmp.push_back(1), tmp.push_back(2), tmp.push_back(1); + a.push_back(tmp); + tmp.clear(); + tmp.push_back(2), tmp.push_back(-1), tmp.push_back(3); + a.push_back(tmp); + tmp.clear(); + tmp.push_back(-1), tmp.push_back(0), tmp.push_back(1); + a.push_back(tmp); + + tmp.clear(); + tmp.push_back(-2), tmp.push_back(3), tmp.push_back(4); + b.push_back(tmp); + tmp.clear(); + tmp.push_back(9), tmp.push_back(-5), tmp.push_back(5); + b.push_back(tmp); + tmp.clear(); + tmp.push_back(10), tmp.push_back(33), tmp.push_back(34); + b.push_back(tmp); + + tmp.clear(); + tmp.push_back(3), tmp.push_back(-1), tmp.push_back(-3); + c.push_back(tmp); + tmp.clear(); + tmp.push_back(-7), tmp.push_back(4), tmp.push_back(-2); + c.push_back(tmp); + tmp.clear(); + tmp.push_back(-11), tmp.push_back(-33), tmp.push_back(-33); + c.push_back(tmp); + + cuhksz::Matrix A(a), B(b), C(c), D(3, 3); + D = A - B; + EXPECT_TRUE(C == D); +} + +TEST(Matrix, multiple) { + std::vector > a, b, c; + a.clear(), b.clear(), c.clear(); + + std::vector tmp; + tmp.clear(); + tmp.push_back(1), tmp.push_back(2), tmp.push_back(1); + a.push_back(tmp); + tmp.clear(); + tmp.push_back(2), tmp.push_back(-1), tmp.push_back(3); + a.push_back(tmp); + tmp.clear(); + tmp.push_back(-1), tmp.push_back(0), tmp.push_back(1); + a.push_back(tmp); + + tmp.clear(); + tmp.push_back(-2), tmp.push_back(3), tmp.push_back(4); + b.push_back(tmp); + tmp.clear(); + tmp.push_back(9), tmp.push_back(-5), tmp.push_back(5); + b.push_back(tmp); + tmp.clear(); + tmp.push_back(10), tmp.push_back(33), tmp.push_back(34); + b.push_back(tmp); + + tmp.clear(); + tmp.push_back(26), tmp.push_back(26), tmp.push_back(48); + c.push_back(tmp); + tmp.clear(); + tmp.push_back(17), tmp.push_back(110), tmp.push_back(105); + c.push_back(tmp); + tmp.clear(); + tmp.push_back(12), tmp.push_back(30), tmp.push_back(30); + c.push_back(tmp); + + cuhksz::Matrix A(a), B(b), C(c), D(3, 3); + D = A * B; + EXPECT_TRUE(C == D); +} From d1436829b74a3d3c1d425d67bb7e6797054a8853 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 15:01:12 +0800 Subject: [PATCH 31/41] add FractionTest.cpp --- src/include/math_utils/Fraction.h | 227 +++++++++++++++--------------- tests/math_utils/FractionTest.cpp | 65 +++++++++ tests/math_utils/MatrixTest.cpp | 5 +- 3 files changed, 184 insertions(+), 113 deletions(-) create mode 100644 tests/math_utils/FractionTest.cpp diff --git a/src/include/math_utils/Fraction.h b/src/include/math_utils/Fraction.h index ee8e31a..e8e880b 100644 --- a/src/include/math_utils/Fraction.h +++ b/src/include/math_utils/Fraction.h @@ -10,123 +10,126 @@ namespace cuhksz { class Fraction { - public: - Fraction() : numerator(0), denominator(1) {} - - Fraction(int const integer) - : numerator(integer), denominator(1) {} // allow implicit conversion - - Fraction(int const numerator, int const denominator) - : numerator(numerator), denominator(denominator) { - if (denominator == 0) { - error("Divide by Zero error"); - } - int divisor = gcd(numerator, denominator); - Fraction::numerator /= divisor, Fraction::denominator /= divisor; - if (Fraction::denominator < 0) { - Fraction::numerator *= -1; - } - Fraction::denominator = abs(Fraction::denominator); - } - - Fraction operator+(Fraction const &other) const { - return Fraction( - numerator * other.denominator + denominator * other.numerator, - denominator * other.denominator); - } - - friend Fraction operator+(int value, Fraction const &self) { - return self + value; - } - - void operator+=(Fraction const &other) { - this->numerator = - numerator * other.denominator + denominator * other.numerator; - this->denominator = denominator * other.denominator; - rmGCD(); - } - - Fraction operator-(Fraction const &other) const { - return Fraction( - numerator * other.denominator - denominator * other.numerator, - denominator * other.denominator); - } - - friend Fraction operator-(int value, Fraction const &self) { - return self - value; - } - - void operator-=(Fraction const &other) { - this->numerator = - numerator * other.denominator - denominator * other.numerator; - this->denominator = denominator * other.denominator; - rmGCD(); - } - - Fraction operator*(Fraction const &other) const { - return Fraction(numerator * other.numerator, +public: + Fraction() : Fraction(0) { } + + Fraction(int const integer) : Fraction(integer, 1) { } // allow implicit conversion + + Fraction(int const numerator, int const denominator) + : numerator(numerator), denominator(denominator) + { + if (denominator == 0) { + error("Divide by Zero error"); + } + int divisor = gcd(numerator, denominator); + Fraction::numerator /= divisor, Fraction::denominator /= divisor; + if (Fraction::denominator < 0) { + Fraction::numerator *= -1; + } + Fraction::denominator = abs(Fraction::denominator); + } + + int getNumerator() { return numerator; } + int getDenominator() { return denominator; } + + Fraction operator+(Fraction const &other) const { + return Fraction( + numerator * other.denominator + denominator * other.numerator, + denominator * other.denominator); + } + + friend Fraction operator+(int value, Fraction const &self) { + return self + value; + } + + void operator+=(Fraction const &other) { + Fraction tmp( + numerator * other.denominator + denominator * other.numerator, + denominator * other.denominator); + numerator = tmp.numerator; + denominator = tmp.denominator; + } + + Fraction operator-(Fraction const &other) const { + return Fraction( + numerator * other.denominator - denominator * other.numerator, + denominator * other.denominator); + } + + friend Fraction operator-(int value, Fraction const &self) { + return self - value; + } + + void operator-=(Fraction const &other) { + Fraction tmp( + numerator * other.denominator - denominator * other.numerator, + denominator * other.denominator); + numerator = tmp.numerator; + denominator = tmp.denominator; + } + + Fraction operator*(Fraction const &other) const { + return Fraction(numerator * other.numerator, denominator * other.denominator); - } + } - friend Fraction operator*(int value, Fraction const &self) { - return self * value; - } + friend Fraction operator*(int value, Fraction const &self) { + return self * value; + } - void operator*=(Fraction const &other) { - this->numerator *= other.numerator; - this->denominator *= other.denominator; - rmGCD(); - } + void operator*=(Fraction const &other) { + Fraction tmp(numerator * other.numerator, + denominator * other.denominator); + numerator = tmp.numerator; + denominator = tmp.denominator; + } - Fraction operator/(Fraction const &other) const { - return Fraction(numerator * other.denominator, + Fraction operator/(Fraction const &other) const { + return Fraction(numerator * other.denominator, denominator * other.numerator); - } - - friend Fraction operator/(int value, Fraction const &self) { - return self / value; - } - - void operator/=(Fraction const &other) { - this->numerator *= other.denominator; - this->denominator *= other.numerator; - rmGCD(); - } - - bool operator==(Fraction const &other) const { - return numerator == other.numerator && denominator == other.denominator; - } - - bool operator!=(Fraction const &other) const { - return numerator != other.numerator || denominator != other.denominator; - } - - bool operator<(Fraction const &other) const { - return numerator * other.denominator < denominator * other.numerator; - } - - bool operator<=(Fraction const &other) const { - return numerator * other.denominator <= denominator * other.numerator; - } - - bool operator>(Fraction const &other) const { - return numerator * other.denominator > denominator * other.numerator; - } - - bool operator>=(Fraction const &other) const { - return numerator * other.denominator >= denominator * other.numerator; - } - - friend std::ostream &operator<<(std::ostream &os, Fraction const &self) { - return os << self.numerator << "/" << self.denominator; - } - - private: - int numerator, denominator; - void rmGCD() { - int divisor = gcd(numerator, denominator); - numerator /= divisor, denominator /= divisor; - } + } + + friend Fraction operator/(int value, Fraction const &self) { + return self / value; + } + + void operator/=(Fraction const &other) { + Fraction tmp(numerator / other.numerator, + denominator / other.denominator); + numerator = tmp.numerator; + denominator = tmp.denominator; + } + + bool operator==(Fraction const &other) const { + return numerator == other.numerator && denominator == other.denominator; + } + + bool operator!=(Fraction const &other) const { + return numerator != other.numerator || denominator != other.denominator; + } + + bool operator<(Fraction const &other) const { + return numerator * other.denominator < denominator * other.numerator; + } + + bool operator<=(Fraction const &other) const { + return numerator * other.denominator <= denominator * other.numerator; + } + + bool operator>(Fraction const &other) const { + return numerator * other.denominator > denominator * other.numerator; + } + + bool operator>=(Fraction const &other) const { + return numerator * other.denominator >= denominator * other.numerator; + } + + friend std::ostream &operator<<(std::ostream &os, Fraction const &self) { + return os << self.numerator << "/" << self.denominator; + } + +private: + int numerator, denominator; }; } // namespace cuhksz diff --git a/tests/math_utils/FractionTest.cpp b/tests/math_utils/FractionTest.cpp new file mode 100644 index 0000000..9cd2674 --- /dev/null +++ b/tests/math_utils/FractionTest.cpp @@ -0,0 +1,65 @@ +#include "math_utils/Fraction.h" + +#include "gtest/gtest.h" + +TEST(Fraction, initialize) { + cuhksz::Fraction a, b(3), c(2, 3); + EXPECT_TRUE(a.getNumerator() == 0 && a.getDenominator() == 1); + EXPECT_TRUE(b.getNumerator() == 3 && b.getDenominator() == 1); + EXPECT_TRUE(c.getNumerator() == 2 && c.getDenominator() == 3); +} + +TEST(Fraction, addition) { + cuhksz::Fraction a(2, 3), b(1, 2), c; + c = a + b; + EXPECT_TRUE(c.getNumerator() == 7 && c.getDenominator() == 6); + + a = cuhksz::Fraction(1, 4); + b = cuhksz::Fraction(1, 4); + a += b; + EXPECT_TRUE(a.getNumerator() == 1 && a.getDenominator() == 2); +} + +TEST(Fraction, subtraction) { + cuhksz::Fraction a(2, 3), b(1, 2), c; + c = a - b; + EXPECT_TRUE(c.getNumerator() == 1 && c.getDenominator() == 6); + + a = cuhksz::Fraction(1, 4); + b = cuhksz::Fraction(1, 2); + a -= b; + EXPECT_TRUE(a.getNumerator() == -1 && a.getDenominator() == 4); +} + +TEST(Fraction, multiplication) { + cuhksz::Fraction a(2, 3), b(1, 2), c; + c = a * b; + EXPECT_TRUE(c.getNumerator() == 1 && c.getDenominator() == 3); + + a = cuhksz::Fraction(1, -4); + b = cuhksz::Fraction(1, 4); + a *= b; + EXPECT_TRUE(a.getNumerator() == -1 && a.getDenominator() == 16); +} + +TEST(Fraction, division) { + cuhksz::Fraction a(2, 3), b(1, 2), c; + c = a / b; + EXPECT_TRUE(c.getNumerator() == 4 && c.getDenominator() == 3); + + a = cuhksz::Fraction(1, -4); + b = cuhksz::Fraction(1, 4); + a /= b; + EXPECT_TRUE(a.getNumerator() == -1 && a.getDenominator() == 1); +} + +TEST(Fraction, compare) { + cuhksz::Fraction a(2, 3), b(1, 2), c(-1, 3), d(5, 4), e(5, 4); + EXPECT_TRUE(a > b); + EXPECT_TRUE(b >= c); + EXPECT_TRUE(d > a); + EXPECT_TRUE(c <= a); + EXPECT_TRUE(b < d); + EXPECT_TRUE(a != e); + EXPECT_TRUE(d == e); +} diff --git a/tests/math_utils/MatrixTest.cpp b/tests/math_utils/MatrixTest.cpp index a65ac50..ab2165c 100644 --- a/tests/math_utils/MatrixTest.cpp +++ b/tests/math_utils/MatrixTest.cpp @@ -25,6 +25,9 @@ TEST(Matrix, initialize) { B = A; EXPECT_TRUE(A == B); + + cuhksz::Matrix C(A); + EXPECT_TRUE(C == A); } TEST(Matrix, addition) { @@ -107,7 +110,7 @@ TEST(Matrix, subtraction) { EXPECT_TRUE(C == D); } -TEST(Matrix, multiple) { +TEST(Matrix, multiplication) { std::vector > a, b, c; a.clear(), b.clear(), c.clear(); From e42a6cb7bc8f5b9b4c2a7b8e92319c4843706ec2 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 16:06:44 +0800 Subject: [PATCH 32/41] add BigNumTest.cpp with math_utils test done --- src/include/math_utils/BigNum.h | 61 ++++++++++++++++++--------------- tests/math_utils/BigNumTest.cpp | 49 ++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 28 deletions(-) create mode 100644 tests/math_utils/BigNumTest.cpp diff --git a/src/include/math_utils/BigNum.h b/src/include/math_utils/BigNum.h index 86505c2..b2d61f6 100644 --- a/src/include/math_utils/BigNum.h +++ b/src/include/math_utils/BigNum.h @@ -5,6 +5,7 @@ #include #include #include +#include namespace cuhksz { @@ -12,7 +13,7 @@ template class BigNum { public: BigNum() { - memset(elem, 0, MAX_SIZE * sizeof(int)); + std::memset(elem, 0, MAX_SIZE * sizeof(int)); sign = 1; len = 0; } @@ -20,7 +21,7 @@ class BigNum { BigNum(const long long x) { len = 0; sign = x < 0 ? -1 : 1; - memset(elem, 0, MAX_SIZE * sizeof(int)); + std::memset(elem, 0, MAX_SIZE * sizeof(int)); for (long long i = std::abs(x); i; i /= BigNum::base) elem[len ++] = i % BigNum::base; } @@ -28,31 +29,35 @@ class BigNum { BigNum(const std::string & s) { sign = s[0] == '-' ? -1 : 1; len = 0; - memset(elem, 0, MAX_SIZE * sizeof(int)); + std::memset(elem, 0, MAX_SIZE * sizeof(int)); for (int i = s.size() - 1; i >= BigNum::order - 1 + (s[0] == '-'); i -= BigNum::order) - elem[len ++] = s.substr(i - BigNum::order + 1, BigNum::order); + elem[len ++] = std::stoi(s.substr(i - BigNum::order + 1, BigNum::order)); if ((s.size() - (s[0] == '-')) % BigNum::order) - elem[len ++] = s.substr((s[0] == '-'), (s.size() - (s[0] == '-')) % BigNum::order); + elem[len ++] = std::stoi(s.substr((s[0] == '-'), (s.size() - (s[0] == '-')) % BigNum::order)); } BigNum(const BigNum &src) { sign = src.sign; len = src.len; - memcpy(elem, src.elem, len * sizeof(int)); + std::memcpy(elem, src.elem, len * sizeof(int)); } ~BigNum() { } // allocation - BigNum& operator= (const BigNum& src) const { + BigNum& operator= (const BigNum& src) { sign = src.sign; len = src.len; - memcpy(elem, src.elem, len * sizeof(int)); + std::memcpy(elem, src.elem, len * sizeof(int)); return *this; } // index - int& operator[] (const int index) const { + int& operator[] (const int index) { + return elem[index]; + } + + int operator[] (const int index) const { return elem[index]; } @@ -88,7 +93,7 @@ class BigNum { } // addition - BigNum& operator+ (const BigNum& other) const { + BigNum operator+ (const BigNum& other) const { BigNum ret; if (sign == other.sign) { ret = add(*this, other); @@ -101,7 +106,7 @@ class BigNum { return ret; } - BigNum& operator+ (const long long smallNum) const { + BigNum operator+ (const long long smallNum) const { BigNum ret, other = BigNum(smallNum); if (sign == other.sign) { ret = add(*this, other); @@ -140,7 +145,7 @@ class BigNum { } // subtraction - BigNum& operator- (const BigNum& other) const { + BigNum operator- (const BigNum& other) const { BigNum ret; if (sign == other.sign) { if (sign < 0) @@ -154,7 +159,7 @@ class BigNum { return ret; } - BigNum& operator- (const long long smallNum) const { + BigNum operator- (const long long smallNum) const { BigNum ret, other = BigNum(smallNum); if (sign == other.sign) { if (sign < 0) @@ -196,12 +201,12 @@ class BigNum { } // multiplication - BigNum& operator* (const BigNum& other) const { + BigNum operator* (const BigNum& other) const { BigNum ret = mul(*this, other); return ret; } - BigNum& operator* (const long long smallNum) const { + BigNum operator* (const long long smallNum) const { BigNum ret, other = BigNum(smallNum); ret = mul(*this, other); return ret; @@ -219,7 +224,7 @@ class BigNum { } // other - BigNum& operator- () const { + BigNum operator- () const { BigNum ret = *this; ret.sign = -ret.sign; return ret; @@ -257,7 +262,7 @@ class BigNum { return 0; } - friend BigNum& add(const BigNum& a, const BigNum& b) { + friend BigNum add(const BigNum& a, const BigNum& b) { BigNum ret; ret.len = std::max(a.len, b.len); for (int i = 0; i < ret.len; i ++) @@ -272,17 +277,17 @@ class BigNum { return ret; } - friend BigNum& sub(const BigNum& a, const BigNum& b) { - BigNum ret, *l, *s; - + friend BigNum sub(const BigNum& a, const BigNum& b) { + BigNum ret; if (cmp(a, b, true) < 0) { - l = &b, s = &a; + ret = sub(b, a); ret.sign = -1; - } else l = &a, s = &b; + return ret; + } - ret.len = l->len; + ret.len = a.len; for (int i = 0; i < ret.len; i ++) - ret[i] = (*l)[i] - (*s)[i]; + ret[i] = a[i] - b[i]; for (int i = 0; i < ret.len; i ++) if (ret[i] < 0) { ret[i] += BigNum::base; @@ -292,7 +297,7 @@ class BigNum { return ret; } - friend BigNum& mul(const BigNum& a, const BigNum& b) { + friend BigNum mul(const BigNum& a, const BigNum& b) { BigNum ret; if (a.len == 0 || b.len == 0) return ret; @@ -323,8 +328,8 @@ class BigNum { std::string toString() const { std::string s; if (sign < 0) s += "-"; - for (int i = len - 1, j = 0; i >= 0; i --, j ++) - s[j] += std::to_string(elem[i]); + for (int i = len - 1; i >= 0; i --) + s += std::to_string(elem[i]); return s; } @@ -346,7 +351,7 @@ template int BigNum::base = 10; template -int BigNum::order = 1; +int BigNum::order = 1; // 10 ^ 1 } // namespace cuhksz diff --git a/tests/math_utils/BigNumTest.cpp b/tests/math_utils/BigNumTest.cpp new file mode 100644 index 0000000..9b26f11 --- /dev/null +++ b/tests/math_utils/BigNumTest.cpp @@ -0,0 +1,49 @@ +#include "math_utils/BigNum.h" + +#include "gtest/gtest.h" + +TEST(BigNum, initialize) { + cuhksz::BigNum<5> a, b(12345), c("-12345"); + EXPECT_EQ(b[1], 4); + EXPECT_EQ(c[3], 2); +} + +TEST(BigNum, addition) { + cuhksz::BigNum<10> a(21312), b(9123421), c; + c = a + b; + EXPECT_EQ(c, 21312 + 9123421); + + a = -1231321; + b = 131231235; + c = a + b; + EXPECT_EQ(c, -1231321 + 131231235); +} + +TEST(BigNum, subtraction) { + cuhksz::BigNum<10> a(21312), b(9123421), c; + c = a - b; + EXPECT_EQ(c, 21312 - 9123421); + + a = -1231321; + b = 131231235; + c = a - b; + EXPECT_EQ(c, -1231321 - 131231235); +} + +TEST(BigNum, multiplication) { + cuhksz::BigNum<20> a(21312), b(9123421), c; + c = a * b; + EXPECT_EQ(c, 21312LL * 9123421); + + a = -1231321; + b = 131231235; + c = a * b; + EXPECT_EQ(c, -1231321LL * 131231235); +} + +TEST(BigNum, compare) { + cuhksz::BigNum<10> a(12312), b(5187381), c(-94214143); + EXPECT_TRUE(a < b); + EXPECT_TRUE(a > c); + EXPECT_TRUE(c < 0); +} From 24d37527d4cca3a228b9515aaf051b1f31ddcdb6 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 17:16:32 +0800 Subject: [PATCH 33/41] add PointTest.cpp --- src/include/geometry/Point.h | 13 +++++++- tests/CMakeLists.txt | 4 ++- tests/geometry/PointTest.cpp | 60 ++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 tests/geometry/PointTest.cpp diff --git a/src/include/geometry/Point.h b/src/include/geometry/Point.h index 974ef3b..e522df8 100644 --- a/src/include/geometry/Point.h +++ b/src/include/geometry/Point.h @@ -44,10 +44,14 @@ class Point { } // elem can be change directly - double& operator[](int const &index) const { + double& operator[](int const index) { return elem[index]; } + double operator[](int const index) const { + return elem[index]; + } + // TODO: what about init a null Point then assign to elem[i] + other.elem[i] Point operator+(Point const &other) const { Point& ret = *(new Point); @@ -159,6 +163,13 @@ class Point { return os << ")"; } + friend double dot(const Point& v, const Point& w) { + double ret = 0.0; + for (int i = 0; i < N; i ++) + ret += v[i] * w[i]; + return ret; + } + // TODO: cross product friend double cross(const Point& v, const Point& w) { static_assert(N == 2, "cross product only apply to 2D"); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cc0478d..130f7a7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -9,8 +9,10 @@ aux_source_directory(./containers CONTAINERS_TESTS) aux_source_directory(./base64 BASE64_TESTS) aux_source_directory(./string_utils STRING_UTILS_TESTS) aux_source_directory(./algorithm ALGORITHM_TESTS) +aux_source_directory(./graph GRAPH_TESTS) +aux_source_directory(./geometry GEOMETRY_TESTS) -add_executable(test_all ${TESTS} ${RANDOM_TESTS} ${MATHUTILS_TESTS} ${NETWORK_TESTS} ${JSON_TESTS} ${BASE64_TESTS} ${ALGORITHM_TESTS} ${STRING_UTILS_TESTS} ${CONTAINERS_TESTS}) +add_executable(test_all ${TESTS} ${RANDOM_TESTS} ${MATHUTILS_TESTS} ${NETWORK_TESTS} ${JSON_TESTS} ${BASE64_TESTS} ${ALGORITHM_TESTS} ${STRING_UTILS_TESTS} ${CONTAINERS_TESTS} ${GRAPH_TESTS} ${GEOMETRY_TESTS}) target_link_libraries(test_all gtest gtest_main cuhkszlib) diff --git a/tests/geometry/PointTest.cpp b/tests/geometry/PointTest.cpp new file mode 100644 index 0000000..b33e180 --- /dev/null +++ b/tests/geometry/PointTest.cpp @@ -0,0 +1,60 @@ +#include "geometry/Point.h" + +#include "gtest/gtest.h" + +TEST(Point, initialize) { + cuhksz::Point<1> a1, b1(5); + EXPECT_DOUBLE_EQ(b1[0], 5); + + cuhksz::Point<2> a2, b2(2, 3); + EXPECT_DOUBLE_EQ(b2[0], 2); + EXPECT_DOUBLE_EQ(b2[1], 3); + + cuhksz::Point<3> a3, b3(1, 2, 3); + EXPECT_DOUBLE_EQ(b3[0], 1); + EXPECT_DOUBLE_EQ(b3[1], 2); + EXPECT_DOUBLE_EQ(b3[2], 3); +} + +TEST(GVector, addition) { + cuhksz::GVector<2> a(2, 3), b(1, 5), c; + c = a + b; + EXPECT_DOUBLE_EQ(c[0], 3); + EXPECT_DOUBLE_EQ(c[1], 8); +} + +TEST(GVector, subtraction) { + cuhksz::GVector<2> a(2, 3), b(1, 5), c; + c = a - b; + EXPECT_DOUBLE_EQ(c[0], 1); + EXPECT_DOUBLE_EQ(c[1], -2); +} + +TEST(GVector, mulNumber) { + cuhksz::GVector<2> a(2, 3), b; + b = a * 2; + EXPECT_DOUBLE_EQ(b[0], 4); + EXPECT_DOUBLE_EQ(b[1], 6); + a = 2 * b; + EXPECT_DOUBLE_EQ(a[0], 8); + EXPECT_DOUBLE_EQ(a[1], 12); +} + +TEST(GVector, dotProduct) { + cuhksz::GVector<2> a(2, 3), b(3, 5); + EXPECT_DOUBLE_EQ(dot(a, b), 21); + + a = cuhksz::GVector<2>(-2, 3); + b = cuhksz::GVector<2>(1, -5); + EXPECT_DOUBLE_EQ(a * b, -17); +} + +TEST(GVector, crossProduct) { + cuhksz::Point<2> a(2, 3), b(3, 5); + EXPECT_DOUBLE_EQ(cross(a, b), 1); +} + +TEST(GVector, len) { + cuhksz::GVector<2> a(3, 4); + EXPECT_DOUBLE_EQ(a.len(), 5); +} From 5d8235b8981d79734a3ade1875f9190fe98df4c5 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 17:35:17 +0800 Subject: [PATCH 34/41] add LineTest.cpp --- src/geometry/Line.cpp | 4 ---- src/include/geometry/Line.h | 7 ------- src/include/geometry/Point.h | 2 +- tests/geometry/LineTest.cpp | 26 ++++++++++++++++++++++++++ 4 files changed, 27 insertions(+), 12 deletions(-) create mode 100644 tests/geometry/LineTest.cpp diff --git a/src/geometry/Line.cpp b/src/geometry/Line.cpp index 32da1a7..99b2a55 100644 --- a/src/geometry/Line.cpp +++ b/src/geometry/Line.cpp @@ -17,10 +17,6 @@ namespace cuhksz { Line::Line(Point<2> A, GVector<2> v) : A(A), v(v) { } -// Line::Line(Point<2> A, Point<2> B) : A(A) { -// v = B - A; -// } - Line::Line(const Line& src) { A = src.A; v = src.v; diff --git a/src/include/geometry/Line.h b/src/include/geometry/Line.h index 1a4e968..03710c4 100644 --- a/src/include/geometry/Line.h +++ b/src/include/geometry/Line.h @@ -8,7 +8,6 @@ namespace cuhksz { class Line { public: Line(Point<2> A, GVector<2> v); - // Line(Point<2> A, Point<2> B); Line(const Line& src); ~Line(); @@ -25,12 +24,6 @@ class Line { GVector<2> v; }; -Point<2> getIntersection(const Line& l1, const Line& l2); - -double disToLine(Point<2> P, Line l); - -double disToSegment(Point<2> P, Line l); - } #endif // CUHKSZ_GEOMETRY_LINE diff --git a/src/include/geometry/Point.h b/src/include/geometry/Point.h index e522df8..3788dea 100644 --- a/src/include/geometry/Point.h +++ b/src/include/geometry/Point.h @@ -119,7 +119,7 @@ class Point { bool operator==(Point const &other) const { for (int i = 0; i < N; i ++) - if (fabs(elem[i] - other.elem[i]) < EPS) + if (std::fabs(elem[i] - other.elem[i]) > EPS) return false; return true; } diff --git a/tests/geometry/LineTest.cpp b/tests/geometry/LineTest.cpp new file mode 100644 index 0000000..5b4e2c9 --- /dev/null +++ b/tests/geometry/LineTest.cpp @@ -0,0 +1,26 @@ +#include "geometry/Line.h" + +#include "gtest/gtest.h" + +TEST(Line, initialize) { + cuhksz::Line a(cuhksz::Point<2>(0, 0), cuhksz::GVector<2>(2, 3)); + cuhksz::Line b(a); +} + +TEST(Line, getIntersection) { + cuhksz::Line a(cuhksz::Point<2>(0, 0), cuhksz::GVector<2>(1, 1)); + cuhksz::Line b(cuhksz::Point<2>(2, 0), cuhksz::GVector<2>(-1, 1)); + EXPECT_EQ(getIntersection(a, b), cuhksz::Point<2>(1, 1)); +} + +TEST(Line, disToLine) { + cuhksz::Line a(cuhksz::Point<2>(0, 0), cuhksz::GVector<2>(1, 1)); + cuhksz::Point<2> b(2, 0); + EXPECT_DOUBLE_EQ(disToLine(b, a), std::sqrt(2)); +} + +TEST(Line, disToSegment) { + cuhksz::Line a(cuhksz::Point<2>(0, 0), cuhksz::GVector<2>(-1, -1)); + cuhksz::Point<2> b(2, 0); + EXPECT_DOUBLE_EQ(disToSegment(b, a), 2); +} From c0419e6ea20440844054efe81317c5dd62a119b5 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 17:44:15 +0800 Subject: [PATCH 35/41] add CircleTest.cpp --- tests/geometry/CircleTest.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 tests/geometry/CircleTest.cpp diff --git a/tests/geometry/CircleTest.cpp b/tests/geometry/CircleTest.cpp new file mode 100644 index 0000000..8b6c420 --- /dev/null +++ b/tests/geometry/CircleTest.cpp @@ -0,0 +1,23 @@ +#include "geometry/Circle.h" + +#include "gtest/gtest.h" + +TEST(Circle, initialize) { + cuhksz::Circle a, b(2), c(cuhksz::Point<2>(2, 3)); + cuhksz::Circle d(cuhksz::Point<2>(2, 3), 2); +} + +TEST(Circle, getArea) { + cuhksz::Circle a(cuhksz::Point<2>(2, 3), 2); + EXPECT_DOUBLE_EQ(a.getArea(), 3.1415926 * 4); +} + +TEST(Circle, getPerimeter) { + cuhksz::Circle a(cuhksz::Point<2>(2, 3), 3); + EXPECT_DOUBLE_EQ(a.getPerimeter(), 3.1415926 * 6); +} + +TEST(Circle, getPoint) { + cuhksz::Circle a(2); + EXPECT_EQ(a.getPoint(3.1415926/4), cuhksz::Point<2>(std::sqrt(2), std::sqrt(2))); +} From a1653e3bb883274c6ac3c180180583f22d6e1253 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 19:05:19 +0800 Subject: [PATCH 36/41] add VertexTest.cpp --- src/graph/Vertex.cpp | 3 --- tests/graph/VertexTest.cpp | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 tests/graph/VertexTest.cpp diff --git a/src/graph/Vertex.cpp b/src/graph/Vertex.cpp index 5786bb1..fba0e90 100644 --- a/src/graph/Vertex.cpp +++ b/src/graph/Vertex.cpp @@ -33,9 +33,6 @@ Vertex::Vertex(const Vertex& src) { } Vertex::~Vertex() { - for (std::list::iterator it = inEdges.begin(); it != inEdges.end(); ++ it) - if (*it != nullptr) - delete *it; for (std::list::iterator it = outEdges.begin(); it != outEdges.end(); ++ it) if (*it != nullptr) delete *it; diff --git a/tests/graph/VertexTest.cpp b/tests/graph/VertexTest.cpp new file mode 100644 index 0000000..0b754ca --- /dev/null +++ b/tests/graph/VertexTest.cpp @@ -0,0 +1,34 @@ +#include "graph/Vertex.h" +#include "graph/Edge.h" + +#include "gtest/gtest.h" + +TEST(Vertex, initialize) { + cuhksz::Vertex v[10]; + v[0] = cuhksz::Vertex(3); +} + +TEST(Vertex, getter) { + cuhksz::Vertex v(3); + EXPECT_EQ(v.getVal(), 3); + +} + +TEST(Vertex, setter) { + cuhksz::Vertex v(3); + v.setVal(5); + EXPECT_EQ(v.getVal(), 5); +} + +TEST(Vertex, compare) { + cuhksz::Vertex v1(3), v2(5); + EXPECT_TRUE(v1 < v2); +} + +TEST(Vertex, addEdge) { + cuhksz::Vertex v1(3); + cuhksz::Vertex v2(5); + v1.addEdge(v2); + EXPECT_EQ(v1.outEdges.front()->getTo()->getVal(), 5); + EXPECT_EQ(v2.inEdges.front()->getFrom()->getVal(), 3); +} From 82e6f7a1cd8ea0e4706082713c79554c89c5e505 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 19:13:58 +0800 Subject: [PATCH 37/41] add EdgeTest.cpp --- tests/graph/EdgeTest.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 tests/graph/EdgeTest.cpp diff --git a/tests/graph/EdgeTest.cpp b/tests/graph/EdgeTest.cpp new file mode 100644 index 0000000..19ac2ac --- /dev/null +++ b/tests/graph/EdgeTest.cpp @@ -0,0 +1,35 @@ +#include "graph/Edge.h" + +#include "gtest/gtest.h" + +TEST(Edge, initialize) { + cuhksz::Vertex v1(3), v2(5); + cuhksz::Edge e(&v1, &v2); + cuhksz::Edge e1(&v2, &v1, 5); + cuhksz::Edge e2(e); +} + +TEST(Edge, getter) { + cuhksz::Vertex v1(3), v2(5); + cuhksz::Edge e(&v1, &v2, 8); + EXPECT_EQ(e.getFrom(), &v1); + EXPECT_EQ(e.getTo(), &v2); + EXPECT_EQ(e.getVal(), 8); +} + +TEST(Edge, setter) { + cuhksz::Vertex v1(3), v2(5); + cuhksz::Edge e(&v1, &v2, 8); + e.setVal(12); + EXPECT_EQ(e.getVal(), 12); +} + +TEST(Edge, validation) { + cuhksz::Vertex v1(3), v2(5); + cuhksz::Edge e(&v1, &v2, 8); + EXPECT_TRUE(e.isValid()); + e.setInvalid(); + EXPECT_TRUE(!e.isValid()); + e.setValid(); + EXPECT_TRUE(e.isValid()); +} From 4cf22b75b2161cb70db025af6bcba03b50f91187 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 19:42:37 +0800 Subject: [PATCH 38/41] add TreeTest.cpp --- src/graph/Tree.cpp | 7 +-- src/include/graph/Tree.h | 1 + tests/graph/TreeTest.cpp | 94 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 tests/graph/TreeTest.cpp diff --git a/src/graph/Tree.cpp b/src/graph/Tree.cpp index 8ffe102..8c22b8c 100644 --- a/src/graph/Tree.cpp +++ b/src/graph/Tree.cpp @@ -11,7 +11,7 @@ Node::~Node() { } Node* Node::getAncestor(int level) { Node* cur = this; - for (int i = 0; level <= (1 << i); i ++) + for (int i = 0; level >= (1 << i); i ++) if (level & (1 << i)) cur = cur->ancestor[i]; @@ -38,8 +38,9 @@ void Tree::addNode(Node* node, Node* fa) { Node* Tree::LCA(Node* x, Node* y) { int hx = x->getHeight(), hy = y->getHeight(); - if (hx < hy) x = x->getAncestor(hy - hx); - else y = y->getAncestor(hx - hy); + if (hx < hy) y = y->getAncestor(hy - hx); + else x = x->getAncestor(hx - hy); + if (x == y) return x; for (int i = x->ancestor.size() - 1; i >= 0; i --) { if (x->ancestor[i] != y->ancestor[i]) { x = x->ancestor[i], y = y->ancestor[i]; diff --git a/src/include/graph/Tree.h b/src/include/graph/Tree.h index c500e58..fa2b663 100644 --- a/src/include/graph/Tree.h +++ b/src/include/graph/Tree.h @@ -36,6 +36,7 @@ class Node { class Tree { public: void setRoot(Node* newRoot); + Node* getRoot() { return root; } void addNode(Node* node, Node* fa); Node* LCA(Node* x, Node* y); diff --git a/tests/graph/TreeTest.cpp b/tests/graph/TreeTest.cpp new file mode 100644 index 0000000..7ca69a1 --- /dev/null +++ b/tests/graph/TreeTest.cpp @@ -0,0 +1,94 @@ +#include "graph/Tree.h" + +#include "gtest/gtest.h" + +#include + +TEST(Node, initialize) { + cuhksz::Node n(1); + cuhksz::Node n1(2, 10); +} + +TEST(Node, getter) { + cuhksz::Node n(2, 10); + EXPECT_EQ(n.getVal(), 10); +} + +TEST(Node, setter) { + cuhksz::Node f(1, 15); + cuhksz::Node n(2, 10); + n.setFa(&f); + EXPECT_EQ(n.getFa(), &f); + n.setHeight(3); + EXPECT_EQ(n.getHeight(), 3); +} + +TEST(Node, son) { + cuhksz::Node f(1, 15); + cuhksz::Node n(2, 10); + f.addSon(&n); + EXPECT_EQ(f.getSon()[0], &n); +} + +TEST(Tree, root) { + cuhksz::Node n(1, 10); + cuhksz::Tree T; + T.setRoot(&n); + cuhksz::Node* root = T.getRoot(); + EXPECT_EQ(root->getHeight(), 0); + EXPECT_EQ(root->getFa(), nullptr); +} + +TEST(Tree, addNode) { + cuhksz::Tree T; + std::vector nodes; + for (int i = 0; i < 5; i ++) + nodes.push_back(new cuhksz::Node(i)); + T.setRoot(nodes[0]); + T.addNode(nodes[1], nodes[0]); + T.addNode(nodes[2], nodes[1]); + T.addNode(nodes[3], nodes[0]); + T.addNode(nodes[4], nodes[1]); +} + +TEST(Tree, LCA) { + cuhksz::Tree T; + std::vector nodes; + for (int i = 0; i < 5; i ++) + nodes.push_back(new cuhksz::Node(i)); + T.setRoot(nodes[0]); + T.addNode(nodes[1], nodes[0]); + T.addNode(nodes[2], nodes[1]); + T.addNode(nodes[3], nodes[0]); + T.addNode(nodes[4], nodes[1]); + + EXPECT_EQ(nodes[2]->ancestor[0], nodes[1]); + EXPECT_EQ(nodes[2]->ancestor[1], nodes[0]); + EXPECT_EQ((int)nodes[2]->ancestor.size(), 2); + EXPECT_EQ(nodes[2]->getHeight(), 2); + + EXPECT_EQ(nodes[3]->ancestor[0], nodes[0]); + EXPECT_EQ((int)nodes[3]->ancestor.size(), 1); + EXPECT_EQ(nodes[3]->getHeight(), 1); + + EXPECT_EQ(T.LCA(nodes[2], nodes[3]), nodes[0]); + EXPECT_EQ(T.LCA(nodes[2], nodes[4]), nodes[1]); + EXPECT_EQ(T.LCA(nodes[0], nodes[4]), nodes[0]); + +} + +TEST(Tree, getDistance) { + cuhksz::Tree T; + std::vector nodes; + for (int i = 0; i < 5; i ++) + nodes.push_back(new cuhksz::Node(i)); + T.setRoot(nodes[0]); + T.addNode(nodes[1], nodes[0]); + T.addNode(nodes[2], nodes[1]); + T.addNode(nodes[3], nodes[0]); + T.addNode(nodes[4], nodes[1]); + + EXPECT_EQ(T.getDistance(nodes[0], nodes[4]), 2); + EXPECT_EQ(T.getDistance(nodes[2], nodes[4]), 2); + EXPECT_EQ(T.getDistance(nodes[3], nodes[4]), 3); +} From 1cc01eee7f97330ab7403a977fad81913e2b848b Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 20:27:54 +0800 Subject: [PATCH 39/41] add BSTTest.cpp --- src/graph/BST.cpp | 10 ++++---- src/include/graph/BST.h | 13 +++++++---- tests/graph/BSTTest.cpp | 52 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 tests/graph/BSTTest.cpp diff --git a/src/graph/BST.cpp b/src/graph/BST.cpp index edbd93a..ed679dd 100644 --- a/src/graph/BST.cpp +++ b/src/graph/BST.cpp @@ -4,11 +4,13 @@ namespace cuhksz { void BST::rotate(BSTNode* x, int c) { BSTNode* y = x->fa; - y->ch[!c] = y->ch[c]; - if (x->ch[0] != nullptr) x->ch[0]->fa = y; + y->ch[!c] = x->ch[c]; + if (x->ch[c] != nullptr) x->ch[c]->fa = y; x->fa = y->fa; - if (y->fa->ch[0] == y) y->fa->ch[0] = x; - else y->fa->ch[1] = x; + if (y->fa != nullptr) { + if (y->fa->ch[0] == y) y->fa->ch[0] = x; + else y->fa->ch[1] = x; + } y->fa = x, x->ch[c] = y; if (y == root) root = x; } diff --git a/src/include/graph/BST.h b/src/include/graph/BST.h index ed1b352..8076d3b 100644 --- a/src/include/graph/BST.h +++ b/src/include/graph/BST.h @@ -14,27 +14,32 @@ class BSTNode { void setVal(int newVal) { val = newVal; } friend class BST; -private: BSTNode* ch[2]; BSTNode* fa; +private: + + int rank; int val; }; class BST { public: + BST() { root = nullptr; } void insert(BSTNode* x); void erase(BSTNode* x); BSTNode* find(int k); BSTNode* pre(BSTNode* x); BSTNode* suf(BSTNode* x); -private: - // c = 0 for left_rotate + BSTNode* root; void rotate(BSTNode* x, int c); void splay(BSTNode* x); +private: + // c = 0 for left_rotate + + - BSTNode* root; }; diff --git a/tests/graph/BSTTest.cpp b/tests/graph/BSTTest.cpp new file mode 100644 index 0000000..470d5c6 --- /dev/null +++ b/tests/graph/BSTTest.cpp @@ -0,0 +1,52 @@ +#include "graph/BST.h" + +#include "gtest/gtest.h" + +#include + +TEST(BSTNode, initialize) { + cuhksz::BSTNode n(1, 2); +} + +TEST(BSTNode, getter) { + cuhksz::BSTNode n(1, 2); + EXPECT_EQ(n.getVal(), 2); + EXPECT_EQ(n.getRank(), 1); +} + +TEST(BSTNode, setter) { + cuhksz::BSTNode n(1, 2); + n.setVal(3); + EXPECT_EQ(n.getVal(), 3); +} + +TEST(BST, insert) { + cuhksz::BST T; + std::vector nodes; + for (int i = 0; i < 4; i ++) { + nodes.push_back(new cuhksz::BSTNode(i, i)); + T.insert(nodes[i]); + } + +} + +TEST(BST, erase) { + cuhksz::BST T; + std::vector nodes; + for (int i = 0; i < 4; i ++) { + nodes.push_back(new cuhksz::BSTNode(i, i)); + T.insert(nodes[i]); + } + T.erase(nodes[0]); + T.erase(nodes[2]); +} + +TEST(BST, find) { + cuhksz::BST T; + std::vector nodes; + for (int i = 0; i < 4; i ++) { + nodes.push_back(new cuhksz::BSTNode(i, i)); + T.insert(nodes[i]); + } + EXPECT_EQ(T.find(3), nodes[3]); +} From 7bc232b173c4484bc6b1ad46ef779da5ebf73694 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 21:02:45 +0800 Subject: [PATCH 40/41] add SegmentTreeTest.cpp --- src/include/graph/BST.h | 11 +++--- src/include/graph/SegmentTree.h | 59 ++++++++++++++++++++++++++------- tests/graph/SegmentTreeTest.cpp | 46 +++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 18 deletions(-) create mode 100644 tests/graph/SegmentTreeTest.cpp diff --git a/src/include/graph/BST.h b/src/include/graph/BST.h index 8076d3b..0a66d94 100644 --- a/src/include/graph/BST.h +++ b/src/include/graph/BST.h @@ -14,11 +14,10 @@ class BSTNode { void setVal(int newVal) { val = newVal; } friend class BST; + +private: BSTNode* ch[2]; BSTNode* fa; -private: - - int rank; int val; }; @@ -32,12 +31,12 @@ class BST { BSTNode* pre(BSTNode* x); BSTNode* suf(BSTNode* x); + +private: + // c = 0 for left_rotate BSTNode* root; void rotate(BSTNode* x, int c); void splay(BSTNode* x); -private: - // c = 0 for left_rotate - }; diff --git a/src/include/graph/SegmentTree.h b/src/include/graph/SegmentTree.h index f112ace..0557345 100644 --- a/src/include/graph/SegmentTree.h +++ b/src/include/graph/SegmentTree.h @@ -1,4 +1,4 @@ -#ifndef CHUKSZ_GRAPH_SEGMENT_TREE +#ifndef CUHKSZ_GRAPH_SEGMENT_TREE #define CUHKSZ_GRAPH_SEGMENT_TREE #include @@ -10,16 +10,20 @@ template class SegmentTree { public: SegmentTree(std::vector& v); - ~SegmentTree(); void init(std::vector& v, int l, int r, int o); - ValueType queryMax(int lv, int rv, int l = 0, int r = size - 1, int o = 1); - ValueType queryMin(int lv, int rv, int l = 0, int r = size - 1, int o = 1); - ValueType querySum(int lv, int rv, int l = 0, int r = size - 1, int o = 1); - void addInterval(int lv, int rv, ValueType x, int l = 0, int r = size - 1, int o = 1); - void mulInterval(int lv, int rv, ValueType x, int l = 0, int r = size - 1, int o = 1); - -private: + ValueType queryMax(int lv, int rv); + ValueType queryMax(int lv, int rv, int l, int r, int o); + ValueType queryMin(int lv, int rv); + ValueType queryMin(int lv, int rv, int l, int r, int o); + ValueType querySum(int lv, int rv); + ValueType querySum(int lv, int rv, int l, int r, int o); + void addInterval(int lv, int rv, ValueType x); + void addInterval(int lv, int rv, ValueType x, int l, int r, int o); + void mulInterval(int lv, int rv, ValueType x); + void mulInterval(int lv, int rv, ValueType x, int l, int r, int o); + +// private: std::vector minVal; std::vector maxVal; std::vector sumVal; @@ -29,7 +33,7 @@ class SegmentTree { std::vector hasMulFlag; int size; - void update(int o); + void update(int o, int l, int r); }; template @@ -39,6 +43,8 @@ SegmentTree::SegmentTree(std::vector& v) { minVal.push_back(v[0]); maxVal.push_back(v[0]); sumVal.push_back(v[0]); + hasAddFlag.push_back(false); + hasMulFlag.push_back(false); } init(v, 0, size - 1, 1); } @@ -109,6 +115,13 @@ void SegmentTree::update(int o, int l, int r) { } + +template +ValueType SegmentTree::queryMax(int lv, int rv) { + return queryMax(lv, rv, 0, size - 1, 1); +} + + template ValueType SegmentTree::queryMax(int lv, int rv, int l, int r, int o) { update(o, l, r); @@ -121,6 +134,11 @@ ValueType SegmentTree::queryMax(int lv, int rv, int l, int r, int o) return std::max(queryMax(lv, rv, l, mid, ls), queryMax(lv, rv, mid + 1, r, rs)); } +template +ValueType SegmentTree::queryMin(int lv, int rv) { + return queryMin(lv, rv, 0, size - 1, 1); +} + template ValueType SegmentTree::queryMin(int lv, int rv, int l, int r, int o) { update(o, l, r); @@ -130,7 +148,12 @@ ValueType SegmentTree::queryMin(int lv, int rv, int l, int r, int o) int ls = o << 1, rs = (o << 1) | 1; if (rv <= mid) return queryMin(lv, rv, l, mid, ls); if (lv > mid) return queryMin(lv, rv, mid + 1, r, rs); - return std::max(queryMin(lv, rv, l, mid, ls), queryMin(lv, rv, mid + 1, r, rs)); + return std::min(queryMin(lv, rv, l, mid, ls), queryMin(lv, rv, mid + 1, r, rs)); +} + +template +ValueType SegmentTree::querySum(int lv, int rv) { + return querySum(lv, rv, 0, size - 1, 1); } template @@ -142,7 +165,12 @@ ValueType SegmentTree::querySum(int lv, int rv, int l, int r, int o) int ls = o << 1, rs = (o << 1) | 1; if (rv <= mid) return querySum(lv, rv, l, mid, ls); if (lv > mid) return querySum(lv, rv, mid + 1, r, rs); - return std::max(querySum(lv, rv, l, mid, ls), querySum(lv, rv, mid + 1, r, rs)); + return querySum(lv, rv, l, mid, ls) + querySum(lv, rv, mid + 1, r, rs); +} + +template +void SegmentTree::addInterval(int lv, int rv, ValueType x) { + addInterval(lv, rv, x, 0, size - 1, 1); } template @@ -159,6 +187,13 @@ void SegmentTree::addInterval(int lv, int rv, ValueType x, int l, int if (rv > mid) addInterval(lv, rv, x, mid + 1, r, rs); } + +template +void SegmentTree::mulInterval(int lv, int rv, ValueType x) { + mulInterval(lv, rv, x, 0, size - 1, 1); +} + + template void SegmentTree::mulInterval(int lv, int rv, ValueType x, int l, int r, int o) { update(o, l, r); diff --git a/tests/graph/SegmentTreeTest.cpp b/tests/graph/SegmentTreeTest.cpp new file mode 100644 index 0000000..878d95b --- /dev/null +++ b/tests/graph/SegmentTreeTest.cpp @@ -0,0 +1,46 @@ +#include "graph/SegmentTree.h" + +#include "gtest/gtest.h" + +TEST(SegmentTree, initialize) { + std::vector v; + for (int i = 0; i < 4; i ++) + v.push_back(i); + v[1] = 10; + v[3] = -2; + cuhksz::SegmentTree T(v); + EXPECT_EQ(T.size, 4); +} + +TEST(SegmentTree, queryMax) { + std::vector v; + for (int i = 0; i < 4; i ++) + v.push_back(i); + v[1] = 10; + v[3] = -2; + cuhksz::SegmentTree T(v); + EXPECT_EQ(T.queryMax(1, 2), 10); + EXPECT_EQ(T.queryMax(1, 3), 10); +} + +TEST(SegmentTree, queryMin) { + std::vector v; + for (int i = 0; i < 4; i ++) + v.push_back(i); + v[1] = 10; + v[3] = -2; + cuhksz::SegmentTree T(v); + EXPECT_EQ(T.queryMin(1, 2), 2); + EXPECT_EQ(T.queryMin(1, 3), -2); +} + +TEST(SegmentTree, querySum) { + std::vector v; + for (int i = 0; i < 4; i ++) + v.push_back(i); + v[1] = 10; + v[3] = -2; + cuhksz::SegmentTree T(v); + EXPECT_EQ(T.querySum(1, 2), 12); + EXPECT_EQ(T.querySum(1, 3), 10); +} From f289f32fbf964bacc9b176653a328732dd482474 Mon Sep 17 00:00:00 2001 From: Xuan Huang <115010159@link.cuhk.edu.cn> Date: Sun, 21 May 2017 21:10:29 +0800 Subject: [PATCH 41/41] del DFS.h --- src/include/graph/DFS.h | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 src/include/graph/DFS.h diff --git a/src/include/graph/DFS.h b/src/include/graph/DFS.h deleted file mode 100644 index a81090e..0000000 --- a/src/include/graph/DFS.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef CUHKSZ_GRAPH_DFS -#define CUHKSZ_GRAPH_DFS - -namespace cuhksz { - -#include -#include - -#include "graph/Vertex.h" - -class DFS : public std::unary_function { -public: - void operator() (Vertex& v) { - vis.insert(v); - for (Edge* e : v.outEdges) { - Vertex& next = *e.to; - if (vis.count(next) == 0) - this->operator(next); - } - } -private: - set vis; -}; - - -} - - -#endif // CUHKSZ_GRAPH_DFS