complex numbers

Fergus Henderson fjh at cs.mu.oz.au
Fri Jul 4 22:20:02 AEST 1997


Thomas Charles CONWAY, you wrote:
> 
> I have a complex number module you may wish to use:
> 	~conway/src/misc/complex.m

I had a look at that, and took a few things from it.
Since you've had a go at this before, perhaps you should
be the one to review my go at it.

Cheers,
	Fergus.

extras/complex_numbers/complex.m:
extras/complex_numbers/complex_float.m:
extras/complex_numbers/float_complex.m:
	New modules to support complex numbers.

extras/complex_numbers/imag.m:
extras/complex_numbers/imag_complex.m:
extras/complex_numbers/complex_imag.m:
extras/complex_numbers/imag_float.m:
extras/complex_numbers/float_imag.m:
	New modules to support imaginary numbers.

extras/complex_numbers/complex_test.m:
extras/complex_numbers/complex_test.exp:
	Tests cases for the above-mentioned new modules.

cvs diff: Diffing .
Index: complex.m
===================================================================
RCS file: complex.m
diff -N complex.m
--- /dev/null	Fri Jul  4 19:59:37 1997
+++ complex.m	Fri Jul  4 22:10:15 1997
@@ -0,0 +1,148 @@
+%---------------------------------------------------------------------------%
+% Copyright (C) 1997 University of Melbourne.
+% This file may only be copied under the terms of the GNU Library General
+% Public License - see the file COPYING.LIB in the Mercury distribution.
+%---------------------------------------------------------------------------%
+%
+% File: complex.m.
+% Main author: fjh.
+% Stability: medium.
+%
+% Complex numbers.
+%
+% Note that the overloaded versions of the binary operators that
+% provide mixed-type arithmetic are defined in other modules.
+%
+% See also:
+%	complex_float.m, float_complex.m
+%	imag.m, complex_imag.m, imag_complex.m
+%
+%---------------------------------------------------------------------------%
+
+:- module complex.
+:- interface.
+
+:- type complex ---> cmplx(float, float).	% real part, imag part
+
+% The constructor cmplx/2 is made public, but
+% generally it is most convenient to use the syntax `X + Y*i' for
+% complex numbers, where `i' is declared in module `imag'.
+% Due to the wonders of logic programming, this works fine for
+% both constructing and pattern matching; with intermodule optimization
+% enabled, the compiler should generate equally good code for it.
+
+	% extract real part
+:- func real(complex) = float.
+
+	% extract imaginary part
+:- func imag(complex) = float.
+
+	% absolute value (a.k.a. modulus)
+:- func abs(complex) = float.
+
+	% argument (a.k.a. phase, or amplitude, or angle)
+	% This function returns the principle value:
+	% for all Z, -pi < arg(Z) and arg(Z) =< pi.
+:- func arg(complex) = float.
+
+	% norm (square of absolute value)
+	% XXX is `norm' the right terminology?
+:- func norm(complex) = float.
+
+	% addition
+:- func complex + complex = complex.
+:- mode in  + in  = uo  is det.
+:- mode uo  + in  = in  is det.
+:- mode in  + uo  = in  is det.
+
+	% subtraction
+:- func complex - complex = complex.
+:- mode in  - in  = uo  is det.
+:- mode uo  - in  = in  is det.
+:- mode in  - uo  = in  is det.
+
+	% multiplication
+:- func complex * complex = complex.
+:- mode in  * in  = uo  is det.
+
+	% division
+:- func complex / complex = complex.
+:- mode in  / in  = uo  is det.
+
+	% unary plus
+:- func + complex = complex.
+:- mode + in    = uo  is det.
+
+	% unary minus
+:- func - complex = complex.
+:- mode - in    = uo  is det.
+
+	% sqr(X) = X * X.
+:- func sqr(complex) = complex.
+:- mode sqr(in) = out is det.
+
+	% square root
+:- func sqrt(complex) = complex.
+:- mode sqrt(in) = out is det.
+
+	% polar_to_complex(R, Theta):
+	% conversion from polar coordinates
+:- func polar_to_complex(float, float) = complex.
+:- mode polar_to_complex(in, in) = out is det.
+
+	% polar_to_complex(Z, R, Theta):
+	% conversion to polar coordinates
+:- pred complex_to_polar(complex, float, float).
+:- mode complex_to_polar(in, out, out) is det.
+
+%---------------------------------------------------------------------------%
+
+:- implementation.
+:- import_module float, math.
+
+real(cmplx(Real, _Imag)) = Real.
+imag(cmplx(_Real, Imag)) = Imag.
+
+cmplx(Xr, Xi) + cmplx(Yr, Yi) = cmplx(Xr + Yr, Xi + Yi).
+cmplx(Xr, Xi) - cmplx(Yr, Yi) = cmplx(Xr - Yr, Xi - Yi).
+cmplx(Xr, Xi) * cmplx(Yr, Yi) =
+		cmplx(Xr * Yr - Xi * Yi, Xr * Yi + Xi * Yr).
+cmplx(Xr, Xi) / cmplx(Yr, Yi) =
+		cmplx((Xr * Yr + Xi * Yi) / Div, (Xi * Yr - Xr * Yi) / Div) :-
+	Div = (Yr * Yr + Yi * Yi).
+% Here's the derivation of the formula for complex division:
+% cmplx(Xr, Xi) / cmplx(Yr, Yi) =
+%	(cmplx(Xr, Xi) / cmplx(Yr, Yi)) * 1.0 =
+%	(cmplx(Xr, Xi) / cmplx(Yr, Yi)) * (cmplx(Yr, -Yi) / cmplx(Yr, -Yi)) =
+%	(cmplx(Xr, Xi) * (cmplx(Yr, -Yi)) / (cmplx(Yr, Yi) * cmplx(Yr, -Yi)) =
+%	(cmplx(Xr, Xi) * (cmplx(Yr, -Yi)) / (Yr * Yr + Yi * Yi) =
+%	cmplx(Xr * Yr + Xi * Yi, Xi * Yr - Xr * Yi) / (Yr * Yr + Yi * Yi) =
+%	cmplx((Xr * Yr + Xi * Yi) / Div, (Xi * Yr - Xr * Yi) / Div) :-
+%		Div = (Yr * Yr + Yi * Yi).
+
++ cmplx(R, I) = cmplx(+ R, + I).
+- cmplx(R, I) = cmplx(- R, - I).
+
+norm(cmplx(R, I)) = R*R + I*I.
+
+abs(Z) = sqrt(norm(Z)).
+
+arg(cmplx(R, I)) = atan2(I, R).
+
+sqr(cmplx(Re0, Im0)) = cmplx(Re, Im) :-
+	Re = Re0 * Re0 - Im0 * Im0,
+	Im = 2.0 * Re0 * Im0.
+
+sqrt(Z0) = Z :-
+	complex_to_polar(Z0, Magnitude0, Theta0),
+	Magnitude = sqrt(Magnitude0),
+	Theta = Theta0 / 2.0,
+	Z = polar_to_complex(Magnitude, Theta).
+
+complex_to_polar(Z, abs(Z), arg(Z)).
+
+polar_to_complex(Magnitude, Theta) = cmplx(Real, Imag) :-
+	Real = Magnitude * cos(Theta),
+	Imag = Magnitude * sin(Theta).
+
+%------------------------------------------------------------------------------%
Index: complex_float.m
===================================================================
RCS file: complex_float.m
diff -N complex_float.m
--- /dev/null	Fri Jul  4 19:59:37 1997
+++ complex_float.m	Fri Jul  4 17:19:00 1997
@@ -0,0 +1,67 @@
+%---------------------------------------------------------------------------%
+% Copyright (C) 1997 University of Melbourne.
+% This file may only be copied under the terms of the GNU Library General
+% Public License - see the file COPYING.LIB in the Mercury distribution.
+%---------------------------------------------------------------------------%
+%
+% File: complex_float.m.
+% Main author: fjh.
+% Stability: medium.
+%
+% This module provides binary operators on (complex, float).
+%
+% See also:
+%	complex, float, complex_float.
+%
+%---------------------------------------------------------------------------%
+
+:- module complex_float.
+:- interface.
+:- import_module complex, float.
+
+	% addition
+:- func complex + float = complex.
+:- mode in   + in   = uo  is det.
+:- mode uo   + in   = in  is det.
+:- mode in   + uo   = in  is det.
+
+	% subtraction
+:- func complex - float = complex.
+:- mode in   - in   = uo  is det.
+:- mode uo   - in   = in  is det.
+:- mode in   - uo   = in  is det.
+
+	% multiplication
+:- func complex * float = complex.
+:- mode in   * in   = uo  is det.
+:- mode uo   * in   = in  is det.
+:- mode in   * uo   = in  is det.
+
+	% division
+:- func complex / float = complex.
+:- mode in   / in   = uo  is det.
+:- mode uo   / in   = in  is det.
+:- mode in   / uo   = in  is det.
+
+	% exponentiation
+:- func pow(complex, float) = complex.
+:- mode pow(in, in) = out is det.
+
+%---------------------------------------------------------------------------%
+
+:- implementation.
+:- import_module complex_float.
+
+cmplx(XR, XI) + YR = cmplx(XR + YR, XI).
+cmplx(XR, XI) - YR = cmplx(XR - YR, XI).
+cmplx(XR, XI) * YR = cmplx(XR * YR, XI * YR).
+cmplx(XR, XI) / YR = cmplx(XR / YR, XI / YR).
+
+pow(cmplx(Re0, Im0), P) = cmplx(Re, Im) :-
+	cartesian_to_polar(Re0, Im0, L0, Th0),
+	L = pow(L0, P),
+	Th = Th0 * P,
+	polar_to_cartesian(L, Th, Re, Im).
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
Index: complex_imag.m
===================================================================
RCS file: complex_imag.m
diff -N complex_imag.m
--- /dev/null	Fri Jul  4 19:59:37 1997
+++ complex_imag.m	Fri Jul  4 16:04:03 1997
@@ -0,0 +1,62 @@
+%---------------------------------------------------------------------------%
+% Copyright (C) 1997 University of Melbourne.
+% This file may only be copied under the terms of the GNU Library General
+% Public License - see the file COPYING.LIB in the Mercury distribution.
+%---------------------------------------------------------------------------%
+%
+% File: complex_imag.m.
+% Main author: fjh.
+% Stability: medium.
+%
+% This module provides binary operators on (complex, imag).
+%
+% See also:
+%	complex.m, imag.m, imag_complex.m.
+%
+%---------------------------------------------------------------------------%
+
+:- module complex_imag.
+:- interface.
+:- import_module complex, imag.
+
+	% addition
+:- func complex + imag = complex.
+:- mode in   + in   = uo  is det.
+:- mode uo   + in   = in  is det.
+:- mode in   + uo   = in  is semidet.
+
+	% subtraction
+:- func complex - imag = complex.
+:- mode in   - in   = uo  is det.
+:- mode uo   - in   = in  is det.
+:- mode in   - uo   = in  is semidet.
+
+	% multiplication
+:- func complex * imag = complex.
+:- mode in   * in   = uo  is det.
+:- mode uo   * in   = in  is det.
+:- mode in   * out   = in  is semidet.
+
+	% division
+:- func complex / imag = complex.
+:- mode in   / in   = uo  is det.
+:- mode uo   / in   = in  is det.
+:- mode in   / out   = in  is semidet.
+
+%---------------------------------------------------------------------------%
+
+:- implementation.
+:- import_module float.
+
+cmplx(XR, XI) + im(YI) = cmplx(0.0 + XR, XI + YI).
+cmplx(XR, XI) - im(YI) = cmplx(0.0 + XR, XI - YI).
+cmplx(XR, XI) * im(YI) = cmplx(0.0 - XI * YI, 0.0 + XR * YI).
+cmplx(XR, XI) / im(YI) = cmplx(0.0 + XI / YI, 0.0 - XR / YI).
+
+% Division of complex / imag formula obtained by simplifying this one:
+% cmplx(Xr, Xi) / cmplx(Yr, Yi) =
+%		cmplx((Xr * Yr + Xi * Yi) / Div, (Xi * Yr - Xr * Yi) / Div) :-
+%	Div = (Yr * Yr + Yi * Yi).
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
Index: complex_test.exp
===================================================================
RCS file: complex_test.exp
diff -N complex_test.exp
--- /dev/null	Fri Jul  4 19:59:37 1997
+++ complex_test.exp	Fri Jul  4 16:43:21 1997
@@ -0,0 +1,54 @@
+tests of (complex op complex)
+X = cmplx(3.00000000000000, 4.00000000000000)
+X + X = cmplx(6.00000000000000, 8.00000000000000)
+X - X = cmplx(0.00000000000000, 0.00000000000000)
+X * X = cmplx(-7.00000000000000, 24.0000000000000)
+X / X = cmplx(1.00000000000000, 0.00000000000000)
+Y = cmplx(-5.00000000000000, 6.00000000000000)
+Y + Y = cmplx(-10.0000000000000, 12.0000000000000)
+Y - Y = cmplx(0.00000000000000, 0.00000000000000)
+Y * Y = cmplx(-11.0000000000000, -60.0000000000000)
+Y / Y = cmplx(1.00000000000000, 0.00000000000000)
+X + Y = cmplx(-2.00000000000000, 10.0000000000000)
+X - Y = cmplx(8.00000000000000, -2.00000000000000)
+X * Y = cmplx(-39.0000000000000, -2.00000000000000)
+X / Y = cmplx(0.147540983606557, -0.622950819672131)
+
+tests of (imag op imag)
+Z = im(4.00000000000000)
+Z + Z = im(8.00000000000000)
+Z - Z = im(0.00000000000000)
+Z * Z = -16.0000000000000
+Z / Z = 1.00000000000000
+
+tests of (float op imag)
+5.0 + Z = cmplx(5.00000000000000, 4.00000000000000)
+5.0 - Z = cmplx(5.00000000000000, -4.00000000000000)
+5.0 * Z = im(20.0000000000000)
+5.0 / Z = im(-1.25000000000000)
+
+tests of (imag op float)
+Z + 5.0 = cmplx(5.00000000000000, 4.00000000000000)
+Z - 5.0 = cmplx(-5.00000000000000, 4.00000000000000)
+Z * 5.0 = im(20.0000000000000)
+Z / 5.0 = im(0.800000000000000)
+
+tests of (complex op imag)
+X + Z = cmplx(3.00000000000000, 8.00000000000000)
+X - Z = cmplx(3.00000000000000, 0.00000000000000)
+X * Z = cmplx(-16.0000000000000, 12.0000000000000)
+X / Z = cmplx(1.00000000000000, -0.750000000000000)
+Y + Z = cmplx(-5.00000000000000, 10.0000000000000)
+Y - Z = cmplx(-5.00000000000000, 2.00000000000000)
+Y * Z = cmplx(-24.0000000000000, -20.0000000000000)
+Y / Z = cmplx(1.50000000000000, 1.25000000000000)
+
+tests of (imag op complex)
+Z + X = cmplx(3.00000000000000, 8.00000000000000)
+Z - X = cmplx(-3.00000000000000, 0.00000000000000)
+Z * X = cmplx(-16.0000000000000, 12.0000000000000)
+Z / X = cmplx(0.640000000000000, 0.480000000000000)
+Z + Y = cmplx(-5.00000000000000, 10.0000000000000)
+Z - Y = cmplx(5.00000000000000, -2.00000000000000)
+Z * Y = cmplx(-24.0000000000000, -20.0000000000000)
+Z / Y = cmplx(0.393442622950820, -0.327868852459016)
Index: complex_test.m
===================================================================
RCS file: complex_test.m
diff -N complex_test.m
--- /dev/null	Fri Jul  4 19:59:37 1997
+++ complex_test.m	Fri Jul  4 16:36:28 1997
@@ -0,0 +1,76 @@
+% A test case for arithmetic on complex, imag, and float.
+
+:- module complex_test.
+:- interface.
+:- import_module io.
+
+:- pred main(state::di, state::uo) is det.
+
+:- implementation.
+:- import_module complex, float, imag.
+:- import_module complex_imag, imag_complex.
+:- import_module float_imag, imag_float.
+
+main -->
+	print("tests of (complex op complex)"), nl,
+	{ X = 3.0 + 4.0 * i},
+	print("X = "), print(X), nl,
+	print("X + X = "), print(X + X), nl,
+	print("X - X = "), print(X - X), nl,
+	print("X * X = "), print(X * X), nl,
+	print("X / X = "), print(X / X), nl,
+	{ Y = - 5.0 + 6.0 * i},
+	print("Y = "), print(Y), nl,
+	print("Y + Y = "), print(Y + Y), nl,
+	print("Y - Y = "), print(Y - Y), nl,
+	print("Y * Y = "), print(Y * Y), nl,
+	print("Y / Y = "), print(Y / Y), nl,
+	print("X + Y = "), print(X + Y), nl,
+	print("X - Y = "), print(X - Y), nl,
+	print("X * Y = "), print(X * Y), nl,
+	print("X / Y = "), print(X / Y), nl,
+	nl,
+
+	print("tests of (imag op imag)"), nl,
+	{ Z = 4.0 * i},
+	print("Z = "), print(Z), nl,
+	print("Z + Z = "), print(Z + Z), nl,
+	print("Z - Z = "), print(Z - Z), nl,
+	print("Z * Z = "), print(Z * Z), nl,
+	print("Z / Z = "), print(Z / Z), nl,
+	nl,
+
+	print("tests of (float op imag)"), nl,
+	print("5.0 + Z = "), print(5.0 + Z), nl,
+	print("5.0 - Z = "), print(5.0 - Z), nl,
+	print("5.0 * Z = "), print(5.0 * Z), nl,
+	print("5.0 / Z = "), print(5.0 / Z), nl,
+	nl,
+
+	print("tests of (imag op float)"), nl,
+	print("Z + 5.0 = "), print(Z + 5.0), nl,
+	print("Z - 5.0 = "), print(Z - 5.0), nl,
+	print("Z * 5.0 = "), print(Z * 5.0), nl,
+	print("Z / 5.0 = "), print(Z / 5.0), nl,
+	nl,
+
+	print("tests of (complex op imag)"), nl,
+	print("X + Z = "), print(X + Z), nl,
+	print("X - Z = "), print(X - Z), nl,
+	print("X * Z = "), print(X * Z), nl,
+	print("X / Z = "), print(X / Z), nl,
+	print("Y + Z = "), print(Y + Z), nl,
+	print("Y - Z = "), print(Y - Z), nl,
+	print("Y * Z = "), print(Y * Z), nl,
+	print("Y / Z = "), print(Y / Z), nl,
+	nl,
+
+	print("tests of (imag op complex)"), nl,
+	print("Z + X = "), print(Z + X), nl,
+	print("Z - X = "), print(Z - X), nl,
+	print("Z * X = "), print(Z * X), nl,
+	print("Z / X = "), print(Z / X), nl,
+	print("Z + Y = "), print(Z + Y), nl,
+	print("Z - Y = "), print(Z - Y), nl,
+	print("Z * Y = "), print(Z * Y), nl,
+	print("Z / Y = "), print(Z / Y), nl.
Index: float_complex.m
===================================================================
RCS file: float_complex.m
diff -N float_complex.m
--- /dev/null	Fri Jul  4 19:59:37 1997
+++ float_complex.m	Fri Jul  4 16:03:02 1997
@@ -0,0 +1,66 @@
+%---------------------------------------------------------------------------%
+% Copyright (C) 1997 University of Melbourne.
+% This file may only be copied under the terms of the GNU Library General
+% Public License - see the file COPYING.LIB in the Mercury distribution.
+%---------------------------------------------------------------------------%
+%
+% File: float_complex.m.
+% Main author: fjh.
+% Stability: medium.
+%
+% This module provides binary operators on (float, complex).
+%
+% See also:
+%	complex.m, float.m, complex_float.m.
+%
+%---------------------------------------------------------------------------%
+
+:- module float_complex.
+:- interface.
+:- import_module float, complex.
+
+	% addition
+:- func float + complex = complex.
+:- mode in   + in   = uo  is det.
+:- mode uo   + in   = in  is det.
+:- mode in   + uo   = in  is det.
+
+	% subtraction
+:- func float - complex = complex.
+:- mode in   - in   = uo  is det.
+:- mode uo   - in   = in  is det.
+:- mode in   - uo   = in  is det.
+
+	% multiplication
+:- func float * complex = complex.
+:- mode in   * in   = uo  is det.
+:- mode uo   * in   = in  is det.
+:- mode in   * uo   = in  is det.
+
+	% division
+:- func float / complex = complex.
+:- mode in   / in   = uo  is det.
+:- mode uo   / in   = in  is det.
+:- mode in   / uo   = in  is det.
+
+%---------------------------------------------------------------------------%
+
+:- implementation.
+:- import_module complex_float.
+
+XR + cmplx(YR, YI) = cmplx(XR + YR, + XI).
+XR - cmplx(YR, YI) = cmplx(XR - YR, - YI).
+XR * cmplx(YR, YI) = cmplx(XR * YR, XR * YI).
+XR / cmplx(YR, YI) = cmplx(XR * YR / Div, - XR * YI / Div) :-
+	Div = YR * YR + YI * YI.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+% Division of float / complex formula obtained by simplifying this one:
+% cmplx(Xr, Xi) / cmplx(Yr, Yi) =
+%		cmplx((Xr * Yr + Xi * Yi) / Div, (Xi * Yr - Xr * Yi) / Div) :-
+%	Div = (Yr * Yr + Yi * Yi).
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
Index: float_imag.m
===================================================================
RCS file: float_imag.m
diff -N float_imag.m
--- /dev/null	Fri Jul  4 19:59:37 1997
+++ float_imag.m	Fri Jul  4 16:09:50 1997
@@ -0,0 +1,54 @@
+%---------------------------------------------------------------------------%
+% Copyright (C) 1997 University of Melbourne.
+% This file may only be copied under the terms of the GNU Library General
+% Public License - see the file COPYING.LIB in the Mercury distribution.
+%---------------------------------------------------------------------------%
+%
+% File: float_imag.m.
+% Main author: fjh.
+% Stability: medium.
+%
+% This module provides binary operators on (float, imag).
+%
+% See also:
+%	complex.m, imag.m, float.m, imag_float.m.
+%
+%---------------------------------------------------------------------------%
+
+:- module float_imag.
+:- interface.
+:- import_module float, imag, complex.
+
+	% addition
+:- func float + imag = complex.
+:- mode in    + in   = uo  is det.
+:- mode uo    + uo   = in  is det.
+
+	% subtraction
+:- func float - imag = complex.
+:- mode in    - in   = uo  is det.
+:- mode uo    - uo   = in  is det.
+
+	% multiplication
+:- func float * imag = imag.
+:- mode in    * in   = uo  is det.
+:- mode in    * uo   = in  is det.
+:- mode uo    * in   = in  is det.
+
+	% division
+:- func float / imag = imag.
+:- mode in    / in   = uo  is det.
+:- mode in    / uo   = in  is det.
+:- mode uo    / in   = in  is det.
+
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+XR + im(YI) = cmplx(0.0 + XR, 0.0 + YI).
+XR - im(YI) = cmplx(0.0 + XR, 0.0 - YI).
+XR * im(YI) = im(XR * YI).
+XR / im(YI) = im(0.0 - XR / YI).
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
Index: imag.m
===================================================================
RCS file: imag.m
diff -N imag.m
--- /dev/null	Fri Jul  4 19:59:37 1997
+++ imag.m	Fri Jul  4 16:27:48 1997
@@ -0,0 +1,85 @@
+%---------------------------------------------------------------------------%
+% Copyright (C) 1997 University of Melbourne.
+% This file may only be copied under the terms of the GNU Library General
+% Public License - see the file COPYING.LIB in the Mercury distribution.
+%---------------------------------------------------------------------------%
+%
+% File: imag.m.
+% Main author: fjh.
+% Stability: medium.
+%
+% Imaginary numbers.
+%
+% There are several reasons for supporting a separate type for imaginary
+% numbers rather than just treating them as a special case of complex
+% numbers.  It is sometimes more convenient, and can be slightly more
+% efficient.   But perhaps the most important reason is to get correct
+% handling of infinity and not-a-number on platforms that support IEEE
+% floating point.
+%
+% Note that the overloaded versions of the binary operators which
+% provide mixed type arithmetic are defined in different modules.
+%
+% See also:
+%	float.m, imag_float.m, float_imag.m,
+%	complex.m, imag_complex.m, complex_imag.m.
+%
+%---------------------------------------------------------------------------%
+
+:- module imag.
+:- interface.
+:- import_module float.
+
+:- type imag ---> im(float).
+
+:- func i = imag.	% i = sqrt(-1)
+:- func j = imag.	% another name for `i'
+
+	% addition
+:- func imag + imag = imag.
+:- mode in   + in   = uo  is det.
+:- mode uo   + in   = in  is det.
+:- mode in   + uo   = in  is det.
+
+	% subtraction
+:- func imag - imag = imag.
+:- mode in   - in   = uo  is det.
+:- mode uo   - in   = in  is det.
+:- mode in   - uo   = in  is det.
+
+	% multiplication
+:- func imag * imag = float.
+:- mode in   * in   = uo  is det.
+:- mode uo   * in   = in  is det.
+:- mode in   * uo   = in  is det.
+
+	% division
+:- func imag / imag = float.
+:- mode in   / in   = uo  is det.
+:- mode uo   / in   = in  is det.
+:- mode in   / uo   = in  is det.
+
+	% unary plus
+:- func + imag = imag.
+:- mode + in   = uo  is det.
+
+	% unary minus
+:- func - imag = imag.
+:- mode - in   = uo  is det.
+
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+i = im(1.0).
+j = i.
+
++im(X) = im(X + 0.0).
+-im(X) = im(-X).
+im(X) + im(Y) = im(X + Y).
+im(X) - im(Y) = im(X - Y).
+im(X) * im(Y) = 0.0 - X * Y.
+im(X) / im(Y) = X / Y.
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
Index: imag_complex.m
===================================================================
RCS file: imag_complex.m
diff -N imag_complex.m
--- /dev/null	Fri Jul  4 19:59:37 1997
+++ imag_complex.m	Fri Jul  4 16:11:56 1997
@@ -0,0 +1,62 @@
+%---------------------------------------------------------------------------%
+% Copyright (C) 1997 University of Melbourne.
+% This file may only be copied under the terms of the GNU Library General
+% Public License - see the file COPYING.LIB in the Mercury distribution.
+%---------------------------------------------------------------------------%
+%
+% File: imag_complex.m.
+% Main author: fjh.
+% Stability: medium.
+%
+% This module provides binary operators on (imag, complex).
+%
+% See also:
+%	complex.m, imag.m, complex_imag.m.
+%
+%---------------------------------------------------------------------------%
+
+:- module imag_complex.
+:- interface.
+:- import_module imag, complex.
+
+	% addition
+:- func imag + complex = complex.
+:- mode in   + in   = uo  is det.
+:- mode uo   + in   = in  is semidet.
+:- mode in   + uo   = in  is det.
+
+	% subtraction
+:- func imag - complex = complex.
+:- mode in   - in   = uo  is det.
+:- mode uo   - in   = in  is semidet.
+:- mode in   - uo   = in  is det.
+
+	% multiplication
+:- func imag * complex = complex.
+:- mode in   * in   = uo  is det.
+
+	% division
+:- func imag / complex = complex.
+:- mode in   / in   = uo  is det.
+
+%---------------------------------------------------------------------------%
+
+:- implementation.
+:- import_module float.
+
+im(XI) + cmplx(YR, YI) = cmplx(0.0 + YR, XI + YI).
+im(XI) - cmplx(YR, YI) = cmplx(0.0 - YR, XI - YI).
+im(XI) * cmplx(YR, YI) = cmplx(-XI * YI, XI * YR).
+im(XI) / cmplx(YR, YI) = cmplx((XI * YI) / Div, (XI * YR) / Div) :-
+	Div = (YR * YR + YI * YI).
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+% Division of imag / complex formula obtained by simplifying this one:
+% cmplx(Xr, Xi) / cmplx(Yr, Yi) =
+%		cmplx((Xr * Yr + Xi * Yi) / Div, (Xi * Yr - Xr * Yi) / Div) :-
+%	Div = (Yr * Yr + Yi * Yi).
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
Index: imag_float.m
===================================================================
RCS file: imag_float.m
diff -N imag_float.m
--- /dev/null	Fri Jul  4 19:59:37 1997
+++ imag_float.m	Fri Jul  4 16:12:12 1997
@@ -0,0 +1,55 @@
+%---------------------------------------------------------------------------%
+% Copyright (C) 1997 University of Melbourne.
+% This file may only be copied under the terms of the GNU Library General
+% Public License - see the file COPYING.LIB in the Mercury distribution.
+%---------------------------------------------------------------------------%
+%
+% File: imag_float.m.
+% Main author: fjh.
+% Stability: medium.
+%
+% This module provides binary operators on (imag, float).
+%
+% See also:
+%	complex.m, imag.m, float_imag.m.
+%
+%---------------------------------------------------------------------------%
+
+:- module imag_float.
+:- interface.
+:- import_module imag, float, complex.
+
+	% addition
+:- func imag + float = complex.
+:- mode in   + in   = uo  is det.
+:- mode uo   + uo   = in  is det.
+
+	% subtraction
+:- func imag - float = complex.
+:- mode in   - in   = uo  is det.
+:- mode uo   - uo   = in  is det.
+
+	% multiplication
+:- func imag * float = imag.
+:- mode in   * in   = uo  is det.
+:- mode in   * uo   = in  is det.
+:- mode uo   * in   = in  is det.
+
+	% division
+:- func imag / float = imag.
+:- mode in   / in   = uo  is det.
+:- mode in   / uo   = in  is det.
+:- mode uo   / in   = in  is det.
+
+%---------------------------------------------------------------------------%
+
+:- implementation.
+:- import_module float.
+
+im(XI) + YR = cmplx(0.0 + YR, 0.0 + XI).
+im(XI) - YR = cmplx(0.0 - YR, 0.0 + XI).
+im(XI) * YR = im(XI * YR).
+im(XI) / YR = im(XI / YR).
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%

-- 
Fergus Henderson <fjh at cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3         |     -- the last words of T. S. Garp.



More information about the developers mailing list