home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / optivc16 / cdmath.h < prev    next >
Encoding:
C/C++ Source or Header  |  1999-03-06  |  15.1 KB  |  450 lines

  1. /*    CDMATH.H
  2.  
  3.       Complex library for the languages C and C++.
  4.  
  5.       This header file contains all definitions for
  6.       double-precision complex numbers (complex double).
  7.  
  8.       Copyright (C) 1996-1999 Martin Sander
  9.       Address of the author:
  10.            Dr. Martin Sander Software Dev.
  11.            Sertuernerstr. 11
  12.            D-37085 Goettingen
  13.            Germany
  14.            MartinSander@Bigfoot.com
  15.            http://www.optivec.com
  16. */
  17.  
  18.  
  19. #ifndef __CDMATH_H
  20. #define __CDMATH_H
  21.  
  22. #if !defined( _CMATH_DEFS )
  23.    #ifdef __BORLANDC__
  24.        #pragma option -a-
  25.    #else /* Visual C++, Optima++ */
  26.        #pragma pack( push,1 )
  27.    #endif /* avoid insertion of dummy bytes  */
  28.    typedef struct {float    Re, Im;} fComplex;
  29.    typedef struct {double   Re, Im;} dComplex;
  30.    #ifdef __BORLANDC__
  31.        typedef long double    extended;
  32.        typedef struct {extended Re, Im;} eComplex;
  33.        #pragma option -a.
  34.    #else /* Visual C++, Optima++ */
  35.        typedef  double extended; /* Visual C++ does not support
  36.                                  80-bit IEEE numbers. So make
  37.                                  extended equal to double    */
  38.        typedef dComplex  eComplex;
  39.        #pragma pack( pop )
  40.    #endif    /* restore default data packing  */
  41.    typedef fComplex fcomplex;
  42.    typedef dComplex dcomplex;
  43.    typedef eComplex ecomplex;  // tolerate all-minuscule
  44.    #define _CMATH_DEFS
  45. #endif
  46. #ifdef __BORLANDC__
  47.     #include <_defs.h>
  48.     #if defined __TINY || defined __SMALL__ || defined __MEDIUM__
  49.         #if defined(_RTLDLL) || defined(_CLASSDLL)
  50.             #error Must use static BC Runtime Library with OptiVec and CMATH in models TINY, SMALL, MEDIUM
  51.         #endif
  52.         #define   _VFAR  near   /* even in case of DS!=SS  */
  53.     #elif defined __FLAT__
  54.         #define  _VFAR
  55.     #else
  56.         #define   _VFAR  far
  57.     #endif
  58.     #if (__BORLANDC__ >= 0x450)
  59.          #define __cmf _RTLENTRY _EXPFUNC
  60.     #else
  61.          #define __cmf  _Cdecl _FARFUNC
  62.     #endif
  63. #else  /* Visual C++, Optima++ */
  64.     #define _VFAR
  65.     #define __cmf  __cdecl
  66. #endif
  67. #define _VFARC const _VFAR
  68.  
  69. /*  first the constructors:  */
  70. #ifdef __cplusplus
  71.    /* since dComplex is declared as a struct instead of a class,
  72.       the constructor cannot get the name "dComplex" here.     */
  73.   #ifndef _DCPLX_DEFINED
  74.   inline dComplex __cmf dcplx( double __ReVal )
  75.   {   dComplex Result;
  76.       Result.Re = __ReVal;
  77.       Result.Im = 0.0;
  78.       return Result;
  79.   }
  80.  
  81.       // up-conversions from single precision
  82.   inline dComplex __cmf dcplx( fComplex _VFARC & __zf )
  83.   {   dComplex Result;
  84.       Result.Re = __zf.Re;
  85.       Result.Im = __zf.Im;
  86.       return Result;
  87.   }
  88.       // down-conversion from extended precision
  89.       // (with OVERFLOW error handling):
  90.   #ifdef __BORLANDC__
  91.       dComplex __cmf dcplx( eComplex __ze );
  92.   #else
  93.       inline dComplex _VFAR & __cmf dcplx( dComplex _VFAR & __zd )
  94.       {   return __zd;  }  // necessary because eComplex=dComplex
  95.   #endif
  96.   #define _DCPLX_DEFINED
  97.   #endif  // _DCPLX_DEFINED
  98. #endif   /* basic form of constructor for C and C++ : */
  99.    dComplex __cmf dcplx( double __ReVal, double __ImVal);
  100.          /* conversion from fComplex and eComplex (with OVERFLOW handling) */
  101. #if !defined __NEWCPLX_H
  102.     #if defined __cplusplus
  103.         extern "C" {
  104.     #endif
  105.     dComplex __cmf cftocd( fComplex __zf );
  106.     dComplex __cmf cetocd( eComplex __ze );
  107.     #if defined __cplusplus
  108.         }
  109.     #endif
  110. #endif
  111.  
  112.    /* Basic complex operations. They are defined both
  113.    for C and C++. However, for C++ you may as well use the
  114.    overloaded operators and functions defined further below. */
  115. #define         cd_real( z )  (z).Re
  116. #define         cd_imag( z )  (z).Im
  117. #if defined __cplusplus && !defined _CMATH_CLASSDEFS 
  118. extern "C" {  // the following functions cannot be "extern C",
  119. #endif        // if dComplex identical to complex<double>
  120. dComplex __cmf  cd_neg(  dComplex __z );
  121. dComplex __cmf  cd_conj( dComplex __z );
  122. #ifdef __cplusplus  // even if _CMATH_CLASSDEFS
  123.     extern "C" double   __cmf  cd_norm( dComplex __z );
  124.     extern "C" double   __cmf  cd_arg(  dComplex __z );
  125. #else
  126.     double   __cmf  cd_norm( dComplex __z );
  127.     double   __cmf  cd_arg(  dComplex __z );
  128. #endif
  129. dComplex __cmf  cd_polar( double __mag, double __angle );
  130.  
  131. dComplex __cmf  cd_add(   dComplex __x, dComplex __y );
  132. dComplex __cmf  cd_addRe( dComplex __x, double __yRe );
  133. dComplex __cmf  cd_sub(   dComplex __x, dComplex __y );
  134. dComplex __cmf  cd_subRe( dComplex __x, double __yRe );  /*  x - yRe  */
  135. dComplex __cmf  cd_subrRe( dComplex __x, double __yRe ); /*  yRe - x  */
  136. dComplex __cmf  cd_mul(   dComplex __x, dComplex __y );
  137. dComplex __cmf  cd_mulRe( dComplex __x, double __yRe );
  138. dComplex __cmf  cd_div(   dComplex __x, dComplex __y );
  139. dComplex __cmf  cd_divRe( dComplex __x, double __yRe );   /*  x / yRe  */
  140. dComplex __cmf  cd_divrRe( dComplex __x, double __yRe );  /*  yRe / x  */
  141.  
  142. /*  mathematical functions with error handling through _matherr: */
  143. #ifdef __cplusplus 
  144.     extern "C" double   __cmf  cd_abs(  dComplex __z );
  145. #else
  146.     double   __cmf  cd_abs(  dComplex __z );
  147. #endif
  148. dComplex __cmf  cd_acos( dComplex __z );
  149. dComplex __cmf  cd_asin( dComplex __z );
  150. dComplex __cmf  cd_atan( dComplex __z );
  151. dComplex __cmf  cd_cos(  dComplex __z );
  152. dComplex __cmf  cd_cosh( dComplex __z );
  153. dComplex __cmf  cd_cubic( dComplex __z );  /* raise to the third power */
  154. dComplex __cmf  cd_exp(  dComplex __z );
  155. dComplex __cmf  cd_inv(  dComplex __z );    /*   1.0 / z   */
  156. dComplex __cmf  cd_ipow( dComplex __z, int __exponent );
  157.                                              /* raise z to integer power */
  158. dComplex __cmf  cd_ln(   dComplex __z );
  159. dComplex __cmf  cd_log(   dComplex __z );  /* sane as cd_ln */
  160. dComplex __cmf  cd_log2(  dComplex __z );
  161. dComplex __cmf  cd_log10( dComplex __z );
  162. dComplex __cmf  cd_pow( dComplex __base, dComplex __exponent );
  163. dComplex __cmf  cd_powReBase( double __base, dComplex __exponent ); /* power of real base */
  164. dComplex __cmf  cd_powReExpo( dComplex __base, double __exponent ); /* raise z to real power */
  165.                          /* for integer exponents, use cd_ipow ! */
  166. dComplex __cmf  cd_quartic( dComplex __z );  /* raise to the fourth power */
  167. dComplex __cmf  cd_sin(  dComplex __z );
  168. dComplex __cmf  cd_sinh( dComplex __z );
  169. dComplex __cmf  cd_square( dComplex __z );
  170. dComplex __cmf  cd_sqrt( dComplex __z );
  171. dComplex __cmf  cd_tan(  dComplex __z );
  172. dComplex __cmf  cd_tanh( dComplex __z );
  173.  
  174.  
  175. #if defined __cplusplus && !defined _CMATH_CLASSDEFS
  176. }    //  end of the extern "C" statement
  177. #endif
  178.  
  179. #if defined __cplusplus && !defined __STD_COMPLEX && !defined __COMPLEX_H && !defined __NEWCPLX_H
  180.    /* in addition to the basic operations defined above for C,
  181.       here is the same complete set of overloaded operators and
  182.       functions as offered by <newcplx.h> for the complex classes.  */
  183.  
  184.     inline double real( dComplex _VFARC & __z )
  185.     {
  186.         return __z.Re;
  187.     }
  188.  
  189.     inline double imag( dComplex _VFARC & __z )
  190.     {
  191.         return __z.Im;
  192.     }
  193.  
  194.     inline dComplex neg( dComplex _VFARC & __z1 )
  195.     {   dComplex Result;
  196.         Result.Re = -__z1.Re;
  197.         Result.Im = -__z1.Im;
  198.         return Result;
  199.     }
  200.  
  201.     inline dComplex conj( dComplex _VFARC & __z)
  202.     {   dComplex Result;
  203.         Result.Re =  __z.Re;
  204.         Result.Im = -__z.Im;
  205.         return Result;
  206.     }
  207.  
  208.     double   __cmf  norm( dComplex __z );
  209.     double   __cmf  arg(  dComplex __z );
  210.     dComplex __cmf  polar( double Mag, double Angle );
  211.  
  212.   //  unary operators:
  213.  
  214.   inline dComplex _VFAR & operator +( dComplex _VFAR & __z1 )
  215.   {
  216.       return __z1;
  217.   }
  218.  
  219.   inline dComplex operator -( dComplex _VFARC & __z1 )
  220.   {   dComplex Result;
  221.       Result.Re = -__z1.Re;
  222.       Result.Im = -__z1.Im;
  223.       return Result;
  224.   }
  225.  
  226.  
  227.   //  binary operators:
  228.  
  229.   inline dComplex operator +( dComplex _VFARC & __z1, dComplex _VFARC & __z2 )
  230.   {   dComplex Result;
  231.       Result.Re = __z1.Re + __z2.Re;
  232.       Result.Im = __z1.Im + __z2.Im;
  233.       return Result;
  234.   }
  235.  
  236.   inline dComplex operator +( dComplex _VFARC & __z1, double __z2Re )
  237.   {   dComplex Result;
  238.       Result.Re = __z1.Re + __z2Re;
  239.       Result.Im = __z1.Im;
  240.       return Result;
  241.   }
  242.  
  243.   inline dComplex operator +( double __z1Re, dComplex _VFARC & __z2 )
  244.   {   dComplex Result;
  245.       Result.Re = __z1Re + __z2.Re;
  246.       Result.Im = __z2.Im;
  247.       return Result;
  248.   }
  249.  
  250.   inline dComplex operator -( dComplex _VFARC & __z1, dComplex _VFARC & __z2 )
  251.   {   dComplex Result;
  252.       Result.Re = __z1.Re - __z2.Re;
  253.       Result.Im = __z1.Im - __z2.Im;
  254.       return Result;
  255.   }
  256.  
  257.   inline dComplex operator -( dComplex _VFARC & __z1, double __z2Re )
  258.   {   dComplex Result;
  259.       Result.Re = __z1.Re - __z2Re;
  260.       Result.Im = __z1.Im;
  261.       return Result;
  262.   }
  263.  
  264.   inline dComplex operator -( double __z1Re, dComplex _VFARC & __z2 )
  265.   {   dComplex Result;
  266.       Result.Re = __z1Re - __z2.Re;
  267.       Result.Im = -__z2.Im;
  268.       return Result;
  269.   }
  270.  
  271.   inline dComplex operator *( dComplex _VFARC & __z1, dComplex _VFARC & __z2 )
  272.   {   dComplex Result;
  273.       Result.Re  = __z1.Re * __z2.Re - __z1.Im * __z2.Im;
  274.       Result.Im  = __z1.Re * __z2.Im + __z1.Im * __z2.Re;
  275.       return Result;
  276.   }
  277.  
  278.   inline dComplex operator *( dComplex _VFARC & __z1, double __z2Re )
  279.   {   dComplex Result;
  280.       Result.Re = __z1.Re * __z2Re;
  281.       Result.Im = __z1.Im * __z2Re;
  282.       return Result;
  283.   }
  284.  
  285.   inline dComplex operator *( double __z1Re, dComplex _VFARC & __z2 )
  286.   {   dComplex Result;
  287.       Result.Re  = __z1Re * __z2.Re;
  288.       Result.Im  = __z1Re * __z2.Im;
  289.       return Result;
  290.   }
  291.  
  292.   inline dComplex operator /( dComplex _VFARC & __z1, double __z2Re )
  293.   {   dComplex Result;
  294.       Result.Re = __z1.Re / __z2Re;
  295.       Result.Im = __z1.Im / __z2Re;
  296.       return Result;
  297.   }
  298.  
  299.  
  300.   dComplex operator /( dComplex _VFARC & __z1, dComplex _VFARC & __z2 );
  301.   dComplex operator /( double __z1Re, dComplex _VFARC & __z2 );
  302.  
  303.     /* most versions of BC will ignore the definitions of
  304.        compound-assignment operators; they are needed for
  305.        MSVC and Optima++                                  */
  306.   inline dComplex _VFAR & operator +=( dComplex _VFAR & __z1, dComplex _VFARC & __z2 )
  307.   {
  308.       __z1.Re += __z2.Re;
  309.       __z1.Im += __z2.Im;
  310.       return __z1;
  311.   }
  312.  
  313.   inline dComplex _VFAR & operator +=( dComplex _VFAR & __z1, double __z2Re )
  314.   {
  315.       __z1.Re += __z2Re;
  316.       return __z1;
  317.   }
  318.  
  319.   inline dComplex _VFAR & operator -=( dComplex _VFAR & __z1, dComplex _VFARC & __z2 )
  320.   {
  321.       __z1.Re -= __z2.Re;
  322.       __z1.Im -= __z2.Im;
  323.       return __z1;
  324.   }
  325.  
  326.   inline dComplex _VFAR & operator -=( dComplex _VFAR & __z1, double __z2Re )
  327.   {
  328.       __z1.Re -= __z2Re;
  329.       return __z1;
  330.   }
  331.  
  332.   inline dComplex _VFAR & operator *=( dComplex _VFAR & __z1, dComplex _VFARC & __z2 )
  333.   {
  334.       double tmpRe;
  335.       tmpRe   = __z1.Re * __z2.Re - __z1.Im * __z2.Im;
  336.       __z1.Im = __z1.Re * __z2.Im + __z1.Im * __z2.Re;
  337.       __z1.Re = tmpRe;
  338.       return __z1;
  339.   }
  340.  
  341.   inline dComplex _VFAR & operator *=( dComplex _VFAR & __z1, double __z2Re )
  342.   {
  343.       __z1.Re *= __z2Re;
  344.       __z1.Im *= __z2Re;
  345.       return __z1;
  346.   }
  347.  
  348.   dComplex _VFAR & operator /=( dComplex _VFAR & __z1, dComplex _VFARC & __z2 );
  349.  
  350.   inline dComplex _VFAR & operator /=( dComplex _VFAR & __z1, double __z2Re )
  351.   {
  352.       __z1.Re /= __z2Re;
  353.       __z1.Im /= __z2Re;
  354.       return __z1;
  355.   }
  356.  
  357.  
  358.   inline int operator ==( dComplex _VFARC & __z1, dComplex _VFARC & __z2 )
  359.   {
  360.       return (__z1.Re == __z2.Re) && (__z1.Im == __z2.Im );
  361.   }
  362.  
  363.   inline int operator ==( dComplex _VFARC & __z1, double __z2Re )
  364.   {
  365.       return (__z1.Re == __z2Re) && (__z1.Im == 0.0 );
  366.   }
  367.  
  368.   inline int operator !=( dComplex _VFARC & __z1, dComplex _VFARC & __z2 )
  369.   {
  370.       return (__z1.Re != __z2.Re) || (__z1.Im != __z2.Im );
  371.   }
  372.  
  373.   inline int operator !=( dComplex _VFARC & __z1, double __z2Re )
  374.   {
  375.       return (__z1.Im != 0.0 ) || (__z1.Re != __z2Re);
  376.   }
  377.  
  378.  
  379.   /*  C++ version of the mathematical functions defined above.
  380.       They use the same code as the C versions. In case of an error,
  381.       you get a message in which the name of the C version is
  382.       stated.
  383.       Note that these functions require complex arguments to be
  384.       passed by value, not by reference, as it is done in the member
  385.       functions of the class complex. In terms of efficiency, this
  386.       is about the same. (The math functions of the class complex
  387.       store complex results at intermediate addresses and copy them
  388.       to the desired address afterwards. This final copy is not
  389.       necessary here.)                                             */
  390.  
  391.   double    __cmf  abs(  dComplex __z );
  392.   dComplex __cmf  acos( dComplex __z );
  393.   dComplex __cmf  asin( dComplex __z );
  394.   dComplex __cmf  atan( dComplex __z );
  395.   dComplex __cmf  cos(  dComplex __z );
  396.   dComplex __cmf  cosh( dComplex __z );
  397.   dComplex __cmf  cubic( dComplex __z );  /* raise to the third power */
  398.   dComplex __cmf  exp(  dComplex __z );
  399.   dComplex __cmf  inv(  dComplex __z );    /*   1.0 / z   */
  400.   dComplex __cmf  ipow( dComplex __z, int __exponent );
  401.                                             /* raise z to integer power */
  402.   dComplex __cmf  ln(  dComplex __z );
  403.   dComplex __cmf  log(  dComplex __z );  /* sane as ln */
  404.   dComplex __cmf  log2( dComplex __z );
  405.   dComplex __cmf  log10( dComplex __z );
  406.   dComplex __cmf  pow( dComplex __z, dComplex __exponent );
  407.   dComplex __cmf  pow( dComplex __z,  double __exponent ); // identical to powReExpo
  408.   dComplex __cmf  pow( double __base,  dComplex __exponent ); // identical to powReBase
  409.   dComplex __cmf  powReBase( double __base, dComplex __exponent ); // power of real base
  410.   dComplex __cmf  powReExpo( dComplex __z, double __exponent );    // raise z to real power
  411.                             // for integer exponents, use ipow !
  412.   dComplex __cmf  quartic( dComplex __z );  // raise to the fourth power
  413.   dComplex __cmf  sin(  dComplex __z );
  414.   dComplex __cmf  sinh( dComplex __z );
  415.   dComplex __cmf  square( dComplex __z );
  416.   dComplex __cmf  sqrt( dComplex __z );
  417.   dComplex __cmf  tan(  dComplex __z );
  418.   dComplex __cmf  tanh( dComplex __z );
  419. #endif //  __cplusplus, not __STD_COMPLEX , __COMPLEX_H, __NEWCPLX_H
  420.  
  421.  
  422. /***  user-accessible error handling functions, borrowed from VectorLib  ****/
  423.  
  424. #ifdef __cplusplus
  425. extern "C" {
  426. #endif
  427. void  __cmf  V_noteError( char _VFAR *fname, unsigned why );
  428. void  __cmf  V_printErrorMsg( char _VFAR *ErrMsg );
  429. void  __cmf  V_setErrorEventFile( char _VFAR *filename,  unsigned ScreenAndFile );
  430. void  __cmf  V_closeErrorEventFile( void );
  431.  
  432. /*** translation of calls to matherr() into _matherr() for BorlandC 4.0+ ***/
  433.  
  434. #if (__BORLANDC__ >= 0x450) && !defined (__FLAT__)
  435.      #if !defined( __MATH_H )
  436.             #include <math.h>
  437.      #endif
  438.      int  _Cdecl _FARFUNC matherr (struct exception _VFAR *__e);
  439.      #define NEWMATHERR  \
  440.          int matherr( struct exception _VFAR *__e ) \
  441.          {  return( _matherr( __e )); }
  442. #else
  443.      #define NEWMATHERR
  444. #endif
  445.  
  446. #ifdef __cplusplus
  447. }   // end of extern "C"
  448. #endif
  449. #endif   /*  __CDMATH_H  */
  450.