TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
quadratic_equations_complex_numbers.cpp
Go to the documentation of this file.
1
31#include <array>
32#include <cassert>
33#include <cmath>
34#include <complex>
35#include <exception>
36#include <iomanip>
37#include <iostream>
38
43namespace math {
44
53std::array<std::complex<long double>, 2> quadraticEquation(long double a,
54 long double b,
55 long double c) {
56 if (a == 0) {
57 throw std::invalid_argument("quadratic coefficient cannot be 0");
58 }
59
60 long double discriminant = b * b - 4 * a * c;
61 std::array<std::complex<long double>, 2> solutions{0, 0};
62
63 if (discriminant == 0) {
64 solutions[0] = -b * 0.5 / a;
65 solutions[1] = -b * 0.5 / a;
66 return solutions;
67 }
68
69 // Complex root (discriminant < 0)
70 // Note that the left term (-b / 2a) is always real. The imaginary part
71 // appears when b^2 - 4ac < 0, so sqrt(b^2 - 4ac) has no real roots. So,
72 // the imaginary component is i * (+/-)sqrt(abs(b^2 - 4ac)) / 2a.
73 if (discriminant > 0) {
74 // Since discriminant > 0, there are only real roots. Therefore,
75 // imaginary component = 0.
76 solutions[0] = std::complex<long double>{
77 (-b - std::sqrt(discriminant)) * 0.5 / a, 0};
78 solutions[1] = std::complex<long double>{
79 (-b + std::sqrt(discriminant)) * 0.5 / a, 0};
80 return solutions;
81 }
82 // Since b^2 - 4ac is < 0, for faster computation, -discriminant is
83 // enough to make it positive.
84 solutions[0] = std::complex<long double>{
85 -b * 0.5 / a, -std::sqrt(-discriminant) * 0.5 / a};
86 solutions[1] = std::complex<long double>{
87 -b * 0.5 / a, std::sqrt(-discriminant) * 0.5 / a};
88
89 return solutions;
90}
91
92} // namespace math
93
100void assertArray(std::array<std::complex<long double>, 2> input,
101 std::array<std::complex<long double>, 2> expected,
102 size_t precision = 10) {
103 long double exponent = std::pow(10, precision);
104 input[0].real(std::round(input[0].real() * exponent));
105 input[1].real(std::round(input[1].real() * exponent));
106 input[0].imag(std::round(input[0].imag() * exponent));
107 input[1].imag(std::round(input[1].imag() * exponent));
108
109 expected[0].real(std::round(expected[0].real() * exponent));
110 expected[1].real(std::round(expected[1].real() * exponent));
111 expected[0].imag(std::round(expected[0].imag() * exponent));
112 expected[1].imag(std::round(expected[1].imag() * exponent));
113
114 assert(input == expected);
115}
116
122static void test() {
123 // Values are equal and real.
124 std::cout << "Input: \n"
125 "a=1 \n"
126 "b=-2 \n"
127 "c=1 \n"
128 "Expected output: \n"
129 "(1, 0), (1, 0)\n\n";
130 std::array<std::complex<long double>, 2> equalCase{
131 std::complex<long double>{1, 0}, std::complex<long double>{1, 0}};
132 assert(math::quadraticEquation(1, -2, 1) == equalCase);
133
134 // Values are equal and complex.
135 std::cout << "Input: \n"
136 "a=1 \n"
137 "b=4 \n"
138 "c=5 \n"
139 "Expected output: \n"
140 "(-2, -1), (-2, 1)\n\n";
141 std::array<std::complex<long double>, 2> complexCase{
142 std::complex<long double>{-2, -1}, std::complex<long double>{-2, 1}};
143 assert(math::quadraticEquation(1, 4, 5) == complexCase);
144
145 // Values are real.
146 std::cout << "Input: \n"
147 "a=1 \n"
148 "b=5 \n"
149 "c=1 \n"
150 "Expected output: \n"
151 "(-4.7912878475, 0), (-0.2087121525, 0)\n\n";
152 std::array<std::complex<long double>, 2> floatCase{
153 std::complex<long double>{-4.7912878475, 0},
154 std::complex<long double>{-0.2087121525, 0}};
155 assertArray(math::quadraticEquation(1, 5, 1), floatCase);
156
157 // Values are complex.
158 std::cout << "Input: \n"
159 "a=1 \n"
160 "b=1 \n"
161 "c=1 \n"
162 "Expected output: \n"
163 "(-0.5, -0.8660254038), (-0.5, 0.8660254038)\n\n";
164 std::array<std::complex<long double>, 2> ifloatCase{
165 std::complex<long double>{-0.5, -0.8660254038},
166 std::complex<long double>{-0.5, 0.8660254038}};
167 assertArray(math::quadraticEquation(1, 1, 1), ifloatCase);
168
169 std::cout << "Exception test: \n"
170 "Input: \n"
171 "a=0 \n"
172 "b=0 \n"
173 "c=0\n"
174 "Expected output: Exception thrown \n";
175 try {
177 } catch (std::invalid_argument& e) {
178 std::cout << "Exception thrown successfully \n";
179 }
180}
181
186int main() {
187 test(); // Run self-test implementation.
188 return 0;
189}
for assert
std::array< std::complex< long double >, 2 > quadraticEquation(long double a, long double b, long double c)
Quadratic equation calculator.
static void test()
Self-test implementations to test quadraticEquation function.
int main()
Main function.
void assertArray(std::array< std::complex< long double >, 2 > input, std::array< std::complex< long double >, 2 > expected, size_t precision=10)
Asserts an array of complex numbers.