Arithmetic/Complex: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|Java}}: Final isn't necessary...someone would probably want methods to change the numbers as well)
Line 197: Line 197:


=={{header|Fortran}}==
=={{header|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
REAL, PARAMETER :: PI = 3.141592653589793 ! The constant π
COMPLEX, PARAMETER :: I = (0.0, 1.0) ! the imaginary unit "i" (&sqrt;-1)
COMPLEX :: A = (5,3), B = (0.5, 6.0)
COMPLEX :: ABSUM, ABPROD, ANEG, AINV, ABDIFF, ABQUOT, ABPOW, ACONJ, ANORM, P2CART
REAL :: AREAL, AIMAG, RHO = 10, THETA = PI / 3.0
INTEGER, PARAMETER :: N = 50
INTEGER :: J
COMPLEX, DIMENSION(0:N-1) :: UNITCIRCLE
ABSUM = A + B
ABPROD = A * B
ANEG = -A
AINV = 1.0 / A

And, although you did not ask, here are demonstrations of some other common complex number operations
ABDIFF = A - B
ABQUOT = A / B
ABPOW = A ** B
AREAL = REAL(A) ! Real part
AIMAG = IMAG(A) ! Imaginary part
ACONJ = CONJG(A) ! Complex conjugate
ANORM = ABS(A) ! Complex norm (or "modulus" or "absolute value"), use CABS before Fortran 90
P2CART = RHO * EXP(I * THETA) ! Euler's polar complex notation to cartesian complex notation conversion,
! use CEXP before Fortran 90
! Creates an array of N evenly spaced points around the complex unit circle
! useful for FFT calculations, among other things
UNITCIRCLE = EXP(I * (/ 2*PI*J/N, J=0, N-1 /) )
END PROGRAM CDEMO


=={{header|Haskell}}==
=={{header|Haskell}}==

Revision as of 23:01, 5 April 2008

Task
Arithmetic/Complex
You are encouraged to solve this task according to the task description, using any language you may know.

A complex number is a number which can be written as "a + b*i" (sometimes shown as "b + a*i") where a and b are real numbers and i is the square root of -1. Typically, complex numbers are represented as a pair of real numbers called the "imaginary part" and "real part", where the imaginary part is the number to be multiplied by i.

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.

Ada

<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 Imaginary_Type is new Ada.Numerics.Generic_Complex_Types(Long_Float);
  use Imaginary_Type;
  package Imaginary_Io is new Ada.Text_Io.Complex_Io(Imaginary_Type);
  use Imaginary_Io;
  use Ada.Text_IO;
  
  A : Complex := Compose_From_Cartesian(Re => 1.0, Im => 1.0);
  B : Complex := Compose_From_Cartesian(Re => 3.14159, Im => 1.25);
  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;

end Complex_Operations; </ada>

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] <c>

  1. 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");

} </c>

Works with: C89

User-defined type: <c>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");

} </c>

C++

<cpp>

  1. 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;

} </cpp>

D

Complex number is a D built-in type. <d>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</d>

Forth

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.

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
     REAL, PARAMETER :: PI = 3.141592653589793 ! The constant π
     COMPLEX, PARAMETER :: I = (0.0, 1.0)      ! the imaginary unit "i" (&sqrt;-1)
     COMPLEX :: A = (5,3), B = (0.5, 6.0)
     COMPLEX :: ABSUM, ABPROD, ANEG, AINV, ABDIFF, ABQUOT, ABPOW, ACONJ, ANORM, P2CART
     REAL :: AREAL, AIMAG, RHO = 10, THETA = PI / 3.0
     INTEGER, PARAMETER :: N = 50
     INTEGER :: J
     COMPLEX, DIMENSION(0:N-1) :: UNITCIRCLE 
     
     ABSUM  = A + B
     ABPROD = A * B
     ANEG   = -A
     AINV   = 1.0 / A

And, although you did not ask, here are demonstrations of some other common complex number operations

     ABDIFF = A - B
     ABQUOT = A / B
     ABPOW  = A ** B
     AREAL = REAL(A)               ! Real part
     AIMAG = IMAG(A)               ! Imaginary part
     ACONJ = CONJG(A)              ! Complex conjugate
     ANORM = ABS(A)                ! Complex norm (or "modulus" or "absolute value"), use CABS before Fortran 90
     P2CART = RHO * EXP(I * THETA) ! Euler's polar complex notation to cartesian complex notation conversion,
                                   ! use CEXP before Fortran 90
     
     ! Creates an array of N evenly spaced points around the complex unit circle
     ! useful for FFT calculations, among other things
     UNITCIRCLE = EXP(I * (/ 2*PI*J/N, J=0, N-1 /) ) 
  END PROGRAM CDEMO

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)

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)

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

Java

<java>public class Complex{

  public double real;
  public 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));
  }

}</java>

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;