
/* 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);
111 # Complex(_r,_i) + _x <-- Complex(r+x,i);
111 # _x + Complex(_r,_i) <-- Complex(r+x,i);

110 # - Complex(_r,_i) <-- Complex(-r,-i);

110 # Complex(_r,_i) - x_IsNotComplex <-- Complex(r-x,i);
110 # x_IsNotComplex - 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);
111 # Complex(_r,_i) * _y <-- Complex(r*y,i*y);
111 # _y * Complex(_r,_i) <-- Complex(r*y,i*y);

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

110 # _x / Complex(_r,_i) <-- (x*Conjugate(Complex(r,i)))/(y*Conjugate(Complex(r,i)));
111 # Complex(_r,_i) / _y <-- Complex(r/y,i/y);

110 # x_IsComplex ^ n_IsPositiveInteger <-- x*(x^(n-1));

/*TODO
Rule("^",2,110 , IsComplex(aLeft) And IsComplex(aRight)) Exp(aRight*Ln(aLeft));
*/

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


