-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcomplexo.cs
143 lines (111 loc) · 3.95 KB
/
complexo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
namespace ComplexoCirculo;
public readonly struct Complex {
public readonly double real;
public readonly double imaginary;
public Complex(double real, double imaginary) {
this.real = real;
this.imaginary = imaginary;
}
public (double x, double y) Point {
get => (real, imaginary);
}
public static Complex FromPolar(double abs, double arg) {
return new Complex(abs * Math.Cos(arg),
abs * Math.Sin(arg));
}
public (double abs, double arg) Polar => (Abs, Arg);
public double Abs => Math.Sqrt(real * real + imaginary * imaginary);
public double Arg {
get {
var arg = Math.Atan2(imaginary, real);
return arg >= 0 ? arg : arg + Math.PI * 2;
}
}
public double ArgDegree => Arg * 180 / Math.PI;
public double AbsRoot(uint n) => Math.Pow(Abs, 1d / n);
public IEnumerable<Complex> Sqrt {
get {
var polar = Polar;
List<Complex> list = new(2);
var abs = Math.Sqrt(polar.abs);
list.Add(FromPolar(abs, polar.arg / 2));
list.Add(FromPolar(abs, polar.arg / 2 + Math.PI));
return list;
}
}
public IEnumerable<Complex> Root(uint n) {
var polar = Polar;
var abs = Math.Pow(polar.abs, 1d / n);
for (int i = 0; i < n; i++) {
var theta = (polar.arg / n) + ((Math.PI * 2 * i) / n);
yield return FromPolar(abs, theta);
}
}
public Complex Pow(uint n) {
var polar = Polar;
var abs = Math.Pow(polar.abs, n);
var theta = polar.arg * n;
return FromPolar(abs, theta);
}
public Complex Conjugate => new(real, -imaginary);
public static implicit operator Complex((double, double) point) {
return new Complex(point.Item1, point.Item2);
}
public static explicit operator Complex(double real) {
return new Complex(real, 0);
}
public static explicit operator (double, double)(Complex c) {
return (c.real, c.imaginary);
}
public static Complex operator +(Complex a, Complex b) {
return new Complex(a.real + b.real, a.imaginary + b.imaginary);
}
public static Complex operator -(Complex a, Complex b) {
return new Complex(a.real - b.real, a.imaginary - b.imaginary);
}
public static Complex operator *(Complex a, Complex b) {
return new Complex(a.real * b.real - a.imaginary * b.imaginary,
a.real * b.imaginary + a.imaginary * b.real);
}
public static Complex operator /(Complex a, Complex b) {
double denominator = b.real * b.real + b.imaginary * b.imaginary;
return new Complex((a.real * b.real + a.imaginary * b.imaginary) / denominator,
(a.imaginary * b.real - a.real * b.imaginary) / denominator);
}
public static Complex operator -(Complex a) {
return new Complex(-a.real, -a.imaginary);
}
public static bool operator ==(Complex a, Complex b) {
return a.real == b.real && a.imaginary == b.imaginary;
}
public static bool operator !=(Complex a, Complex b) {
return a.real != b.real || a.imaginary != b.imaginary;
}
public override int GetHashCode()
{
return HashCode.Combine(real, imaginary);
}
public override bool Equals(object? obj)
{
if (obj is Complex c) {
return this == c;
}
return false;
}
public override string ToString()
{
if (imaginary == 0 && real == 0) {
return "0";
} else if (imaginary == 0) {
return $"{real:F2}";
} else if (real == 0) {
return $"{imaginary:F2}i";
} else if (imaginary > 0) {
return $"{real:F2} + {imaginary:F2}i";
} else if (imaginary < 0) {
return $"{real:F2} - {-imaginary:F2}i";
} else {
return "0";
}
}
}