next up previous contents
Next: The Definition File mycomplex.c: Up: The Complex Class: MYCOMPLEX Previous: The Complex Class: MYCOMPLEX

The MYCOMPLEX header: mycomplex.h:

Now the full header file is presented below: much of it is standard by now, but there are some issues that we need to discuss more fully.

#ifndef Complex_h
#define Complex_h
#include <sys/types.h>
#include <sys/stat.h>
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

class MYCOMPLEX{
    friend istream& operator>>(istream&,MYCOMPLEX&);
    friend istream& operator>>(istream&,MYCOMPLEX*);
    friend ostream& operator<<(ostream&,const MYCOMPLEX&);
    friend ostream& operator<<(ostream&,const MYCOMPLEX*);
    friend double modulus(const MYCOMPLEX& w);
    friend double arg(const MYCOMPLEX& w);
    friend MYCOMPLEX cexp(const MYCOMPLEX& w);
    friend MYCOMPLEX epsilon(); 
    friend MYCOMPLEX ZERO();
    friend MYCOMPLEX ID();
    friend MYCOMPLEX IMAGINARY();
    friend MYCOMPLEX* unity(int n);
  public:
    MYCOMPLEX(double r = 0,double i = 0);
    MYCOMPLEX(const MYCOMPLEX& w);
    MYCOMPLEX operator*(const MYCOMPLEX& w);
    //
    friend MYCOMPLEX operator*(const int& i,const MYCOMPLEX& w);
    friend MYCOMPLEX operator*(const float& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator*(const double& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator*(const MYCOMPLEX& w,const int& i);
    friend MYCOMPLEX operator*(const MYCOMPLEX& w,const float& x);
    friend MYCOMPLEX operator*(const MYCOMPLEX& w,const double& x);    
    //
    MYCOMPLEX& operator*=(const MYCOMPLEX& w);
    friend MYCOMPLEX operator*=(int& i,const MYCOMPLEX& w);
    friend MYCOMPLEX operator*=(float& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator*=(double& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator*=(MYCOMPLEX& w,const int& i);
    friend MYCOMPLEX operator*=(MYCOMPLEX& w,const float& x);
    friend MYCOMPLEX operator*=(MYCOMPLEX& w,const double& x);
    //
    MYCOMPLEX operator/(const MYCOMPLEX& w);
    friend MYCOMPLEX operator/(const int& i,const MYCOMPLEX& w);
    friend MYCOMPLEX operator/(const float& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator/(const double& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator/(const MYCOMPLEX& w,const int& i);
    friend MYCOMPLEX operator/(const MYCOMPLEX& w,const float& x);
    friend MYCOMPLEX operator/(const MYCOMPLEX& w,const double& x);    
    //               
    MYCOMPLEX& operator/=(const MYCOMPLEX& w);
    friend MYCOMPLEX operator/=(int& i,const MYCOMPLEX& w);
    friend MYCOMPLEX operator/=(float& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator/=(double& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator/=(MYCOMPLEX& w,const int& i);
    friend MYCOMPLEX operator/=(MYCOMPLEX& w,const float& x);
    friend MYCOMPLEX operator/=(MYCOMPLEX& w,const double& x);    
    //          
    MYCOMPLEX operator+(const MYCOMPLEX& w);
    friend MYCOMPLEX operator+(const int& i,const MYCOMPLEX& w);
    friend MYCOMPLEX operator+(const float& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator+(const double& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator+(const MYCOMPLEX& w,const int& i);
    friend MYCOMPLEX operator+(const MYCOMPLEX& w,const float& x);
    friend MYCOMPLEX operator+(const MYCOMPLEX& w,const double& x);    
    //
    MYCOMPLEX& operator+=(const MYCOMPLEX& w);
    friend MYCOMPLEX operator+=(int& i,const MYCOMPLEX& w);
    friend MYCOMPLEX operator+=(float& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator+=(double& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator+=(MYCOMPLEX& w,const int& i);
    friend MYCOMPLEX operator+=(MYCOMPLEX& w,const float& x);
    friend MYCOMPLEX operator+=(MYCOMPLEX& w,const double& x);
    //
    MYCOMPLEX operator-(const MYCOMPLEX& w);
    friend MYCOMPLEX operator-(const int& i,const MYCOMPLEX& w);
    friend MYCOMPLEX operator-(const float& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator-(const double& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator-(const MYCOMPLEX& w,const int& i);
    friend MYCOMPLEX operator-(const MYCOMPLEX& w,const float& x);
    friend MYCOMPLEX operator-(const MYCOMPLEX& w,const double& x);    
    //
    MYCOMPLEX& operator-=(const MYCOMPLEX& w);
    friend MYCOMPLEX operator-=(int& i,const MYCOMPLEX& w);
    friend MYCOMPLEX operator-=(float& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator-=(double& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator-=(MYCOMPLEX& w,const int& i);
    friend MYCOMPLEX operator-=(MYCOMPLEX& w,const float& x);
    friend MYCOMPLEX operator-=(MYCOMPLEX& w,const double& x);
    //
    MYCOMPLEX& operator=(const MYCOMPLEX& w);   
    //
    int operator>(const MYCOMPLEX& w);
    friend int operator>(const MYCOMPLEX& w,const int& i);
    friend int operator>(const MYCOMPLEX& w,const float& x);
    friend int operator>(const MYCOMPLEX& w,const double& x);
    //
    int operator<(const MYCOMPLEX& w);
    friend int operator<(const MYCOMPLEX& w,const int& i);
    friend int operator<(const MYCOMPLEX& w,const float& x);
    friend int operator<(const MYCOMPLEX& w,const double& x);
    //
    int operator==(const MYCOMPLEX& w);
    friend int operator==(const MYCOMPLEX& w,const int& i);
    friend int operator==(const MYCOMPLEX& w,const float& x);
    friend int operator==(const MYCOMPLEX& w,const double& x);
    //   
    int operator!=(const MYCOMPLEX& w);
    friend int operator!=(const MYCOMPLEX& w,const int& i);
    friend int operator!=(const MYCOMPLEX& w,const float& x);
    friend int operator!=(const MYCOMPLEX& w,const double& x);
    double Real(){ return real;};
    double Imag(){ return imaginary;};
    MYCOMPLEX conjugate()
      { MYCOMPLEX w = *this; w.imaginary *= -1.0; return w;};
  private:
    istream& grab(istream& in);
    ostream& print(ostream& out) const;
    double real;
    double imaginary;
  };
#endif

Here are some of the details:

Multiplication:

There is the usual overloaded operator * for class multiplication MYCOMPLEX operator*(const MYCOMPLEX& w); but as you can see there a many additional overloaded multiplication operators. Why? Consider the following code fragment that might appear in a given application:

float x = 2.0;
double y = 3.0;
int p = 4;
MYCOMPLEX z(1.2,3.4);
MYCOMPLEX u = y * z;      //multiply on left by double
MYCOMPLEX v = z * x;      //multiply on right by float
MYCOMPLEX w = p * z;      //multiply on

We can easily see situations where we want to scale a given complex number by scalars that we normally think of as being special cases of complex numbers with no imaginary component; e.g., integers and real numbers. In C++, we must define these actions ourselves with appropriate overloaded multiplication operators as you can see below. Our implementation defines six such possibilities. Of course, multplication by unsigned ints, short ints and others are also possible, but they are not implemented here. These additional operators must be defined as friends to the MYCOMPLEX class in order to have access to the internals of given MYCOMPLEX objects.

    MYCOMPLEX operator*(const MYCOMPLEX& w);
    //
    friend MYCOMPLEX operator*(const int& i,const MYCOMPLEX& w);
    friend MYCOMPLEX operator*(const float& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator*(const double& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator*(const MYCOMPLEX& w,const int& i);
    friend MYCOMPLEX operator*(const MYCOMPLEX& w,const float& x);
    friend MYCOMPLEX operator*(const MYCOMPLEX& w,const double& x);    
    //
    MYCOMPLEX operator*=(const MYCOMPLEX& w);
    friend MYCOMPLEX operator*=(int& i,const MYCOMPLEX& w);
    friend MYCOMPLEX operator*=(float& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator*=(double& x,const MYCOMPLEX& w);
    friend MYCOMPLEX operator*=(MYCOMPLEX& w,const int& i);
    friend MYCOMPLEX operator*=(MYCOMPLEX& w,const float& x);
    friend MYCOMPLEX operator*=(MYCOMPLEX& w,const double& x);
:

Consider the following code fragment:

    MYCOMPLEX *z;
    z = new MYCOMPLEX[5];
How should we initialize this complex vector? An efficient way is to use the agent MYCOMPLEX IMAGINARY() to build the complex number 0.0 + 1.0i and then rely on our overloaded friend arithmetic operators and our overloaded equal to set the values for each of the complex vector components: for example, we could use the fragment
    double A[10] = {1.2,3.3, 4.4,5.6, 7.8,-10.2, 19.45,110.2, 
                    25.1,-119.293};
    MYCOMPLEX I = IMAGINARY();
    for(int j=0;i<5;++j){
      z[j] = (A[2*j] + (A[2*j+1]*I));
      }
At index j = 2, we would set z[2] = 7.8 -10.2I, where I has been defined earlier to be the complex number 0.0 + 1.0i. The multiplication 10.2I uses the friend multiplication operator with the right operand a double. The result of this multiplication is then subtracted from the double 7.8 using the overloaded friend subtraction operator with the left operand a double. The result of the subtraction is a new complex number which overwrites the previous value of the complex number z[2] using the overloaded equal operator.
    friend MYCOMPLEX ZERO();
    friend MYCOMPLEX ID();
    friend MYCOMPLEX IMAGINARY();
The other friend functions listed serve similar purposes: MYCOMPLEX ZERO() returns the complex number 0.0 + 0.0i and MYCOMPLEX ID() returns the complex identity 1.0 + 0.0i.


next up previous contents
Next: The Definition File mycomplex.c: Up: The Complex Class: MYCOMPLEX Previous: The Complex Class: MYCOMPLEX
Jim Peterson
1999-04-22