OptiVec logo 

CMATH
 
Version 8


for C/C++ and for Pascal (Delphi, Lazarus)

OptiCode
Dr. Martin Sander Software Development
Brahmsstr. 6
D-32756 Detmold
Germany
http://www.optivec.com
e-mail: optivec@gmx.de
 

CMATH is available both separately and as a part of OptiVec. If you ordered or downloaded CMATH alone, please disregard all references to OptiVec in this documentation.
If you got CMATH as a part of OptiVec, you may wish to refer to HANDBOOK.HTM for a description of the basic principles of the OptiVec libraries and an overview over VectorLib, the first part of OptiVec. The second part, MatrixLib is described in MATRIX.HTM.
Chapter 1.2 of this file contains the licence terms for the Shareware version, Chapter 1.3 for the Registered version.
 
OptiCode™ and OptiVec™ are trademarks of 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.
 
Translations: Sie finden die deutsche Beschreibung separat unter CMDOCD.ZIP.
 Lithuanian translation provided by Giedrius Sadauskas
 Translation into Serbo-Croatian by Jovana Milutinovich from Webhostinggeeks.com

Contents

1. Introduction
     1.1 What is CMATH ?
          1.1.1 C/C++ Specifics
          1.1.2 Pascal/Delphi Specifics
     1.2 Licence Terms for the Shareware Version
     1.3 Registered Versions
          1.3.1 Registered Versions: Ordering
          1.3.2 License Terms for the Registered Versions
     1.4 Getting Started
2. Overview over the Functions of CMATH
     2.1 Initialization of Complex Numbers
     2.2 Data-Type Interconversions
     2.3 Basic Complex Operations
     2.4 Arithmetic Operations
     2.5 Mathematical Functions
3. Error Handling
     3.1 Error Handling of Complex Functions
     3.2 Advanced Error Handling: Writing Messages into a File
4. Syntax Reference
     4.1 Plain-C, Pascal/Delphi Functions
     4.2 Overloaded C++/Delphi Functions


1. Introduction

1.1 What is CMATH ?

CMATH is a comprehensive library for complex-number arithmetics and mathematics, both in cartesian and in polar coordinates. All functions may alternatively be called from classic C and Pascal with type-specific function names (like cf_sin,   cd_exp,   pe_sqrt), or from C++ and Pascal/Delphi with overloaded function names and operators (like sin,   exp,   sqrt,  operator +; operators only in C++). As far as possible, all functions have the same names in the Pascal/Delphi version as in the C/C++ version.

Superior speed, accuracy and safety are achieved through the implementation in Assembly language (as opposed to the compiled or inline code of available complex C++ class libraries). Only for the most simple tasks, alternative inline C++ functions are used in the C++ version.

As far as the scope of CMATH overlaps with the complex class implementations of Visual C++, Borland C++, and Delphi / Lazarus, CMATH is a high-quality replacement for the latter, which are all awfully inefficient and inaccurate.

In contrast to the written-down-and-compiled textbook formulas of most other available complex libraries (including those coming with Visual C++ and the Borland compilers), the implementation of CMATH was guided by the following rules:

  1. Without any compromise, top priority is always given to the mathematically 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. (Textbook formulas do not need to treat these situations separately, as they theoretically assume infinite accuracy of intermediate results; an actual implementation, however, has to work with the limited accuracy given by real-life processors.)
  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.

This documentation describes the CMATH implementations for


Please note that only the "outside appearance" and thus the documentation is the same for these different compilers. The libraries themselves are compiler-specific; each library can be used only with one compiler and, in the case of C/C++, with one memory model or one target:
  1. Embarcadero / Borland / CodeGear C++:
    You have to include two libraries: a base-library, specific for the compiler version and configuration, and a processor-specific library. For example, for the classic bcc32 compiler with static BC++ run-time library and with widest processor compatibility, you would link CMATHFS.LIB + CMATHF4W.LIB. For details, see chapter 1.4.
     
  2. Microsoft Visual C++:
    The Shareware version offers the libraries for "multi-thread debug (static RTL)", and "multi-thread DLL debug". The full (registered) version for Microsoft Visual C++ also contains the corresponding release libraries. There is no actual debug information enclosed in the OptiVec "debug" libraries, but they have to be used with the debug libraries of Visual C++.
    The 32-bit Shareware version runs on any processor from Pentium or Athlon on.
    The 64-bit Shareware version requires at least a Core2xxx or AMD x64 processor.
  3. GCC and LLVM CLang:
    In contrast to the conditions for the commercial compilers, we provide the Community with the OptiVec 32-bit P4D library and the 64-bit P8D library for the free compilers as Freeware.
    Only GCC: Both for 32-bit and for 64-bit, the standard configurations of GCC are covered by individual OptiVec base libraries, i.e. for Windows or Posix threads, and for each of those, the selection between SEH, Dwarf, or Setjmp-Longjmp exceptions.
     
  4. Delphi:
    Each Delphi release requires its own OptiVec library version.
     
  5. Lazarus:
    All CMATH routines are cdecl. This means their names are case-sensitive, and you have to write them exactly as in the documention. The technical reason for this is that, in the other calling models, Lazarus decorates all function names with encoded type information. So the CMATH function names would not be found in the included *.o files.
    The Shareware version requires, at least, a Pentium-class or Athlon computer. The Registered version offers an additional library optimized for current processors.

Back to Table of Contents

1.1.1 C/C++ Specifics

The complex C++ classes and the C structs fComplex etc. are binary compatible with each other. This point may become important for large projects with mixed C and C++ modules. Existing C++ code which uses the complex class library of Borland C++, contained in <complex.h>, can be left unchanged, because the CMATH functions and data types are also binary compatible with those of <complex.h>. The single exception is the member function polar, which had to be replaced by magargtoc, as the word "polar" now denotes the complex classes in polar coordinates.

Here is a detailed description of how to switch from the complex classes of Borland C++ to the new implementation given by CMATH:

  1. In C++ modules, replace the statement
    #include <complex.h>
    by the statement
    #include <newcplx.h>
    Then, the following six complex classes are defined:
    class complex<float>, class complex<double>, class complex<long double>, class polar<float>, class polar<double>, and class polar<long double>.

    The data types fComplex, dComplex, eComplex, fPolar, dPolar, and ePolar are defined as synonyms for these classes.
    In order to avoid the letter "L" (which is already over-used by long and unsigned long, extended is used as a synonym for long double in the Borland C++ version of CMATH. In the MSVC version, it is a synonym for double, as MSVC does not support 80-bit IEEE reals. Consequently, the complex data types of extended precision are named eComplex and ePolar. Thereby, the way is held open for a future inclusion of whole-number complex types into CMATH. Then, liComplex and ulComplex shall denote the complex types consisting of long int and unsigned long parts, respectively.

     
  2. If you prefer to have the "classic" class complex of older releases of Borland C++, you have to declare
    #define CMATH_CLASSIC_COMPLEX
    before (!) including <newcplx.h>.
    In this case, only the class complex will be defined and gets the synonym dComplex. Here you will have no access to the complex-number functions of float and of extended precision, and all functions in polar coordinates are unavailable as well.
     
  3. For plain-C modules, you cannot include <newcplx.h>. Rather, please declare
    #include <cmath.h>
    If you are using only one level of floating-point precision, you may wish to include only one of the type-specific include-files: <cfmath.h>, <cdmath.h>, or <cemath.h>, respectively.
    The plain-C implementation of CMATH is based upon the following definitions of the complex data types:
    typedef struct { float Re, Im; } fComplex;
    typedef struct { double Re, Im; } dComplex;
    typedef struct { extended Re, Im; } eComplex;
    typedef struct { float Mag, Arg; } fPolar;
    typedef struct { double Mag, Arg; } dPolar;
    typedef struct { extended Mag, Arg; } ePolar;

    As described above, the data type extended is used as a synonym for long double (Borland C++ version) or double (MSVC version).
     
  4. Replace calls to the complex member function polar by calls to magargtoc.
     
  5. The constituent parts of the C++ classes are declared as public (in contrast to Borland C++ !). They are named "Re" and "Im" in the cartesian classes, and "Mag" and "Arg" in the polar classes. This allows to access them as z.Re, z.Im, p.Mag, or p.Arg in C++ modules as well as in plain-C modules.
     
  6. For time-critical applications, we recommend to use the C rather than the C++ version of CMATH, as C/C++ compilers handle structs much more efficiently than classes. To use the C version with your C++ modules, please note the following points:

Back to Table of Contents

1.1.2 Pascal/Delphi Specifics

CMATH for Pascal/Delphi defines six complex data types:
type fComplex = record Re, Im: Single; end;
type dComplex = record Re, Im: Double; end;
type eComplex = record Re, Im: Extended; end;
type fPolar = record Mag, Arg: Float; end;
type dPolar = record Mag, Arg: Double; end;
type ePolar = record Mag, Arg: 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.

The CMATH-Pascal data types are binary compatible with those of the C/C++ versions.

The type-specific function names are the same as in the plain-C version. The syntax, however, is somewhat different, as complex numbers as return values could be implemented most efficiently by passed them as var arguments to the complex functions, e.g.
procedure cf_sin( var zy:fComplex; zx:fComplex );

The overloaded function names are the same as in the C++ version. Here, the results are treated as true return values, e.g.
function sin( zx:fComplex ): fComplex;

Back to Table of Contents

1.2 Licence Terms for the Shareware Version

In case you got CMATH as a part of OptiVec, the CMATH licence is included in the OptiVec licence. Otherwise, the following licence terms apply to the Shareware version of CMATH. For the licence terms of the Registered version, please see paragraph 1.3.
 
This is the Shareware version of CMATH ("SOFTWARE").
It may be used under the following licence terms:
  1. You may test the SOFTWARE free of charge for a period of up to 90 days on one computer.
  2. Applications, created with the Shareware version of this SOFTWARE, will run only on the same computer on which this SOFTWARE has been installed. They cannot and may not be distributed to others. After the end of the trial period, they will cease functioning.
  3. Special conditions apply for the 32-bit P4 and the 64-bit P8 library for GCC and for LLVM CLang: These libraries are Freeware. You can use them free of charge for as long as you wish, both for non-commercial and commercial applications. Applications, created with these libraries, may be distributed free of restrictions to others.
  4. If you want to continue using this SOFTWARE after testing, and/or if you wish to distribute programs containing functions of this SOFTWARE, you have to purchase the registered version (see chapter 1.3).
  5. This SOFTWARE is provided on an "as is" basis. Any explicit or implicit warranties for the SOFTWARE are excluded.
  6. 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.
  7. 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.
  8. You may not decompile, disassemble, or otherwise reverse engineer the SOFTWARE into a machine-readable form. You may, however, inspect the functions it contains by means of debuggers like those included in the Borland and Microsoft compilers.
Copyright for the SOFTWARE and its documentation © 1996-2024 OptiCode - Dr. Martin Sander Software Dev.
All rights reserved, including those of translation into foreign languages.

Back to Table of Contents

1.3 Registered Versions

1.3.1 Registered Versions: Ordering

You can either get a license for the CMATH version designed for one specific compiler ("CMATH for xxx"), or you can acquire a CMATH Master License, covering all supported compilers.
In order to make this product affordable also for those who will not themselves make money using it, we offer an educational edition at a strongly reduced rate, in addition to the full commercial edition. The contents of these two editions is identical. The only difference lies in the restrictions of use: The educational edition may not be used for commercial / business / government purposes, but is restricted to private and educational use.

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.

The right to distribute applications employing functions of CMATH is included in the commercial-version licence. No run-time licence are needed for your customers! Corporate site and world-wide licences are available upon request.

Price List

 
OptiVec for single compilers:
C++ Builder,    Visual C++,   GCC (Win),   LLVM CLang (Win),   Delphi,   Lazarus / FreePascal,    or Linux (GCC / LLVM CLang)
  Prices incl. 19% German VATPrices net
Commercial Edition 
Single license
 5 units
10 units
EUR   199
EUR   595 (119.00 per unit)
EUR   995 ( 99.50 per unit)
EUR   167.23
EUR   500.00 (100.00 per unit)
EUR   836.13 ( 83.61 per unit)
Educational Edition
Single license
 5 units
10 units
EUR    99
EUR   269 ( 53.80 per unit)
EUR   499 ( 49.90 per unit)
EUR    83,19
EUR   226.05 ( 45.21 per unit)
EUR   419.33 ( 41.93 per unit)
 
OptiVec Master License for all supported compilers
  Prices incl. 19% German VATPrices net
Commercial Edition 
Single license
 5 units
10 units
EUR   299
EUR   899 (179.80 per unit)
EUR  1499 ( 149.90 per unit)
EUR   251.26
EUR   755.46 (151.09 per unit)
EUR  1259.66 (125.97 per unit)
Educational Edition
Single license
 5 units
10 units
EUR   149
EUR   445  (89.00 per unit)
EUR   745  (74.50 per unit)
EUR   125.21
EUR   373.95  (74.79 per unit)
EUR   626.05  (62.61 per unit)
 
CMATH for single compilers:
C++ Builder,    Visual C++,   GCC (Win),   LLVM CLang (Win),   Delphi,   Lazarus / FreePascal,    or Linux (GCC / LLVM CLang)
  Prices incl. 19% German VATPrices net
Commercial Edition 
Single license
 5 units
10 units
EUR    59
EUR   175  (35.00 per unit)
EUR   295  (29.50 per unit)
EUR    49.58
EUR   147.06  (29.41 per unit)
EUR   247.90  (24.79 per unit)
Educational Edition
Single license
 5 units
10 units
EUR    29
EUR    85  (17.00 per unit)
EUR   145  (14.50 per unit)
EUR    24.37
EUR    71.43  (14.29 per unit)
EUR   121.85  (12.19 per unit)
 
CMATH master license for all supported compilers
  Prices incl. 19% German VATPrices net
Commercial Edition 
Single license
 5 units
10 units
EUR    89
EUR   265  (53.00 per unit)
EUR   445  (44.50 per unit)
EUR    74.79
EUR   222.69  (44.54 per unit)
EUR   373.95  (37.40 per unit)
Educational Edition
Single license
 5 units
10 units
EUR    49
EUR   145  (29.00 per unit)
EUR   245  (24.50 per unit)
EUR   41.18
EUR   121.85  (24.37 per unit)
EUR   205.88  (20.59 per unit)

If you have a European VAT ID, or if you order from outside the European Union, you are exempt from German VAT, and it will be deduced from your bill, but you may have to pay your local VAT and/or import duties according to local laws.

Please order through www.optivec.de/order/
or send this order form to

OptiCode – Dr. Martin Sander Software Dev.
Brahmsstr. 6
D-32756 Detmold
Germany
optivec@gmx.de

For any other questions related to ordering CMATH, please contact us at: optivec@gmx.de

Back to Table of Contents

1.3.2 License Terms for the Registered version

In case you got CMATH as a part of OptiVec, the CMATH licence is included in the OptiVec licence. Otherwise, these are the license terms valid for you, if you got this file with the registered version of CMATH:
 
This is a single copy license for CMATH ("SOFTWARE"), granted by OptiCode - Dr. Martin Sander Software Development ("OptiCode").

The SOFTWARE in this package is licensed to you as the user. It is not sold. The term "user" means a programmer who links binary code of this SOFTWARE into his own applications. Those people using, in turn, his applications without the need of installing this SOFTWARE themselves, do not need any runtime license for the SOFTWARE. The right to distribute applications containing code of this SOFTWARE is included in the license fee for the commercial version.
 
Once you have paid the required license fee, you may use the SOFTWARE for as long as you like, provided you do not violate the copyright and if you observe the following rules:

  1. You may use the SOFTWARE on any computer for which it is designed, as long as not more than one person uses it at any time.
  2. You may make backup copies of the SOFTWARE for your personal use. You may only transfer the SOFTWARE to somebody else if you transfer the original and all copies, retaining no copies for yourself. You may not lease or rent the SOFTWARE to others.
  3. You may not decompile, disassemble, or otherwise reverse engineer the SOFTWARE into a machine-readable form. You may, however, inspect the functions contained in this SOFTWARE by means of debuggers like those included in the Borland and Microsoft compilers.
  4. If you payed the reduced licence fee for the "educational version" rather than the full rate for the "commercial version", the use of this SOFTWARE is restricted to private and educational purposes. In this case, you may not use the SOFTWARE for commercial purposes or for government purposes other than education.
    Applications using functions of this SOFTWARE may be freely distributed (i.e. without any run-time licence) only if created with the "commercial edition" and on condition that the functions of this SOFTWARE are permanently linked into a program etc., but do not appear as a library to the user of that application.
  5. 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.
  6. OptiCode's liability is limited by the enclosed Limited Warranty. In no case shall OptiCode's liability exceed the license paid for the right to use the SOFTWARE.

Limited Warranty for the Registered version
  1. OptiCode warrants that the magnetic or optic media on which the SOFTWARE is recorded are free from defects in materials and workmanship under normal use. The SOFTWARE itself will perform substantially in accordance with the specifications set forth in the documentation.
  2. The above express warranties are made for a period of six months from the date the SOFTWARE is delivered to you as the first user.
  3. Any magnetic/optic or printed media from this package proving defective in materials or workmanship will be replaced on an exchange basis.
  4. Great care has been taken to ensure that the SOFTWARE operates in accordance with the specifications as described in the documentation. However, it is not guaranteed that this SOFTWARE will operate completely free of errors or that the documentation is free of errors.
  5. Any implied warranties including any warranties of merchantability, of fitness for a particular purpose, or of noninfringement are limited to the terms of the above express warranties.
  6. OptiCode shall not in any case be liable for special, incidental, consequential, indirect or other damages arising from any breach of these warranties or of the license conditions, even if he has been notified of the possibility of such damages.

Copyright for the SOFTWARE and its documentation © 1996-2010 OptiCode – Dr. Martin Sander Software Development. All rights reserved.

Back to Table of Contents

1.4 Getting Started

If you got CMATH as a part of OptiVec, you should read chapter 1.4 of HANDBOOK.HTM instead of the remainder of the present paragraph. If you have already read that, continue with chapter 2, or go back to the Table of Contents.

In order to use CMATH, you need an already installed copy of your C/C++, Delphi, or Pascal compiler. Install CMATH by executing INSTALL.EXE. Normally, CMATH will be installed into a directory named "CMATH". This directory holds the documentation. You will need to include the CMATH lib and include (C/C++) or units (Delphi) subdirectories into the search path.
Jump to the description for your specific version:
 CMATH for C++ Builder (Embarcadero / Borland C++)
CMATH for Visual C++
CMATH for GCC
CMATH for LLVM CLang
CMATH for Delphi
CMATH for Lazarus / FreePascal

1.4.1 CMATH for C++ Builder (Embarcadero / Borland C++)

Assuming your CMATH directory is C:\CMATH, add
C:\CMATH\LIB to the library search path and
C:\CMATH\INCLUDE to the include-file search path of the IDE (and of the configuration file BCC32.CFG in case you are using the command-line compilers).

You have to include not only one, but two CMATH libraries: First the CMATH base library:
 
PlatformCompilerstatic runtime libraryruntime library as DLL
Win64bcc64, from RAD Studio 12 (2023) oncmbcbase64.acmbcbase64.a
 bcc64, all versions until RAD Studio 11.xcmbcx64.acmbcx64.a
Win32bcc32 (classic), RAD Studio 12+cmbcbase32s.libcmbcbase32d.lib
 bcc32 (classic), all versions until RAD Studio 11.xcmathfs.libcmathfd.lib
 bcc32c (CLang-enhanced), RAD Studio 12+cmbcbase32cs.libcmbcbase32cd.lib
 bcc32c (CLang-enhanced), RADS 10.x, 11cmbc10_11base32cs.libcmbc10_11base32cd.lib

Second, select the required processor-specific library from the following table and add it to your project.
 
PlatformCompilerProcessor back-compatibilityCMATH Library
Win64bcc64min. Core2xx, AMD x64)CMBC64_8.a
Win32bcc32 (classic)current processors (min. Core2xx, AMD x64)CMATHF8W.LIB
  486DX/PentiumCMATHF4W.LIB
 bcc32c (CLang)
from C++ Builder 10.1 Berlin on
current processors (min. Core2xx, AMD x64)cmbc32c_8.lib
  486DX/Pentiumcmbc32c_4.lib
 bcc32c (CLang)
up until C++ Builder 10 Seattle
current processors (min. Core2xx, AMD x64)CMATHF8W.LIB
  486DX/PentiumCMATHF4W.LIB
 

In previous versions, there were certain restrictions concerning the use of CMATH with the 32-bit CLang-enhanced Borland Compiler bcc32c.exe. All of them have now been lifted.

Continue with chap. 1.5 Declaration of CMATH functions in C/C++

1.4.2 CMATH for Visual C++ (Microsoft Visual Studio)

Assuming your CMATH directory is C:\CMATH, add
C:\CMATH\LIB to the library search path and
C:\CMATH\INCLUDE to the include-file search path.
You have to include two CMATH libraries. The first one ("base library") contains the interface between CMATH and the VC++ runtime library; it has to be matched with the specific version of the VC++ runtime library you chose for your project. The second one is independent from the configuration and runtime library; you have to choose it according to the desired CPU support.
First choose the project configuration and runtime library. The latter is set at Project / (Configuration) Settings / C/C++ / Code Generation / Runtime Library. Under Project / (Configuration) Settings / Linker / Input, add the matching CMATH library to your project, according to the following table.
 
PlatformVisual Studio VersionRuntime: Debug DLLDebug StaticRelease DLLRelease Static
Win64VS 2022CMVC17x64MDD.LIBCMVCx64MTD.LIBCMVC17x64MDR.LIBCMVCx64MTR.LIB
Win64VS 2019CMVC16x64MDD.LIBCMVCx64MTD.LIBCMVC16x64MDR.LIBCMVCx64MTR.LIB
 VS 2017CMVC15x64MDD.LIBCMVCx64MTD.LIBCMVC15x64MDR.LIBCMVCx64MTR.LIB
 VS 2015CMVC14x64MDD.LIBCMVCx64MTD.LIBCMVC14x64MDR.LIBCMVCx64MTR.LIB
 VS 2013CMVC12x64MDD.LIBCMVC8_12x64MTD.LIBCMVC12x64MDR.LIBCMVC8_12x64MTR.LIB
 VS 2012CMVC11x64MDD.LIBCMVC8_12x64MTD.LIBCMVC11x64MDR.LIBCMVC8_12x64MTR.LIB
 VS 2010CMVC8x64MDR.LIB*CMVC8_12x64MTD.LIBCMVC8x64MDR.LIB*CMVC8_12x64MTR.LIB
 VS 2008CMVC8x64MDR.LIB*CMVC8_12x64MTD.LIBCMVC8x64MDR.LIB*CMVC8_12x64MTR.LIB
 VS 2005CMVC8x64MDD.LIBCMVC8_12x64MTD.LIBCMVC8x64MDR.LIBCMVC8_12x64MTR.LIB
Win32VS 2022CMVC17MDD.LIBCMVCMTD.LIBCMVC17MDR.LIBCMVCMTR.LIB
 VS 2019CMVC16MDD.LIBCMVCMTD.LIBCMVC16MDR.LIBCMVCMTR.LIB
 VS 2017CMVC15MDD.LIBCMVCMTD.LIBCMVC15MDR.LIBCMVCMTR.LIB
 VS 2015CMVC14MDD.LIBCMVCMTD.LIBCMVC14MDR.LIBCMVCMTR.LIB
 VS 2013CMVC12MDD.LIBCMVC8_12MTD.LIBCMVC12MDR.LIBCMVC8_12MTR.LIB
 VS 2012CMVC11MDD.LIBCMVC8_12MTD.LIBCMVC11MDR.LIBCMVC8_12MTR.LIB
 VS 2010CMVC10MDD.LIBCMVC8_12MTD.LIBCMVC10MDR.LIBCMVC8_12MTR.LIB
 VS 2008CMVC9MDD.LIBCMVC8_12MTD.LIBCMVC9MDR.LIBCMVC8_12MTR.LIB
 VS 2005CMVC8MDD.LIBCMVC8_12MTD.LIBCMVC8MDR.LIBCMVC8_12MTR.LIB
 
*For the outdated VS versions 2008 and 2010, the 64-bit base-libraries for dynamic runtime are not available. As a work-around, you may use the VS2005 library instead. In this case, however, you may have to install additional redistributable DLL's. You find these redistributables at www.microsoft.com/download. Enter "vcredist_x86" or "vcredist_x64" into the search field to get a list of available redistributables. Choose the ones for Visual Studio 2005.
Please note that there is a certain inconsistency in the description of the configurations in Visual Studio: The default configurations "Debug" and "Release" actually use the runtime library and MFC as DLL. Therefore, you have to use the CMath base libraries CMVC??MDD.lib and CMVC??MDR.lib with these configurations. There is a problem with using these configurations, however: you always need the RTL and MFC DLL's for the specific compiler version installed on your computer. For many applications, it is therefore recommended to change Project / Properties / Configuration Properties / C/C++ / Code Generation / Runtime Library into "Multi-Thread Debug (/MTd)" or "Multi-Thread Release (MT)", respectively, in order to get rid of the DLL redistributables. This is done in the "DebugStatic" configuration in the demo files coming with CMath.

After that, please add the second, processor-specific CMATH library according to the following table:
 
Processor32-bit CMATH library64-bit CMATH library
P8: latest processors (Core2xxx, i3, i5, i7, AMDx64)CMVC8.LIBCMVC64_8.LIB
P4: full FPU accuracy (at least 486DX/Pentium)CMVC4.LIB ----
 
In order to allow CMATH to be used in applications both with and without MFC, it calls the Windows API only directly, not via MFC. However, if you use MFC (either as a static library or as a DLL), Visual C++ does not automatically link the import library, user32.lib. You have to explicitly do this yourself: The line, Project / Settings / Linker / Object and Library Modules must contain user32.lib. Otherwise you would get the linker error "error LNK2001: Unresolved external symbol __imp__MessageBoxA@??".
 

Continue with chap. 1.5 Declaration of OptiVec functions in C/C++

1.4.3 CMATH for GCC (GNU Compiler Collection)

Assuming your CMATH directory is C:\CMATH, you need to compile with the option -I C:\CMATH\Include.

You have to include two CMATH libraries. The first one ("base library") contains the interface between CMATH and the GCC runtime libraries; it has to be matched with the specific configuration of GCC. The second one is independent from the configuration and runtime library; you have to choose it according to the desired CPU support.
First choose the base library from the following table:
 
PlatformGCC thread modelGCC exception modelMatching CMATH base library
Win64Windows threadsSEHovgcbase64ws.lib
 Windows threadsSetjmp/Longjmpovgcbase64wj.lib
 Posix threadsSEHovgcbase64ps.lib
 Posix threadsSetjmp/Longjmpovgcbase64pj.lib
Win32Windows threadsDwarfovgcbase32wd.lib
 Windows threadsSetjmp/Longjmpovgcbase32wj.lib
 Posix threadsDwarfovgcbase32pd.lib
 Posix threadsSetjmp/Longjmpovgcbase32pj.lib

After that, choose the second, processor-specific CMATH library according to the following table:
 
Processor32-bit CMATH library64-bit CMATH library
P8: latest processors (Core2xxx, i3, i5, i7, AMDx64)cmgc32_8.libcmgc64_8.lib
P4: full FPU accuracy (at least 486DX/Pentium)cmgc32_4.lib ----
 

One very important point to observe when working with GCC is that the linker resolves dependencies from "left to right". As the processor-specific library calls functions from the base library, the processor-specific library needs to be included first.

GCC is the only of the "big" compilers to support 80-bit real numbers (long double or extended) in 64-bit (all other compilers implicitly demote long double / extended do double). This is a very valuable feature, as the extra accuracy and range can make life much simpler on many occasions. CMATH supports eComplex, i.e., complex numbers in extended precision, both in 32-bit and in 64-bit.

A Linux version of CMATH for GCC is being prepared and will be included, when it becomes available.

Continue with chap. 1.5 Declaration of CMATH functions in C/C++

1.4.4 CMATH for LLVM CLang

Assuming your CMATH directory is C:\CMATH, you need to compile with the option -I C:\CMATH\Include.

You have to include two CMATH libraries. The first one ("base library") contains the interface between CMATH and the CLang runtime libraries. (Actually, CLang heavily relies on the Visual C++ runtime libraries and is almost compatible with Visual C++. This "almost" compatibility, however, is not perfect, to the point that CMATH has to come with an individual CLang version.) This base library is ovclbase64.lib for 64-bit and ovclbase32.lib for 32-bit.

The second library is specific to the desired CPU support:
 
Processor32-bit CMATH library64-bit CMATH library
P8: latest processors (Core2xxx, i3, i5, i7, AMDx64)cmcl32_8.libcmcl64_8.lib
P4: full FPU accuracy (at least 486DX/Pentium)cmcl32_4.lib ----

A Linux version of CMATH for LLVM CLang is being prepared and will be included, when it becomes available.

Continue with chap. 1.5 Declaration of CMATH functions in C/C++

1.4.5 CMATH for Delphi

Shareware version: The units (.DCU files) are in the directory CMATH\LIB4 (32-bit) or CMATH\Win64\LIB8 (64-bit).
Registered version: The units (.DCU files) for current processors are in CMATH\LIB8 (32-bit) and CMATH\Win64\LIB8 (64-bit) / CMATH\Win64\LIB8D (64-bit Debug), those for 32-bit museum hardware (down to Pentium and 486DX) are in CMATH\LIB4 and in CMATH\LIB4D (Debug).
You need to set the units search path accordingly.

Continue with chap. 1.5.2 Declaration of CMATH functions in Pascal / Delphi

1.4.6 OptiVec for Lazarus / FreePascal

The units (.PPU files) and object files (*.o) are in the directory CMATH\LIB8. You need to enter this information into the "Other Units" search path.
 

1.5 Declaration of CMATH functions

1.5.1 Declare the use of CMATH functions in C/C++

Declare the use of CMATH functions in your program by the directive
#include <newcplx.h> (only C++, not plain-C) or
#inlucde <cmath.h> (both plain-C and C++), as described above.
If you are writing MFC or Borland C++ ObjectWindows applications, the CMATH header files should be included after the MFC or OWL header files.

1.5.2 Declare the use of CMATH functions in Pascal / Delphi

Declare the use of CMATH units as usual with the "uses CMATH" statement.

1.6 Sample programs

Have a look into the sample programs by opening the project appropriate for your compiler:

After these preparations, all CMATH functions are available for your programs.
Should you wish to remove CMATH from your computer, please run UNINSTAL.EXE, or simply delete the directory CMATH with its subdirectories.

Back to Table of Contents


2. Overview over the Functions of CMATH

In the following, it is often only the fComplex or fPolar version of a function that is explicitly mentioned. The versions for dComplex / dPolar, and eComplex / ePolar are always exactly analogous.
All functions for the languages C and Pascal/Delphi have a prefix denoting the data type on which the function works:
"cf_" or "pf_" stands for single precision (arguments and return values of the data types fComplex, fPolar, sometimes together with float),
"cd_" or "pd_" stands for double precision (arguments and return values of the data types dComplex, dPolar, sometimes together with double), whereas
"ce_" and "pe_" denote extended-precision functions.

In C++ and Delphi, synonyms are defined for all these functions. The synonyms do not have a prefix, since the data type information is implicitly handled by the compiler. The overloaded function names are mostly identical to those found in the complex class libraries (if the respective function exists there). Note, however, that the member function polar had to be replaced by magargtoc, as the name "polar" is now reserved for the polar classes.

C++ only: If you wish to use the C function names in your C++ modules, be sure to include <cmath.h> instead of <newcplx.h>.


2.1. Initialization of Complex Numbers

In the following, we denote the complex classes by by their short names, fComplex, fPolar, etc. In C++, you can always use the template nomenclature instead, writing "complex<float>" wherever "fComplex" is written here, and so on for all other complex types and classes.

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

(Of course, for Pascal/Delphi, the assignment operator is written ":=").
Alternatively, the same initialization can be accomplished by the functions fcplx or fpolr:
C/C++:
z = fcplx( 3.0, 5.7 );
p = fpolr( 4.0, 0.7 );

Pascal/Delphi:
fcplx( z, 3.0, 5.7 );
fpolr( p, 3.0, 5.7 );

For double-precision complex numbers, use dcplx and dpolr, for extended-precision complex numbers, use ecplx and epolr.


2.2. Data-Type Interconversions

Interconversions between the various complex types are performed via the functions:
cftocd,   cdtocf,   cftoce,   cetocf,   cdtoce,   cetocdup- or down-conversion of accuracy within the cartesian-complex types
pftopd,   pdtopf,   pftope,   petopf,   pdtope,   petopdup- or down-conversion of accuracy within the polar-complex types
cftopf,   cftopd,   cftope,
cdtopf,   cdtopd,   cdtope,
cetopf,   cetopd,   cetope
conversion from cartesian into polar complex
pftocf,   pftocd,   pftoce,
pdtocf,   pdtocd,   pdtoce,
petocf,   petocd,   petoce
conversion from polar into cartesian complex
 
OVERFLOW errors in the course of down-conversions are silently cured: program execution is continued with the largest value possible.
C++ only: For C++ modules, there are several overloaded constructors as an alternative to the above functions:
basic forms:
   fComplex fComplex( float RePart, float ImPart=0 );
   fComplex fComplex( dComplex );
   fComplex fComplex( eComplex );
   fPolar fPolar( float MagPart, float ArgPart=0 );
   fPolar fPolar( dPolar );
   fPolar fPolar( ePolar );

interconversion cartesian <--> polar:
   fComplex fComplex( fPolar );
   fComplex fComplex( dPolar );
   fComplex fComplex( ePolar );
   fPolar fPolar( fComplex );
   fPolar fPolar( dComplex );
   fPolar fPolar( eComplex );

Similarly to the constructors fComplex() and fPolar(), also dComplex(), dPolar(), eComplex, and ePolar() exist in overloaded versions performing the same tasks for the classes dComplex, dPolar, eComplex, and ePolar, respectively. As described above for the C/Pascal/Delphi versions, OVERFLOW errors in the course of down-conversions are silently cured, without calling _matherr.

 
A special constructor for polar numbers is
fPolar pf_principal( fPolar __p );
and, for C++ only, its overloaded form for two separate real input numbers
fPolar principal( float Mag, float Arg );
These functions reduce the input Arg to the range -p < Arg <= +p. You might recall that each complex number has an infinite number of representations in polar coordinates, with the angles differing by an integer multiple of 2 p. The representation with -p < Arg <= +p is called the principal value.
Please note that, along with the polar square-root function, pf_sqrt, these are the only polar functions reducing the output to the principal value. All others accept and return arguments whose angles may fall outside this range.

The conversion between cartesian and polar format involves transcedental functions and is, therefore, quite time-consuming. It is true that multiplications are faster in polar coordinates, whereas additions are much faster in Cartesian. The difference, however, is so much smaller than the cost of switching back and forth between the different representations, that we recommend you stay in general with the cartesian format. Only in the following cases, the conversion really makes sense:

  1. You have only multiplications and related math functions (like squaresqrtipow). Then, you should start out with polar coordinates.
  2. You have to call the complex exponential function. In this case, cf_exptop brings you into polar coordinates in a very natural manner.
  3. You are in polar coordinates and have to calculate the logarithm. In this case, pf_logtoc (or similarly pf_log2toc,   pf_log10toc) brings you "down" to the cartesian representation.

Zurück zum Inhaltsverzeichnis

2.3 Basic Complex Operations

The following basic complex operations are defined in CMATH
cartesian C/Pascal/Delphi functionpolar C/Pascal/Delphi function overloaded C++/Delphi functionexplanation
cf_conjpf_conj conjcomplex-conjugate form
cf_negpf_neg neg (or -)negation
cf_realpf_real realextraction of the real part
cf_imagpf_imag imagextraction of the imaginary part
cf_magargtocN.A. magargtocconversion of polar coordinates, entered as separate real numbers, into cartesian format
N.A.pf_reimtop reimtopconversion of complex coordinates, entered as separate real numbers, into polar format
cf_abspf_abs absabsolute value (magnitude of the pointer in the complex plane; this is treated as a math function with error handling)
cf_argpf_arg argargument (angle of the pointer in the complex plane) 
cf_normpf_norm normnorm (defined here as the square of the absolute value) 
N.A.pf_principal principalprincipal value, with -p < Arg <= +p
 
(The double and extended-precision versions are exactly analogous to the cf_ / pf_ version)

Back to Table of Contents

2.4 Arithmetic Operations

Only C++ or Delphi from version 2006 on:Arithmetic operators are available for all complex classes / data types. They exist also for "mixed" arguments, where one argument is complex, the other real and where the arguments are of different floating-point accuracies.

C++, cartesian-complex classes:
    +   -   *   /   +=   -=   *=   /=   ==   !=
C++, polar-complex classes:
    *   /   *=    /=    ==    !=

Delphi 2006 or higher, cartesian-complex types:
    +   -   *   /   =   <>
Delphi 2006+, polar-complex types:
    *   /   =    <>

 
Delphi before v2006 only:Instead of the operators defined for the more recent Delphi versions, you can use the following functions:
add     sub     mul     divide
They work for two complex arguments or for one complex and one real argument.

Since it is only C++ and Delphi, but neither plain-C nor Pascal, which allows overloaded arithmetic operators, all arithmetic operations of complex numbers are implemented additionally as functions which may be called from C/Pascal/Delphi as well as C++ modules:
 
CartesianPolar  
cf_addN.A. addition of two complex numbers
cf_addReN.A. addition of a complex number and a real number
cf_subN.A. subtraction of two complex numbers (first operand minus the second operand)
cf_subReN.A. subtraction of a real number from a complex number
cf_subrReN.A. subtraction of a complex number from a real number
cf_mulpf_mul multiplication of two complex numbers
cf_mulRepf_mulRe multiplication of a complex number and a real number
cf_mulconjpf_mulconj multiplication of one complex number with the complex conjugate of another
cf_divpf_div division of two complex numbers (first operand divided by the second operand)
cf_divRepf_divRe division of a complex number by a real number
cf_divrRepf_divrRe division of a real number by a complex number

(similarly the double- and extended-precision versions) 

The assignment operator "=" or ":=" is the only operator defined also in plain-C and Pascal/Delphi for complex numbers.

Back to Table of Contents

2.5 Mathematical Functions

CMATH contains all mathematical functions you would usually find in the complex class libraries of C++, along with several additional ones:
 
cartesian C/Pascal/Delphi functionpolar C/Pascal/Delphi functionoverloaded C++ function formulaexplanation
cf_abspf_absabs ry = | zx |absolute value
cf_acosN.A.acos zy = acos( zx )arcus cosine function
cf_asinN.A.asin zy = asin( zx )arcus sine function
cf_atanN.A.atan zy = atan( zx )arcus tangent function
cf_cosN.A.cos zy = cos( zx )cosine
cf_coshN.A.cosh zy = cosh( zx )hyperbolic cosine
cf_cubicpf_cubiccubic zy = zx3third power
cf_expcf_exptopexp zy = exp( zx )exponential function
cf_invpf_invinv zy = 1.0 / zxinverse
cf_ipowpf_ipowipow zy = zxninteger power
cf_lnpf_lntocln zy = ln( zx )natural logarithm
cf_logpf_logtoclog zy = ln( zx )identical to cf_ln,   pf_lntoc,   ln
cf_log2pf_log2toclog2 zy = lb( zx )binary logarithm
cf_log10pf_log10toclog10 zy = lg( zx )decadic logarithm
cf_powN.A.pow zy = zxzexparbitrary power
cf_powReBaseN.A.pow, powReBase zy = rzxreal base to complex power
cf_powReExpopf_powReExpopow, powReExpo zy = zxrreal power of complex base
cf_quarticpf_quarticquartic zy = zx4fourth power
cf_sinN.A.sin zy = sin( zx )sine
cf_sinhN.A.sinh zy = sinh( zx )hyperbolic sine
cf_squarepf_squaresquare zy = zx2square
cf_sqrtpf_sqrtsqrt zy = sqrt( zx )square root
cf_tanN.A.tan zy = tan( zx )tangent
cf_tanhN.A.tanh zy = tanh( zx )hyperbolic tangent

As noted above, the exponential and logarithm functions provide a natural transition between cartesian and polar coordinates. While there are exp and log functions for fComplex as argument and as return value, cf_exptop takes an fComplex argument and returns fPolar. In the opposite direction, pf_logtoc takes an fPolar argument and returns fComplex.

Back to Table of Contents


3. Error Handling

3.1 General Error Handling of Complex Functions

The error handling of complex functions follows the rules employed generally 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. All error messages eventually generated use the C/Pascal name (rather than the overloaded C++/Delphi name) of the failing function.

If you got CMATH as a part of OptiVec, you should read chapter 5 of HANDBOOK.HTM rather than the present chapter.

Overflow, singularity, and loss-of-precision errors are treated by setting the result to the default value appropriate for each function. DOMAIN / ERANGE errors lead to the result NAN (not-a-number).

Debug libraries only: One may call V_setFPErrorHandling( int fpHandlingMode ); in order to select which error types lead to a message and which may lead to program execution being broken off. The available options are set by the predefined constants fperrXXX:
OptionMeaning
fperrIgnoreTreat all floating-point errors silently
fperrNoteDOMAINNotify in case of DOMAIN / ERANGE errors
fperrAbortDOMAINNotify and break off in case of DOMAIN / ERANGE errors
fperrNoteSINGNotify in case of Singularities (divisions by 0)
fperrAbortSINGNotify and break off in case of Singularities
fperrNoteOVERFLOWNotify in case of Overflow
fperrAbortOVERFLOW  Notify and break off in case of Overflow
fperrNoteTLOSSNotify in case of Total Loss of Precision)
fperrAbortTLOSSNotify and break off in case of Total Loss of Precision
fperrDefaultDefault setting = fperrAbortDOMAIN + fperrNoteSING + fperrNoteOVERFLOW
 
When calling V_setFPErrorHandling, combine these constants by the + or better the OR operator. Note that this influences only the way errors are handled within OptiVec functions. It does not affect the way how the standard C/C++ or Pascal/Delphi functions handle errors.
The repeated occurrence of the same type of error within one and the same function will lead to only one message being generated. Subsequent errors will be treated silently.

Back to Table of Contents

3.2 Advanced Error Handling: Writing Messages into a File

Quite generally, the libraries shipped with compilers do not offer the programmer much control over the way error messages are printed. 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. An additional motivation could come from the fact that, for any error occurring in a Windows program, a message box is displayed and program execution interrupted until you acknowledge having taken notice of the error.

You might wish to circumvent this. To this end, OptiVec and CMATH provide the function V_setErrorEventFile. This function needs as arguments the desired name of your event file and a switch named ScreenAndFile which decides if you wish to have error messages printed simultaneously into the file and onto the screen (ScreenAndFile = TRUE (non-zero)) or exclusively into the file (ScreenAndFile = FALSE (0)).

Example:
V_setErrorEventFile( "MyLogFil.TXT", 0 ); /* C/C++ */
V_setErrorEventFile( 'MyLogFil.TXT', FALSE ); (* Pascal/Delphi *)

Here, you will get all subsequent error messages only into your log file, MyLogFil.TXT and no messages on the screen. The default, i.e., printing error messages to the screen, is restored by V_closeErrorEventFile. (That function does not take any arguments and does not return anything.)

Note that this redirection of error messages is valid only for errors occurring in OptiVec (CMATH) routines. It is possible, however, for a user program to use V_printErrorMsg( const char *MyMessage ) for its own error messages.

Certain configurations of the compilers supported by CMATH do not allow the full set of options described above. For some, either output into a message box is missing or output to the console screen. In these cases, an error message is displayed and the output redirected to the available other option.

Zurück zum Inhaltsverzeichnis


4. Syntax Reference

Except for the data-type conversion functions, only the float / fComplex / fPolar syntax is given. The syntax of the functions for double and extended precisions is exactly analogous.
If you chose the "classic" class complex, this is also similar. Just replace "float" by "double" and "fComplex" by "complex". No polar functions are available in the "classic" class complex, neither do any of the type-casting operators and interconversion functions exist, if there is only one type.

Zurück zum Inhaltsverzeichnis

4.1 Plain-C, Pascal/Delphi Functions

For the functions of double / dComplex / dPolar and extended / eComplex / ePolar precision, the prefixes are cd_, pd_, ce_, and pe_, respectively. The duality of Delphi functions (result returned) and procedures (result stored in variable) ows its existence to historic reasons, namely that early versions of Delphi die not support complex return values. Both forms are, however, completely equivalent.
 
float cf_abs( fComplex __z );
function cf_abs( zx:fComplex ): Single;
 
float pf_abs( fPolar __p );
function pf_abs( px:fPolar ): Single;
 
fComplex cf_acos( fComplex __z );
function cf_acos( zx:fComplex ): fComplex;
procedure cf_acos( var zy:fComplex; zx:fComplex );
 
fComplex cf_add( fComplex __x, fComplex __y );
function cf_add( zx, zy:fComplex ): fComplex;
procedure cf_add( var zz:fComplex; zx, zy:fComplex );
 
fComplex cf_addRe( fComplex __x, float __yRe );
function cf_addRe( zx:fComplex; yRe:Single ): fComplex;
procedure cf_addRe( var zz:fComplex; zx:fComplex; yRe:Single );
 
float cf_arg( fComplex __z );
function cf_arg( zx:fComplex ): Single;
 
float pf_arg( fPolar __z );
function pf_arg( px:fPolar ): Single;
 
fComplex cf_asin( fComplex __z );
function cf_asin( zx:fComplex ): fComplex;
procedure cf_asin( var zy:fComplex; zx:fComplex );
 
fComplex cf_atan( fComplex __z );
function cf_atan( zx:fComplex ): fComplex;
procedure cf_atan( var zy:fComplex; zx:fComplex );
 
eComplex cdtoce( dComplex __zd );
function cdtoce( zx:dComplex ): eComplex;
procedure cdtoce( var zy:eComplex; zx:dComplex );
 
fComplex cdtocf( dComplex __zd );
function cdtocf( zx:dComplex ): fComplex;
procedure cdtocf( var zy:fComplex; zx:dComplex );
 
dPolar cdtopd( dComplex __zd );
function cdtopd( zx:dComplex ): dPolar;
procedure cdtopd( var py:dPolar; zx:dComplex );
 
ePolar cdtope( dComplex __zd );
function cdtope( zx:dComplex ): ePolar;
procedure cdtope( var py:ePolar; zx:dComplex );
 
fPolar cdtopf( dComplex __zd );
function cdtopf( zx:dComplex ): fPolar;
procedure cdtopf( var py:fPolar; zx:dComplex );
 
dComplex cetocd( eComplex __ze );
function cetocd( zx:eComplex ): dComplex;
procedure cetocd( var zy:dComplex; zx:eComplex );
 
fComplex cetocf( eComplex __ze );
function cetocf( zx:eComplex ): fComplex;
procedure cetocf( var zy:fComplex; zx:eComplex );
 
dPolar cetopd( eComplex __ze );
function cetopd( zx:eComplex ): dPolar;
procedure cetopd( var py:dPolar; zx:eComplex );
 
ePolar cetope( eComplex __ze );
function cetope( zx:eComplex ): ePolar;
procedure cetope( var py:ePolar; zx:eComplex );
 
fPolar cetopf( eComplex __ze );
function cetopf( zx:eComplex ): fPolar;
procedure cetopf( var py:fPolar; zx:eComplex );
 
dComplex cftocd( fComplex __zf );
function cftocd( zx:fComplex ): dComplex;
procedure cftocd( var zy:dComplex; zx:fComplex );
 
eComplex cftoce( fComplex __zf );
function cftoce( zx:fComplex ): eComplex;
procedure cftoce( var zy:eComplex; zx:fComplex );
 
dPolar cftopd( fComplex __zf );
function cftopd( zx:fComplex ): dPolar;
procedure cftopd( var py:dPolar; zx:fComplex );
 
ePolar cftope( fComplex __zf );
function cftope( zx:fComplex ): ePolar;
procedure cftope( var py:ePolar; zx:fComplex );
 
fPolar cftopf( fComplex __zf );
function cftopf( zx:fComplex ): fPolar;
procedure cftopf( var py:fPolar; zx:fComplex );
 
fComplex cf_conj( fComplex __z );
function cf_conj( zx:fComplex ): fComplex;
procedure cf_conj( var zy:fComplex; zx:fComplex );
 
fPolar pf_conj( fPolar __p );
function pf_conj( px:fPolar ): fPolar;
procedure pf_conj( var py:fPolar; px:fPolar );
 
fComplex cf_cos( fComplex __z );
function cf_cos( zx:fComplex ): fComplex;
procedure cf_cos( var zy:fComplex; zx:fComplex );
 
fComplex cf_cosh( fComplex __z );
function cf_cosh( zx:fComplex ): fComplex;
procedure cf_cosh( var zy:fComplex; zx:fComplex );
 
fComplex cf_cubic( fComplex __z );
function cf_cubic( zx:fComplex ): fComplex;
procedure cf_cubic( var zy:fComplex; zx:fComplex );
 
fPolar pf_cubic( fPolar __p );
function pf_cubic( px:fPolar ): fPolar;
procedure pf_cubic( var py:fPolar; px:fPolar );
 
fComplex cf_div( fComplex __x, fComplex __y );
function cf_div( zx, zy:fComplex ): fComplex;
procedure cf_div( var zz:fComplex; zx, zy:fComplex );
 
fPolar pf_div( fPolar __x, fPolar __y );
function pf_div( px, py:fPolar ): fPolar;
procedure pf_div( var pz:fPolar; px, py:fPolar );
 
fComplex cf_divRe( fComplex __x, float __yRe ); /* x / yRe */
function cf_divRe( zx:fComplex; yRe:Single ): fComplex;
procedure cf_divRe( var zz:fComplex; zx:fComplex; yRe:Single );
 
fPolar pf_divRe( fPolar __x, float __yRe ); /* x / yRe */
function pf_divRe( px:fPolar; yRe:Single ): fPolar;
procedure pf_divRe( var pz:fPolar; px:fPolar; yRe:Single );
 
fComplex cf_divrRe( fComplex __x, float __yRe ); /* yRe / x */
function cf_divrRe( zx:fComplex; yRe:Single ): fComplex;
procedure cf_divrRe( var zz:fComplex; zx:fComplex; yRe:Single );
 
fPolar pf_divrRe( fPolar __x, float __yRe ); /* yRe / x */
function pf_divrRe( px:fPolar; yRe:Single ): fPolar;
procedure pf_divrRe( var pz:fPolar; px:fPolar; yRe:Single );
 
fComplex cf_exp( fComplex __z );
function cf_exp( zx:fComplex ): fComplex;
procedure cf_exp( var zy:fComplex; zx:fComplex );
 
fPolar cf_exptop( fComplex __z );
function cf_exptop( zx:fComplex ): fPolar;
procedure cf_exptop( var py:fPolar; zx:fComplex );
 
fComplex fcplx( float __ReVal, float __ImVal);
function fcplx( xRe, xIm:Single ): fComplex;
procedure fcplx( var zy:fComplex; xRe, xIm:Single );
 
fPolar fpolr( float __MagVal, float __ArgVal);
function fpolr( xMag, xArg:Single ): fPolar;
procedure fpolr( var py:fPolar; xMag, xArg:Single );
 
float cf_imag( fComplex __z );
function cf_imag( zx:fComplex ): Single;
 
float pf_imag( fPolar __p );
function pf_imag( px:fPolar ): Single;
 
fComplex cf_inv( fComplex __z );
function cf_inv( zx:fComplex ): fComplex;
procedure cf_inv( var zy:fComplex; zx:fComplex );
 
fPolar pf_inv( fPolar __p );
function pf_inv( px:fPolar ): fPolar;
procedure pf_inv( var py:fPolar; zx:fComplex );
 
fComplex cf_ipow( fComplex __z, int __exponent );
function cf_ipow( zx:fComplex; exponent:Integer ): fComplex;
procedure cf_ipow( var zy:fComplex; zx:fComplex; exponent:Integer );
 
fPolar pf_ipow( fPolar __p, int __exponent );
function pf_ipow( px:fPolar; exponent:Integer ): fPolar;
procedure pf_ipow( var py:fPolar; px:fPolar; exponent:Integer );
 
fComplex cf_ln( fComplex __z );
function cf_ln( zx:fComplex ): fComplex;
procedure cf_ln( var zy:fComplex; zx:fComplex );
 
fComplex pf_lntoc( fPolar __p );
function pf_lntoc( px:fPolar ): fComplex;
procedure pf_lntoc( var zy:fComplex; px:fPolar );
 
fComplex cf_log( fComplex __z );
function cf_log( zx:fComplex ): fComplex;
procedure cf_log( var zy:fComplex; zx:fComplex );
 
fComplex pf_logtoc( fPolar __p );
function pf_logtoc( px:fPolar ): fComplex;
procedure pf_logtoc( var zy:fComplex; zx:fPolar );
 
fComplex cf_log2( fComplex __z );
function cf_log2( zx:fComplex ): fComplex;
procedure cf_log2( var zy:fComplex; zx:fComplex );
 
fComplex pf_log2toc( fPolar __p );
function pf_log2toc( px:fPolar ): fComplex;
procedure pf_log2toc( var zy:fComplex; px:fPolar );
 
fComplex cf_log10( fComplex __z );
function cf_log10( zx:fComplex ): fComplex;
procedure cf_log10( var zy:fComplex; zx:fComplex );
 
fComplex pf_log10toc( fPolar __p );
function pf_log10toc( px:fPolar ): fComplex;
procedure pf_log10toc( var zy:fComplex; px:fPolar );
 
fComplex cf_magargtoc( float __mag, float __angle );
function cf_magargtoc( mag, angle:Single ): fComplex;
procedure cf_magargtoc( var zy:fComplex; mag, angle:Single );
 
fComplex cf_mul( fComplex __x, fComplex __y );
function cf_mul( zx, zy:fComplex ): fComplex;
procedure cf_mul( var zz:fComplex; zx, zy:fComplex );
 
fPolar pf_mul( fPolar __x, fPolar __y );
function pf_mul( px, py:fPolar ): fPolar;
procedure pf_mul( var zz:fPolar; zx, zy:fPolar );
 
fComplex cf_mul( fComplex __x, fComplex __y );
function cf_mulconj( zx, zy:fComplex ): fComplex;
procedure cf_mulconj( var zz:fComplex; zx, zy:fComplex );
 
fPolar pf_mulconj( fPolar __x, fPolar __y );
function pf_mulconj( px, py:fPolar ): fPolar;
procedure pf_mulconj( var zz:fPolar; zx, zy:fPolar );
 
fComplex cf_mulRe( fComplex __x, float __yRe );
function cf_mulRe( zx:fComplex; yRe:Single ): fComplex;
procedure cf_mulRe( var zz:fComplex; zx:fComplex; yRe:Single );
 
fPolar pf_mulRe( fPolar __x, float __yRe );
function pf_mulRe( px:fPolar; yRe:Single ): fPolar;
procedure pf_mulRe( var pz:fPolar; px:fPolar; yRe:Single );
 
fComplex cf_neg( fComplex __z );
function cf_neg( zx:fComplex ): fComplex;
procedure cf_neg( var zy:fComplex; zx:fComplex );
 
fPolar pf_neg( fPolar __p );
function pf_neg( px:fPolar ): fPolar;
procedure pf_neg( var py:fPolar; px:fPolar );
 
float cf_norm( fComplex __z );
function cf_norm( zx:fComplex ): Single;
 
float pf_norm( fPolar __p );
function pf_norm( px:fPolar ): Single;
 
dComplex pdtocd( dPolar __pd );
function pdtocd( px:dPolar ): dComplex;
procedure pdtocd( var zy:dComplex; px:dPolar );
 
eComplex pdtoce( dPolar __pd );
function pdtoce( px:dPolar ): eComplex;
procedure pdtoce( var zy:eComplex; px:dPolar );
 
fComplex pdtocf( dPolar __pd );
function pdtocf( px:dPolar ): fComplex;
procedure pdtocf( var zy:fComplex; px:dPolar );
 
ePolar pdtope( dPolar __pd );
function pdtope( px:dPolar ): ePolar;
procedure pdtope( var py:ePolar; px:dPolar );
 
fPolar pdtopf( dPolar __pd );
function pdtopf( px:dPolar ): fPolar;
procedure pdtopf( var py:fPolar; px:dPolar );
 
dComplex petocd( ePolar __pe );
function petocd( px:ePolar ): dComplex;
procedure petocd( var zy:dComplex; px:ePolar );
 
eComplex petoce( ePolar __pe );
function petoce( px:ePolar ): eComplex;
procedure petoce( var zy:eComplex; px:ePolar );
 
fComplex petocf( ePolar __pe );
function petocf( px:ePolar ): fComplex;
procedure petocf( var zy:fComplex; px:ePolar );
 
dPolar petopd( ePolar __pe );
function petopd( px:ePolar ): dPolar;
procedure petopd( var py:dPolar; px:ePolar );
 
fPolar petopf( ePolar __pe );
function petopf( px:ePolar ): fPolar;
procedure petopf( var zy:fPolar; zx:ePolar );
 
dComplex pftocd( fPolar __pf );
function pftocd( px:fPolar ): dComplex;
procedure pftocd( var zy:dComplex; px:fPolar );
 
eComplex pftoce( fPolar __pf );
function pftoce( px:fPolar ): eComplex;
procedure pftoce( var zy:eComplex; px:fPolar );
 
fComplex pftocf( fPolar __pf );
function pftocf( px:fPolar ): fComplex;
procedure pftocf( var zy:fComplex; px:fPolar );
 
dPolar pftopd( fPolar __pf );
function pftopd( px:fPolar ): dPolar;
procedure pftopd( var zy:dPolar; zx:fPolar );
 
ePolar pftope( fPolar __pf );
function pftope( px:fPolar ): ePolar;
procedure pftope( var zy:ePolar; zx:fPolar );
 
fComplex cf_polar( float mag, float arg ); /* same as cf_magargtoc */
function cf_polar( mag, arg:Single ): fComplex;
procedure cf_polar( var zy:fComplex; mag, arg:Single );
 
fComplex cf_pow( fComplex __base, fComplex __exponent );
function cf_pow( zx:fComplex; exponent:Integer ): fComplex;
procedure cf_pow( var zy:fComplex; zx:fComplex; exponent:Integer );
 
fComplex cf_powReBase( float __base, fComplex __exponent );
function cf_powReBase( base:Single; exponent:fComplex ): fComplex;
procedure cf_powReBase( var zy:fComplex; base:Single; exponent:fComplex );
 
fComplex cf_powReExpo( fComplex __base, float __exponent );
function cf_powReExpo( zx:fComplex; exponent:Single ): fComplex;
procedure cf_powReExpo( var zy:fComplex; zx:fComplex; exponent:Single );
 
fPolar pf_powReExpo( fPolar __base, float __exponent );
function pf_powReExpo( px:fPolar; exponent:Single ): fPolar;
procedure pf_powReExpo( var py:fPolar; px:fPolar; exponent:Single );
 
fComplex cf_quartic( fComplex __z );
function cf_quartic( zx:fComplex ): fComplex;
procedure cf_quartic( var zy:fComplex; zx:fComplex );
 
fPolar pf_quartic( fPolar __p );
function pf_quartic( px:fPolar ): fPolar;
procedure pf_quartic( var py:fPolar; zx:fPolar );
 
float cf_real( fComplex __z );
function cf_real( zx:fComplex ): Single;
 
float pf_real( fPolar __p );
function pf_real( px:fPolar ): Single;
 
fComplex cf_sin( fComplex __z );
function cf_sin( zx:fComplex ): fComplex;
procedure cf_sin( var zy:fComplex; zx:fComplex );
 
fComplex cf_sinh( fComplex __z );
function cf_sinh( zx:fComplex ): fComplex;
procedure cf_sinh( var zy:fComplex; zx:fComplex );
 
fComplex cf_square( fComplex __z );
function cf_square( zx:fComplex ): fComplex;
procedure cf_square( var zy:fComplex; zx:fComplex );
 
fPolar pf_square( fPolar __p );
function pf_square( px:fPolar ): fPolar;
procedure pf_square( var py:fPolar; zx:fPolar );
 
fComplex cf_sqrt( fComplex __z );
function cf_sqrt( zx:fComplex ): fComplex;
procedure cf_sqrt( var zy:fComplex; zx:fComplex );
 
fPolar pf_sqrt( fPolar __p );
function pf_sqrt( px:fPolar ): fPolar;
procedure pf_sqrt( var py:fPolar; px:fPolar );
 
fComplex cf_sub( fComplex __x, fComplex __y );
function cf_sub( zx, zy:fComplex ): fComplex;
procedure cf_sub( var zz:fComplex; zx, zy:fComplex );
 
fComplex cf_subRe( fComplex __x, float __yRe ); /* x - yRe */
function cf_subRe( zx:fComplex; yRe:Single ): fComplex;
procedure cf_subRe( var zz:fComplex; zx:fComplex; yRe:Single );
 
fComplex cf_subrRe( fComplex __x, float __yRe ); /* yRe - x */
function cf_subrRe( zx:fComplex; yRe:Single ): fComplex;
procedure cf_subrRe( var zz:fComplex; zx:fComplex; yRe:Single );
 
fComplex cf_tan( fComplex __z );
function cf_tan( zx:fComplex ): fComplex;
procedure cf_tan( var zy:fComplex; zx:fComplex );
 
fComplex cf_tanh( fComplex __z );
function cf_tanh( zx:fComplex ): fComplex;
procedure cf_tanh( var zy:fComplex; zx:fComplex );

Back to Table of Contents


 

4.2 Overloaded C++/Delphi Functions

float abs( fComplex _z );
function abs( zx:fComplex ): Single;
 
float abs( fPolar _p );
function abs( px:fPolar ): Single;
 
fComplex acos( fComplex _z );
function acos( zx:fComplex ): fComplex;
 
function add( zx, zy:fComplex ): fComplex;
function add( zx:fComplex; yRe:Single ): fComplex;
function add( yRe:Single; zx:fComplex ): fComplex;
function addRe( zx:fComplex; yRe:Single ): fComplex;
 
float arg( fComplex _z );
function arg( zx:fComplex ): Single;
 
float arg( fPolar _p );
function arg( px:fPolar ): Single;
 
fComplex asin( fComplex _z );
function asin( zx:fComplex ): fComplex;
 
fComplex atan( fComplex _z );
function atan( zx:fComplex ): fComplex;
 
fComplex conj( fComplex _z );
function conj( zx:fComplex ): fComplex;
 
fPolar conj( fPolar _p );
function conj( px:fPolar ): fPolar;
 
fComplex cos( fComplex _z );
function cos( zx:fComplex ): fComplex;
 
fComplex cosh( fComplex _z );
function cosh( zx:fComplex ): fComplex;
 
fComplex cubic( fComplex _z );
function cubic( zx:fComplex ): fComplex;
 
fPolar cubic( fPolar _p );
function cubic( px:fPolar ): fPolar;
 
function divide( zx, zy:fComplex ): fComplex;
function divide( zx:fComplex; yRe:Single ): fComplex;
function divide( yRe:Single; zx:fComplex ): fComplex;
function divide( px, py:fPolar ): fPolar;
function divide( px:fPolar; yRe:Single ): fPolar;
function divide( yRe:Single; px:fPolar ): fPolar;
 
function divRe( zx:fComplex; yRe:Single ): fComplex;
function divRe( px:fPolar; yRe:Single ): fPolar;
function divrRe( zx:fComplex; yRe:Single ): fComplex;
function divrRe( px:fPolar; yRe:Single ): fPolar;
 
fComplex exp( fComplex _z );
function exp( zx:fComplex ): fComplex;
 
fPolar exptop( fComplex _z );
function exptop( zx:fComplex ): fPolar;
 
fComplex fComplex( float Re_part, float Im_part=0 );
fComplex fComplex( dComplex cd );
fComplex fComplex( eComplex ce ); // type-casting constructors
fComplex fComplex( fPolar pf ); // interconversion from polar
fComplex fComplex( dPolar pd );
fComplex fComplex( ePolar pe );
 
float imag(); // to be used as zim = z.imag();
float imag( fComplex _z ); // to be used as zim = imag( z );
function imag( zx:fComplex ): Single;
 
float imag( fPolar _p );
function imag( px:fPolar ): Single;
fComplex inv( fComplex _z );
function inv( zx:fComplex ): fComplex;
 
fPolar inv( fPolar _p );
function inv( px:fPolar ): fPolar;
 
fComplex ipow( fComplex __base, int __expon );
function ipow( zx:fComplex; exponent:Integer ): fComplex;
 
fPolar ipow( fPolar __base, int __expon );
function ipow( px:fPolar; exponent:Integer ): fPolar;
 
fComplex ln( fComplex _z );
function ln( zx:fComplex ): fComplex;
 
fComplex lntoc( fPolar _p );
function lntoc( px:fPolar ): fComplex;
 
fComplex log( fComplex _z );
function log( zx:fComplex ): fComplex;
 
fComplex logtoc( fPolar _p );
function logtoc( px:fPolar ): fComplex;
 
fComplex log2( fComplex _z );
function log2( zx:fComplex ): fComplex;
 
fComplex log2toc( fPolar _p );
function log2toc( px:fPolar ): fComplex;
 
fComplex log10( fComplex _z );
function log10( zx:fComplex ): fComplex;
 
fComplex log10toc( fPolar _p );
function log10toc( px:fPolar ): fComplex;
 
fComplex magargtoc( float _mag, float _angle );
function magargtoc( mag, angle:Single ): fComplex;
 
function mul( zx, zy:fComplex ): fComplex;
function mul( zx:fComplex; yRe:Single ): fComplex;
function mul( yRe:Single; zx:fComplex ): fComplex;
function mul( px, py:fPolar ): fPolar;
function mul( px:fPolar; yRe:Single ): fPolar;
function mul( yRe:Single; px:fPolar ): fPolar;
 
function mulRe( zx:fComplex; yRe:Single ): fComplex;
function mulRe( px:fPolar; yRe:Single ): fPolar;
 
fComplex neg( fComplex _z );
function neg( zx:fComplex ): fComplex;
 
fPolar neg( fPolar _p );
function neg( px:fPolar ): fPolar;
 
float norm( fComplex _z );
function norm( zx:fComplex ): Single;
 
float norm( fPolar _p );
function norm( px:fPolar ): Single;
 
fComplex pow( fComplex __base, fComplex __expon);
fComplex pow( float __base, fComplex __expon);
fComplex pow( fComplex __base, float __expon );
function pow( zx, exponent:fComplex ): fComplex;
function pow( zx:fComplex; exponent:Single ): fComplex;
function pow( base:Single; exponent:fComplex ): fComplex;
function pow( px:fPolar; exponent:Single ): fPolar;
 
fComplex powReBase( float __base, fComplex __expon );
function powReBase( base:Single; exponent:fComplex ): fComplex;
 
fComplex powReExpo( fComplex __base, float __expon );
function powReExpo( zx:fComplex; exponent:Single ): fComplex;
 
fPolar powReExpo( fPolar __base, float __expon );
function powReExpo( px:fPolar; exponent:Single ): fPolar;
 
fPolar principal( fPolar _p );
fPolar principal( floag __mag, float __arg );
function principal( px:fPolar ): fPolar;
 
fComplex quartic( fComplex _z );
function quartic( zx:fComplex ): fComplex;
 
fPolar quartic( fPolar _p );
function quartic( px:fPolar ): fPolar;
 
float z.real(); // to be used as zre = z.real();
float real( fComplex _z ); // to be used as zre = real ( _z );
function real( zx:fComplex ): Single;
 
float real( fPolar _p );
function real( px:fPolar ): Single;
 
fPolar reimtop( float _re, float _im );
function reimtop( re, im:Single ): fPolar;
 
fComplex sin( fComplex _z );
function sin( zx:fComplex ): fComplex;
 
fComplex sinh( fComplex _z );
function sinh( zx:fComplex ): fComplex;
 
fComplex sqrt( fComplex _z );
function sqrt( zx:fComplex ): fComplex;
 
fPolar sqrt( fPolar _p );
function sqrt( px:fPolar ): fPolar;
 
fComplex square( fComplex _z );
function square( zx:fComplex ): fComplex;
 
fPolar square( fPolar _z );
function square( px:fPolar ): fPolar;
 
function sub( zx, zy:fComplex ): fComplex;
function sub( zx:fComplex; yRe:Single ): fComplex;
function sub( yRe:Single; zx:fComplex ): fComplex;
function subRe( zx:fComplex; yRe:Single ): fComplex;
function subrRe( zx:fComplex; yRe:Single ): fComplex;
 
fComplex tan( fComplex _z );
function tan( zx:fComplex ): fComplex;
 
fComplex tanh( fComplex _z );
function tanh( zx:fComplex ): fComplex;

Back to Table of Contents


E N D

Copyright for OptiVec and CMATH software and documentation
© 1996-2024 OptiCode - Dr. Martin Sander Software Dev.
All rights reserved!