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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
| using System;
namespace ComplexConsole
{
public struct ComplexDouble : IFormattable, IEquatable<ComplexDouble>
{
public static readonly ComplexDouble I = new ComplexDouble(0, 1);
public double Re { get; set; }
public double Im { get; set; }
public double Abs { get { return Math.Sqrt(SqrAbs); } set { this *= value/Abs; } }
public double SqrAbs { get { return Re*Re + Im*Im; } set { this *= Math.Sqrt(value/SqrAbs); } }
public double Arg
{
get { return Math.Atan2(Im, Re); }
set
{
double abs = Abs;
Re = abs*Math.Cos(value);
Im = abs*Math.Sin(value);
}
}
public ComplexDouble MultipleI { get { return new ComplexDouble(-Im, Re); } }
public ComplexDouble DivideI { get { return new ComplexDouble(Im, -Re); } }
public ComplexDouble(double x, double y) : this()
{
Re = x;
Im = y;
}
//
#region Методы предков System.(Object, IFormattable, IEquatable<ComplexDouble>)
public bool Equals(ComplexDouble other)
{
return Re.Equals(other.Re) && Im.Equals(other.Im);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is ComplexDouble && Equals((ComplexDouble)obj);
}
public override int GetHashCode()
{
unchecked
{
return (Re.GetHashCode() * 397) ^ Im.GetHashCode();
}
}
public override string ToString()
{
if (Math.Abs(Im) <= double.Epsilon) //если ноль
return Re.ToString();
return Re.ToString() + (Im < 0 ? " " : " +") + Im.ToString() + 'i';
}
public string ToString(string format, IFormatProvider provider)
{
if (Math.Abs(Im) <= double.Epsilon) //если ноль
return Re.ToString(format, provider);
return Re.ToString(format, provider) + (Im < 0 ? " " : " +") + Im.ToString(format, provider) + 'i';
}
#endregion
//
#region Тригонометрические функции
public static ComplexDouble Exp(ComplexDouble z)
{
return Math.Exp(z.Re)*(new ComplexDouble(Math.Cos(z.Im), Math.Sin(z.Im)));
}
public static ComplexDouble Log(ComplexDouble z)
{
return Log(z, 0);
}
public static ComplexDouble Log(ComplexDouble z, int k)
{
return new ComplexDouble(Math.Log(z.Abs), z.Arg + 2d*k*Math.PI);
}
public static ComplexDouble Log(ComplexDouble z, int kz, ComplexDouble a, int ka)
{
return Log(z, kz)/Log(a, ka);
}
public static ComplexDouble Pow(ComplexDouble z, double n)
{
return Math.Pow(z.Abs, n)*new ComplexDouble(Math.Cos(z.Arg*n), Math.Sin(z.Arg*n));
}
public static ComplexDouble Pow(ComplexDouble z, ComplexDouble n)
{
return Pow(z, n, 0);
}
public static ComplexDouble Pow(ComplexDouble z, ComplexDouble n, int k)
{
return Exp(n*Log(z, k));
}
public static ComplexDouble Sqrt(ComplexDouble z, int k)
{
return Pow(z, new ComplexDouble(0.5d, 0d), k);
}
//
public static ComplexDouble Sin(ComplexDouble z)
{
return Sinh(z.MultipleI).DivideI;
}
public static ComplexDouble Cos(ComplexDouble z)
{
return Cosh(z.MultipleI);
}
public static ComplexDouble Tan(ComplexDouble z)
{
return Tanh(z.MultipleI).DivideI;
}
public static ComplexDouble Cot(ComplexDouble z)
{
return Coth(z.MultipleI).MultipleI;
}
public static ComplexDouble Sec(ComplexDouble z)
{
return Sech(z.MultipleI);
}
public static ComplexDouble Csc(ComplexDouble z)
{
return Csch(z.MultipleI).MultipleI;
}
public static ComplexDouble Sinh(ComplexDouble z)
{
return Sinh2(z)/2d;
}
public static ComplexDouble Sinh2(ComplexDouble z)
{
return (Exp(z) - Exp(-z));
}
public static ComplexDouble Cosh(ComplexDouble z)
{
return Cosh2(z)/2d;
}
public static ComplexDouble Cosh2(ComplexDouble z)
{
return (Exp(z) + Exp(-z));
}
public static ComplexDouble Tanh(ComplexDouble z)
{
return Sinh2(z)/Cosh2(z);
}
public static ComplexDouble Coth(ComplexDouble z)
{
return Cosh2(z)/Sinh2(z);
}
public static ComplexDouble Sech(ComplexDouble z)
{
return 2d/Cosh2(z);
}
public static ComplexDouble Csch(ComplexDouble z)
{
return 2d/Sinh2(z);
}
//
public static ComplexDouble Asin(ComplexDouble z, int kLog, int kSqrt)
{
return Asinh(z.MultipleI, kLog, kSqrt).DivideI;
}
public static ComplexDouble Acos(ComplexDouble z, int kLog, int kSqrt)
{
return Acosh(z, kLog, kSqrt).DivideI;
}
public static ComplexDouble Atan(ComplexDouble z, int kLog)
{
return Atanh(z.DivideI, kLog).MultipleI;
}
public static ComplexDouble Acot(ComplexDouble z, int kLog)
{
return Atan(1d/z, kLog);
}
public static ComplexDouble Asec(ComplexDouble z, int kLog, int kSqrt)
{
return Acos(1d/z, kLog, kSqrt);
}
public static ComplexDouble Acsc(ComplexDouble z, int kLog, int kSqrt)
{
return Asin(1d/z, kLog, kSqrt);
}
public static ComplexDouble Asinh(ComplexDouble z, int kLog, int kSqrt)
{
return Log(z + Sqrt(z*z + 1d, kSqrt), kLog);
}
public static ComplexDouble Acosh(ComplexDouble z, int kLog, int kSqrt)
{
return Log(z + Sqrt(z*z - 1d, kSqrt), kLog);
}
public static ComplexDouble Atanh(ComplexDouble z, int kLog)
{
return Log((1d + z)/(1d - z), kLog)/2d;
}
public static ComplexDouble Acoth(ComplexDouble z, int kLog)
{
return Atanh(1d/z, kLog);
}
public static ComplexDouble Asech(ComplexDouble z, int kLog, int kSqrt)
{
return Acosh(1d/z, kLog, kSqrt);
}
public static ComplexDouble Acsch(ComplexDouble z, int kLog, int kSqrt)
{
return Asinh(1d/z, kLog, kSqrt);
}
#endregion
//
#region Операторы
public static ComplexDouble operator ~(ComplexDouble z)
{
return new ComplexDouble(z.Re, -z.Im);
}
public static ComplexDouble operator !(ComplexDouble z)
{
return ~z;
}
public static ComplexDouble operator ++(ComplexDouble z)
{
return new ComplexDouble(++z.Re, z.Im);
}
public static ComplexDouble operator --(ComplexDouble z)
{
return new ComplexDouble(--z.Re, z.Im);
}
public static ComplexDouble operator +(ComplexDouble z)
{
return z;
}
public static ComplexDouble operator -(ComplexDouble z)
{
return new ComplexDouble(-z.Re, -z.Im);
}
public static ComplexDouble operator +(ComplexDouble z1, ComplexDouble z2)
{
return new ComplexDouble(z1.Re + z2.Re, z1.Im + z2.Im);
}
public static ComplexDouble operator -(ComplexDouble z1, ComplexDouble z2)
{
return z1 + -z2;
}
public static ComplexDouble operator *(ComplexDouble z1, ComplexDouble z2)
{
return new ComplexDouble(z1.Re*z2.Re - z1.Im*z2.Im, z1.Re*z2.Im + z1.Im*z2.Re);
}
public static ComplexDouble operator /(ComplexDouble z1, ComplexDouble z2)
{
return z1*~z2/z2.SqrAbs;
}
public static ComplexDouble operator %(ComplexDouble z1, ComplexDouble z2)
{
return new ComplexDouble(z1.Re%z2.Re, z1.Im%z2.Im);
}
public static ComplexDouble operator +(ComplexDouble z1, double d2)
{
return z1 + new ComplexDouble(d2, 0d);
}
public static ComplexDouble operator -(ComplexDouble z1, double d2)
{
return z1 + -d2;
}
public static ComplexDouble operator *(ComplexDouble z1, double d2)
{
return new ComplexDouble(z1.Re*d2, z1.Im*d2);
}
public static ComplexDouble operator %(ComplexDouble z1, double d2)
{
return z1%new ComplexDouble(d2, 0d);
}
public static ComplexDouble operator /(ComplexDouble z1, double d2)
{
return z1*(1d/d2);
}
public static ComplexDouble operator +(double d1, ComplexDouble z2)
{
return z2 + d1;
}
public static ComplexDouble operator -(double d1, ComplexDouble z2)
{
return -z2 + d1;
}
public static ComplexDouble operator *(double d1, ComplexDouble z2)
{
return z2*d1;
}
public static ComplexDouble operator /(double d1, ComplexDouble z2)
{
return new ComplexDouble(d1, 0d)/z2;
}
public static ComplexDouble operator %(double d1, ComplexDouble z2)
{
return new ComplexDouble(d1, 0d)%z2;
}
public static bool operator ==(ComplexDouble z1, ComplexDouble z2)
{
return z1.Equals(z2);
}
public static bool operator !=(ComplexDouble z1, ComplexDouble z2)
{
return !(z1 == z2);
}
public static implicit operator ComplexDouble(double d)
{
return new ComplexDouble(d, 0d);
}
public static explicit operator double(ComplexDouble z)
{
return z.Re;
}
#endregion
}
} |