%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%  
%%  bigcomplex.tex       LiDIA documentation
%%  
%%  This file contains the documentation of the class bigcomplex
%%  
%%  Copyright   (c)   1995   by  LiDIA-Group
%%  
%%  Authors: Thomas Papanikolaou
%%

\begin{lidia_man}
\markright{\BF{bigcomplex}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\NAME
\BF{bigcomplex}\DOTFILL multiple precision complex floating point arithmetic

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ABSTRACT
\BF{bigcomplex} is a class for doing multiprecision complex
floating point arithmetic. It supports for example arithmetic
operations, comparisons and basic triginometric functions.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\DESCRIPTION 
A \BF{bigcomplex} is a pair of two \BF{bigfloats}
\MATH{ (re,im)}, where \MATH{re} is called the \BF{real part} and \MATH{im} the
\BF{imaginary part}.  This pair represents the complex number \MATH{re +
im * i}, where \MATH{i} is the imaginary unit. Before declaring a
\BF{bigcomplex} it is possible to set the decimal precision of the
\BF{bigfloats} \MATH{ (re, im)} to \MATH{p}  by \TT{bigcomplex::precision(p)}
or by \TT{bigfloat::precision(p)}. Both calls have the same effect
and set the \TT{bigfloat} precision to \MATH{p} (compare class \BF{bigfloat}, page
\pageref{bigfloat_class}).

If the precision has   not   been   set, a default precision of \MATH{t = 5}
\BF{bigint} base digits is used. 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\CONS
\fcode{ct}{bigcomplex}{}
{
Initializes with \MATH{0}.}

\fcode{ct}{bigcomplex}{const bigfloat \& \MATH{b}}
{
initializes the real part with \MATH{b}, the imaginary part with \MATH{0}.}

\fcode{ct}{bigcomplex}{const bigcomplex \& \MATH{c}}
{
initializes with \MATH{c}.}

\fcode{ct}{bigcomplex}{const bigfloat \& \MATH{re}\k const bigfloat \& \MATH{im}}
{
initializes the real with \MATH{re} and the imaginary part with \MATH{im}.}

\fcode{dt}{\SIM bigcomplex}{}
{
deletes the bigfloat object.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\INIT

\fcode{{static void}}{precision}{long p}
{
sets the global decimal
precision of the \BF{bigfloats} \MATH{re, im} to \MATH{p} decimal places
(compare \BF{bigfloat}). Note that the \BF{bigfloat} precision
is set globally to \MATH{p} by this call. Whenever necessary internal 
computations are done with a higher precision.}


\fcode{{static void}}{mode}{int m}
{
sets the rounding mode for the normalization routine according to the
IEEE standard (see \cite{IEE87}).
The following modes are available:

\TT{MP\_TRUNC}: round to zero.

\TT{MP\_RND}: round to nearest. If there are two possibilities to do this, round
to even.

\TT{MP\_RND\_UP} round to \MATH{+\INFTY}.

\TT{MP\_RND\_DOWN} round to \MATH{-\INFTY}.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\TYPE
Before assigning a \BF{bigcomplex} to a \BF{bigfloat} it is often
useful to check whether the assignment can be done without error,
i.e. whether the imaginary part \MATH{im} is zero. 


\fcode{bool}{is\_bigfloat}{const bigcomplex \&}
{
returns \TRUE\ if the imaginary part is zero, \FALSE\, otherwise.}

% \fcode{bool}{is\_double}{const bigcomplex \&}
% {
% returns \TRUE, if the imaginary part is zero and the real part is not to
% large to be stored in a double variable, \FALSE\, otherwise.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ASGN
Let \MATH{x} be of type \BF{bigcomplex}.

The operator \TT{=} is overloaded. For efficiency reasons the following functions are implemented:


\fcode{void}{x.assign\_zero}{}
{
\MATH{x = 0}.}

\fcode{void}{x.assign\_one}{}
{
\MATH{x = 1}.}

\fcode{void}{x.assign}{const bigfloat \& y}
{
\MATH{x = y}.}

\fcode{void}{x.assign}{const bigfloat \&y\k const bigfloat \& z}
{
\MATH{x = y + z * i}.}

\fcode{void}{x.assign}{const bigcomplex \& y}
{
\MATH{x = y}.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ACCS
Let \MATH{x} be of type \BF{bigcomplex}.

\cfcode{bigfloat}{x.real}{}
{
returns the real part of \MATH{x}.}

\fcode{bigfloat}{real}{const bigcomplex \& x}
{
returns the real part of \MATH{x}.}

\cfcode{bigfloat}{x.imag}{}
{
returns the imaginary part of \MATH{x}.}

\fcode{bigfloat}{imag}{const bigcomplex \& x}
{
returns the imaginary part of \MATH{x}.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ARTH
The following operators are overloaded and can be used in exactly the same
way as in C:

\begin{center}
\mbox{\TT{(unary) -}}\\
\mbox{\TT{(binary) +, -, *, /}}\\
\mbox{\TT{(binary with assignment) +=, -=, *=, /=}}
\end{center}


\fcode{void}{add}{bigcomplex \& x\k const bigcomplex \& y\k const bigcomplex \& z}
{
\MATH{x = y + z}.}

\fcode{void}{add}{bigcomplex \& x\k const bigcomplex \& y\k const bigfloat \& z}
{
\MATH{x = y + z}.}

\fcode{void}{add}{bigcomplex \& x\k const bigfloat \& y\k const bigcomplex \& z}
{
\MATH{x = y + z}.}

\fcode{void}{subtract}{bigcomplex \& x\k const bigcomplex \& y\k const bigcomplex \& z}
{
\MATH{x = y - z}.}

\fcode{void}{subtract}{bigcomplex \& x\k const bigcomplex \& y\k const  bigfloat \& z}
{
\MATH{x = y - z}.}

\fcode{void}{subtract}{bigcomplex \& x\k const bigfloat \& y\k const bigcomplex \& z}
{
\MATH{x = y - z}.}

\fcode{void}{multiply}{bigcomplex \& x\k const bigcomplex \& y\k const bigcomplex \& z}
{
\MATH{x = y * z}.}

\fcode{void}{multiply}{bigcomplex \& x\k const bigcomplex \& y\k const bigfloat \& z}
{
\MATH{x = y * z}.}

\fcode{void}{multiply}{bigcomplex \& x\k const bigfloat \& y\k const bigcomplex \& z}
{
\MATH{x = y * z}.}

\fcode{void}{divide}{bigcomplex \& x\k const bigcomplex \& y\k const bigcomplex \& z}
{
\MATH{x = y / z} if \MATH{z \NEQ 0}.
Otherwise the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{divide}{bigcomplex \& x\k const bigcomplex \& y\k const bigfloat \& z}
{
\MATH{x = y / z} if \MATH{z \NEQ 0}.
Otherwise the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{divide}{bigcomplex \& x\k const bigfloat \& y\k const bigcomplex \& z}
{
\MATH{x = y / z} if \MATH{z \NEQ 0}.
Otherwise the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{negate}{bigcomplex \& x\k const bigcomplex \& y}
{
\MATH{x = -y}.}

\fcode{void}{x.negate}{}
{
\MATH{x = -x}.}

\fcode{void}{x.invert}{}
{
\MATH{x = 1 / x} if \MATH{x \NEQ 0}. Otherwise the \TT{lidia\_error\_handler}
will be invoked.}

\fcode{void}{invert}{bigcomplex \& x\k const bigcomplex \& y}
{
\MATH{x = 1 / y} if \MATH{y \NEQ 0}. Otherwise the \TT{lidia\_error\_handler}
will be invoked.}

\fcode{bigcomplex}{inverse}{const bigcomplex \& x}
{
returns \MATH{1 / x} if \MATH{x \NEQ 0}. 
Otherwise the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{square}{bigcomplex \& x\k const bigcomplex \& y}
{
\MATH{x = \MATH{y^2}}.}

\fcode{bigcomplex}{square}{const bigcomplex \& x}
{
returns \MATH{ \MATH{x^{2}}}.}

\fcode{void}{sqrt}{bigcomplex \& x\k const bigcomplex \& x}
{
\MATH{x=\SQRT{y}}.}

\fcode{bigcomplex}{sqrt}{const bigcomplex \& x}
{
returns \MATH{\SQRT{x}}.}

\fcode{void}{power}{bigcomplex \& x\k const bigcomplex \& y\k const        bigcomplex \& z}
{
sets \MATH{x = y^z}.}

\fcode{void}{power}{bigcomplex \& x\k const bigcomplex \& y\k const        bigfloat \& z}
{
sets \MATH{x=y^z}.}

\fcode{void}{power}{bigcomplex \& x\k const bigcomplex \& y\k long i}
{
sets \MATH{x = y^i}.}

\fcode{bigcomplex}{power}{const bigcomplex \& y\k const bigcomplex \& z}
{
returns \MATH{ y^z}.}

\fcode{bigcomplex}{power}{const bigcomplex \& y\k const bigfloat \& z}
{
returns \MATH{y^z}.}

\fcode{bigcomplex}{power}{const bigcomplex \& y\k long i}
{
returns \MATH{ y^i}.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\COMP
\BF{bigcomplex} supports the binary operators \TT{==} and
\TT{!=}. Furthermore there exists the following function:


\cfcode{bool}{x.is\_zero}{}
{
returns \TRUE\ if x = 0, \FALSE\ otherwise.}

\cfcode{bool}{x.is\_real}{}
{
returns \TRUE\ if imaginary part of \MATH{x} is zero, \FALSE\ otherwise.}

\cfcode{bool}{x.is\_imaginary}{}
{
returns \TRUE\ if real part of \MATH{x}, \FALSE\ otherwise.}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\BASIC
\fcode{void}{conj}{bigcomplex \& x\k const bigcomplex \& y}
{
returns \MATH{x} as the complex conjugate of \MATH{y}.}

\fcode{bigcomplex}{conj}{const bigcomplex \& x}
{
returns the complex conjugate of \MATH{x}.}

\fcode{void}{exp}{bigcomplex \& x\k const bigcomplex \& y}
{
\MATH{x=e^y}.}

\fcode{bigcomplex}{exp}{const bigcomplex \& x}
{
returns \MATH{e^x}.}

\fcode{void}{log}{bigcomplex \& x\k const bigcomplex \& y}
{
\MATH{x=\log (y)} (natural logarithm to base \MATH{e=2.718\LDOTS}).}

\fcode{bigcomplex}{log}{const bigcomplex \& x}
{
returns \MATH{ \log (x)}.}

\fcode{void}{polar}{bigcomplex \& x\k const bigfloat \& r\k const bigfloat \& t}
{
\MATH{x=r*\cos (t)+r*\sin (t)*i}.}

\fcode{bigcomplex}{polar}{const bigfloat \& r\k const bigfloat \& t}
{
returns the complex number \MATH{r*\cos (t)+r*\sin (t)*i}.}

\fcode{bigfloat}{abs}{const bigcomplex \& x}
{
returns \MATH{ \SQRT{(x.re)^2 + (x.im)^2}}.}

\fcode{bigfloat}{hypot}{const bigcomplex \& x}
{
returns \MATH{ \TT{abs}(x)}.}

\fcode{bigfloat}{arg}{const bigcomplex \& x}
{
returns \MATH{ \TT{atan}(x.im / x.re)}.}

\fcode{bigfloat}{norm}{const bigcomplex \& x}
{
returns the norm of \MATH{x}.}

\fcode{void}{swap}{bigcomplex \& x\k bigcomplex \& y}
{
exchanges the values of \MATH{x} and \MATH{y}.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\STITLE{(Inverse) Trigonometric Functions}
\fcode{void}{sin}{bigcomplex \& x\k const bigcomplex \& y}
{
\MATH{x=\sin (y)}.}

\fcode{bigcomplex}{sin}{const bigcomplex \& x}
{
returns \MATH{ \sin (x)}.}

\fcode{void}{cos}{bigcomplex \& x\k const bigcomplex \& y}
{
\MATH{x=\cos (y)}.}

\fcode{bigcomplex}{cos}{const bigcomplex \& x}
{
returns \MATH{ \cos (x)}.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\STITLE{(Inverse) Hyperbolic Trigonometric Functions}
\fcode{void}{sinh}{bigcomplex \& x\k const bigcomplex \& y}
{
\MATH{x=\sinh (y)}.}

\fcode{bigcomplex}{sinh}{const bigcomplex \& x}
{
returns \MATH{ \sinh (x)}.}

\fcode{void}{cosh}{bigcomplex \& x\k const bigcomplex \& x}
{
\MATH{x=\cosh (y)}.}

\fcode{bigcomplex}{cosh}{const bigcomplex \& x}
{
returns \MATH{ \cosh (x)}.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\IO
\BF{istream} operator \TT{>>} and \BF{ostream} operator \TT{<<} are overloaded 
and can be used in the same way as in C++.  If the imaginary part
of the \BF{bigcomplex} is zero, then input and output of a 
\BF{bigcomplex} may be in one of the following formats:
\[re  \mbox{\ \ \  or\ \ \  } (re,0)\]
where \MATH{re} is a \BF{bigfloat} in the appropriate format described
in the \BF{bigfloat} class description.  If the imaginary part
of the \BF{bigfloat} is not zero, then input and output have the format
\[ (re,im)\]
where \MATH{re} and \MATH{im} are  \BF{bigfloat}s in the appropriate format 
described in the \BF{bigfloat} class description.  

Note that you have to manage 
by yourself that successive \BF{bigcomplex} numbers have to be 
separated by blanks. 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\SEEALSO
\BF{bigfloat}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\NOTES
The structure of \BF{bigcomplex} is strongly based on AT\&T's and
GNU's complex class. \BF{bigcomplex} is not yet complete. Further
methods will be incorporated in the next release. 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\EXAMPLES

\begin{verbatim}
 #include <LiDIA/bigcomplex.h>

 int main()
 {
    bigcomplex::precision(100);

    bigcomplex a, b, c;

    cout << "Please enter a : "; cin >> a ; 

    cout << "Please enter b : "; cin >> b ;

    cout << "\n";

    c = a + b;

    cout << "a + b = " << c << "\n";

 } 

\end{verbatim}

For further reference please refer to\\
\TT{LiDIA/src/simple\_classes/bigcomplex\_appl.c}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\AUTHOR
Ingrid Biehl, Thomas Papanikolaou


\end{lidia_man}
