Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quadratic equations complex numbers #2451

Merged
merged 23 commits into from
Apr 28, 2023
Merged
Changes from 16 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
bcca2fb
Added quadratic_equations_complex_numbers.cpp
Renjian-buchai Apr 19, 2023
ff88511
Added a demonstration
Renjian-buchai Apr 19, 2023
685469d
Added test cases
Renjian-buchai Apr 19, 2023
a1433a9
Added test cases
Renjian-buchai Apr 19, 2023
fde4060
Revert "Added test cases"
Renjian-buchai Apr 19, 2023
0b1336c
Added test cases and made docs /// instead of //
Renjian-buchai Apr 19, 2023
194fc6e
test: Added test cases for quadraticEquation
Renjian-buchai Apr 19, 2023
30c3fa7
Merge branch 'master' into Quadratic-Equations-Complex-Numbers
Renjian-buchai Apr 22, 2023
cb111d0
test: more test cases
Renjian-buchai Apr 23, 2023
9212fd1
Merge branch 'master' into Quadratic-Equations-Complex-Numbers
Renjian-buchai Apr 23, 2023
f710554
docs: Updated description
Renjian-buchai Apr 23, 2023
249b53d
Merge branch 'Quadratic-Equations-Complex-Numbers' of https://github.…
Renjian-buchai Apr 23, 2023
e7b8c52
chore: removed redundant returns
Renjian-buchai Apr 23, 2023
fd3e7a8
chore: fixed formatting to pass Code Formatter checks
Renjian-buchai Apr 26, 2023
c4c40ab
Merge branch 'master' into Quadratic-Equations-Complex-Numbers
Renjian-buchai Apr 26, 2023
5c63af7
chore: apply suggestions from code review
Panquesito7 Apr 27, 2023
bd12179
Merge branch 'master' into Quadratic-Equations-Complex-Numbers
Renjian-buchai Apr 27, 2023
b61dda6
test: Added exception test
Renjian-buchai Apr 28, 2023
d89ee9d
Merge branch 'Quadratic-Equations-Complex-Numbers' of https://github.…
Renjian-buchai Apr 28, 2023
3b13a62
Update math/quadratic_equations_complex_numbers.cpp
Renjian-buchai Apr 28, 2023
7ef2b50
Update math/quadratic_equations_complex_numbers.cpp
Renjian-buchai Apr 28, 2023
e240b50
Update math/quadratic_equations_complex_numbers.cpp
Renjian-buchai Apr 28, 2023
d44a1d2
Merge branch 'master' into Quadratic-Equations-Complex-Numbers
tjgurwara99 Apr 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions math/quadratic_equations_complex_numbers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/**
* @file
* @brief Calculate quadratic equation with complex roots, i.e. b^2 - 4ac < 0.
*
* @author [Renjian-buchai](https://github.com/Renjian-buchai)
*
Panquesito7 marked this conversation as resolved.
Show resolved Hide resolved
* @description Calculates any quadratic equation in form ax^2 + bx + c.
*
* Quadratic equation:
* x = (-b +/- sqrt(b^2 - 4ac)) / 2a
*
* @example
* int main() {
* using std::array;
* using std::complex;
* using std::cout;
*
* array<complex<long double, 2> solutions = quadraticEquation(1, 2, 1);
* cout << solutions[0] << " " << solutions[1] << "\n";
*
* solutions = quadraticEquation(1, 1, 1); // Reusing solutions.
* cout << solutions[0] << " " << solutions[1] << "\n";
* return 0;
* }
*
* Output:
* (-1, 0) (-1, 0)
* (-0.5,0.866025) (-0.5,0.866025)
*/

#include <array> /// std::array
#include <cassert> /// assert
#include <cmath> /// std::sqrt, std::trunc, std::pow
#include <complex> /// std::complex
#include <exception> /// std::invalid_argument
#include <iomanip> /// std::setprecision
#include <iostream> /// std::cout

/**
Panquesito7 marked this conversation as resolved.
Show resolved Hide resolved
* @namespace
* @brief Mathematical algorithms
*/
namespace math {

/**
* @brief Quadratic equation calculator.
* @param a quadratic coefficient.
* @param b linear coefficient.
* @param c constant
* @return Array containing the roots of quadratic equation, incl. complex
* root.
*/
std::array<std::complex<long double>, 2> quadraticEquation(long double a,
long double b,
long double c) {
if (a == 0) {
throw std::invalid_argument("quadratic coefficient cannot be 0");
}

long double discriminant = b * b - 4 * a * c;
Renjian-buchai marked this conversation as resolved.
Show resolved Hide resolved
std::array<std::complex<long double>, 2> solutions{0, 0};

// Complex root (discriminant < 0)
// Note that the left term (-b / 2a) is always real. The imaginary part
// appears when b^2 - 4ac < 0, so sqrt(b^2 - 4ac) has no real roots. So,
// the imaginary component is i * (+/-)sqrt(abs(b^2 - 4ac)) / 2a.
if (discriminant < 0) {
// Since b^2 - 4ac is < 0, for faster computation, -discriminant is
// enough to make it positive.
solutions[0] = std::complex<long double>{
-b * 0.5 / a, -std::sqrt(-discriminant) * 0.5 / a};
solutions[1] = std::complex<long double>{
-b * 0.5 / a, std::sqrt(-discriminant) * 0.5 / a};
} else {
// Since discriminant > 0, there are only real roots. Therefore,
// imaginary component = 0.
solutions[0] = std::complex<long double>{
(-b - std::sqrt(discriminant)) * 0.5 / a, 0};
solutions[1] = std::complex<long double>{
(-b + std::sqrt(discriminant)) * 0.5 / a, 0};
}

return solutions;
Renjian-buchai marked this conversation as resolved.
Show resolved Hide resolved
}
Panquesito7 marked this conversation as resolved.
Show resolved Hide resolved

} // namespace math

/**
* @brief Asserts an array of complex numbers.
* @param input Input array of complex numbers. .
* @param expected Expected array of complex numbers.
* @param precision Precision to be asserted. Default=10
*/
void assertArray(std::array<std::complex<long double>, 2> input,
std::array<std::complex<long double>, 2> expected,
size_t precision = 10) {
long double exponent = std::pow(10, precision);
input[0].real(std::round(input[0].real() * exponent));
input[1].real(std::round(input[1].real() * exponent));
input[0].imag(std::round(input[0].imag() * exponent));
input[1].imag(std::round(input[1].imag() * exponent));

expected[0].real(std::round(expected[0].real() * exponent));
expected[1].real(std::round(expected[1].real() * exponent));
expected[0].imag(std::round(expected[0].imag() * exponent));
expected[1].imag(std::round(expected[1].imag() * exponent));

assert(input == expected);
}

/**
* @brief Self-test implementations to test quadraticEquation function.
* @note There are 4 different types of solutions: Real and equal, real,
* complex, complex and equal.
*/
static void test() {
Renjian-buchai marked this conversation as resolved.
Show resolved Hide resolved
// Values are equal and real.
std::cout << "Input: \n"
"a=1 \n"
"b=-2 \n"
"c=1 \n"
"Expected output: \n"
"(1, 0), (1, 0)\n\n";
std::array<std::complex<long double>, 2> equalCase{
std::complex<long double>{1, 0}, std::complex<long double>{1, 0}};
assert(math::quadraticEquation(1, -2, 1) == equalCase);

// Values are equal and complex.
std::cout << "Input: \n"
"a=1 \n"
"b=4 \n"
"c=5 \n"
"Expected output: \n"
"(-2, -1), (-2, 1)\n\n";
std::array<std::complex<long double>, 2> complexCase{
std::complex<long double>{-2, -1}, std::complex<long double>{-2, 1}};
assert(math::quadraticEquation(1, 4, 5) == complexCase);

// Values are real.
std::cout << "Input: \n"
"a=1 \n"
"b=5 \n"
"c=1 \n"
"Expected output: \n"
"(-4.7912878475, 0), (-0.2087121525, 0)\n\n";
std::array<std::complex<long double>, 2> floatCase{
std::complex<long double>{-4.7912878475, 0},
std::complex<long double>{-0.2087121525, 0}};
assertArray(math::quadraticEquation(1, 5, 1), floatCase);

Renjian-buchai marked this conversation as resolved.
Show resolved Hide resolved
// Values are complex.
std::cout << "Input: \n"
"a=1 \n"
"b=1 \n"
"c=1 \n"
"Expected output: \n"
"(-0.5, -0.8660254038), (-0.5, 0.8660254038)\n\n";
std::array<std::complex<long double>, 2> ifloatCase{
std::complex<long double>{-0.5, -0.8660254038},
std::complex<long double>{-0.5, 0.8660254038}};
assertArray(math::quadraticEquation(1, 1, 1), ifloatCase);
}

Panquesito7 marked this conversation as resolved.
Show resolved Hide resolved
/**
* @brief Main function
* @returns 0 on exit
*/
int main() {
test(); // Run self-test implementation.
return 0;
}