{@abstract(Complex Math Types, constants and routines<br>
  Based on EBK&NVS Pascal-Delphi Math Library: )
author: Nikolai V. Shokhirev )
author: Eugene B. Krissinel )
created: February 02, 1994)
last modified: February 02, 2003)
ŠNikolai V. Shokhirev, 2002-2003 

Januaty 2004: 
Incorporated some definitions, names and functions from Earl F. Glynn's 
ComplexMathlibrary unit (www.efg2.com/Lab/Mathematics/ComplexMath.htm)
They alre labeled "From EFG Unit" below.
NOTE: the type Complex differs from TComplex in EFG Unit}
unit uComplexType;

interface

uses
  uMatTypes, SysUtils;

type
  { complex number }
  Complex = record
              Re,Im: TFloat;
            end;

  {array [1.. ] of Complex - The dimension in declarations can be of any value}
  CVector   =  array [1..999] of Complex;
  { ^CVector }
  CVcPtr    =  ^CVector;
  { array [1.. ] of CVcPtr }
  CMatrix   =  array [1..999] of CVcPtr;
  { ^CMatrix }
  CMtPtr    =  ^CMatrix;

  TComplexfunction = function (const z: Complex): Complex; // From EFG Unit

  EComplexLnZero     = class(exception);  // From EFG Unit
  EComplexZerodivide = class(exception);  // From EFG Unit  
  EComplexinvalidop  = class(exception);  // From EFG Unit
  EComplexZerotoZero = class(exception);  // From EFG Unit

  { Complex 1D array memory allocation }
  procedure  GetCVectorMemory (var Vc: CVcPtr; N: integer );
  { Complex 1D array memory release }
  procedure  FreeCVectorMemory(var Vc: CVcPtr; N: integer );

  { Complex 2D array memory allocation }
  procedure  GetCMatrixMemory (var Mt: CMtPtr; M, N: integer );
  { Complex 2D array memory release }
  procedure  FreeCMatrixMemory(var Mt: CMtPtr; M, N: integer );

  { Conversion functions for Complex }

  { Basic Conversion functions for Complex }
  function ComplexToStr(const z: Complex): string;
  { Conversion: zero Im is not diaplayed }
  function CmplxToStr(const z: Complex; Width: TInt; Decimals: TInt): string;
  { Conversion: zero Im is diaplayed }
  function CmplxToStr0(const z: Complex; Width: TInt; Decimals: TInt): string;
  { Conversion }
  function StrToCmplx(const s: string): Complex;

  { Polar To Complex Conversion: (r, angle) -> (Re, Im) }
  function PolarToComplex(r, angle: TFloat): Complex;
  { Complex To Polar Conversion: (Re, Im) -> (r, angle) }
  procedure ComplexToPolar(const z: Complex; var r, angle: TFloat);

  { Basic functions for Complex Calculations }

  { result = max(|z1.re-z2.re|,|z1.im-z2.im|) }
  function Diff0(const z1, z2: Complex): TFloat;
  { abs(c1.Re-c2.Re) < eps And abs(c1.Im-c2.Im) < eps }
  function SameComplex(const c1, c2: Complex; eps: TFloat): boolean;
  { result = x + i*y}
  function cmplx(x: TFloat; y: TFloat = 0.0): Complex;
  { result = x + i*y - same as cmplx [From EFG Unit] }
  function Cset (x: TFloat; y: TFloat = 0.0): Complex;
  { result = sqrt(sqr(z.Re)+sqr(x.Im)) = |z|  }
  function Cabs (const z: Complex): TFloat;
  { max(abs(z.re),abs(z.im)) }
  function Cabs0(const z: Complex): TFloat;
  { result = abs(z.Re) + abs(z.Im)    }
  function Cabs1(const z: Complex): TFloat;
  { result = sqr(z.Re)+ sqr(z.Im) = |z|^2  }
  function Cabs2(const z: Complex): TFloat;
  { result = sqr(z.Re)+ sqr(z.Im) = |z|^2 same as Cabs2 [From EFG Unit] }
  function CAbsSqr (const z: Complex): TFloat;
  { result = -z }
  function Cneg(const z: Complex): Complex;
  { result = 1/z }
  function Cinv(const z: Complex): Complex;
  { result = z.Re -i*z.Im }
  function conjug(const z: Complex): Complex;
  { result = z.Re -i*z.Im same as conjug [From EFG Unit]}
  function Cconjugate(const z: Complex): Complex;
  { result = z.Re }
  function Re(const z: Complex): TFloat;
  { result = z.Im }
  function Im(const z: Complex): TFloat;
  { result = z/r r := Cabs (z) }
  function Cunit(const z: Complex; var r: TFloat): Complex;
  { result = z + w }
  function Cadd(const z: Complex;  w: Complex): Complex; overload;
  { result = z + x }
  function Cadd(const z: Complex;  x: TFloat): Complex; overload;
  { result = x + w }
  function Cadd(x: TFloat; const w: Complex): Complex; overload;
  { result = z - w }
  function Csub(const z, w: Complex): Complex; overload;
  { result = z - x }
  function Csub(const z: Complex;  x: TFloat): Complex; overload;
  { result = x - w }
  function Csub(x: TFloat; const w: Complex): Complex; overload;
  { result = z * w }
  function Cmul(const z, w: Complex): Complex; overload;
  { result = x * w }
  function Cmul(x: TFloat; const w: Complex): Complex; overload;
  { result = z * x }
  function Cmul(const z: Complex;  x: TFloat): Complex; overload;
  { result = z / w }
  function Cdiv(const z, w: Complex): Complex; overload;
  { result = x / w }
  function Cdiv(x: TFloat; const w: Complex): Complex; overload;
  { result = z / x }
  function Cdiv(const z: Complex;  x: TFloat): Complex; overload;
  { result = exp(v)  }
  function Cexp(const z: Complex): Complex;
  { result = exp(i*f)  }
  function CexpIm(f: TFloat): Complex;
  { result = sqrt(z), result.Re > 0 }
  function Csqrt(const z: Complex): Complex; overload;
  { result = sqrt(z), result.Re > 0 }
  function Csqrt(const x: TFloat): Complex; overload;
  // result = SQR(a)  [From EFG Unit]
  function CSqr  (const z: Complex): Complex;

  { result = sqrt(x) }
  //function Croot(x: TFloat): Complex;

  // -PI < theta <= PI     [From EFG Unit]
  function FixAngle (const theta: TFloat): TFloat;
  { complex natural log: result = ln(a)
    NOTE: principal value only [From EFG Unit] }
  function CLn (const z: Complex): Complex;

  { s := s + z }
  procedure Csum(var s: Complex; const z: Complex); overload;
  { s := s + x }
  procedure Csum(var s: Complex; x: TFloat); overload;

  { r1 <= re < r2, i1 <= im < i2 }
  function RndComplex(r1, r2, i1, i2: TFloat): Complex;

  { result = er(z) }
  function cer(const z: Complex): Complex;

const
  // cmplx(0.0, 0.0)
  Cmplx0: Complex = (Re: 0.0; Im: 0.0);
  // cmplx(1.0, 0.0)
  Cmplx1: Complex = (Re: 1.0; Im: 0.0);
  // cmplx(0.0, 1.0)
  CmplxIm1: Complex = (Re: 0.0; Im: 1.0);

  // cmplx(0.0, 0.0) [From EFG Unit]
  ComplexZero: Complex = (Re: 0.0; Im: 0.0);
  // cmplx(1.0, 0.0)  [From EFG Unit]
  ComplexOne: Complex = (Re: 1.0; Im: 0.0);
  // TwoPI = 2.0*PI;  [From EFG Unit]
  TwoPI = 6.283185307179586; // 6.283185307179586476925286766559;
  // HalfLn2PI = 0.5*(Ln(TwoPI));  [From EFG Unit]
  HalfLn2PI = 0.9189385332046727;  // 0.91893853320467274178032973640562


implementation

end.
Up \MatTypes