
/* Complex numbers */

0 # Complex(_r,0) <-- r;
2 # Complex(Complex(_r1,_i1),_i2) <-- Complex(r1,i1+i2);
2 # Complex(_r1,Complex(_r2,_i2)) <-- Complex(r1-i2,r2);


/*Real parts */
110 # Re(Complex(_r,_i)) <-- r;
300 # Re(_x) <-- x;

/* Imaginary parts */
110 # Im(Complex(_r,_i)) <-- i;
300 # Im(_x) <-- 0;

/* All things you can request a real and imaginary part for are complex */
1 # IsComplex(x_IsNumber)     <-- True;
2 # IsComplex(Complex(_r,_i)) <-- True;
3 # IsComplex(_x)             <-- False;

IsNotComplex(x) := Not(IsComplex(x));
/* Addition */

110 # Complex(_r1,_i1) + Complex(_r2,_i2) <-- Complex(r1+r2,i1+i2);
300 # Complex(_r,_i) + x_IsConstant <-- Complex(r+x,i);
300 # x_IsConstant + Complex(_r,_i) <-- Complex(r+x,i);
 
110 # - Complex(_r,_i) <-- Complex(-r,-i);

300 # Complex(_r,_i) - x_IsConstant <-- Complex(r-x,i);
300 # x_IsConstant - Complex(_r,_i) <-- Complex((-r)+x,-i);
111 # Complex(_r1,_i1) - Complex(_r2,_i2) <-- Complex(r1-r2,i1-i2);

/* Multiplication */
110 # Complex(_r1,_i1) * Complex(_r2,_i2) <--
    Complex(r1*r2-i1*i2,r1*i2+r2*i1);
300 # Complex(_r,_i) * y_IsConstant <-- Complex(r*y,i*y);
300 # y_IsConstant * Complex(_r,_i) <-- Complex(r*y,i*y);

330 # Complex(_r,_i) * (y_IsConstant / _z) <-- (Complex(r*y,i*y))/z;
330 # (y_IsConstant / _z) * Complex(_r,_i) <-- (Complex(r*y,i*y))/z;


110 # x_IsConstant / Complex(_r,_i) <-- (x*Conjugate(Complex(r,i)))/(r^2+i^2);


300 # Complex(_r,_i) / y_IsConstant <-- Complex(r/y,i/y);

110 # (_x ^ Complex(_r,_i)) <-- Exp(Complex(r,i)*Ln(x));

110 # Sqrt(Complex(_r,_i)) <-- Exp(Ln(Complex(r,i))/2);
110 # (Complex(_r,_i) ^ x_IsRationalOrNumber)_(Not(IsInteger(x))) <-- Exp(x*Ln(Complex(r,i)));

120 # Complex(0,_i) ^ n_IsPositiveInteger <--
  If(IsOdd(n),
    Complex(0,If(IsZero(Mod(n-1,4)),1,-1)*i^n),
    If(IsZero(Mod(n,4)),1,-1)*i^n); 

121 # Complex(_r,_i) ^ n_IsPositiveInteger <-- 
[
  Local(rr,ii,count,sign);
  
  rr:=r^n;
  ii:=0;
  For(count:=1,count<=n,count:=count+2) [
    sign:=If(IsZero(Mod(count-1,4)),1,-1);
    ii:=ii+sign*Bin(n,count)*i^count*r^(n-count);
    If(count<n, 
      rr:=rr-sign*Bin(n,count+1)*i^(count+1)*r^(n-count-1));
  ];
  Complex(rr,ii);
];


Function("Conjugate",{a})
  Substitute(a,{{x},Type(x)="Complex"},{{x},Complex(x[1],-(x[2]))});

Function("Magnitude",{x}) [
	Sqrt(Re(x)^2 + Im(x)^2);
];

10 # Arg(Complex(Cos(_x),Sin(_x))) <-- x;
10 # Arg(x_IsZero) <-- Undefined;
15 # Arg(x_IsPositiveReal) <-- 0;
15 # Arg(x_IsNegativeReal) <-- Pi;
20 # Arg(Complex(r_IsZero,i_IsConstant)) <-- Sign(i)*Pi/2;
30 # Arg(Complex(r_IsPositiveReal,i_IsConstant)) <-- ArcTan(i/r);
40 # Arg(Complex(r_IsNegativeReal,i_IsPositiveReal)) <-- Pi+ArcTan(i/r);
50 # Arg(Complex(r_IsNegativeReal,i_IsNegativeReal)) <-- ArcTan(i/r)-Pi;

