Skip to content

Commit 765c5e4

Browse files
Merge pull request hsf-training#200 from bernhardmgruber/complex
Refactor Complex in STL exercise
2 parents 5a8306f + 95a44a4 commit 765c5e4

File tree

1 file changed

+101
-65
lines changed

1 file changed

+101
-65
lines changed

code/stl/Complex.hpp

Lines changed: 101 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,110 @@
11
#include <ostream>
2+
#include <cmath>
23

34
template <typename T=float>
45
class Complex_t {
56
public:
6-
Complex_t(T r, T i);
7-
Complex_t();
8-
9-
T real() const {return m_r;};
10-
T imaginary() const {return m_i;};
11-
12-
Complex_t operator+(const Complex_t& other) const;
13-
Complex_t operator-(const Complex_t& other) const;
14-
Complex_t operator*(const Complex_t& other) const;
15-
Complex_t operator*(const T factor) const;
16-
Complex_t operator/(const T dividend) const;
17-
Complex_t& operator+=(const Complex_t& other);
18-
bool operator<(const Complex_t& a) const;
7+
Complex_t() = default;
8+
Complex_t(T r, T i) : m_r(r), m_i(i) {}
9+
10+
T real() const { return m_r; }
11+
T imaginary() const { return m_i; }
12+
13+
T norm_sqr() const {
14+
return m_r * m_r + m_i * m_i;
15+
}
16+
17+
T norm() const {
18+
return std::sqrt(norm_sqr());
19+
}
20+
21+
Complex_t& operator+=(const Complex_t& other) {
22+
m_r += other.m_r;
23+
m_i += other.m_i;
24+
return *this;
25+
}
26+
27+
Complex_t& operator-=(const Complex_t& other) {
28+
m_r -= other.m_r;
29+
m_i -= other.m_i;
30+
return *this;
31+
}
32+
33+
Complex_t& operator*=(const Complex_t& other) {
34+
const auto r = m_r * other.m_r - m_i * other.m_i;
35+
const auto i = m_r * other.m_i + m_i * other.m_r;
36+
m_r = r;
37+
m_i = i;
38+
return *this;
39+
}
40+
41+
Complex_t& operator*=(T factor) {
42+
m_r *= factor;
43+
m_i *= factor;
44+
return *this;
45+
}
46+
47+
Complex_t& operator/=(const Complex_t& other) {
48+
const T ns = other.norm_sqr();
49+
const auto r = (m_r * other.m_r + m_i * other.m_i) / ns;
50+
const auto i = (m_i * other.m_r - m_r * other.m_i) / ns;
51+
m_r = r;
52+
m_i = i;
53+
return *this;
54+
}
55+
56+
Complex_t& operator/=(T divisor) {
57+
m_r /= divisor;
58+
m_i /= divisor;
59+
return *this;
60+
}
61+
62+
friend Complex_t operator+(Complex_t a, const Complex_t& b) {
63+
return a += b;
64+
}
65+
66+
friend Complex_t operator-(Complex_t a, const Complex_t& b) {
67+
return a -= b;
68+
}
69+
70+
friend Complex_t operator*(Complex_t a, const Complex_t& b) {
71+
return a *= b;
72+
}
73+
74+
friend Complex_t operator*(Complex_t c, T factor) {
75+
return c *= factor;
76+
}
77+
78+
friend Complex_t operator*(T factor, Complex_t c) {
79+
return c *= factor;
80+
}
81+
82+
friend Complex_t operator/(Complex_t a, Complex_t b) {
83+
return a /= b;
84+
}
85+
86+
friend Complex_t operator/(Complex_t c, T divisor) {
87+
return c /= divisor;
88+
}
89+
90+
friend Complex_t operator/(T dividend, const Complex_t& c) {
91+
return Complex_t(dividend, 0) / c;
92+
}
93+
94+
friend bool operator==(const Complex_t& a, const Complex_t& b) {
95+
return a.m_r == b.m_r && a.m_i == b.m_i;
96+
}
97+
98+
friend bool operator<(const Complex_t& a, const Complex_t& b) {
99+
return a.norm_sqr() < b.norm_sqr();
100+
}
101+
102+
friend std::ostream& operator<<(std::ostream& os, const Complex_t<T>& c) {
103+
return os << "(" << c.real() << ", " << c.imaginary() << ")";
104+
}
105+
19106
private:
20107
T m_r{}, m_i{};
21108
};
22109

23-
typedef Complex_t<> Complex;
24-
25-
template <typename T>
26-
Complex_t<T>::Complex_t() {}
27-
28-
template <typename T>
29-
Complex_t<T>::Complex_t(T r, T i) : m_r(r), m_i(i) {}
30-
31-
template <typename T>
32-
Complex_t<T> Complex_t<T>::operator+(const Complex_t<T>& other) const {
33-
return Complex_t(m_r + other.m_r, m_i + other.m_i);
34-
}
35-
36-
template <typename T>
37-
Complex_t<T> Complex_t<T>::operator-(const Complex_t<T>& other) const {
38-
return Complex_t(m_r - other.m_r, m_i - other.m_i);
39-
}
40-
41-
template <typename T>
42-
Complex_t<T> Complex_t<T>::operator*(const Complex_t<T>& other) const {
43-
return Complex_t(m_r*other.m_r - m_i*other.m_i,
44-
m_r*other.m_i + m_i*other.m_r);
45-
}
46-
47-
template <typename T>
48-
Complex_t<T> Complex_t<T>::operator*(const T factor) const {
49-
return Complex_t(m_r*factor, m_i*factor);
50-
}
51-
52-
template <typename T>
53-
Complex_t<T> Complex_t<T>::operator/(const T dividend) const {
54-
return Complex_t(m_r/dividend, m_i/dividend);
55-
}
56-
57-
template <typename T>
58-
Complex_t<T>& Complex_t<T>::operator+=(const Complex_t<T>& other) {
59-
m_r += other.m_r;
60-
m_i += other.m_i;
61-
return *this;
62-
}
63-
64-
template <typename T>
65-
bool Complex_t<T>::operator<(const Complex_t<T>& other) const {
66-
return (m_r*m_r+m_i*m_i) < (other.m_r*other.m_r+other.m_i*other.m_i);
67-
}
68-
69-
template <typename T>
70-
std::ostream& operator<<(std::ostream& os,
71-
const Complex_t<T>& c) {
72-
os << "(" << c.real() << ", " << c.imaginary() << ")";
73-
return os;
74-
}
110+
using Complex = Complex_t<>;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy