From 1158e626cb8fe76d6b3de9fdd7bd39672e62460a Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 14:29:48 +0100 Subject: [PATCH 01/15] feat: Added a class implemetation of complex numbers along with implementation of all (most) binary operations involved with complex numbers. --- math/complex_numbers.cpp | 183 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 math/complex_numbers.cpp diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp new file mode 100644 index 000000000..8d778d735 --- /dev/null +++ b/math/complex_numbers.cpp @@ -0,0 +1,183 @@ +/** + * Copyright 2020 @author tjgurwara99 + * @file + * + * A basic implementation of Complex Number field as a class with operators overloaded to accommodate (mathematical) field operations. + */ + +#include +#include +#include + +/** + * Class Complex to represent complex numbers as a field. + */ +class Complex { + // The real value of the complex number + double re; + // The imaginary value of the complex number + double im; + + public: + /** + * Complex Constructor which initialises the complex number which takes two arguments. + * @param x The real value of the complex number. + * @param y The imaginary value of the complex number. + */ + Complex(double x, double y) { + this->re = x; + this->im = y; + } + + /** + * Complex Constructor which initialises the complex number with no arguments. + */ + Complex() { + Complex(0.0,0.0); + } + + /** + * Member function (getter) to access the class' re value. + */ + double real() const { + return this->re; + } + + /** + * Member function (getter) to access the class' im value. + */ + double imag() const { + return this->im; + } + + /** + * Member function to which gives the absolute value (modulus) of our complex number + * @return \f$ \sqrt{z \dot \bar{z} \f$ where \f$ z \f$ is our complex number. + */ + double abs() const { + return std::sqrt(this->re*this->re + this->im*this->im); + } + + /** + * Operator overload to be able to add two complex numbers. + * @param other The other number that is added to the current number. + * @return result current number plus other number + */ + Complex operator+(const Complex& other) { + Complex result(this->re + other.re, this->im + other.im); + return result; + } + + /** + * Operator overload to be able to subtract two complex numbers. + * @param other The other number being subtracted from the current number. + * @return result current number subtract other number + */ + Complex operator-(const Complex& other) { + Complex result(this->re - other.re, this->im - other.im); + return result; + } + + /** + * Operator overload to be able to multiple two complex numbers. + * @param other The other number to multiply the current number to. + * @return result current number times other number. + */ + Complex operator*(const Complex& other) { + Complex result(this->re * other.re - this->im * other.im, + this->re * other.im + this->im * other.re); + return result; + } + + /** + * Operator overload of the BITWISE NOT which gives us the conjugate of our complex number. + * NOTE: This is overloading the BITWISE operator but its not a BITWISE operation in this definition. + * @return result The conjugate of our complex number. + */ + Complex operator~() const { + Complex result(this->re, -(this->im)); + return result; + } + + /** + * Operator overload to be able to divide two complex numbers. This function would throw an exception if the other number is zero. + * @param other The other number we divide our number by. + * @return result Current number divided by other number. + */ + Complex operator/(const Complex& other) { + Complex result = *this * ~other; + double denominator = other.abs() * other.abs(); + if (denominator != 0) { + result = Complex(result.real() / denominator, result.imag() / denominator); + return result; + } + else { + throw std::invalid_argument("Undefined Value"); + } + } +}; + +/** + * Logical Equal overload for our Complex class. + * @param a Left hand side of our expression + * @param b Right hand side of our expression + * @return 'True' If real and imaginary parts of a and b are same + * @return 'False' Otherwise. + */ +bool operator==(const Complex& a, const Complex& b) { + double del_real = a.real() - b.real(); + double del_imag = a.imag() - b.imag(); + return ((del_real <= 1e-15 && del_real >= - 1e-15 ) && (del_imag <= 1e-15 && del_imag >= - 1e-15)); +} + +/** + * Overloaded insersion operator to accommodate the printing of our complex number in their standard form. + * @param os The console stream + * @param num The complex number. + */ +std::ostream& operator<<(std::ostream& os, const Complex& num) { + os << num.real(); + if (num.imag() < 0) { + os << " - " << -num.imag(); + } + else { + os << " + " << num.imag(); + } + os << "i"; + return os; +} + +/** + * Tests Function + */ +void tests() { + Complex num1(1,1), num2(1,1); + // Test for addition + assert(((void)"1 + 1i + 1 + 1i is equal to 2 + 2i but the addition doesn't add up \n", + (num1 + num2) == Complex(2,2))); + std::cout << "First test passes." << std::endl; + // Test for subtraction + assert(((void)"1 + 1i - 1 - 1i is equal to 0 but the program says otherwise. \n", + (num1 - num2) == Complex(0,0))); + std::cout << "Second test passes." << std::endl; + // Test for multiplication + assert(((void)"(1 + 1i) * (1 + 1i) is equal to 2i but the program says otherwise. \n", + (num1 * num2) == Complex(0,2))); + std::cout << "Third test passes." << std::endl; + // Test for division + assert(((void)"(1 + 1i) / (1 + 1i) is equal to 1 but the program says otherwise.\n", + (num1 / num2) == Complex(1,0))); + std::cout << "Fourth test passes." << std::endl; + // Test for conjugates + assert(((void)"(1 + 1i) has a conjugate which is equal to (1 - 1i) but the program says otherwise.\n", + ~num1 == Complex(1,-1))); + std::cout << "Fifth test passes." << std::endl; + +} +/** + * Main function + */ +int main() { + tests(); + return 0; +} From f4fa366da501e41cac6bd274df4a02fc345d0c3b Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 14:32:08 +0100 Subject: [PATCH 02/15] docs: Fixed some clangformat issues with the documentation --- math/complex_numbers.cpp | 98 +++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 8d778d735..9a381b125 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -2,11 +2,12 @@ * Copyright 2020 @author tjgurwara99 * @file * - * A basic implementation of Complex Number field as a class with operators overloaded to accommodate (mathematical) field operations. + * A basic implementation of Complex Number field as a class with operators + * overloaded to accommodate (mathematical) field operations. */ -#include #include +#include #include /** @@ -18,9 +19,10 @@ class Complex { // The imaginary value of the complex number double im; - public: + public: /** - * Complex Constructor which initialises the complex number which takes two arguments. + * Complex Constructor which initialises the complex number which takes two + * arguments. * @param x The real value of the complex number. * @param y The imaginary value of the complex number. */ @@ -28,34 +30,31 @@ class Complex { this->re = x; this->im = y; } - + /** - * Complex Constructor which initialises the complex number with no arguments. + * Complex Constructor which initialises the complex number with no + * arguments. */ - Complex() { - Complex(0.0,0.0); - } + Complex() { Complex(0.0, 0.0); } /** * Member function (getter) to access the class' re value. */ - double real() const { - return this->re; - } + double real() const { return this->re; } /** * Member function (getter) to access the class' im value. */ - double imag() const { - return this->im; - } + double imag() const { return this->im; } /** - * Member function to which gives the absolute value (modulus) of our complex number - * @return \f$ \sqrt{z \dot \bar{z} \f$ where \f$ z \f$ is our complex number. + * Member function to which gives the absolute value (modulus) of our + * complex number + * @return \f$ \sqrt{z \dot \bar{z}} \f$ where \f$ z \f$ is our complex + * number. */ double abs() const { - return std::sqrt(this->re*this->re + this->im*this->im); + return std::sqrt(this->re * this->re + this->im * this->im); } /** @@ -63,7 +62,7 @@ class Complex { * @param other The other number that is added to the current number. * @return result current number plus other number */ - Complex operator+(const Complex& other) { + Complex operator+(const Complex &other) { Complex result(this->re + other.re, this->im + other.im); return result; } @@ -73,7 +72,7 @@ class Complex { * @param other The other number being subtracted from the current number. * @return result current number subtract other number */ - Complex operator-(const Complex& other) { + Complex operator-(const Complex &other) { Complex result(this->re - other.re, this->im - other.im); return result; } @@ -83,15 +82,16 @@ class Complex { * @param other The other number to multiply the current number to. * @return result current number times other number. */ - Complex operator*(const Complex& other) { + Complex operator*(const Complex &other) { Complex result(this->re * other.re - this->im * other.im, this->re * other.im + this->im * other.re); return result; } /** - * Operator overload of the BITWISE NOT which gives us the conjugate of our complex number. - * NOTE: This is overloading the BITWISE operator but its not a BITWISE operation in this definition. + * Operator overload of the BITWISE NOT which gives us the conjugate of our + * complex number. NOTE: This is overloading the BITWISE operator but its + * not a BITWISE operation in this definition. * @return result The conjugate of our complex number. */ Complex operator~() const { @@ -100,18 +100,19 @@ class Complex { } /** - * Operator overload to be able to divide two complex numbers. This function would throw an exception if the other number is zero. + * Operator overload to be able to divide two complex numbers. This function + * would throw an exception if the other number is zero. * @param other The other number we divide our number by. * @return result Current number divided by other number. */ - Complex operator/(const Complex& other) { + Complex operator/(const Complex &other) { Complex result = *this * ~other; double denominator = other.abs() * other.abs(); if (denominator != 0) { - result = Complex(result.real() / denominator, result.imag() / denominator); + result = Complex(result.real() / denominator, + result.imag() / denominator); return result; - } - else { + } else { throw std::invalid_argument("Undefined Value"); } } @@ -124,23 +125,24 @@ class Complex { * @return 'True' If real and imaginary parts of a and b are same * @return 'False' Otherwise. */ -bool operator==(const Complex& a, const Complex& b) { +bool operator==(const Complex &a, const Complex &b) { double del_real = a.real() - b.real(); double del_imag = a.imag() - b.imag(); - return ((del_real <= 1e-15 && del_real >= - 1e-15 ) && (del_imag <= 1e-15 && del_imag >= - 1e-15)); + return ((del_real <= 1e-15 && del_real >= -1e-15) && + (del_imag <= 1e-15 && del_imag >= -1e-15)); } /** - * Overloaded insersion operator to accommodate the printing of our complex number in their standard form. + * Overloaded insersion operator to accommodate the printing of our complex + * number in their standard form. * @param os The console stream * @param num The complex number. */ -std::ostream& operator<<(std::ostream& os, const Complex& num) { +std::ostream &operator<<(std::ostream &os, const Complex &num) { os << num.real(); if (num.imag() < 0) { os << " - " << -num.imag(); - } - else { + } else { os << " + " << num.imag(); } os << "i"; @@ -151,28 +153,32 @@ std::ostream& operator<<(std::ostream& os, const Complex& num) { * Tests Function */ void tests() { - Complex num1(1,1), num2(1,1); + Complex num1(1, 1), num2(1, 1); // Test for addition - assert(((void)"1 + 1i + 1 + 1i is equal to 2 + 2i but the addition doesn't add up \n", - (num1 + num2) == Complex(2,2))); + assert(((void)"1 + 1i + 1 + 1i is equal to 2 + 2i but the addition doesn't " + "add up \n", + (num1 + num2) == Complex(2, 2))); std::cout << "First test passes." << std::endl; // Test for subtraction - assert(((void)"1 + 1i - 1 - 1i is equal to 0 but the program says otherwise. \n", - (num1 - num2) == Complex(0,0))); + assert(((void)"1 + 1i - 1 - 1i is equal to 0 but the program says " + "otherwise. \n", + (num1 - num2) == Complex(0, 0))); std::cout << "Second test passes." << std::endl; // Test for multiplication - assert(((void)"(1 + 1i) * (1 + 1i) is equal to 2i but the program says otherwise. \n", - (num1 * num2) == Complex(0,2))); + assert(((void)"(1 + 1i) * (1 + 1i) is equal to 2i but the program says " + "otherwise. \n", + (num1 * num2) == Complex(0, 2))); std::cout << "Third test passes." << std::endl; // Test for division - assert(((void)"(1 + 1i) / (1 + 1i) is equal to 1 but the program says otherwise.\n", - (num1 / num2) == Complex(1,0))); + assert(((void)"(1 + 1i) / (1 + 1i) is equal to 1 but the program says " + "otherwise.\n", + (num1 / num2) == Complex(1, 0))); std::cout << "Fourth test passes." << std::endl; // Test for conjugates - assert(((void)"(1 + 1i) has a conjugate which is equal to (1 - 1i) but the program says otherwise.\n", - ~num1 == Complex(1,-1))); + assert(((void)"(1 + 1i) has a conjugate which is equal to (1 - 1i) but the " + "program says otherwise.\n", + ~num1 == Complex(1, -1))); std::cout << "Fifth test passes." << std::endl; - } /** * Main function From 8969047d3ff8fe6f08966f0a465b239a4fdc16a0 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 14:41:46 +0100 Subject: [PATCH 03/15] fix: Added missing header --- math/complex_numbers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 9a381b125..4505b5677 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -9,6 +9,7 @@ #include #include #include +#include /** * Class Complex to represent complex numbers as a field. From 626ab310955b5417675b0487a8d4f79f1786d355 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 14:53:09 +0100 Subject: [PATCH 04/15] fix: incorrect constructor delegation --- math/complex_numbers.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 4505b5677..10e50b22a 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -36,7 +36,10 @@ class Complex { * Complex Constructor which initialises the complex number with no * arguments. */ - Complex() { Complex(0.0, 0.0); } + Complex() { + this->re = 0.0; + this.im = 0.0; + } /** * Member function (getter) to access the class' re value. From c419e1f7882298fb98567898f82482fd2cd4c29a Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 14:54:10 +0100 Subject: [PATCH 05/15] fix: arrow operator instead of dot --- math/complex_numbers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 10e50b22a..189d0b831 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -38,7 +38,7 @@ class Complex { */ Complex() { this->re = 0.0; - this.im = 0.0; + this->im = 0.0; } /** From 1708de2296204efd863e485068a96078ce76f5af Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 16:23:49 +0100 Subject: [PATCH 06/15] fix: fixed all pull request suggestions --- math/complex_numbers.cpp | 88 +++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 24 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 189d0b831..4ae5c493b 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -6,10 +6,11 @@ * overloaded to accommodate (mathematical) field operations. */ +#include #include +#include #include #include -#include /** * Class Complex to represent complex numbers as a field. @@ -27,19 +28,13 @@ class Complex { * @param x The real value of the complex number. * @param y The imaginary value of the complex number. */ - Complex(double x, double y) { - this->re = x; - this->im = y; - } + explicit Complex(double x = 0.f, double y = 0.f) : re(x), im(y) { ; } /** - * Complex Constructor which initialises the complex number with no - * arguments. + * Copy Constructor + * @param other The other number to equate our number to. */ - Complex() { - this->re = 0.0; - this->im = 0.0; - } + Complex(const Complex &other) : re(other.real()), im(other.imag()) { ; } /** * Member function (getter) to access the class' re value. @@ -61,6 +56,26 @@ class Complex { return std::sqrt(this->re * this->re + this->im * this->im); } + /** + * Member function which gives the argument of our complex number. + * @return Argument of our Complex number. + */ + double arg() const { + if (this->re > 0) { + return std::atan(this->im / this->re); + } else if (this->re < 0 && this->im >= 0) { + return std::atan(this->im / this->re) + M_PI; + } else if (this->re < 0 && this->im < 0) { + return std::atan(this->im / this->re) - M_PI; + } else if (this->re == 0 && this->im > 0) { + return M_PI / 2; + } else if (this->re == 0 && this->im < 0) { + return -M_PI / 2; + } else { + throw std::invalid_argument("Undefined Value"); + } + } + /** * Operator overload to be able to add two complex numbers. * @param other The other number that is added to the current number. @@ -111,7 +126,8 @@ class Complex { */ Complex operator/(const Complex &other) { Complex result = *this * ~other; - double denominator = other.abs() * other.abs(); + double denominator = + other.real() * other.real() + other.imag() * other.imag(); if (denominator != 0) { result = Complex(result.real() / denominator, result.imag() / denominator); @@ -120,6 +136,16 @@ class Complex { throw std::invalid_argument("Undefined Value"); } } + + /** + * Operator overload to be able to copy RHS instance of Complex to LHS + * instance of Complex + */ + const Complex &operator=(const Complex &other) { + this->re = other.real(); + this->im = other.imag(); + return *this; + } }; /** @@ -130,10 +156,7 @@ class Complex { * @return 'False' Otherwise. */ bool operator==(const Complex &a, const Complex &b) { - double del_real = a.real() - b.real(); - double del_imag = a.imag() - b.imag(); - return ((del_real <= 1e-15 && del_real >= -1e-15) && - (del_imag <= 1e-15 && del_imag >= -1e-15)); + return a.real() == b.real() && a.imag() == b.imag(); } /** @@ -143,13 +166,13 @@ bool operator==(const Complex &a, const Complex &b) { * @param num The complex number. */ std::ostream &operator<<(std::ostream &os, const Complex &num) { - os << num.real(); + os << "(" << num.real(); if (num.imag() < 0) { os << " - " << -num.imag(); } else { os << " + " << num.imag(); } - os << "i"; + os << "i)"; return os; } @@ -158,32 +181,49 @@ std::ostream &operator<<(std::ostream &os, const Complex &num) { */ void tests() { Complex num1(1, 1), num2(1, 1); + std::complex cnum1(1, 1), cnum2(1, 1); // Test for addition assert(((void)"1 + 1i + 1 + 1i is equal to 2 + 2i but the addition doesn't " "add up \n", - (num1 + num2) == Complex(2, 2))); + ((num1 + num2).real() == (cnum1 + cnum2).real() && + (num1 + num2).imag() == (cnum1 + cnum2).imag()))); std::cout << "First test passes." << std::endl; // Test for subtraction assert(((void)"1 + 1i - 1 - 1i is equal to 0 but the program says " "otherwise. \n", - (num1 - num2) == Complex(0, 0))); + ((num1 - num2).real() == (cnum1 - cnum2).real() && + (num1 - num2).imag() == (cnum1 - cnum2).imag()))); std::cout << "Second test passes." << std::endl; // Test for multiplication assert(((void)"(1 + 1i) * (1 + 1i) is equal to 2i but the program says " "otherwise. \n", - (num1 * num2) == Complex(0, 2))); + ((num1 * num2).real() == (cnum1 * cnum2).real() && + (num1 * num2).imag() == (cnum1 * cnum2).imag()))); std::cout << "Third test passes." << std::endl; // Test for division assert(((void)"(1 + 1i) / (1 + 1i) is equal to 1 but the program says " "otherwise.\n", - (num1 / num2) == Complex(1, 0))); + ((num1 / num2).real() == (cnum1 / cnum2).real() && + (num1 / num2).imag() == (cnum1 / cnum2).imag()))); std::cout << "Fourth test passes." << std::endl; // Test for conjugates assert(((void)"(1 + 1i) has a conjugate which is equal to (1 - 1i) but the " "program says otherwise.\n", - ~num1 == Complex(1, -1))); - std::cout << "Fifth test passes." << std::endl; + ((~num1).real() == std::conj(cnum1).real() && + (~num1).imag() == std::conj(cnum1).imag()))); + std::cout << "Fifth test passes.\n"; + // Test for Argument of our complex number + assert(((void)"(1 + 1i) has argument PI / 4 but the program differs from " + "the std::complex result.\n", + (num1.arg() == std::arg(cnum1)))); + std::cout << "Sixth test passes.\n"; + // Test for absolute value of our complex number + assert(((void)"(1 + 1i) has absolute value sqrt(2) but the program differs " + "from the std::complex result. \n", + (num1.abs() == std::abs(cnum1)))); + std::cout << "Seventh test passes.\n"; } + /** * Main function */ From 52f918a4ffb11aec4fbc4b22d026e2e0a39b867d Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 16:33:54 +0100 Subject: [PATCH 07/15] fix: Fixed issue with Windows CI test - M_PI doesn't work on Windows CI --- math/complex_numbers.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 4ae5c493b..9d6ede15d 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -12,6 +12,11 @@ #include #include +/** + * Global constant for pi to work with Windows environment + */ +const double pi = 3.14159265358979323846; + /** * Class Complex to represent complex numbers as a field. */ @@ -64,13 +69,13 @@ class Complex { if (this->re > 0) { return std::atan(this->im / this->re); } else if (this->re < 0 && this->im >= 0) { - return std::atan(this->im / this->re) + M_PI; + return std::atan(this->im / this->re) + pi; } else if (this->re < 0 && this->im < 0) { - return std::atan(this->im / this->re) - M_PI; + return std::atan(this->im / this->re) - pi; } else if (this->re == 0 && this->im > 0) { - return M_PI / 2; + return pi / 2; } else if (this->re == 0 && this->im < 0) { - return -M_PI / 2; + return -pi / 2; } else { throw std::invalid_argument("Undefined Value"); } From b9658104cb024a1044f2b621566dadf9a184f8a2 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 17:56:53 +0100 Subject: [PATCH 08/15] fix: Taken onboard some suggested changes --- math/complex_numbers.cpp | 70 ++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 9d6ede15d..03dfe1069 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -12,11 +12,6 @@ #include #include -/** - * Global constant for pi to work with Windows environment - */ -const double pi = 3.14159265358979323846; - /** * Class Complex to represent complex numbers as a field. */ @@ -30,8 +25,8 @@ class Complex { /** * Complex Constructor which initialises the complex number which takes two * arguments. - * @param x The real value of the complex number. - * @param y The imaginary value of the complex number. + * @param x The real value of the complex number (optional). + * @param y The imaginary value of the complex number (optional). */ explicit Complex(double x = 0.f, double y = 0.f) : re(x), im(y) { ; } @@ -63,23 +58,9 @@ class Complex { /** * Member function which gives the argument of our complex number. - * @return Argument of our Complex number. + * @return Argument of our Complex number in radians. */ - double arg() const { - if (this->re > 0) { - return std::atan(this->im / this->re); - } else if (this->re < 0 && this->im >= 0) { - return std::atan(this->im / this->re) + pi; - } else if (this->re < 0 && this->im < 0) { - return std::atan(this->im / this->re) - pi; - } else if (this->re == 0 && this->im > 0) { - return pi / 2; - } else if (this->re == 0 && this->im < 0) { - return -pi / 2; - } else { - throw std::invalid_argument("Undefined Value"); - } - } + double arg() const { return atan2(this->im, this->re); } /** * Operator overload to be able to add two complex numbers. @@ -181,41 +162,60 @@ std::ostream &operator<<(std::ostream &os, const Complex &num) { return os; } +/** + * Function to get random numbers to generate our complex numbers for test + */ +double get_rand() { return (std::rand() % 100 - 50) / 100.f; } + /** * Tests Function */ void tests() { - Complex num1(1, 1), num2(1, 1); - std::complex cnum1(1, 1), cnum2(1, 1); + std::srand(std::time(nullptr)); + double x1 = get_rand(), y1 = get_rand(), x2 = get_rand(), y2 = get_rand(); + Complex num1(x1, y1), num2(x2, y2); + std::complex cnum1(x1, y1), cnum2(x2, y2); + Complex result; + std::complex expected; // Test for addition + result = num1 + num2; + expected = cnum1 + cnum2; assert(((void)"1 + 1i + 1 + 1i is equal to 2 + 2i but the addition doesn't " "add up \n", - ((num1 + num2).real() == (cnum1 + cnum2).real() && - (num1 + num2).imag() == (cnum1 + cnum2).imag()))); + (result.real() == expected.real() && + result.imag() == expected.imag()))); std::cout << "First test passes." << std::endl; // Test for subtraction + result = num1 - num2; + expected = cnum1 - cnum2; assert(((void)"1 + 1i - 1 - 1i is equal to 0 but the program says " "otherwise. \n", - ((num1 - num2).real() == (cnum1 - cnum2).real() && - (num1 - num2).imag() == (cnum1 - cnum2).imag()))); + (result.real() == expected.real() && + result.imag() == expected.imag()))); std::cout << "Second test passes." << std::endl; // Test for multiplication + result = num1 * num2; + expected = cnum1 * cnum2; assert(((void)"(1 + 1i) * (1 + 1i) is equal to 2i but the program says " "otherwise. \n", - ((num1 * num2).real() == (cnum1 * cnum2).real() && - (num1 * num2).imag() == (cnum1 * cnum2).imag()))); + (result.real() == expected.real() && + result.imag() == expected.imag()))); std::cout << "Third test passes." << std::endl; // Test for division + result = num1 / num2; + expected = cnum1 / cnum2; assert(((void)"(1 + 1i) / (1 + 1i) is equal to 1 but the program says " "otherwise.\n", - ((num1 / num2).real() == (cnum1 / cnum2).real() && - (num1 / num2).imag() == (cnum1 / cnum2).imag()))); + (result.real() == expected.real() && + result.imag() == expected.imag()))); std::cout << "Fourth test passes." << std::endl; // Test for conjugates + result = ~num1; + expected = std::conj(cnum1); assert(((void)"(1 + 1i) has a conjugate which is equal to (1 - 1i) but the " "program says otherwise.\n", - ((~num1).real() == std::conj(cnum1).real() && - (~num1).imag() == std::conj(cnum1).imag()))); + (result.real() == expected.real() && + result.imag() == expected.imag()))); std::cout << "Fifth test passes.\n"; // Test for Argument of our complex number assert(((void)"(1 + 1i) has argument PI / 4 but the program differs from " From 907b8298309d898b6d3b967a9ba5b3fc62a6afe8 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 18:00:53 +0100 Subject: [PATCH 09/15] docs: copyright message --- math/complex_numbers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 03dfe1069..b2353d785 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -1,5 +1,5 @@ /** - * Copyright 2020 @author tjgurwara99 + * @author tjgurwara99 * @file * * A basic implementation of Complex Number field as a class with operators From ce81700380e656ce6ec8898c7e87e3669ec9e5c3 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 18:04:42 +0100 Subject: [PATCH 10/15] fix: added missing header for std::time --- math/complex_numbers.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index b2353d785..43b1d5fda 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -11,6 +11,7 @@ #include #include #include +#include /** * Class Complex to represent complex numbers as a field. From 61084adbd3b73aa5312836aa1836188dc24881f8 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 18:16:26 +0100 Subject: [PATCH 11/15] fix: fixed forgotten namespace --- math/complex_numbers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 43b1d5fda..9168c08aa 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -61,7 +61,7 @@ class Complex { * Member function which gives the argument of our complex number. * @return Argument of our Complex number in radians. */ - double arg() const { return atan2(this->im, this->re); } + double arg() const { return std::atan2(this->im, this->re); } /** * Operator overload to be able to add two complex numbers. From bcd5df725d83e06ae2fb69b0ccacbef5c56e454b Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 19:23:15 +0100 Subject: [PATCH 12/15] feat: added polar form initialisation to our Complex class --- math/complex_numbers.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 9168c08aa..35e11ba1d 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -9,9 +9,9 @@ #include #include #include +#include #include #include -#include /** * Class Complex to represent complex numbers as a field. @@ -26,10 +26,22 @@ class Complex { /** * Complex Constructor which initialises the complex number which takes two * arguments. - * @param x The real value of the complex number (optional). - * @param y The imaginary value of the complex number (optional). + * @param x If the third parameter is 'true' then this x is the absolute + * value of the complex number, if the third parameter is 'false' then this + * x is the real value of the complex number (optional). + * @param y If the third parameter is 'true' then this y is the argument of + * the complex number, if the third parameter is 'false' then this y is the + * imaginary value of the complex number (optional). + * @param is_polar 'false' by default. If we want to initialise our complex + * number using polar form then set this to true, otherwise set it to false + * to use initialiser which initialises real and imaginary values using the + * first two parameters (optional). */ - explicit Complex(double x = 0.f, double y = 0.f) : re(x), im(y) { ; } + explicit Complex(double x = 0.f, double y = 0.f, bool is_polar = false) + : re(is_polar ? x * std::cos(y) : x), + im(is_polar ? x * std::sin(y) : y) { + ; + } /** * Copy Constructor From 95320b38a4a2aefaf0eb6b757438560b36d272f4 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 19:29:11 +0100 Subject: [PATCH 13/15] fix: cpplint issues --- math/complex_numbers.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 35e11ba1d..a4ee69829 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -22,7 +22,7 @@ class Complex { // The imaginary value of the complex number double im; - public: + public: /** * Complex Constructor which initialises the complex number which takes two * arguments. @@ -39,9 +39,7 @@ class Complex { */ explicit Complex(double x = 0.f, double y = 0.f, bool is_polar = false) : re(is_polar ? x * std::cos(y) : x), - im(is_polar ? x * std::sin(y) : y) { - ; - } + im(is_polar ? x * std::sin(y) : y) { ; } /** * Copy Constructor From 9048e19184c3df765465c150ec7fa89151c41cd5 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 19:32:05 +0100 Subject: [PATCH 14/15] fix: cpplint issues --- math/complex_numbers.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index a4ee69829..30edf4964 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -39,13 +39,13 @@ class Complex { */ explicit Complex(double x = 0.f, double y = 0.f, bool is_polar = false) : re(is_polar ? x * std::cos(y) : x), - im(is_polar ? x * std::sin(y) : y) { ; } + im(is_polar ? x * std::sin(y) : y) {} /** * Copy Constructor * @param other The other number to equate our number to. */ - Complex(const Complex &other) : re(other.real()), im(other.imag()) { ; } + Complex(const Complex &other) : re(other.real()), im(other.imag()) {} /** * Member function (getter) to access the class' re value. From 75d8ee7cf07ee546e5f9fdbfad904060840fa607 Mon Sep 17 00:00:00 2001 From: Tajmeet Singh Date: Tue, 23 Jun 2020 19:43:56 +0100 Subject: [PATCH 15/15] fix: Readability issues --- math/complex_numbers.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/math/complex_numbers.cpp b/math/complex_numbers.cpp index 30edf4964..8b24c6d3c 100644 --- a/math/complex_numbers.cpp +++ b/math/complex_numbers.cpp @@ -37,9 +37,16 @@ class Complex { * to use initialiser which initialises real and imaginary values using the * first two parameters (optional). */ - explicit Complex(double x = 0.f, double y = 0.f, bool is_polar = false) - : re(is_polar ? x * std::cos(y) : x), - im(is_polar ? x * std::sin(y) : y) {} + explicit Complex(double x = 0.f, double y = 0.f, bool is_polar = false) { + if (!is_polar) { + re = x; + im = y; + return; + } + + re = x * std::cos(y); + im = x * std::sin(y); + } /** * Copy Constructor