Complex numbers
From Rosetta Code
Programming Task
This is a programming task. It lays out a problem which Rosetta Code users are encouraged to solve, using languages they know.
Show addition, multiplication, negation, and inversion of complex numbers in separate functions (subtraction and division operations can be made with pairs of these operations). Print the results for each operation tested.
Some languages have complex number libraries available. If your language does, show the operations. If your language does not, also show the definition of this type.
Contents |
[edit] Ada
with Ada.Numerics.Generic_Complex_Types; with Ada.Text_IO.Complex_IO; procedure Complex_Operations is -- Ada provides a pre-defined generic package for complex types -- That package contains definitions for composition, -- negation, addition, subtraction, multiplication, division, -- conjugation, exponentiation, and absolute value, as well as -- basic comparison operations. -- Ada provides a second pre-defined package for sin, cos, tan, cot, -- arcsin, arccos, arctan, arccot, and the hyperbolic versions of -- those trigonometric functions. -- The package Ada.Numerics.Generic_Complex_Types requires definition -- with the real type to be used in the complex type definition. package Complex_Types is new Ada.Numerics.Generic_Complex_Types (Long_Float); use Complex_Types; package Complex_IO is new Ada.Text_IO.Complex_IO (Complex_Types); use Complex_IO; use Ada.Text_IO; A : Complex := Compose_From_Cartesian (Re => 1.0, Im => 1.0); B : Complex := Compose_From_Polar (Modulus => 1.0, Argument => 3.14159); C : Complex; begin -- Addition C := A + B; Put("A + B = "); Put(C); New_Line; -- Multiplication C := A * B; Put("A * B = "); Put(C); New_Line; -- Inversion C := 1.0 / A; Put("1.0 / A = "); Put(C); New_Line; -- Negation C := -A; Put("-A = "); Put(C); New_Line; -- Conjugation C := Conjugate (C); end Complex_Operations;
[edit] ALGOL 68
main:(
FORMAT compl fmt = $g(-7,5)"⊥"g(-7,5)$;
PROC compl operations = VOID: (
LONG COMPL a = 1.0 ⊥ 1.0;
LONG COMPL b = 3.14159 ⊥ 1.2;
LONG COMPL c;
printf(($x"a="f(compl fmt)l$,a));
printf(($x"b="f(compl fmt)l$,b));
# addition #
c := a + b;
printf(($x"a+b="f(compl fmt)l$,c));
# multiplication #
c := a * b;
printf(($x"a*b="f(compl fmt)l$,c));
# inversion #
c := 1.0 / a;
printf(($x"1/c="f(compl fmt)l$,c));
# negation #
c := -a;
printf(($x"-a="f(compl fmt)l$,c))
);
compl operations
)
Output:
a=1.00000⊥1.00000 b=3.14159⊥1.20000 a+b=4.14159⊥2.20000 a*b=1.94159⊥4.34159 1/c=0.50000⊥-.50000 -a=-1.0000⊥-1.0000
[edit] C
Works with: C99
The more recent C99 standard has built-in complex number primitive types, which can be declared with float, double, or long double precision. To use these types and their associated library functions, you must include the <complex.h> header. (Note: this is a different header than the <complex> templates that are defined by C++.) [1] [2]
#include <complex.h> void cprint(double complex c) { printf("%lf%+lfI", creal(c), cimag(c)); } void complex_operations() { double complex a = 1.0 + 1.0I; double complex b = 3.14159 + 1.2I; double complex c; printf("\na="); cprint(a); printf("\nb="); cprint(b); // addition c = a + b; printf("\na+b="); cprint(c); // multiplication c = a * b; printf("\na*b="); cprint(c); // inversion c = 1.0 / a; printf("\n1/c="); cprint(c); // negation c = -a; printf("\n-a="); cprint(c); printf("\n"); }
Works with: C89
User-defined type:
typedef struct{ double real; double imag; } Complex; Complex add(Complex a, Complex b){ Complex ans; ans.real = a.real + b.real; ans.imag = a.imag + b.imag; return ans; } Complex mult(Complex a, Complex b){ Complex ans; ans.real = a.real * b.real - a.imag * b.imag; ans.imag = a.real * b.imag + a.imag * b.real; return ans; } Complex inv(Complex a){ Complex ans; double denom = a.real * a.real + a.imag * a.imag; ans.real = a.real / denom; ans.imag = -a.imag / denom; return ans; } Complex neg(Complex a){ Complex ans; ans.real = -a.real; ans.imag = -a.imag; return ans; } void put(Complex c) { printf("%lf%+lfI", c.real, c.imag); } void complex_ops(void) { Complex a = { 1.0, 1.0 }; Complex b = { 3.14159, 1.2 }; printf("\na="); put(a); printf("\nb="); put(b); printf("\na+b="); put(add(a,b)); printf("\na*b="); put(mult(a,b)); printf("\n1/a="); put(inv(a)); printf("\n-a="); put(neg(a)); printf("\n"); }
[edit] C++
#include <complex> using std::complex; void complex_operations() { complex<double> a(1.0, 1.0); complex<double> b(3.14159, 1.25); complex<double> c; // addition c = a + b; // multiplication c = a * b; // inversion c = 1.0 / a; // negation c = -a; }
[edit] Common Lisp
Complex numbers are a built-in numeric type in Common Lisp. The literal syntax for a complex number is #C(real imaginary). The components of a complex number may be integers, ratios, or floating-point. Arithmetic operations automatically return complex (or real) numbers when appropriate:
> (sqrt -1) #C(0.0 1.0)
> (expt #c(0 1) 2) -1
Here are some arithmetic operations on complex numbers:
> (+ #c(0 1) #c(1 0)) #C(1 1) > (* #c(1 1) 2) #C(2 2) > (* #c(1 1) #c(0 2)) #C(-2 2) > (- #c(1 1)) #C(-1 -1) > (/ #c(0 2)) #C(0 -1/2)
Complex numbers can be constructed from real and imaginary parts using the complex function, and taken apart using the realpart and imagpart functions.
> (complex 64 (/ 3 4)) #C(64 3/4)
> (realpart #c(5 5)) 5
> (imagpart (complex 0 pi)) 3.141592653589793d0
[edit] D
Complex number is a D built-in type.
auto x = 1F+1i ; // auto type to cfloat auto y = 3.14159+1.2i ; // cdouble creal z ; // addition z = x + y ; writefln(z) ; // => 4.14159+2.2i // multiplication z = x * y ; writefln(z) ; // => 1.94159+4.34159i // inversion z = 1.0 / x ; writefln(z) ; // => 0.5+-0.5i // negation z = -x ; writefln(z) ; // => -1+-1i
[edit] Forth
Library: Forth Scientific Library
There is no standard syntax or mechanism for complex numbers. The FSL provides several implementations suitable for different uses. This example uses the existing floating point stack, but other libraries define a separate complex stack and/or a fixed-point implementation suitable for microcontrollers and DSPs.
include complex.seq : ZNEGATE ( r i -- -r -i ) fswap fnegate fswap fnegate ; zvariable x zvariable y 1e 1e x z! pi 1.2e y z! x z@ y z@ z+ z. x z@ y z@ z* z. 1+0i x z@ z/ z. x z@ znegate z.
[edit] Fortran
In ANSI FORTRAN 66 or later, COMPLEX is a built-in data type with full access to intrinsic arithmetic operations. Putting each native operation in a function is horribly inefficient, so I will simply demonstrate the operations. This example shows usage for Fortran 90 or later:
program cdemo
complex :: a = (5,3), b = (0.5, 6.0) ! complex initializer
complex :: absum, abprod, aneg, ainv
absum = a + b
abprod = a * b
aneg = -a
ainv = 1.0 / a
end program cdemo
And, although you did not ask, here are demonstrations of some other common complex number operations
program cdemo2
complex :: a = (5,3), b = (0.5, 6) ! complex initializer
real, parameter :: pi = 3.141592653589793 ! The constant "pi"
complex, parameter :: i = (0, 1) ! the imaginary unit "i" (sqrt(-1))
complex :: abdiff, abquot, abpow, aconj, p2cart, newc
real :: areal, aimag, anorm, rho = 10, theta = pi / 3.0, x = 2.3, y = 3.0
integer, parameter :: n = 50
integer :: j
complex, dimension(0:n-1) :: unit_circle
abdiff = a - b
abquot = a / b
abpow = a ** b
areal = real(a) ! Real part
aimag = imag(a) ! Imaginary part
newc = cmplx(x,y) ! Creating a complex on the fly from two reals intrinsically
! (initializer only works in declarations)
newc = x + y*i ! Creating a complex on the fly from two reals arithmetically
anorm = abs(a) ! Complex norm (or "modulus" or "absolute value")
! (use CABS before Fortran 90)
aconj = conjg(a) ! Complex conjugate (same as real(a) - i*imag(a))
p2cart = rho * exp(i * theta) ! Euler's polar complex notation to cartesian complex notation
! conversion (use CEXP before Fortran 90)
! The following creates an array of N evenly spaced points around the complex unit circle
! useful for FFT calculations, among other things
unit_circle = exp(2*i*pi/n * (/ (j, j=0, n-1) /) )
end program cdemo2
[edit] Haskell
Complex numbers are parameterized in their base type, so you can have Complex Integer for the Gaussian Integers, Complex Float, Complex Double, etc. The operations are just the usual overloaded numeric operations.
import Data.Complex main = do let a = 1.0 :+ 2.0 -- complex number 1+2i let b = fromInteger 4 -- complex number 4+0i putStrLn $ "Add: " ++ show (a + b) putStrLn $ "Subtract: " ++ show (a - b) putStrLn $ "Multiply: " ++ show (a * b) putStrLn $ "Divide: " ++ show (a / b) putStrLn $ "Negate: " ++ show (-a) putStrLn $ "Inverse: " ++ show (recip a)
Output:
*Main> main Add: 5.0 :+ 2.0 Subtract: (-3.0) :+ 2.0 Multiply: 4.0 :+ 8.0 Divide: 0.25 :+ 0.5 Negate: (-1.0) :+ (-2.0) Inverse: 0.2 :+ (-0.4)
[edit] IDL
complex (and dcomplex for double-precision) is a built-in data type in IDL:
x=complex(1,1) y=complex(!pi,1.2) print,x+y ( 4.14159, 2.20000) print,x*y ( 1.94159, 4.34159) print,-x ( -1.00000, -1.00000) print,1/x ( 0.500000, -0.500000)
[edit] J
Complex numbers are a native numeric data type in J. Although the examples shown here are performed on scalars, all numeric operations naturally apply to arrays of complex numbers.
x=: 1j1 y=: 3.14159j1.2 x+y 4.14159j2.2 x*y 1.94159j4.34159 %x 0.5j_0.5 -x _1j_1
[edit] Java
public class Complex{ public final double real; public final double imag; public Complex(){this(0,0)}//default values to 0...force of habit public Complex(double r, double i){real = r; imag = i;} public Complex add(Complex b){ return new Complex(this.real + b.real, this.imag + b.imag); } public Complex mult(Complex b){ //FOIL of (a+bi)(c+di) with i*i = -1 return new Complex(this.real * b.real - this.imag * b.imag, this.real * b.imag + this.imag * b.real); } public Complex inv(){ //1/(a+bi) * (a-bi)/(a-bi) = 1/(a+bi) but it's more workable double denom = real * real + imag * imag; return new Complex(real/denom,-imag/denom); } public Complex neg(){ return new Complex(-real, -imag); } public String toString(){ //override Object's toString return real + " + " + imag + " * i"; } public static void main(String[] args){ Complex a = new Complex(Math.PI, -5) //just some numbers Complex b = new Complex(-1, 2.5); System.out.println(a.neg()); System.out.println(a.add(b)); System.out.println(a.inv()); System.out.println(a.mult(b)); } }
[edit] Maple
Maple has "I" (the square root of -1) built-in. Thus:
x := 1+I; y := Pi+I*1.2;
By itself, it will perform mathematical operations symbolically, i.e. it will not try to perform computational evaluation unless specifically asked to do so. Thus:
x*y;
==> (1 + I) (Pi + 1.2 I)
simplify(x*y);
==> 1.941592654 + 4.341592654 I
Other than that, the task merely asks for
x+y; x*y; -x; 1/x;
[edit] OCaml
The "Complex" module provides the functionality of complex numbers.
open Complex let print_complex z = Printf.printf "%f + %f i\n" z.re z.im let () = let a = { re = 1.0; im = 1.0 } and b = { re = 3.14159; im = 1.25 } in print_complex (add a b); print_complex (mul a b); print_complex (inv a); print_complex (neg a)
[edit] Perl
The Math::Complex module provides the functionality of complex numbers.
use Math::Complex; $a = 1 + 1*i; $b = 3.14159 + 1.25*i; $c = $a + $b; $c = $a * $b; $c = 1 / $a; $c = -$a;
[edit] Pop11
Complex numbers are a built-in data type in Pop11. Real and imaginary part of complex numbers can be floating point or exact (integer or rational) value (both part must be of the same type). Operations on floating point complex numbers always produce complex numbers. Operations on exact complex numbers give real result (integer or rational) if imaginary part of the result is 0. The '+:' and '-:' operators create complex numbers: '1 -: 3' is '1 - 3i' in mathematical notation.
lvars a = 1.0 +: 1.0, b = 2.0 +: 5.0 ; a+b => a*b => 1/a => a-b => a-a => a/b => a/a => ;;; The same, but using exact values 1 +: 1 -> a; 2 +: 5 -> b; a+b => a*b => 1/a => a-b => a-a => a/b => a/a =>
[edit] Python
a = 1 + 1j b = 3.14159 + 1.25j c = a + b c = a * b c = 1 / a c = -a
[edit] Scheme
(define a (make-rectangular 1 1)) (define b (make-rectangular 3.14159 1.25)) (define c (+ a b)) (define c (* a b)) (define c (/ 1 a)) (define c (- a))
Categories: Programming Tasks | Arithmetic operations | Ada | ALGOL 68 | C | C++ | Common Lisp | D | Forth | Forth Scientific Library | Fortran | Haskell | IDL | J | Java | Maple | OCaml | Perl | Pop11 | Python | Scheme

