int drand(); /* void exit(); */ /* int printf(); */
/* Provide inverses for square root and cube root: */ double complex
csquare(x) double complex x;
{ return( x * x );
}
double complex
ccube(x) double complex x;
{ return( x * x * x );
}
/* lookup table for each function */ struct fundef
{ char *nam1; /* the function */ double complex (*name )(); char *nam2; /* its inverse */ double complex (*inv )(); int nargs; /* number of function arguments */ int tstyp; /* type code of the function */ long ctrl; /* relative error flag */ double arg1w; /* width of domain for 1st arg */ double arg1l; /* lower bound domain 1st arg */ long arg1f; /* flags, e.g. integer arg */ double arg2w; /* same info for args 2, 3, 4 */ double arg2l; long arg2f; /* doublearg3w; doublearg3l; longarg3f; doublearg4w; doublearg4l; longarg4f;
*/
};
int main()
{ double complex (*fun )(); double complex (*ifun )(); struct fundef *d; int i, k, itst; int m, ntr;
#if SETPREC
dprec(); /* set coprocessor precision */ #endif
ntr = NTRIALS;
printf( "Consistency test of complex math functions.\n" );
printf( "Max and rms relative errors for %d random arguments.\n",
ntr );
for( itst=STRTST; itst<NTESTS; itst++ )
{
d = &defs[itst];
k = 0;
m = 0;
max = 0.0;
rmsa = 0.0;
ave = 0.0;
fun = d->name;
ifun = d->inv;
/* Error criterion is controlled by RELERR now. Letter "A" in the
result display indicates absolute error criterion. */ #if0 /* Absolute error criterion starts with gamma function *(putallsuchatendoftable)
*/ if( d->tstyp == GAMMA )
printf( "Absolute error criterion (but relative if >1):\n" ); #endif
/* Smaller number of trials for Wronksians *(putthematendoflist)
*/ if( d->tstyp == WRONK1 )
{
ntr = WTRIALS;
printf( "Absolute error and only %d trials:\n", ntr );
}
printf( headrs[d->tstyp], d->nam2, d->nam1 );
for( i=0; i<ntr; i++ )
{
m++;
/* make random number(s) in desired range(s) */ switch( d->nargs )
{
default: goto illegn;
case2:
drand( &dr );
drand( &di );
dr = d->arg2w * ( dr - 1.0 ) + d->arg2l;
di = d->arg2w * ( di - 1.0 ) + d->arg2l;
a = dr + di * I;
if( d->arg2f & EXPSCAL )
{
a = exp(dr) + I * exp(di);
drand( &dr );
drand( &di );
y2 = dr + di * I;
a -= 1.0e-13 * a * y2;
} if( d->arg2f & INT )
{
k = cabs(a) + 0.25;
a = k;
}
case1:
drand( &dr );
drand( &di );
dr = d->arg1w * ( dr - 1.0 ) + d->arg1l;
di = d->arg1w * ( di - 1.0 ) + d->arg1l;
x = dr + di * I; if( d->arg1f & EXPSCAL )
{
x = exp(dr) + I * exp(di);
drand( &dr );
drand( &di );
a = dr + di * I;
x += 1.0e-13 * x * a;
}
}
/* compute function under test */ switch( d->nargs )
{ case1: switch( d->tstyp )
{ case ELLIP:
yy1 = ( *(fun) )(x);
y2 = ( *(fun) )(1.0-x);
y3 = ( *(ifun) )(x);
y4 = ( *(ifun) )(1.0-x); break;
case GAMMA:
z = cgamma(x);
y = cexp(clgam(x));
x = z; /* This breaks the printout of large errors. */ break;
default:
z = ( *(fun) )(x);
y = ( *(ifun) )(z);
} break;
case2: if( d->arg2f & INT )
{ switch( d->tstyp )
{ case WRONK1:
yy1 = (*fun)( k, x ); /* jn */
y2 = (*fun)( k+1, x );
y3 = (*ifun)( k, x ); /* yn */
y4 = (*ifun)( k+1, x ); break;
case WRONK2:
yy1 = (*fun)( a, x ); /* iv */
y2 = (*fun)( a+1.0, x );
y3 = (*ifun)( k, x ); /* kn */
y4 = (*ifun)( k+1, x ); break;
default:
z = (*fun)( k, x );
y = (*ifun)( k, z );
}
} else
{ if( d->tstyp == POWER )
{
z = (*fun)( x, a );
y = (*ifun)( z, 1.0/a );
} else
{
z = (*fun)( a, x );
y = (*ifun)( a, z );
}
} break;
switch( d->tstyp )
{ case WRONK1:
e = (y2*y3 - yy1*y4) - 2.0/(PI*x); /* Jn, Yn */ break;
case WRONK2:
e = (y2*y3 + yy1*y4) - 1.0/x; /* In, Kn */ break;
case ELLIP:
e = (yy1-y3)*y4 + y3*y2 - PIO2; break;
case SQRT: /* Square root could have either sign. */
de = cabs ((y - x) / x); if (de > 1.5)
{ /* Try -y. */
dr = cabs ((-y - x) / x); if (dr < de)
{
y = -y;
de = dr;
}
} goto statistics;
default:
e = y - x; break;
}
if( d->ctrl & RELERR )
e /= x; else
{ if( cabs(x) > 1.0 )
e /= x;
}
de = cabs(e);
statistics:
ave +=de; /* absolute value of error */ if( de < 0 )
de = -de;
/* peak detect the error */ if( de > max )
{
max = de;
if( de > 1.0e-10 )
{
printf("x (%.16E,%.16E) z (%.16E,%.16E) y (%.16E,%.16E) max %.4E\n",
creal(x), cimag(x), creal(z), cimag(z),
creal(y), cimag(y), max); if( d->tstyp == POWER )
{
printf( "a (%.6E,%.6E)\n", creal(a), cimag(a) );
} if( d->tstyp == WRONK1 )
{
printf( "yy1 (%.4E,%.4E) y2 (%.4E,%.4E) y3 (%.4E,%.4E) y4 (%.4E,%.4E) k %d x (%.4E,%.4E)\n",
creal(yy1), cimag(yy1), creal(y2), cimag(y2),
creal(y3), cimag(y3), creal(y4), cimag(y4), k, creal(x), cimag(x) );
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.