Category : C++ Source Code
Archive   : ZPP10.ZIP
Filename : COMPLEX.CPP

 
Output of file : COMPLEX.CPP contained in archive : ZPP10.ZIP
/* -------------------------------------------------------------------- */
/* complex.cpp */
/* */
/* Z++ Version 1.0 Last revised 04/03/92 */
/* */
/* Complex number class for Turbo C++/Borland C++. */
/* Copyright 1992 by Carl W. Moreland */
/* This source code may be freely distributed as long as the copyright */
/* notice remains intact. */
/* -------------------------------------------------------------------- */

#include "complex.h"

unsigned char complex::zArgMode = Z_RADIANS;
unsigned char complex::zPrintMode = Z_COMMA;
unsigned char complex::zLetter = 'i';

/* ----- Constructors ------------------------------------------------- */

complex::complex(void)
{
re = 0;
im = 0;
}

complex::complex(const double real, const double imag)
{
re = real;
im = imag;
}

complex::complex(const complex& z)
{
re = z.re;
im = z.im;
}

/* -------------------------------------------------------------------- */

double re(const complex& z) // friend version
{
return z.re;
}

double im(const complex& z) // friend version
{
return z.im;
}

double real(const complex& z) // friend version
{
return z.re;
}

double imag(const complex& z) // friend version
{
return z.im;
}

double mag(const complex& z) // magnitude |z|
{
return sqrt(z.re*z.re + z.im*z.im);
}

double arg(const complex& z) // argument (angle)
{
if(z.re == 0 && z.im == 0) // this is actually a domain error
return 0;
if(complex::zArgMode == Z_RADIANS)
return atan2(z.im, z.re);
return atan2(z.im, z.re)/M_PI*180;
}

complex conj(const complex& z) // complex conjugate
{
return complex(z.re, -z.im);
}

double norm(const complex& z)
{
return z.re*z.re + z.im*z.im;
}

complex ptor(double mag, double angle) // polar-to-rectangular
{
if(complex::zArgMode == Z_RADIANS)
return complex(mag*cos(angle), mag*sin(angle));
return complex(mag*cos(angle/180*M_PI), mag*sin(angle/180*M_PI));
}

complex rtop(double x, double y) // rectangular-to-polar
{
if(x == 0 && y == 0) // this is actually a domain error
return Z0;
if(complex::zArgMode == Z_RADIANS)
return complex(sqrt(x*x + y*y), atan2(y, x));
return complex(sqrt(x*x + y*y), atan2(y, x)*180/M_PI);
}

complex& complex::topolar(void)
{
double re_tmp = re;

if(re != 0 || im != 0) // z = (0,0) is a domain error
{
re = sqrt(re*re + im*im);
im = atan2(im, re_tmp);
}

if(complex::zArgMode == Z_DEGREES)
im *= (180/M_PI);

return *this;
}

complex& complex::torect(void)
{
double re_tmp = re;

re = re_tmp*cos(im);
im = re_tmp*sin(im);

return *this;
}

/* ----- Operators ---------------------------------------------------- */

void complex::operator=(const complex& z)
{
re = z.re;
im = z.im;
}

complex& complex::operator+=(const complex& z)
{
re += z.re;
im += z.im;
return *this;
}

complex& complex::operator-=(const complex& z)
{
re -= z.re;
im -= z.im;
return *this;
}

complex& complex::operator*=(const complex& z)
{
*this = *this * z;
return *this;
}

complex& complex::operator/=(const complex& z)
{
*this = *this / z;
return *this;
}

complex complex::operator+() const
{
return *this;
}

complex complex::operator-() const
{
return complex(-re, -im);
}

complex operator+(const complex& z1, const complex& z2)
{
return complex(z1.re + z2.re, z1.im + z2.im);
}

complex operator+(const complex& z, const double x)
{
return complex(z.re+x, z.im);
}

complex operator+(const double x, const complex& z)
{
return complex(z.re+x, z.im);
}

complex operator-(const complex& z1, const complex& z2)
{
return complex(z1.re - z2.re, z1.im - z2.im);
}

complex operator-(const complex& z, const double x)
{
return complex(z.re-x, z.im);
}

complex operator-(const double x, const complex& z)
{
return complex(x-z.re, -z.im);
}

complex operator*(const complex& z1, const complex& z2)
{
double re = z1.re*z2.re - z1.im*z2.im;
double im = z1.re*z2.im + z1.im*z2.re;
return complex(re, im);
}

complex operator*(const complex& z, const double x)
{
return complex(z.re*x, z.im*x);
}

complex operator*(const double x, const complex& z)
{
return complex(z.re*x, z.im*x);
}

complex operator/(const complex& z1, const complex& z2)
{
if(z2 == Z0)
return complex(Zinf); // z2 = Z0 is an error!

double denom = z2.re*z2.re + z2.im*z2.im;
double re = (z1.re*z2.re + z1.im*z2.im)/denom;
double im = (z2.re*z1.im - z2.im*z1.re)/denom;
return complex(re, im);
}

complex operator/(const complex& z, const double x)
{
return complex(z.re/x, z.im/x);
}

complex operator/(const double x, const complex& z)
{
if(z == Z0)
return complex(Zinf); // z = Z0 is an error!

double denom = z.re*z.re + z.im*z.im;
return complex(x*z.re/denom, -z.im*x/denom);
}

complex operator^(const complex& z1, const complex& z2)
{
return pow(z1, z2);
}

int operator==(const complex& z1, const complex& z2)
{
return (z1.re == z2.re) && (z1.im == z2.im);
}

int operator!=(const complex& z1, const complex& z2)
{
return (z1.re != z2.re) || (z1.im != z2.im);
}

/* ----- Math functions ----------------------------------------------- */

double abs(const complex& z)
{
return sqrt(z.re*z.re + z.im*z.im);
}

complex sqrt(const complex& z)
{
return ptor(sqrt(abs(z)), arg(z)/2);
}

complex pow(const complex& base, const double exponent)
{
if(base != Z0 && exponent == 0.0)
return complex(1,0);

if (base == Z0 && exponent > 0)
return Z0;

// base == Z0 && exponent == 0 is undefined!

return ptor(pow(abs(base), exponent), exponent*arg(base));
}

complex pow(const double base, const complex& exponent)
{
if(base != 0.0 && exponent == Z0)
return complex(1,0);

if (base == 0 && re(exponent) > 0)
return complex(0,0);

// base == 0 && re(exponent) == 0 is undefined!

if(base > 0.0)
return exp(exponent * log(fabs(base)));

return exp(exponent * complex(log(fabs(base)), M_PI));
}

complex pow(const complex& base, const complex& exponent)
{
if(base != Z0 && exponent == Z0)
return complex(1,0);

if(base == Z0 && re(exponent) > 0)
return complex(0,0);

// base == Z0 && re(exponent) == 0 is undefined!

return exp(exponent * log(base));
}

/* ----- Trig functions ----------------------------------------------- */

complex exp(const complex& z)
{
double mag = exp(z.re);
return complex(mag*cos(z.im), mag*sin(z.im));
}

complex log(const complex& z)
{
return complex(log(mag(z)), atan2(z.im, z.re));
}

complex log10(const complex& z)
{
return log(z) * M_LOG10E;
}

complex sin(const complex& z)
{
return (exp(Zi*z) - exp(-Zi*z))/(2*Zi);
}

complex cos(const complex& z)
{
return (exp(Zi*z) + exp(-Zi*z))/2;
}

complex tan(const complex& z)
{
return sin(z)/cos(z);
}

complex asin(const complex& z)
{
return -Zi*log(Zi*z+sqrt(1-z*z));
}

complex acos(const complex& z)
{
return -Zi*log(z+Zi*sqrt(1-z*z));
}

complex atan(const complex& z)
{
return -0.5*Zi * log((1+Zi*z)/(1-Zi*z));
}

complex sinh(const complex& z)
{
return (exp(z) - exp(-z))/2;
}

complex cosh(const complex& z)
{
return (exp(z) + exp(-z))/2;
}

complex tanh(const complex& z)
{
return sinh(z)/cosh(z);
}

/* ----- Misc functions ----------------------------------------------- */

void complex::SetArgMode(unsigned char mode) const
{
if(mode == Z_RADIANS || mode == Z_DEGREES)
zArgMode = mode;
}

void complex::SetPrintMode(unsigned char mode) const
{
if(mode == Z_COMMA || mode == Z_LETTER)
zPrintMode = mode;
}

void complex::SetLetter(unsigned char letter) const
{
zLetter = letter;
}

/* ----- Stream I/O --------------------------------------------------- */

ostream& operator<<(ostream& s, const complex& z)
{
char sign[] = " ";

if(complex::zPrintMode == Z_COMMA)
return s << "(" << z.re << ", " << z.im << ")";

if(z.im == 0 || z.im/fabs(z.im) == 1)
sign[1] = '+';
else
sign[1] = '-';
return s << z.re << sign << complex::zLetter << fabs(z.im);

}

istream& operator>>(istream& s, complex& z)
{
char ch;
double real=0, imag=0;

s >> ch;
if(ch == '(')
{
s >> real >> ch;
if(ch == ',')
s >> imag >> ch;
if(ch != ')')
s.clear(ios::badbit | s.rdstate());
}
else
{
s.putback(ch);
s >> real;
}

z = complex(real, imag);
return s;
}



  3 Responses to “Category : C++ Source Code
Archive   : ZPP10.ZIP
Filename : COMPLEX.CPP

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/