home *** CD-ROM | disk | FTP | other *** search
- /*
- ctest -- complex arithmetic test
-
- last edit: 86/01/04 D A Gwyn
-
- SCCS ID: @(#)cx_test.c 1.1 (modified for public version)
- */
-
- #include <stdio.h>
- #include <math.h>
-
- #include <complex.h>
-
- #define DEGRAD 57.2957795130823208767981548141051703324054724665642
- /* degrees per radian */
- #define Abs( x ) ((x) < 0 ? -(x) : (x))
- #define Max( a, b ) ((a) > (b) ? (a) : (b))
-
- extern void exit();
-
- #define Printf (void)printf
-
- #define TOL 1.0e-10 /* tolerance for checks */
-
- static int errs = 0; /* tally errors */
-
- static void CCheck(), RCheck();
- static double RelDif();
-
-
- /*ARGSUSED*/
- main( argc, argv )
- int argc;
- char *argv[];
- {
- complex a, *bp, *cp;
-
- /* CxAllo test */
- bp = CxAllo();
- if ( bp == NULL )
- {
- Printf( "CxAllo failed\n" );
- exit( 1 );
- }
-
- /* CxReal, CxImag test */
- CxReal( bp ) = 1.0;
- CxImag( bp ) = 2.0;
- RCheck( "CxReal", CxReal( bp ), 1.0 );
- RCheck( "CxImag", CxImag( bp ), 2.0 );
-
- /* CxCons test */
- cp = CxCons( &a, -3.0, -4.0);
- CCheck( "CxCons 1", a, -3.0, -4.0 );
- CCheck( "CxCons 2", *cp, -3.0, -4.0 );
-
- /* CxNeg test */
- cp = CxNeg( &a );
- CCheck( "CxNeg 1", a, 3.0, 4.0 );
- CCheck( "CxNeg 2", *cp, 3.0, 4.0 );
-
- /* CxCopy test */
- cp = CxCopy( bp, &a );
- (void)CxCons( &a, 1.0, sqrt( 3.0 ) );
- CCheck( "CxCopy 1", *bp, 3.0, 4.0 );
- CCheck( "CxCopy 2", *cp, 3.0, 4.0 );
-
- /* CxAmpl, CxPhas test */
- RCheck( "CxAmpl 1", CxAmpl( &a ), 2.0 );
- RCheck( "CxPhas 1", CxPhas( &a ) * DEGRAD, 60.0 );
- /* try other quadrants */
- a.re = -a.re;
- RCheck( "CxAmpl 2", CxAmpl( &a ), 2.0 );
- RCheck( "CxPhas 2", CxPhas( &a ) * DEGRAD, 120.0 );
- a.im = -a.im;
- RCheck( "CxAmpl 3", CxAmpl( &a ), 2.0 );
- RCheck( "CxPhas 3", CxPhas( &a ) * DEGRAD, -120.0 );
- a.re = -a.re;
- RCheck( "CxAmpl 4", CxAmpl( &a ), 2.0 );
- RCheck( "CxPhas 4", CxPhas( &a ) * DEGRAD, -60.0 );
- /* one more for good measure */
- RCheck( "CxAmpl 5", CxAmpl( bp ), 5.0 );
-
- /* CxPhsr test */
- cp = CxPhsr( &a, 100.0, -20.0 / DEGRAD );
- RCheck( "CxPhsr 1", CxAmpl( &a ), 100.0 );
- RCheck( "CxPhsr 2", CxPhas( &a ) * DEGRAD, -20.0 );
- RCheck( "CxPhsr 3", CxAmpl( cp ), 100.0 );
- RCheck( "CxPhsr 4", CxPhas( cp ) * DEGRAD, -20.0 );
-
- /* CxConj test */
- cp = CxConj( bp );
- CCheck( "CxConj 1", *bp, 3.0, -4.0 );
- CCheck( "CxConj 2", *cp, 3.0, -4.0 );
-
- /* CxScal test */
- cp = CxScal( bp, 2.0 );
- CCheck( "CxScal 1", *bp, 6.0, -8.0 );
- CCheck( "CxScal 2", *cp, 6.0, -8.0 );
-
- /* CxAdd test */
- cp = CxAdd( CxCons( &a, -4.0, 11.0 ), bp );
- CCheck( "CxAdd 1", a, 2.0, 3.0 );
- CCheck( "CxAdd 2", *cp, 2.0, 3.0 );
-
- /* CxSub test */
- cp = CxSub( CxCons( &a, 4.0, 7.0 ), bp );
- CCheck( "CxSub 1", a, -2.0, 15.0 );
- CCheck( "CxSub 2", *cp, -2.0, 15.0 );
-
- /* CxMul test */
- cp = CxMul( CxCons( bp, -1.0, 3.0 ), CxCons( &a, 1.0, 2.0 ) );
- CCheck( "CxMul 1", *bp, -7.0, 1.0 );
- CCheck( "CxMul 2", *cp, -7.0, 1.0 );
-
- /* CxDiv test */
- cp = CxDiv( bp, &a );
- CCheck( "CxDiv 1", *bp, -1.0, 3.0 );
- CCheck( "CxDiv 2", *cp, -1.0, 3.0 );
-
- /* CxSqrt and overlapping CxMul tests */
- (void)CxCons( &a, -1.0, 2.0 );
- cp = CxSqrt( CxMul( &a, &a ) );
- CCheck( "CxSqrt 1", a, -1.0, 2.0 );
- CCheck( "CxSqrt 2", *cp, -1.0, 2.0 );
- (void)CxCons( &a, 3.0, 2.0 );
- cp = CxSqrt( CxMul( &a, &a ) );
- CCheck( "CxSqrt 3", a, 3.0, 2.0 );
- CCheck( "CxSqrt 4", *cp, 3.0, 2.0 );
-
- /* CxFree "test" */
- CxFree( bp );
-
- return errs;
- }
-
-
- static void
- CCheck( s, c, r, i ) /* check complex number */
- char *s; /* message string for failure */
- complex c; /* complex to be checked */
- double r, i; /* expected real, imaginary parts */
- {
- if ( RelDif( CxReal( &c ), r ) > TOL
- || RelDif( CxImag( &c ), i ) > TOL
- ) {
- ++errs;
- Printf( "%s; s.b. (%f,%f), was (%g,%g)\n",
- s, r, i, c.re, c.im
- );
- }
- }
-
-
- static void
- RCheck( s, d, r ) /* check real number */
- char *s; /* message string for failure */
- double d; /* real to be checked */
- double r; /* expected value */
- {
- if ( RelDif( d, r ) > TOL )
- {
- ++errs;
- Printf( "%s; s.b. %f, was %g\n", s, r, d );
- }
- }
-
-
- static double
- RelDif( a, b ) /* returns relative difference: */
- double a, b; /* 0.0 if exactly the same,
- otherwise ratio of difference
- to the larger of the two */
- {
- double c = Abs( a );
- double d = Abs( b );
-
- d = Max( c, d );
-
- return d == 0.0 ? 0.0 : Abs( a - b ) / d;
- }
-