1 /**
2 * Copyright: Copyright Auburn Sounds 2015-2016
3 * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
4 * Authors:   Guillaume Piolat
5 */
6 module dplug.core.complex;
7 
8 // Helpers to use builtin D language complex numbers.
9 
10 
11 template BuiltinComplex(T)
12 {
13     static if (is(T == float))
14         alias BuiltinComplex = cfloat;
15     else static if (is(T == double))
16         alias BuiltinComplex = cdouble;
17     else static if (is(T == real))
18         alias BuiltinComplex = creal;
19     else
20         static assert("This type doesn't match any builtin complex type");
21 }
22 
23 template BuiltinImaginary(T)
24 {
25     static if (is(T == float))
26         alias BuiltinComplex = ifloat;
27     else static if (is(T == double))
28         alias BuiltinComplex = idouble;
29     else static if (is(T == real))
30         alias BuiltinComplex = ireal;
31     else
32         static assert("This type doesn't match any builtin imaginary complex type");
33 }
34 
35 @safe pure nothrow @nogc:
36 
37 /// Returns: The argument (or phase) of `z`.
38 float arg(cfloat z)
39 {
40     import std.math : atan2;
41     return atan2(z.im, z.re);
42 }
43 
44 /// Returns: The argument (or phase) of `z`.
45 double arg(cdouble z)
46 {
47     import std.math : atan2;
48     return atan2(z.im, z.re);
49 }
50 
51 deprecated("Use the builtin complex syntax x + y * 1i instead") BuiltinComplex!T makeComplex(T)(T re, T im)
52 {
53     return re + im * 1i;
54 }
55 
56 /// Returns: The squared modulus of `z`.
57 float sqAbs(cfloat z)
58 {
59     return z.re*z.re + z.im*z.im;
60 }
61 
62 /// Returns: The squared modulus of `z`.
63 float sqAbs(cdouble z)
64 {
65     return z.re*z.re + z.im*z.im;
66 }
67 
68 /// Returns: Complex number from polar coordinates.
69 cfloat fromPolar(float modulus, float argument)
70 {
71     import std.math : sin, cos;
72     return (modulus*cos(argument)) + 1i * (modulus*sin(argument));
73 }
74 
75 /// Returns: Complex number from polar coordinates.
76 cdouble fromPolar(double modulus, double argument)
77 {
78     import std.math : sin, cos;
79     return (modulus*cos(argument)) + 1i * (modulus*sin(argument));
80 }