    CCCCCCC     MM         MM          A         TTTTTTTTTT    HH      HH
  CC            MMM       MMM         AAA            TT        HH      HH
 CCC            MMMM     MMMM        AA AA           TT        HH      HH
 CCC            MM MM   MM MM       AA   AA          TT        HHHHHHHHHH
 CCC            MM  MM MM  MM      AAAAAAAAA         TT        HH      HH
  CC            MM   MMM   MM     AA       AA        TT        HH      HH
    CCCCCCC     MM    M    MM    AA         AA       TT        HH      HH


                    CMATH 1.4  for Borland Pascal 7

                    Dr. Martin Sander Software Development
                    Sertrnerstr. 11
                    D-37085 Gttingen
                    Germany
                    e-mail: MartinSander@Bigfoot.com
                    http://www.optivec.com

For the commercial version, see chapter 1.3.

*****************************************************************************

!!     This is an ASCII text file!  It is best viewed with a simple        !!
!!     DOS editor.                                                         !!
!!     If you load this file into a word processor under Windows, you      !!
!!     must use the filter "DOS text".                                     !!
!!     Alternatively, you may use FCONVERT (shipped with Borland C++) to   !!
!!     convert from ASCII (OEM) into the ANSI character set.               !!
!!     preferably use the lettertype CourierNew 10 pt.                     !!


OptiCode (TM) and OptiVec (TM) are trademarks of
    OptiCode - Dr. Martin Sander Software Dev.
Other brand and product names mentioned in this handbook for identification
purposes are trademarks or registered trademarks of their respective holders.


****************************************************************************
*                                                                          *
*******                           Contents                           *******
*                                                                          *
****************************************************************************

1. Introduction
   1.1 What is CMATH ?
   1.2 Licence Terms
   1.3 Registered Version

2. Getting Started
   2.1 Installation
   2.2 De-Installation

3. Overview over the Functions of CMATH
   3.1 Initialization of Complex Numbers
   3.2 Data-Type Interconversions
   3.3 Basic Complex Operations
   3.4 Arithmetic Operations
   3.5 Mathematical Functions

4. Error Handling
   4.1 General Error Handling of Complex Functions
   4.2 Advanced Error Handling: Writing Messages into a File

5. Syntax Reference

****************************************************************************
*                                                                          *
*******                       1. Introduction                        *******
*                                                                          *
*****************************************************************************


1.1 What is CMATH ?
-------------------

CMATH is a comprehensive library for complex-number arithmetis and
mathematics. Superior speed, accuracy and safety are achieved through the
implementation in Assembly language (as opposed to the compiled or
inline code you might know from C++ compilers' complex class libraries).

The implementation was guided by the following rules:

   1. Without any compromise, top priority is always given to the mathema-
      tically correct result, with the accuracy demanded for the respective
      data type. Especially for complex functions, this necessitates a
      very thorough treatment of many different situations. To this end,
      the various cases have to be distinguished with pedantic care.
   2. Mathematical functions must be "safe" under all circumstances.
      They may for no reason simply crash, but have to perform a decent
      error treatment. This is true even - and perhaps especially - for
      seemingly nonsense arguments, with the single exception of the
      non-numbers INF and NAN, which occur themselves only as a result
      of serious errors in other functions.
   3. By all possible means, greatest execution speed must be attained.
      (After all, you did not buy your fast computer for nothing!)
   4. The program code has to be as compact as possible. However, in case
      of conflicts, faster execution speed is always given priority
      over smaller code size.

Unlike the C++ version of CMATH, the Pascal/Delphi versions define
complex numbers as records instead of classes. The reason is that,
in Object-Pascal, overloading of arithmetic operators and of functions
is not possible to the same degree as in C++.
The CMATH-Pascal data types are binary compatible with those of the
C/C++ versions. The function names are also the same as in the plain-C
version. The syntax, however, is somewhat different, as C supports
complex numbers as return values, whereas Pascal does not.

CMATH defines three complex data types:
    type  fComplex = record   Re, Im: Single;    end;
    type  dComplex = record   Re, Im: Double;    end;
    type  eComplex = record   Re, Im: Extended;  end;

The reason why the single-precision type gets the name fComplex instead
of sComplex is that the letter "s" is already over-used by "ShortInt"
and "SmallInt" in Pascal. Therefore, this name is derived from the C/C++
analogue of Single, which is "float."
This also holds the way open for a future inclusion of whole-number
complex types into CMATH. Then,"siComplex" and "usComplex" will denote
the complex types consisting of "SmallInt" or "Word" ("UnsignedSmall")
parts, respectively.

All data types and functions are contained in one single unit: CMATH.

The implementation described in this documentation refers to Borland
(Turbo) Pascal, version 7.0 for DOS and Microsoft Windows 3.0 or later
(or Win-OS sessions under IBM OS/2 2.0 or later; in the following, we
will simply speak of "Windows"). Versions for Delphi are in preparation.
You cannot use the CMATH.TPW unit for Delphi.

Depending on your choice when ordering or downloading the Shareware version
of CMATH, you have got either the real-mode DOS or the Windows unit.
Either of them requires, at least, a 386 computer equipped with a 387
coprocessor. This means: no emulation, no 486SX, but preferrably 486DX,
Pentium or higher.
The full (registered) version contains units for real-mode DOS,
DPMI, and Windows. These units, in turn, are shipped in three versions:
one for 486DX and Pentium computers, the second for 386 with 387,
the third for 286 with or without coprocessor, i.e. with emulation.


1.2 Licence Terms
-----------------

This is the English Shareware version of CMATH for Borland Pascal ("Software").
It may be used under the following licence terms:

1. You may test the SOFTWARE free of charge for an unlimited period of time.
   This testing phase ends when you permanently integrate functions of this
   SOFTWARE into any of your applications (programs, program parts...).
2. If you want to use this SOFTWARE for commercial purposes, you have
   to purchase the registered version (see chapter 1.3).
3. Use of this SOFTWARE for educational purposes at schools and universities
   remains free of charge. However, if any application created under these
   terms is sold to others or otherwise used for commercial purposes,
   paragraph 2 applies.
4. Distributing this SOFTWARE to others is allowed only in one of the
   following two ways:
   a) linked into your programs, so that the parts stemming from this
      SOFTWARE do no longer appear as a library.
   b) as a whole in unchanged form (in particular the Copyright and Licence
      statements!), whereby you may ask a fee only and exclusively for the
      physical act of copying the SOFTWARE.
5. This SOFTWARE is provided on an "as is" basis. Any explicit or implicit
   warranties for the SOFTWARE are excluded.
   Despite thorough testing of the SOFTWARE, errors and bugs cannot
   be excluded with certainty. No claims as to merchantability or fitness
   for a particular purpose are made.
   You may not use the SOFTWARE in any environment or situation where
   personal injury or excessive damage to anyone's property (including
   your own) could arise from malfunctioning of the SOFTWARE.


Copyright for the SOFTWARE and its documentation (C) 1996-1999 Martin Sander

All rights reserved, including those of translation into foreign languages.

Address of the author:
              Dr. Martin Sander Software Development
              Sertrnerstr. 11
              D-37085 Gttingen
              Germany
              e-mail: MartinSander@Bigfoot.com



1.3 Registered Version
----------------------

The full (registered) version of CMATH for Borland Pascal

-  supports real-mode DOS, DPMI, and Windows 3.x

-  has individually optimized units for each degree of processor
   backward-compatibility:
      486DX/Pentium+
      386+ (387 coprocessor required)
      286+ (no coprocessor required).

-  comes with printed documentation.

-  costs  $25 or EUR 19 per unit
          plus a mailing fee of  $5 or EUR 5.

   For ordering, please send a printout of ORDER.TXT with enclosed cheque
   to the author.

-  if you upgrade to CMATH for Delphi after that version
   becomes available, the above registration fee will be deduced
   from the price of CMATH for Delphi.

Purchasing the full (registered) version gives you the right to use it on
as many computers at a time as the number of units you bought.



****************************************************************************
*                                                                          *
*******                 2. Getting Started                           *******
*                                                                          *
****************************************************************************

2.1 Installation
----------------
If you got CMATH as a part of OptiVec (a comprehensive library of
vectorized functions by the same author), CMATH is automatically installed
when you install OptiVec itself. In this case, installation of CMATH is
already included and you should skip this chapter to continue with chapter 3.

Otherwise, please note the following points:

1.  In order to use CMATH, you need an already installed copy of Borland
    (Turbo) Pascal 7.0. Install CMATH by executing INSTALL.EXE on the
    installation disk.

2.  If you can, use the protected-mode version of the compiler, i.e.,
    BP.EXE or TPX.EXE.  The real-mode version, TP.EXE, might run out
    of linker memory. If you encounter that problem, set the linker
    option "link buffer" to "disk". If even that does not help, you
    can only use the command-line compiler.

3.  Add the installation directory (which you chose during installation) to
    the Units search path of the IDE (in the "Options/Directories" menu).

4.  Choose the target "real-mode DOS" (BP.EXE only).
    You should also choose 286 code generation and real coprocessor
    commands (i.e., switch emulation off !).

5.  Add CMATH to the "uses" clause in the header of your programs/units,
    which call functions of CMATH.

After these preparations, all CMATH functions are available for your programs.


2.2 De-Installation
-------------------

Should you wish to remove CMATH from your computer after testing, please
simply delete the directory CMATH with its subdirectories. The installation
of CMATH does not affect any files outside its own directory, so there
is nothing else to get rid of.



****************************************************************************
*                                                                          *
*******       3. Overview over the Functions of CMATH                *******
*                                                                          *
****************************************************************************

All functions of CMATH are contained in the unit CMATH.

In the following, it is often only the fComplex-version of a function that
is explicitly mentioned. The versions for dComplex and eComplex are always
exactly analogous.

All functions have a prefix denoting the data type on which the function
works:
"cf_" stands for single precision (arguments and return values of the data
      type fComplex, sometimes together with Single),
"cd_" stands for double precision (dComplex and double), whereas
"ce_" denotes extended-precision functions.


3.1 Initialization of Complex Numbers
-------------------------------------

Complex numbers are initialized by separately assigning
a value to the imaginary and real parts, e.g.:
        z.Re := 3.0;   z.Im := 5.7;

Alternatively, you may use fcplx, dcplx, or ecplx, respectively:
       fcplx( z, 3.0, 5.7 );

Interconversions between the various complex types are performed via the
functions cftocd,  cdtocf,  cftoce,  cetocf,  cdtoce,  and cetocd.
OVERFLOW errors in the course of down-conversions lead to an error
message; program execution is continued with the largest value possible.


3.2 Basic Complex Operations
----------------------------

The following basic complex operations are defined in CMATH:

cf_conj     complex-conjugate form,
cf_neg      negation,
cf_real     extraction of the real part,
cf_imag     extraction of the imaginary part,
cf_polar    conversion of polar coordinates into the "normal",
            Cartesian complex format
cf_abs      absolute value (magnitude of the pointer in the
            complex plane; this is treated as a math function
            with error handling),
cf_arg      argument (angle of the pointer in the complex plane),
cf_norm     norm (defined here as the square of the absolute value)

(The cd_ and ce_ versions are exactly analogous to the cf_ version)


3.3 Arithmetic Operations
-------------------------

The following functions are used for arithmetics of complex numbers:

cf_add        addition of two complex numbers
cf_addRe      addition of a complex number and a real number
cf_sub        subtraction of two complex numbers (first operand
              minus the second operand)
cf_subRe      subtraction of a real number from a complex number
cf_subrRe     subtraction of a complex number from a real number
cf_mul        multiplication of two complex numbers
cf_mulRe      multiplication of a complex number and a real number
cf_div        division of two complex numbers (first operand
              divided by the second operand)
cf_divRe      division of a complex number by a real number
cf_divrRe     division of a real number by a complex number

(similarly the cd_ and ce_ versions)

The assignment operator ":=" is the only simple operator defined for
complex numbers.


3.4 Mathematical Functions
--------------------------

Here are the complex-number math functions of CMATH:

cf_abs         ry = | zx |          absolute value
cf_acos        zy = acos( zx )      arcus cosine function
cf_asin        zy = asin( zx )      arcus sine function
cf_atan        zy = atan( zx )      arcus tangent function
cf_cos         zy = cos( zx )       cosine
cf_cosh        zy = cosh( zx )      hyperbolic cosine
cf_cubic       zy = zx**3           third power
cf_exp         zy = exp( zx )       exponential function
cf_inv         zy = 1.0 / zx        inverse
cf_ipow        zy = zx**n           integer power
cf_ln          zy = ln( zx )        natural logarithm
cf_log         zy = ln( zx )        identical to cf_ln, ln
cf_log2        zy = lb( zx )        binary logarithm
cf_log10       zy = lg( zx )        decadic logarithm
cf_pow         zy = zx**zexp        arbitrary power
cf_powReBase   zy = r**zx           real base to complex power
cf_powReExpo   zy = zx**r           real power of complex base
cf_quartic     zy = zx**4           fourth power
cf_sin         zy = sin( zx )       sine
cf_sinh        zy = sinh( zx )      hyperbolic sine
cf_square      zy = zx             square
cf_sqrt        zy = sqrt( zx )      square root
cf_tan         zy = tan( zx )       tangent
cf_tanh        zy = tanh( zx )      hyperbolic tangent

(similarly the cd_ and ce_ versions)


****************************************************************************
*                                                                          *
*******                      4. Error Handling                       *******
*                                                                          *
*****************************************************************************

4.1 General Error Handling of Complex Functions
-----------------------------------------------

The error handling of complex functions follows the rules employed also
for real-number functions and operations. For all arithmetic operations,
the design of the algorithms eliminates the danger of failure due to
irregular intermediate results. Overflowing or otherwise irregular
final results, however, will lead to a hardware interrupt being generated
and, as a consequence, to a program abort.

In contrast to the arithmetic operations, all mathematical functions and
all data-type interconversions perform a tight error checking and catch
any detected error conditions.
You can decide how to react on floating-point errors by calling
V_setFPErrorHandling. The syntax is as follows:
   type  V_fphand = 0..$1717;
   procedure V_setFPErrorHandling( hand:V_fpHand );
Please use one of the following pre-defined constants for "hand":
  const fperrIgnore          =     0;
        fperrNoteDOMAIN      = $0001;
        fperrNoteSING        = $0002;
        fperrNoteOVERFLOW    = $0004;
        fperrNoteTLOSS       = $0010;
        fperrAbortDOMAIN     = $0101;
        fperrAbortSING       = $0202;
        fperrAbortOVERFLOW   = $0404;
        fperrAbortTLOSS      = $1010;
        fperrDefaultHandling = $0107;

All fperrNote...  options mean that only an error message is printed,
but program execution is continued with a default result (in the
case of OVERFLOW or SING errors, this is usually the largest representable
number).  All fperrAbort...  options mean that the program halts upon
encountering an error of the respective type.

If you use CMATH as a part of OptiVec, consult also chapter 5 of
HANDBOOK.TXT for further information on floating-point error handling.
If you use CMATH separately from OptiVec, you should at least know
about some advanced error handling features, borrowed from VectorLib and
described in the following chapter.


4.2 Advanced Error Handling: Writing Messages into a File
---------------------------------------------------------

In Borland Pascal/Delphi, the way error messages are printed is normally not
controllable by the programmer. While this is fine in most instances, there
may be situations in which you might, for example, wish the error messages
not to be printed to the screen, but rather into a file, so that you could
check later what has gone wrong.
To this end, CMATH borrows from VectorLib the function V_setErrorEventFile.
This function needs as arguments the desired name of your event file and a
switch named  ScreenAndFile  which decides if the error message is printed
only into the file, or additionally to the screen as well. The default
printing of error messages to the screen alone is restored by
V_closeErrorEventFile.

Note that the described redirection of error messages is valid only for
errors occurring in CMATH (and, of course, VectorLib) routines. Errors
occurring outside CMATH lead to the standard action of Borland
Pascal/Delphi.


****************************************************************************
*                                                                          *
*******               5. Syntax Reference                            *******
*                                                                          *
****************************************************************************

In the following, the syntax of all CMATH functions of float (Single) /
fComplex accuracy is given. These functions have the prefix cf_.
The syntax of the functions for Double and Extended precisions is exactly
analogous. Here, the prefix is cd_ or ce_, respectively.

function  cf_abs( zx:fComplex ): Single;
procedure cf_acos( var zy:fComplex; zx:fComplex );
procedure cf_add( var zz:fComplex; zx, zy:fComplex );
procedure cf_addRe( var zz:fComplex; zx:fComplex; yRe:Single );
function  cf_arg( zx:fComplex ): Single;
procedure cf_asin( var zy:fComplex; zx:fComplex );
procedure cf_atan( var zy:fComplex; zx:fComplex );
procedure    cdtoce( var zy:eComplex; zx:dComplex );
procedure    cdtocf( var zy:fComplex; zx:dComplex );
procedure    cetocd( var zy:dComplex; zx:eComplex );
procedure    cetocf( var zy:fComplex; zx:eComplex );
procedure    cftocd( var zy:dComplex; zx:fComplex );
procedure    cftoce( var zy:eComplex; zx:fComplex );
procedure cf_conj( var zy:fComplex; zx:fComplex );
procedure cf_cos( var zy:fComplex; zx:fComplex );
procedure cf_cosh( var zy:fComplex; zx:fComplex );
procedure cf_cubic( var zy:fComplex; zx:fComplex );
procedure cf_div( var zz:fComplex; zx, zy:fComplex );
procedure cf_divRe( var zz:fComplex; zx:fComplex; yRe:Single );
procedure cf_divrRe( var zz:fComplex; zx:fComplex; yRe:Single );
procedure cf_exp( var zy:fComplex; zx:fComplex );
procedure    fcplx( var zy:fComplex; xRe, xIm:Single );
procedure cf_inv( var zy:fComplex; zx:fComplex );
procedure cf_ipow( var zy:fComplex; zx:fComplex; exponent:Integer );
procedure cf_ln( var zy:fComplex; zx:fComplex );
procedure cf_log( var zy:fComplex; zx:fComplex );
procedure cf_log2( var zy:fComplex; zx:fComplex );
procedure cf_log10( var zy:fComplex; zx:fComplex );
procedure cf_mul( var zz:fComplex; zx, zy:fComplex );
procedure cf_mulRe( var zz:fComplex; zx:fComplex; yRe:Single );
procedure cf_neg( var zy:fComplex; zx:fComplex );
function  cf_norm( zx:fComplex ): Single;
procedure cf_polar( var zy:fComplex; mag, angle:Single );
procedure cf_pow( var zy:fComplex; zx:fComplex; exponent:Integer );
procedure cf_powReBase( var zy:fComplex; base:Single; exponent:fComplex );
procedure cf_powReExpo( var zy:fComplex; zx:fComplex; exponent:Single );
procedure cf_quartic( var zy:fComplex; zx:fComplex );
procedure cf_sin( var zy:fComplex; zx:fComplex );
procedure cf_sinh( var zy:fComplex; zx:fComplex );
procedure cf_square( var zy:fComplex; zx:fComplex );
procedure cf_sqrt( var zy:fComplex; zx:fComplex );
procedure cf_sub( var zz:fComplex; zx, zy:fComplex );
procedure cf_subRe( var zz:fComplex; zx:fComplex; yRe:Single );
procedure cf_subrRe( var zz:fComplex; zx:fComplex; yRe:Single );
procedure cf_tan( var zy:fComplex; zx:fComplex );
procedure cf_tanh( var zy:fComplex; zx:fComplex );


*****************************************************************************

Although CMATH underwent thorough testing, there is always a possibility
that a problem might have escaped our attention. Should you feel you dis-
covered a "bug", please kindly try to specify the conditions under which
you observed the problem as exactly as possible. Please let the author
know what you have found!
e-mail:  MartinSander@Bigfoot.com

Copyright (C) Martin Sander 1996-1999

*****************************************************************************
