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

  1. /*    CEMATH.H
  2.  
  3.       Complex library for the languages C and C++.
  4.  
  5.       This header file contains all definitions for
  6.       extended-precision complex numbers (complex long 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.  
  20. #ifndef __CEMATH_H
  21. #define __CEMATH_H
  22.  
  23. #if !defined( _CMATH_DEFS )
  24.    #ifdef __BORLANDC__
  25.        #pragma option -a-
  26.    #else /* Visual C++, Optima++ */
  27.        #pragma pack( push,1 )
  28.    #endif /* avoid insertion of dummy bytes  */
  29.    typedef struct {float    Re, Im;} fComplex;
  30.    typedef struct {double   Re, Im;} dComplex;
  31.    #ifdef __BORLANDC__
  32.        typedef long double    extended;
  33.        typedef struct {extended Re, Im;} eComplex;
  34.        #pragma option -a.
  35.    #else /* Visual C++, Optima++ */
  36.        typedef  double extended; /* No support of 80-bit IEEE numbers.
  37.                                  So make 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 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.     #if __BORLANDC__ < 0x500
  64.         #define VBOOL int
  65.     #else
  66.         #define VBOOL bool
  67.     #endif
  68. #else  /* Visual C++, Optima++ */
  69.     #define _VFAR
  70.     #define __cmf  __cdecl
  71.     #ifndef __CDMATH_H
  72.         #include <cdmath.h>
  73.     #endif
  74. #endif
  75. #define _VFARC const _VFAR
  76.  
  77. #ifdef __BORLANDC__   /* 80-bit IEEE numbers supported:
  78.                          the following 340 lines apply
  79.                          only to Borland C++  */
  80. #ifdef __cplusplus
  81.     /*  first the constructors:
  82.       since eComplex is declared as a struct instead of a class,
  83.       the constructor cannot get the name "eComplex" here.     */
  84.   #ifndef _ECPLX_DEFINED
  85.   inline eComplex __cmf ecplx( extended __ReVal )
  86.   {   eComplex Result;
  87.       Result.Re = __ReVal;
  88.       Result.Im = 0.0;
  89.       return Result;
  90.   }
  91.  
  92.       // up-conversions from single and double precision:
  93.   inline eComplex __cmf ecplx( fComplex _VFARC & __zf )
  94.   {   eComplex Result;
  95.       Result.Re = __zf.Re;
  96.       Result.Im = __zf.Im;
  97.       return Result;
  98.   }
  99.  
  100.   inline eComplex __cmf ecplx( dComplex _VFARC & __zd )
  101.   {   eComplex Result;
  102.       Result.Re = __zd.Re;
  103.       Result.Im = __zd.Im;
  104.       return Result;
  105.   }
  106.  
  107.   #ifdef __COMPLEX_H
  108.         // conversion from class complex
  109.      inline eComplex __cmf ecplx( complex _VFARC & __zc )
  110.      {   eComplex Result;
  111.          Result.Re = real(__zc);
  112.          Result.Im = imag(__zc);
  113.          return Result;
  114.      }
  115.   #endif  // __COMPLEX_H
  116.   #define _ECPLX_DEFINED
  117.   #endif  // _ECPLX_DEFINED
  118. #endif   /* __cplusplus */
  119.        /* basic form of constructor for C and C++ : */
  120. eComplex __cmf ecplx( extended __ReVal, extended __ImVal);
  121.  
  122.      /* conversion from fComplex and dComplex */
  123. #if !defined __NEWCPLX_H
  124.     #if defined __cplusplus
  125.         extern "C" {
  126.     #endif
  127.     eComplex __cmf cftoce( fComplex __zf );
  128.     eComplex __cmf cdtoce( dComplex __zd );
  129.     #if defined __cplusplus
  130.         }
  131.     #endif
  132. #endif
  133.  
  134.    /* Basic complex operations. They are defined both
  135.    for C and C++. However, for C++ you may as well use the
  136.    overloaded operators and functions defined further below. */
  137. #define         ce_real( z )  (z).Re
  138. #define         ce_imag( z )  (z).Im
  139. #if defined __cplusplus && !defined _CMATH_CLASSDEFS 
  140. extern "C" {  // the following functions cannot be "extern C",
  141. #endif       // if eComplex identical with complex<extended>
  142. eComplex __cmf  ce_neg(  eComplex __z );
  143. eComplex __cmf  ce_conj( eComplex __z );
  144. #ifdef __cplusplus  // even if _CMATH_CLASSDEFS
  145.     extern "C" extended __cmf  ce_norm( eComplex __z );
  146.     extern "C" extended __cmf  ce_arg(  eComplex __z );
  147. #else
  148.     extended __cmf  ce_norm( eComplex __z );
  149.     extended __cmf  ce_arg(  eComplex __z );
  150. #endif
  151. eComplex __cmf  ce_polar( extended __mag, extended __angle );
  152.  
  153. eComplex __cmf  ce_add(   eComplex __x, eComplex __y );
  154. eComplex __cmf  ce_addRe( eComplex __x, extended __yRe );
  155. eComplex __cmf  ce_sub(   eComplex __x, eComplex __y );
  156. eComplex __cmf  ce_subRe( eComplex __x, extended __yRe );  /* x - yRe */
  157. eComplex __cmf  ce_subrRe( eComplex __x, extended __yRe ); /* yRe - x */
  158. eComplex __cmf  ce_mul(   eComplex __x, eComplex __y );
  159. eComplex __cmf  ce_mulRe( eComplex __x, extended __yRe );
  160. eComplex __cmf  ce_div(   eComplex __x, eComplex __y );
  161. eComplex __cmf  ce_divRe( eComplex __x, extended __yRe );  /*  x / yRe  */
  162. eComplex __cmf  ce_divrRe( eComplex __x, extended __yRe ); /* yRe / x   */
  163.  
  164. /*  mathematical functions with error handling through _matherr: */
  165. #ifdef __cplusplus  // even if _CMATH_CLASSDEFS
  166.     extern "C" extended __cmf  ce_abs(  eComplex __z );
  167. #else
  168.     extended __cmf  ce_abs(  eComplex __z );
  169. #endif
  170. eComplex __cmf  ce_acos( eComplex __z );
  171. eComplex __cmf  ce_asin( eComplex __z );
  172. eComplex __cmf  ce_atan( eComplex __z );
  173. eComplex __cmf  ce_cos(  eComplex __z );
  174. eComplex __cmf  ce_cosh( eComplex __z );
  175. eComplex __cmf  ce_cubic( eComplex __z );  /* raise to the third power */
  176. eComplex __cmf  ce_exp(  eComplex __z );
  177. eComplex __cmf  ce_inv(  eComplex __z );    /*   1.0 / z   */
  178. eComplex __cmf  ce_ipow( eComplex __z, int __exponent );
  179.                                              /* raise z to integer power */
  180. eComplex __cmf  ce_ln(    eComplex __z );
  181. eComplex __cmf  ce_log(   eComplex __z ); /* same as ce_ln */
  182. eComplex __cmf  ce_log2(  eComplex __z );
  183. eComplex __cmf  ce_log10( eComplex __z );
  184. eComplex __cmf  ce_pow( eComplex __base, eComplex __exponent );
  185. eComplex __cmf  ce_powReBase( extended __base, eComplex __exponent ); /* power of real base */
  186. eComplex __cmf  ce_powReExpo( eComplex __base, extended __exponent ); /* raise z to real power */
  187.                          /* for integer exponents, use ce_ipow ! */
  188. eComplex __cmf  ce_quartic( eComplex __z );  /* raise to the fourth power */
  189. eComplex __cmf  ce_sin(  eComplex __z );
  190. eComplex __cmf  ce_sinh( eComplex __z );
  191. eComplex __cmf  ce_square( eComplex __z );
  192. eComplex __cmf  ce_sqrt( eComplex __z );
  193. eComplex __cmf  ce_tan(  eComplex __z );
  194. eComplex __cmf  ce_tanh( eComplex __z );
  195.  
  196. #if defined __cplusplus && !defined _CMATH_CLASSDEFS
  197. }    //  end of the extern "C" statement
  198. #endif
  199.  
  200. #if defined __cplusplus && !defined __STD_COMPLEX && !defined __NEWCPLX_H
  201.    /* in addition to the basic operations defined above for C,
  202.       here is the same complete set of overloaded operators and
  203.       functions as offered by <newcplx.h> for the complex classes.  */
  204.  
  205.     inline extended real( eComplex _VFARC & __z )
  206.     {
  207.         return __z.Re;
  208.     }
  209.  
  210.     inline extended imag( eComplex _VFARC & __z )
  211.     {
  212.         return __z.Im;
  213.     }
  214.  
  215.     inline eComplex neg( eComplex _VFARC & __z1 )
  216.     {   eComplex Result;
  217.         Result.Re = -__z1.Re;
  218.         Result.Im = -__z1.Im;
  219.         return Result;
  220.     }
  221.  
  222.     inline eComplex conj( eComplex _VFARC & __z)
  223.     {   eComplex Result;
  224.         Result.Re =  __z.Re;
  225.         Result.Im = -__z.Im;
  226.         return Result;
  227.     }
  228.  
  229.     extended __cmf  norm( eComplex __z );
  230.     extended __cmf  arg(  eComplex __z );
  231.     eComplex __cmf  polar( extended Mag, extended Angle );
  232.       //  unary operators:
  233.  
  234.     inline eComplex _VFAR & operator +( eComplex _VFAR & __z1 )
  235.     {
  236.         return __z1;
  237.     }
  238.  
  239.     inline eComplex operator -( eComplex _VFARC & __z1 )
  240.     {   eComplex Result;
  241.         Result.Re = -__z1.Re;
  242.         Result.Im = -__z1.Im;
  243.         return Result;
  244.     }
  245.  
  246.       //  binary operators:
  247.  
  248.     inline eComplex operator +( eComplex _VFARC & __z1, eComplex _VFARC & __z2 )
  249.     {   eComplex Result;
  250.         Result.Re = __z1.Re + __z2.Re;
  251.         Result.Im = __z1.Im + __z2.Im;
  252.         return Result;
  253.     }
  254.  
  255.     inline eComplex operator +( eComplex _VFARC & __z1, extended __z2Re )
  256.     {   eComplex Result;
  257.         Result.Re = __z1.Re + __z2Re;
  258.         Result.Im = __z1.Im;
  259.         return Result;
  260.     }
  261.  
  262.     inline eComplex operator +( extended __z1Re, eComplex _VFARC & __z2 )
  263.     {   eComplex Result;
  264.         Result.Re = __z1Re + __z2.Re;
  265.         Result.Im = __z2.Im;
  266.         return Result;
  267.     }
  268.  
  269.     inline eComplex operator -( eComplex _VFARC & __z1, eComplex _VFARC & __z2 )
  270.     {   eComplex Result;
  271.         Result.Re = __z1.Re - __z2.Re;
  272.         Result.Im = __z1.Im - __z2.Im;
  273.         return Result;
  274.     }
  275.  
  276.     inline eComplex operator -( eComplex _VFARC & __z1, extended __z2Re )
  277.     {   eComplex Result;
  278.         Result.Re = __z1.Re - __z2Re;
  279.         Result.Im = __z1.Im;
  280.         return Result;
  281.     }
  282.  
  283.     inline eComplex operator -( extended __z1Re, eComplex _VFARC & __z2 )
  284.     {   eComplex Result;
  285.         Result.Re = __z1Re - __z2.Re;
  286.         Result.Im = -__z2.Im;
  287.         return Result;
  288.     }
  289.  
  290.     inline eComplex operator *( eComplex _VFARC & __z1, eComplex _VFARC & __z2 )
  291.     {   eComplex Result;
  292.         Result.Re  = __z1.Re * __z2.Re - __z1.Im * __z2.Im;
  293.         Result.Im  = __z1.Re * __z2.Im + __z1.Im * __z2.Re;
  294.         return Result;
  295.     }
  296.  
  297.     inline eComplex operator *( eComplex _VFARC & __z1, extended __z2Re )
  298.     {   eComplex Result;
  299.         Result.Re = __z1.Re * __z2Re;
  300.         Result.Im = __z1.Im * __z2Re;
  301.         return Result;
  302.     }
  303.  
  304.     inline eComplex operator *( extended __z1Re, eComplex _VFARC & __z2 )
  305.     {   eComplex Result;
  306.         Result.Re  = __z1Re * __z2.Re;
  307.         Result.Im  = __z1Re * __z2.Im;
  308.         return Result;
  309.     }
  310.  
  311.     eComplex operator /( eComplex _VFARC & __z1, eComplex _VFARC & __z2 );
  312.     eComplex operator /( extended __z1Re, eComplex _VFARC & __z2 );
  313.            // cannot be safely inlined for extended precision
  314.     
  315.     inline eComplex operator /( eComplex _VFARC & __z1, extended __z2Re )
  316.     {   eComplex Result;
  317.         Result.Re = __z1.Re / __z2Re;
  318.         Result.Im = __z1.Im / __z2Re;
  319.         return Result;
  320.     }
  321.  
  322.     /* most versions of BC will ignore the definitions of
  323.        compound-assignment operators; include them to be
  324.        on the safe side with future versions          */
  325.     inline eComplex _VFAR & operator +=( eComplex _VFAR & __z1, eComplex _VFARC & __z2 )
  326.     {
  327.         __z1.Re += __z2.Re;
  328.         __z1.Im += __z2.Im;
  329.         return __z1;
  330.     }
  331.  
  332.     inline eComplex _VFAR & operator +=( eComplex _VFAR & __z1, extended __z2Re )
  333.     {
  334.         __z1.Re += __z2Re;
  335.         return __z1;
  336.     }
  337.  
  338.     inline eComplex _VFAR & operator -=( eComplex _VFAR & __z1, eComplex _VFARC & __z2 )
  339.     {
  340.         __z1.Re -= __z2.Re;
  341.         __z1.Im -= __z2.Im;
  342.         return __z1;
  343.     }
  344.  
  345.     inline eComplex _VFAR & operator -=( eComplex _VFAR & __z1, extended __z2Re )
  346.     {
  347.         __z1.Re -= __z2Re;
  348.         return __z1;
  349.     }
  350.  
  351.     inline eComplex _VFAR & operator *=( eComplex _VFAR & __z1, eComplex _VFARC & __z2 )
  352.     {
  353.         extended tmpRe;
  354.         tmpRe   = __z1.Re * __z2.Re - __z1.Im * __z2.Im;
  355.         __z1.Im = __z1.Re * __z2.Im + __z1.Im * __z2.Re;
  356.         __z1.Re = tmpRe;
  357.         return __z1;
  358.     }
  359.  
  360.     inline eComplex _VFAR & operator *=( eComplex _VFAR & __z1, extended __z2Re )
  361.     {
  362.         __z1.Re *= __z2Re;
  363.         __z1.Im *= __z2Re;
  364.         return __z1;
  365.     }
  366.  
  367.     eComplex _VFAR & operator /=( eComplex _VFAR & __z1, eComplex _VFARC & __z2 );
  368.  
  369.     inline eComplex _VFAR & operator /=( eComplex _VFAR & __z1, extended __z2Re )
  370.     {
  371.         __z1.Re /= __z2Re;
  372.         __z1.Im /= __z2Re;
  373.         return __z1;
  374.     }
  375.  
  376.  
  377.     inline VBOOL operator ==( eComplex _VFARC & __z1, eComplex _VFARC & __z2 )
  378.     {
  379.         return (__z1.Re == __z2.Re) && (__z1.Im == __z2.Im );
  380.     }
  381.  
  382.     inline VBOOL operator ==( eComplex _VFARC & __z1, extended __z2Re )
  383.     {
  384.         return (__z1.Re == __z2Re) && (__z1.Im == 0.0 );
  385.     }
  386.  
  387.     inline VBOOL operator !=( eComplex _VFARC & __z1, eComplex _VFARC & __z2 )
  388.     {
  389.         return (__z1.Re != __z2.Re) || (__z1.Im != __z2.Im );
  390.     }
  391.  
  392.     inline VBOOL operator !=( eComplex _VFARC & __z1, extended __z2Re )
  393.     {
  394.         return (__z1.Im != 0.0 ) || (__z1.Re != __z2Re);
  395.     }
  396.  
  397.   /*  C++ version of the mathematical functions defined above.
  398.       They use the same code as the C versions. In case of an error,
  399.       you get a message in which the name of the C version is
  400.       stated.
  401.       Note that these functions require complex arguments to be
  402.       passed by value, not by reference, as it is done in the member
  403.       functions of the class complex. In terms of efficiency, this
  404.       is about the same. (The math functions of the class complex
  405.       store complex results at intermediate addresses and copy them
  406.       to the desired address afterwards. This final copy is not
  407.       necessary here.)
  408.  
  409.   */
  410.  
  411.   extended __cmf  abs(  eComplex __z );
  412.   eComplex __cmf  acos( eComplex __z );
  413.   eComplex __cmf  asin( eComplex __z );
  414.   eComplex __cmf  atan( eComplex __z );
  415.   eComplex __cmf  cos(  eComplex __z );
  416.   eComplex __cmf  cosh( eComplex __z );
  417.   eComplex __cmf  cubic( eComplex __z );  /* raise to the third power */
  418.   eComplex __cmf  exp(  eComplex __z );
  419.   eComplex __cmf  inv(  eComplex __z );    /*   1.0 / z   */
  420.   eComplex __cmf  ipow( eComplex __z, int __exponent );
  421.                                             /* raise z to integer power */
  422.   eComplex __cmf  ln(   eComplex __z );
  423.   eComplex __cmf  log(  eComplex __z );  /* same as ln */
  424.   eComplex __cmf  log2( eComplex __z );
  425.   eComplex __cmf  log10( eComplex __z );
  426.   eComplex __cmf  pow( eComplex __z,  eComplex __exponent );
  427.   eComplex __cmf  pow( eComplex __z,  extended __exponent ); // identical to powReExpo
  428.   eComplex __cmf  pow( extended __base,  eComplex __exponent ); // identical to powReBase
  429.   eComplex __cmf  powReBase( extended __base, eComplex __exponent ); // power of real base
  430.   eComplex __cmf  powReExpo( eComplex __z, extended __exponent );    // raise z to real power
  431.                             // for integer exponents, use ipow !
  432.   eComplex __cmf  quartic( eComplex __z );  // raise to the fourth power
  433.   eComplex __cmf  sin(  eComplex __z );
  434.   eComplex __cmf  sinh( eComplex __z );
  435.   eComplex __cmf  square( eComplex __z );
  436.   eComplex __cmf  sqrt( eComplex __z );
  437.   eComplex __cmf  tan(  eComplex __z );
  438.   eComplex __cmf  tanh( eComplex __z );
  439. #endif //  __cplusplus, not __STD_COMPLEX , __NEWCPLX_H
  440.  
  441. #else /* no 80-bit IEEE number support:
  442.         The following 50 lines apply only to
  443.         Visual C++ and Optima++:          */
  444.  
  445. #define ecplx     dcplx
  446. #define cftoce    cftocd
  447. #define cdtoce(z) (z)
  448. #define ce_real( z )  (z).Re
  449. #define ce_imag( z )  (z).Im
  450. #define ce_neg      cd_neg
  451. #define ce_conj     cd_conj
  452. #define ce_norm     cd_norm
  453. #define ce_arg      cd_arg
  454. #define ce_polar    cd_polar
  455. #define ce_add      cd_add
  456. #define ce_addRe    cd_addRe
  457. #define ce_sub      cd_sub
  458. #define ce_subRe    cd_subRe
  459. #define ce_subrRe   cd_subrRe
  460. #define ce_mul      cd_mul
  461. #define ce_mulRe    cd_mulRe
  462. #define ce_div      cd_div
  463. #define ce_divRe    cd_divRe
  464. #define ce_divrRe   cd_divrRe
  465.  
  466. #define ce_abs      cd_abs
  467. #define ce_acos     cd_acos
  468. #define ce_asin     cd_asin
  469. #define ce_atan     cd_atan
  470. #define ce_cos      cd_cos
  471. #define ce_cosh     cd_cosh
  472. #define ce_cubic    cd_cubic
  473. #define ce_exp      cd_exp
  474. #define ce_inv      cd_inv
  475. #define ce_ipow     cd_ipow
  476. #define ce_log      cd_log
  477. #define ce_log2     cd_log2
  478. #define ce_log10    cd_log10
  479. #define ce_pow      cd_pow
  480. #define ce_powReBase    cd_powReBase
  481. #define ce_powReExpo    cd_powReExpo
  482. #define ce_quartic  cd_quartic
  483. #define ce_sin      cd_sin
  484. #define ce_sinh     cd_sinh
  485. #define ce_square   cd_square
  486. #define ce_sqrt     cd_sqrt
  487. #define ce_tan      cd_tan
  488. #define ce_tanh     cd_tanh
  489.  
  490. #endif  /* Borland C++, Visual C++, or Optima++ */
  491.  
  492.  
  493. /***  user-accessible error handling functions, borrowed from VectorLib  ****/
  494.  
  495. #ifdef __cplusplus
  496. extern "C" {
  497. #endif
  498.  
  499. void  __cmf  V_noteError( char _VFAR *fname, unsigned why );
  500. void  __cmf  V_printErrorMsg( char _VFAR *ErrMsg );
  501. void  __cmf  V_setErrorEventFile( char _VFAR *filename,  unsigned ScreenAndFile );
  502. void  __cmf  V_closeErrorEventFile( void );
  503.  
  504. #ifdef __cplusplus
  505. }   // end of extern "C"
  506. #endif
  507.  
  508. #endif /*  __CEMATH_H  */
  509.