sokobo
Loading...
Searching...
No Matches
complex_number.cpp
1#include <cmath>
2#include <sstream>
3#include <stdexcept>
4#ifndef M_PI
5# define M_PI 3.14159265358979323846
6#endif
7
8#ifndef M_E
9# define M_E 2.71828
10#endif
11#include "include/complex_number.h"
12#include "include/numerical_methods.h"
13
14//ComplexNumber::ComplexNumber(double real, double imag)
15// : value(real, imag)
16//{
17//}
18
19
20
21ComplexNumber::ComplexNumber(std::complex<double> val)
22 : value(val)
23{
24}
25
26ComplexNumber ComplexNumber::operator+(const ComplexNumber& other) const
27{
28 return ComplexNumber(value + other.value);
29}
30
31ComplexNumber ComplexNumber::operator-(const ComplexNumber& other) const
32{
33
34 return ComplexNumber(value - other.value);
35}
36
37ComplexNumber ComplexNumber::operator*(const ComplexNumber& other) const
38{
39 return ComplexNumber(value * other.value);
40}
41
42ComplexNumber ComplexNumber::operator/(const ComplexNumber& other) const
43{
44 if (std::abs(other.value) < 1e-10) {
45 throw std::runtime_error("Division by zero complex number");
46 }
47 return ComplexNumber(value / other.value);
48}
49
50ComplexNumber ComplexNumber::operator^(int n) const
51{
52 if (n == 0) {
53 return ComplexNumber(1, 0);
54 }
55
56 ComplexNumber result(1, 0);
57 ComplexNumber base = *this;
58 int exp = std::abs(n);
59
60 while (exp > 0) {
61 if (exp % 2 == 1) {
62 result = result * base;
63 }
64 base = base * base;
65 exp /= 2;
66 }
67
68 if (n < 0) {
69 return ComplexNumber(1, 0) / result;
70 }
71
72 return result;
73}
74
75ComplexNumber ComplexNumber::conjugate() const
76{
77 return ComplexNumber(std::conj(value));
78}
79
80double ComplexNumber::magnitude() const
81{
82 return std::abs(value);
83}
84
85double ComplexNumber::phase() const
86{
87 return std::arg(value);
88}
89
90ComplexNumber ComplexNumber::exp() const
91{
92 return ComplexNumber(std::exp(value));
93}
94
95ComplexNumber ComplexNumber::log() const
96{
97 if (std::abs(value) < 1e-10) {
98 throw std::runtime_error("Logarithm of zero");
99 }
100 return ComplexNumber(std::log(value));
101}
102
103ComplexNumber ComplexNumber::sin() const
104{
105 return ComplexNumber(std::sin(value));
106}
107
108ComplexNumber ComplexNumber::cos() const
109{
110 return ComplexNumber(std::cos(value));
111}
112
113ComplexNumber ComplexNumber::tan() const
114{
115 return ComplexNumber(std::tan(value));
116}
117
118ComplexNumber ComplexNumber::sqrt() const
119{
120 return ComplexNumber(std::sqrt(value));
121}
122
123std::vector<ComplexNumber> ComplexNumber::rootsOfUnity(int n)
124{
125 if (n <= 0) {
126 throw std::runtime_error("n must be positive for roots of unity");
127 }
128
129 std::vector<ComplexNumber> roots;
130 double angle = 2.0 * M_PI / n;
131
132 for (int k = 0; k < n; k++) {
133 double theta = k * angle;
134 roots.emplace_back(std::cos(theta), std::sin(theta));
135 }
136
137 return roots;
138}
139
140std::string ComplexNumber::toString() const
141{
142 std::ostringstream oss;
143 double real = value.real();
144 double imag = value.imag();
145
146 if (std::abs(imag) < 1e-10) {
147 oss << real;
148 } else if (std::abs(real) < 1e-10) {
149 if (std::abs(imag - 1) < 1e-10) {
150 oss << "i";
151 } else if (std::abs(imag + 1) < 1e-10) {
152 oss << "-i";
153 } else {
154 oss << imag << "i";
155 }
156 } else {
157 oss << real;
158 if (imag > 0) {
159 if (std::abs(imag - 1) < 1e-10) {
160 oss << " + i";
161 } else {
162 oss << " + " << imag << "i";
163 }
164 } else {
165 if (std::abs(imag + 1) < 1e-10) {
166 oss << " - i";
167 } else {
168 oss << " - " << (-imag) << "i";
169 }
170 }
171 }
172
173 return oss.str();
174}
175
176std::string ComplexNumber::toPolarString() const
177{
178 double r = magnitude();
179 double theta = phase();
180
181 std::ostringstream oss;
182 oss << r << " * e^(i * " << theta << ")";
183 return oss.str();
184}