deferred class
	COMPLEX_NUMBER

feature -- Primitive

	a,
	real: like real_anchor
			-- Real part of current complex number
		deferred
		end

	b,
	imaginary: like real_anchor
			-- Imaginary part of current complex number
		deferred
		end

feature -- Access

	zero: like integer_anchor
			-- The natural number 0
		deferred
		ensure
			value: Result.value = 0
		end

feature -- Operation

	conjugate: like complex_anchor
			-- Complex number in the form `a' - `b'i
		deferred
		ensure
			real: Result.a ≍ a
			imaginary: Result.b ≍ - b
		end

	identity alias "+": like Current
			-- Unary plus; this number itself.
		do
			Result := Current
		ensure
			real: Result.a ≍ a
			imaginary: Result.b ≍ b
		end

	product alias "*" alias "×" (z: COMPLEX_NUMBER): like complex_anchor
			-- Current complex number multiplied by `z`
		deferred
		ensure
			real: Result.a.value = Result.a.normalized_value (product_real (a.value, b.value, z.a.value, z.b.value))
			imaginary: Result.b.value = Result.b.normalized_value (product_imaginary (a.value, b.value, z.a.value, z.b.value))
		end

feature -- Math

	product_real (x, y, u, v: REAL): REAL
			-- Real part of the product (``x'+`y'i)(`u'+`v'i)
		external
			"C inline use <complex.h>"
		alias
			"{
				float complex z1 = $x + $y*I;
				float complex z2 = $u + $v*I;
				return crealf (z1 * z2)
				}"
		ensure
			class
		end

	product_imaginary (x, y, u, v: REAL): REAL
			-- Imaginary part of the product (``x'+`y'i)(`u'+`v'i)
		external
			"C inline use <complex.h>"
		alias
			"{
				float complex z1 = $x + $y*I;
				float complex z2 = $u + $v*I;
				return cimagf (z1 * z2)
				}"
		ensure
			class
		end

feature -- Anchor

	complex_anchor: COMPLEX_NUMBER
			-- Anchor for complex numbers
		do
			Result := Current
		end

	real_anchor: REAL_NUMBER
			-- Anchor for real numbers
		do
			Result := a
		end

	integer_anchor: INTEGER_NUMBER
			-- Anchor for integer numbers
		deferred
		end

invariant
	real: real ≍ a
	imaginary: imaginary ≍ b

end
