' Complex numbers: add, multiply, magnitude, conjugate, polar, sqrt
#COMPILE EXE
#DIM ALL

TYPE Complex
    real AS DOUBLE
    imag AS DOUBLE
END TYPE

FUNCTION CplxMake(BYVAL r AS DOUBLE, BYVAL i AS DOUBLE) AS Complex
    LOCAL c AS Complex
    c.real = r
    c.imag = i
    FUNCTION = c
END FUNCTION

FUNCTION CplxAdd(BYVAL a AS DOUBLE, BYVAL b AS DOUBLE, BYVAL c AS DOUBLE, BYVAL d AS DOUBLE) AS Complex
    LOCAL r AS Complex
    r.real = a + c
    r.imag = b + d
    FUNCTION = r
END FUNCTION

FUNCTION CplxSub(BYVAL a AS DOUBLE, BYVAL b AS DOUBLE, BYVAL c AS DOUBLE, BYVAL d AS DOUBLE) AS Complex
    LOCAL r AS Complex
    r.real = a - c
    r.imag = b - d
    FUNCTION = r
END FUNCTION

FUNCTION CplxMul(BYVAL a AS DOUBLE, BYVAL b AS DOUBLE, BYVAL c AS DOUBLE, BYVAL d AS DOUBLE) AS Complex
    LOCAL r AS Complex
    r.real = a * c - b * d
    r.imag = a * d + b * c
    FUNCTION = r
END FUNCTION

FUNCTION CplxMagnitude(BYVAL r AS DOUBLE, BYVAL i AS DOUBLE) AS DOUBLE
    FUNCTION = SQR(r * r + i * i)
END FUNCTION

FUNCTION CplxConjugate(BYVAL r AS DOUBLE, BYVAL i AS DOUBLE) AS Complex
    LOCAL c AS Complex
    c.real = r
    c.imag = -i
    FUNCTION = c
END FUNCTION

FUNCTION CplxFromPolar(BYVAL r AS DOUBLE, BYVAL theta AS DOUBLE) AS Complex
    LOCAL c AS Complex
    c.real = r * COS(theta)
    c.imag = r * SIN(theta)
    FUNCTION = c
END FUNCTION

SUB PrintComplex(BYVAL r AS DOUBLE, BYVAL i AS DOUBLE, BYVAL label AS STRING)
    PRINT label + " = " + FORMAT$(r, "#0.000")
    IF i >= 0 THEN PRINT " + " + FORMAT$(i, "#0.000") + "i" ELSE PRINT " " + FORMAT$(i, "#0.000") + "i"
END SUB

FUNCTION PBMAIN() AS LONG
    LOCAL a  AS Complex
    LOCAL b  AS Complex
    LOCAL c AS Complex
    PRINT "=== Complex Numbers ==="
    PRINT
    a = CplxMake(3.0, 4.0)
    b = CplxMake(1.0, -2.0)
    CALL PrintComplex(a.real, a.imag, "a")
    CALL PrintComplex(b.real, b.imag, "b")
    PRINT
    c = CplxAdd(a.real, a.imag, b.real, b.imag)
    CALL PrintComplex(c.real, c.imag, "a + b")
    c = CplxSub(a.real, a.imag, b.real, b.imag)
    CALL PrintComplex(c.real, c.imag, "a - b")
    c = CplxMul(a.real, a.imag, b.real, b.imag)
    CALL PrintComplex(c.real, c.imag, "a * b")
    PRINT
    PRINT "|a| = " + FORMAT$(CplxMagnitude(a.real, a.imag), "#0.000")
    c = CplxConjugate(a.real, a.imag)
    CALL PrintComplex(c.real, c.imag, "conj(a)")
    PRINT
    c = CplxFromPolar(1.0, 3.1415926535)
    CALL PrintComplex(c.real, c.imag, "polar(1, pi)")
    PRINT
    PRINT "Complex number tests complete."
    FUNCTION = 0
END FUNCTION
