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

  1. /*    CFMATH.H
  2.  
  3.       Complex library for the languages C and C++.
  4.  
  5.       This header file contains all definitions for
  6.       single-precision complex numbers (complex float).
  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 __CFMATH_H
  20. #define __CFMATH_H
  21.  
  22. #if !defined( _CMATH_DEFS )
  23.    #ifdef __BORLANDC__
  24.        #pragma option -a-
  25.    #else /* Visual C++ */
  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++ */
  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-lower case
  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 fComplex is declared as a struct instead of a class,
  72.       the constructor cannot get the name "fComplex" here.     */
  73.   #ifndef _FCPLX_DEFINED
  74.   inline fComplex __cmf fcplx( float __ReVal )
  75.   {   fComplex Result;
  76.       Result.Re = __ReVal;
  77.       Result.Im = 0.0f;
  78.       return Result;
  79.   }
  80.  
  81.       // down-conversions from double and extended precision
  82.       // (with OVERFLOW error handling):
  83.   fComplex __cmf fcplx( dComplex __zd );
  84.   #if defined __COMPLEX_H
  85.       fComplex __cmf fcplx( complex __z );
  86.   #endif
  87.   #ifdef __BORLANDC__
  88.       fComplex __cmf fcplx( eComplex __ze );
  89.   #endif
  90.   #define _FCPLX_DEFINED
  91.   #endif  // _FCPLX_DEFINED
  92. #endif  
  93.       /* basic form of constructor for C and C++ : */
  94.    fComplex __cmf fcplx( float __ReVal, float __ImVal);
  95.          /* down-conversion with OVERFLOW-handling:  */
  96. #if !defined __NEWCPLX_H
  97.     #if defined __cplusplus
  98.         extern "C" {
  99.     #endif
  100.     fComplex __cmf cdtocf( dComplex __zd );
  101.     fComplex __cmf cetocf( eComplex __ze );
  102.     #if defined __cplusplus
  103.         }
  104.     #endif
  105. #endif
  106.  
  107.    /* Basic complex operations. They are defined both
  108.    for C and C++. However, for C++ you may as well use the
  109.    overloaded operators and functions defined further below. */
  110. #define         cf_real( z )  (z).Re
  111. #define         cf_imag( z )  (z).Im
  112. #if defined __cplusplus && !defined _CMATH_CLASSDEFS 
  113. extern "C" {  // the following functions cannot be "extern C",
  114. #endif       // if fComplex identical with complex<float>
  115.  
  116. fComplex __cmf  cf_neg(  fComplex __z );
  117. fComplex __cmf  cf_conj( fComplex __z );
  118.  
  119. #ifdef __cplusplus  // even if _CMATH_CLASSDEFS
  120.     extern "C" float __cmf  cf_norm( fComplex __z );
  121.     extern "C" float __cmf  cf_arg(  fComplex __z );
  122. #else
  123.     float __cmf  cf_norm( fComplex __z );
  124.     float __cmf  cf_arg(  fComplex __z );
  125. #endif
  126. fComplex __cmf  cf_polar( float __mag, float __angle );
  127.  
  128. fComplex __cmf  cf_add(   fComplex __x, fComplex __y );
  129. fComplex __cmf  cf_addRe( fComplex __x, float __yRe );
  130. fComplex __cmf  cf_sub(   fComplex __x, fComplex __y );
  131. fComplex __cmf  cf_subRe( fComplex __x, float __yRe );  /* x - yRe */
  132. fComplex __cmf  cf_subrRe( fComplex __x, float __yRe ); /* yRe - x */
  133. fComplex __cmf  cf_mul(   fComplex __x, fComplex __y );
  134. fComplex __cmf  cf_mulRe( fComplex __x, float __yRe );
  135. fComplex __cmf  cf_div(   fComplex __x, fComplex __y );
  136. fComplex __cmf  cf_divRe( fComplex __x, float __yRe );   /*  x / yRe  */
  137. fComplex __cmf  cf_divrRe( fComplex __x, float __yRe );  /*  yRe / x  */
  138.  
  139. /*  mathematical functions with error handling through _matherr: */
  140. #ifdef __cplusplus  // even if _CMATH_CLASSDEFS
  141.     extern "C" float  __cmf  cf_abs(  fComplex __z );
  142. #else
  143.     float  __cmf  cf_abs(  fComplex __z );
  144. #endif
  145. fComplex __cmf  cf_acos( fComplex __z );
  146. fComplex __cmf  cf_asin( fComplex __z );
  147. fComplex __cmf  cf_atan( fComplex __z );
  148. fComplex __cmf  cf_cos(  fComplex __z );
  149. fComplex __cmf  cf_cosh( fComplex __z );
  150. fComplex __cmf  cf_cubic( fComplex __z );  /* raise to the third power */
  151. fComplex __cmf  cf_exp(  fComplex __z );
  152. fComplex __cmf  cf_inv(  fComplex __z );    /*   1.0 / z   */
  153. fComplex __cmf  cf_ipow( fComplex __z, int __exponent );
  154.                                              /* raise z to integer power */
  155. fComplex __cmf  cf_ln(    fComplex __z );
  156. fComplex __cmf  cf_log(   fComplex __z ); /* same as cf_ln */
  157. fComplex __cmf  cf_log2(  fComplex __z );
  158. fComplex __cmf  cf_log10( fComplex __z );
  159. fComplex __cmf  cf_pow( fComplex __base, fComplex __exponent );
  160. fComplex __cmf  cf_powReBase( float __base, fComplex __exponent ); /* power of real base */
  161. fComplex __cmf  cf_powReExpo( fComplex __base, float __exponent ); /* raise z to real power */
  162.                          /* for integer exponents, use cf_ipow ! */
  163. fComplex __cmf  cf_quartic( fComplex __z );  /* raise to the fourth power */
  164. fComplex __cmf  cf_sin(  fComplex __z );
  165. fComplex __cmf  cf_sinh( fComplex __z );
  166. fComplex __cmf  cf_square( fComplex __z );
  167. fComplex __cmf  cf_sqrt( fComplex __z );
  168. fComplex __cmf  cf_tan(  fComplex __z );
  169. fComplex __cmf  cf_tanh( fComplex __z );
  170.  
  171.  
  172. #if defined __cplusplus && !defined _CMATH_CLASSDEFS
  173. }    //  end of the extern "C" statement
  174. #endif
  175.  
  176. #if defined __cplusplus && !defined __STD_COMPLEX && !defined __NEWCPLX_H
  177.    /* in addition to the basic operations defined above for C,
  178.       here is the same complete set of overloaded operators and
  179.       functions as offered by <newcplx.h> for the complex classes.  */
  180.  
  181.     inline float real( fComplex _VFARC & __z )
  182.     {
  183.         return __z.Re;
  184.     }
  185.  
  186.     inline float imag( fComplex _VFARC & __z )
  187.     {
  188.         return __z.Im;
  189.     }
  190.  
  191.     inline fComplex neg( fComplex _VFARC & __z1 )
  192.     {   fComplex Result;
  193.         Result.Re = -__z1.Re;
  194.         Result.Im = -__z1.Im;
  195.         return Result;
  196.     }
  197.  
  198.     inline fComplex conj( fComplex _VFARC & __z)
  199.     {   fComplex Result;
  200.         Result.Re =  __z.Re;
  201.         Result.Im = -__z.Im;
  202.         return Result;
  203.     }
  204.  
  205.     float    __cmf norm( fComplex __z );
  206.     float    __cmf arg(  fComplex __z );
  207.     fComplex __cmf polar( float Mag, float Angle );
  208.  
  209.   //  unary operators:
  210.  
  211.   inline fComplex _VFAR & operator +( fComplex _VFAR & __z1 )
  212.   {
  213.       return __z1;
  214.   }
  215.  
  216.   inline fComplex operator -( fComplex _VFARC & __z1 )
  217.   {   fComplex Result;
  218.       Result.Re = -__z1.Re;
  219.       Result.Im = -__z1.Im;
  220.       return Result;
  221.   }
  222.  
  223.   //  binary operators:
  224.  
  225.   inline fComplex operator +( fComplex _VFARC & __z1, fComplex _VFARC & __z2 )
  226.   {   fComplex Result;
  227.       Result.Re = __z1.Re + __z2.Re;
  228.       Result.Im = __z1.Im + __z2.Im;
  229.       return Result;
  230.   }
  231.  
  232.   inline fComplex operator +( fComplex _VFARC & __z1, float __z2Re )
  233.   {   fComplex Result;
  234.       Result.Re = __z1.Re + __z2Re;
  235.       Result.Im = __z1.Im;
  236.       return Result;
  237.   }
  238.  
  239.   inline fComplex operator +( float __z1Re, fComplex _VFARC & __z2 )
  240.   {   fComplex Result;
  241.       Result.Re = __z1Re + __z2.Re;
  242.       Result.Im = __z2.Im;
  243.       return Result;
  244.   }
  245.  
  246.   inline fComplex operator -( fComplex _VFARC & __z1, fComplex _VFARC & __z2 )
  247.   {   fComplex Result;
  248.       Result.Re = __z1.Re - __z2.Re;
  249.       Result.Im = __z1.Im - __z2.Im;
  250.       return Result;
  251.   }
  252.  
  253.   inline fComplex operator -( fComplex _VFARC & __z1, float __z2Re )
  254.   {   fComplex Result;
  255.       Result.Re = __z1.Re - __z2Re;
  256.       Result.Im = __z1.Im;
  257.       return Result;
  258.   }
  259.  
  260.   inline fComplex operator -( float __z1Re, fComplex _VFARC & __z2 )
  261.   {   fComplex Result;
  262.       Result.Re = __z1Re - __z2.Re;
  263.       Result.Im = -__z2.Im;
  264.       return Result;
  265.   }
  266.  
  267.   inline fComplex operator *( fComplex _VFARC & __z1, fComplex _VFARC & __z2 )
  268.   {   fComplex Result;
  269.       Result.Re  = __z1.Re * __z2.Re - __z1.Im * __z2.Im;
  270.       Result.Im  = __z1.Re * __z2.Im + __z1.Im * __z2.Re;
  271.       return Result;
  272.   }
  273.  
  274.   inline fComplex operator *( fComplex _VFARC & __z1, float __z2Re )
  275.   {   fComplex Result;
  276.       Result.Re = __z1.Re * __z2Re;
  277.       Result.Im = __z1.Im * __z2Re;
  278.       return Result;
  279.   }
  280.  
  281.   inline fComplex operator *( float __z1Re, fComplex _VFARC & __z2 )
  282.   {   fComplex Result;
  283.       Result.Re  = __z1Re * __z2.Re;
  284.       Result.Im  = __z1Re * __z2.Im;
  285.       return Result;
  286.   }
  287.  
  288.   inline fComplex operator /( fComplex _VFARC & __z1, fComplex _VFARC & __z2 )
  289.   {   fComplex Result;
  290.       double denom;
  291.       Result.Re = (float)((__z1.Re * __z2.Re + __z1.Im * __z2.Im) /
  292.         (denom = (double)(__z2.Re) * __z2.Re + (double)(__z2.Im) * __z2.Im));
  293.       Result.Im = (float)((__z1.Im * __z2.Re - __z1.Re * __z2.Im ) / denom);
  294.       return Result;
  295.   }
  296.  
  297.   inline fComplex operator /( fComplex _VFARC & __z1, float __z2Re )
  298.   {   fComplex Result;
  299.       Result.Re = __z1.Re / __z2Re;
  300.       Result.Im = __z1.Im / __z2Re;
  301.       return Result;
  302.   }
  303.  
  304.   inline fComplex operator /( float __z1Re, fComplex _VFARC & __z2 )
  305.   {   fComplex Result;
  306.       double denom;
  307.       Result.Re = (float)((__z1Re * __z2.Re) /
  308.         (denom = (double)(__z2.Re) * __z2.Re + (double)(__z2.Im) * __z2.Im));
  309.       Result.Im = -(float)((__z1Re * __z2.Im ) / denom);
  310.       return Result;
  311.   }
  312.  
  313.     /* most versions of BC will ignore the definitions of
  314.        compound-assignment operators; they are needed for
  315.        MSVC and Optima++                                  */
  316.   inline fComplex _VFAR & operator +=( fComplex _VFAR & __z1, fComplex _VFARC & __z2 )
  317.   {
  318.       __z1.Re += __z2.Re;
  319.       __z1.Im += __z2.Im;
  320.       return __z1;
  321.   }
  322.  
  323.   inline fComplex _VFAR & operator +=( fComplex _VFAR & __z1, float __z2Re )
  324.   {
  325.       __z1.Re += __z2Re;
  326.       return __z1;
  327.   }
  328.  
  329.   inline fComplex _VFAR & operator -=( fComplex  _VFAR & __z1, fComplex _VFARC & __z2 )
  330.   {
  331.       __z1.Re -= __z2.Re;
  332.       __z1.Im -= __z2.Im;
  333.       return __z1;
  334.   }
  335.  
  336.   inline fComplex _VFAR & operator -=( fComplex _VFAR & __z1, float __z2Re )
  337.   {
  338.       __z1.Re -= __z2Re;
  339.       return __z1;
  340.   }
  341.  
  342.   inline fComplex _VFAR & operator *=( fComplex _VFAR & __z1, fComplex _VFARC & __z2 )
  343.   {
  344.       float tmpRe;
  345.       tmpRe   = __z1.Re * __z2.Re - __z1.Im * __z2.Im;
  346.       __z1.Im = __z1.Re * __z2.Im + __z1.Im * __z2.Re;
  347.       __z1.Re = tmpRe;
  348.       return __z1;
  349.   }
  350.  
  351.   inline fComplex _VFAR & operator *=( fComplex _VFAR & __z1, float __z2Re )
  352.   {
  353.       __z1.Re *= __z2Re;
  354.       __z1.Im *= __z2Re;
  355.       return __z1;
  356.   }
  357.  
  358.   inline fComplex _VFAR & operator /=( fComplex _VFAR & __z1, fComplex _VFARC & __z2 )
  359.   {   double denom;
  360.       float  tmpRe;
  361.       tmpRe = (float)((__z1.Re * __z2.Re + __z1.Im * __z2.Im) /
  362.         (denom = (double)(__z2.Re) * __z2.Re + (double)(__z2.Im) * __z2.Im));
  363.       __z1.Im = (float)((__z1.Im * __z2.Re - __z1.Re * __z2.Im ) / denom);
  364.       __z1.Re = tmpRe;
  365.       return __z1;
  366.   }
  367.  
  368.   inline fComplex _VFAR & operator /=( fComplex _VFAR & __z1, float __z2Re )
  369.   {
  370.       __z1.Re /= __z2Re;
  371.       __z1.Im /= __z2Re;
  372.       return __z1;
  373.   }
  374.  
  375.   inline int operator ==( fComplex _VFARC & __z1, fComplex _VFARC & __z2 )
  376.   {
  377.       return (__z1.Re == __z2.Re) && (__z1.Im == __z2.Im );
  378.   }
  379.  
  380.   inline int operator ==( fComplex _VFARC & __z1, float __z2Re )
  381.   {
  382.       return (__z1.Re == __z2Re) && (__z1.Im == 0.0 );
  383.   }
  384.  
  385.   inline int operator !=( fComplex _VFARC & __z1, fComplex _VFARC & __z2 )
  386.   {
  387.       return (__z1.Re != __z2.Re) || (__z1.Im != __z2.Im );
  388.   }
  389.  
  390.   inline int operator !=( fComplex _VFARC & __z1, float __z2Re )
  391.   {
  392.       return (__z1.Im != 0.0 ) || (__z1.Re != __z2Re);
  393.   }
  394.  
  395.  
  396.   /*  C++ version of the mathematical functions defined above.
  397.       They use the same code as the C versions. In case of an error,
  398.       you get a message in which the name of the C version is
  399.       stated.
  400.       Note that these functions require complex arguments to be
  401.       passed by value, not by reference, as it is done in the member
  402.       functions of the class complex. In terms of efficiency, this
  403.       is about the same. (The math functions of the class complex
  404.       store complex results at intermediate addresses and copy them
  405.       to the desired address afterwards. This final copy is not
  406.       necessary here.)                                             */
  407.  
  408.   float    __cmf  abs(  fComplex __z );
  409.   fComplex __cmf  acos( fComplex __z );
  410.   fComplex __cmf  asin( fComplex __z );
  411.   fComplex __cmf  atan( fComplex __z );
  412.   fComplex __cmf  cos(  fComplex __z );
  413.   fComplex __cmf  cosh( fComplex __z );
  414.   fComplex __cmf  cubic( fComplex __z );  /* raise to the third power */
  415.   fComplex __cmf  exp(  fComplex __z );
  416.   fComplex __cmf  inv(  fComplex __z );    /*   1.0 / z   */
  417.   fComplex __cmf  ipow( fComplex __z, int __exponent );
  418.                                             /* raise z to integer power */
  419.   fComplex __cmf  ln(  fComplex __z );
  420.   fComplex __cmf  log(  fComplex __z );  /* same as ln */
  421.   fComplex __cmf  log2( fComplex __z );
  422.   fComplex __cmf  log10( fComplex __z );
  423.   fComplex __cmf  pow( fComplex __z, fComplex __exponent );
  424.   fComplex __cmf  pow( fComplex __z,  float __exponent ); // identical to powReExpo
  425.   fComplex __cmf  pow( float __base,  fComplex __exponent ); // identical to powReBase
  426.   fComplex __cmf  powReBase( float __base, fComplex __exponent ); // power of real base
  427.   fComplex __cmf  powReExpo( fComplex __z, float __exponent );    // raise z to real power
  428.                             // for integer exponents, use ipow !
  429.   fComplex __cmf  quartic( fComplex __z );  // raise to the fourth power
  430.   fComplex __cmf  sin(  fComplex __z );
  431.   fComplex __cmf  sinh( fComplex __z );
  432.   fComplex __cmf  square( fComplex __z );
  433.   fComplex __cmf  sqrt( fComplex __z );
  434.   fComplex __cmf  tan(  fComplex __z );
  435.   fComplex __cmf  tanh( fComplex __z );
  436. #endif //  __cplusplus, not __STD_COMPLEX , __NEWCPLX_H
  437.  
  438.  
  439. /***  user-accessible error handling functions, borrowed from VectorLib  ****/
  440.  
  441. #ifdef __cplusplus
  442. extern "C" {
  443. #endif
  444.  
  445. void  __cmf  V_noteError( char _VFAR *fname, unsigned why );
  446. void  __cmf  V_printErrorMsg( char _VFAR *ErrMsg );
  447. void  __cmf  V_setErrorEventFile( char _VFAR *filename,  unsigned ScreenAndFile );
  448. void  __cmf  V_closeErrorEventFile( void );
  449.  
  450. /*** translation of calls to matherr() into _matherr() for BorlandC 4.0+ ***/
  451.  
  452. #if defined __BORLANDC__ && (__BORLANDC__ >= 0x450) && !defined (__FLAT__)
  453.      #if !defined( __MATH_H )
  454.             #include <math.h>
  455.      #endif
  456.      int  _Cdecl _FARFUNC matherr (struct exception _VFAR *__e);
  457.      #define NEWMATHERR  \
  458.          int matherr( struct exception _VFAR *__e ) \
  459.          {  return( _matherr( __e )); }
  460. #else
  461.      #define NEWMATHERR
  462. #endif
  463.  
  464. #ifdef __cplusplus
  465. }   // end of extern "C"
  466. #endif
  467. #endif /*  __CFMATH_H  */
  468.