5 ^super.newCopyArgs(real, imag);
8 + { arg aNumber, adverb;
9 if ( aNumber.isNumber, {
10 ^Complex.new(real + aNumber.real, imag + aNumber.imag)
12 ^aNumber.performBinaryOpOnComplex('+', this, adverb)
15 - { arg aNumber, adverb;
16 if ( aNumber.isNumber, {
17 ^Complex.new(real - aNumber.real, imag - aNumber.imag)
19 ^aNumber.performBinaryOpOnComplex('-', this, adverb)
22 * { arg aNumber, adverb;
23 if ( aNumber.isNumber, {
25 // these are implemented as additional message sends so that UGens can
26 // optimize the 6 operations down to 2 UGen instances.
27 (real * aNumber.real) - (imag * aNumber.imag),
28 (real * aNumber.imag) + (imag * aNumber.real)
31 ^aNumber.performBinaryOpOnComplex('*', this, adverb)
34 / { arg aNumber, adverb;
36 if ( aNumber.isNumber, {
39 denom = 1.0 / (yr * yr + (yi * yi));
41 ((real * yr) + (imag * yi)) * denom,
42 ((imag * yr) - (real * yi)) * denom)
44 ^aNumber.performBinaryOpOnComplex('/', this, adverb)
48 < { arg aNumber, adverb;
49 if ( aNumber.isNumber, {
52 ^aNumber.performBinaryOpOnComplex('<', this, adverb)
56 == { arg aNumber, adverb;
57 if ( aNumber.isNumber, {
58 ^real == aNumber.real and: { imag == aNumber.imag }
60 ^aNumber.performBinaryOpOnComplex('==', this, adverb)
64 ^real.hash bitXor: imag.hash
68 performBinaryOpOnSimpleNumber { arg aSelector, aNumber, adverb;
69 ^aNumber.asComplex.perform(aSelector, this, adverb)
71 performBinaryOpOnSignal { arg aSelector, aSignal, adverb;
72 ^aSignal.asComplex.perform(aSelector, this)
74 performBinaryOpOnComplex { arg aSelector, aNumber, adverb;
75 ^error("Math operation failed.\n")
77 performBinaryOpOnUGen { arg aSelector, aUGen, adverb;
78 ^aUGen.asComplex.perform(aSelector, this, adverb)
81 neg { ^Complex.new(real.neg, imag.neg) }
82 conjugate { ^Complex.new(real, imag.neg) }
84 squared { ^this * this }
85 cubed { ^this * this * this }
86 exp { ^exp(real) * Complex.new(cos(imag), sin(real)) }
88 pow { arg aNumber; // return(this ** aNumber)
91 // t=this, p=power, i=sqrt(-1)
93 // t ** p = exp(p*log(t)) = ... = r*exp(i*a)
95 var p_real, p_imag, t_mag, t_phase, t_maglog;
98 aNumber = aNumber.asComplex;
100 p_real = aNumber.real;
101 p_imag = aNumber.imag;
102 if(p_real == 0.0 and: { p_imag == 0 }) { ^Complex(1.0, 0.0) };
103 if(p_imag == 0.0 and: { imag == 0.0 } and: { real > 0.0 }) {
104 ^Complex(real ** p_real, 0.0)
107 t_mag = this.magnitude;
108 if(t_mag == 0.0) { ^Complex(0.0, 0.0) };
109 t_maglog = 0.5 * log(t_mag);
110 t_phase = this.phase;
112 mag = exp((p_real * t_maglog) - (p_imag * t_phase));
113 phase = (p_imag * t_maglog) + (p_real * t_phase);
115 ^Complex(mag * cos(phase), mag * sin(phase))
118 magnitude { ^hypot(real, imag) }
119 abs { ^hypot(real, imag) }
120 rho { ^hypot(real, imag) }
122 magnitudeApx { ^hypotApx(real, imag) }
124 angle { ^atan2(imag, real) }
125 phase { ^atan2(imag, real) }
126 theta { ^atan2(imag, real) }
128 coerce { arg aNumber; ^aNumber.asComplex }
129 round { arg aNumber = 1.0;
130 ^Complex(real.round(aNumber), imag.round(aNumber))
133 asInteger { ^real.asInteger }
134 asFloat { ^real.asFloat }
137 asPolar { ^Polar.new(this.rho, this.theta) }
138 asPoint { ^Point.new(this.real, this.imag) }
140 printOn { arg stream;
141 stream << "Complex( " << real << ", " << imag << " )";