// finds the complex roots of the polynomial using Bairstow's method
//  _p      :   polynomial array, ascending powers [size: _k x 1]
//  _k      :   polynomials length (poly order = _k - 1)
//  _roots  :   resulting complex roots [size: _k-1 x 1]
void POLY(_findroots_bairstow)(T * _p,
                               unsigned int _k,
                               TC * _roots)
{
    T p0[_k];       // buffer 0
    T p1[_k];       // buffer 1
    T * p   = NULL; // input polynomial
    T * pr  = NULL; // output (reduced) polynomial

    unsigned int i;
    unsigned int k=0;   // output roots counter
    memmove(p0, _p, _k*sizeof(T));

    T u, v;

    unsigned int n = _k;        // input counter (decrementer)
    unsigned int r = _k % 2;    // polynomial length odd? (order even?)
    unsigned int L = (_k-r)/2;  // semi-length
    for (i=0; i<L-1+r; i++) {
        // set polynomial and reduced polynomial buffer pointers
        p  = (i % 2) == 0 ? p0 : p1;
        pr = (i % 2) == 0 ? p1 : p0;

        // initial estimates for u, v
        // TODO : ensure no division by zero
        if (p[n-1] == 0) {
            fprintf(stderr,"warning: poly_findroots_bairstow(), irreducible polynomial");
            p[n-1] = 1e-12;
        }
        u = p[n-2] / p[n-1];
        v = p[n-3] / p[n-1];

        // compute factor using Bairstow's recursion
        POLY(_findroots_bairstow_recursion)(p,n,pr,&u,&v);

        // compute complex roots of x^2 + u*x + v
        TC r0 = 0.5f*(-u + csqrtf(u*u - 4.0*v));
        TC r1 = 0.5f*(-u - csqrtf(u*u - 4.0*v));

        // append result to output
        _roots[k++] = r0;
        _roots[k++] = r1;

#if 0
        // print debugging info
        unsigned int j;
        printf("initial polynomial:\n");
        for (j=0; j<n; j++)
            printf("  p[%3u]  = %12.8f + j*%12.8f\n", j, crealf(p[j]), cimagf(p[j]));

        printf("polynomial factor: x^2 + u*x + v\n");
        printf("  u : %12.8f + j*%12.8f\n", crealf(u), cimagf(u));
        printf("  v : %12.8f + j*%12.8f\n", crealf(v), cimagf(v));

        printf("roots:\n");
        printf("  r0 : %12.8f + j*%12.8f\n", crealf(r0), cimagf(r0));
        printf("  r1 : %12.8f + j*%12.8f\n", crealf(r1), cimagf(r1));

        printf("reduced polynomial:\n");
        for (j=0; j<n-2; j++)
            printf("  pr[%3u] = %12.8f + j*%12.8f\n", j, crealf(pr[j]), cimagf(pr[j]));
#endif

        // decrement new (reduced) polynomial size by 2
        n -= 2;
    }

    if (r==0) {
        assert(n==2);
        _roots[k++] = -pr[0]/pr[1];
    }
    //assert( k == _k-1 );
}
Exemple #2
0
static long double complex
_csqrtf(long double complex d)
{

	return (csqrtf((float complex)d));
}
int main() {
    unsigned int n=32;  // number of tests
    unsigned int d=2;   // number of items per line

    // data arrays
    float complex z[n];
    float complex test[n];

    float complex err_max = 0.0f;
    unsigned int i;
    for (i=0; i<n; i++) {
        // generate random complex number
        z[i] = 2.0f*(2.0f*sandbox_randf() - 1.0f) +
               2.0f*(2.0f*sandbox_randf() - 1.0f) * _Complex_I;

        test[i] = csqrtf(z[i]);
        float complex sqrtz_hat = sandbox_csqrtf(z[i]);

        float complex err = test[i] - sqrtz_hat;

        printf("%3u: z=%6.2f+j%6.2f, sqrt(z)=%6.2f+j%6.2f (%6.2f+j%6.2f) e=%12.4e\n",
                i,
                crealf(test[i]),    cimagf(z[i]),
                crealf(test[i]),    cimagf(test[i]),
                crealf(sqrtz_hat),  cimagf(sqrtz_hat),
                cabsf(err));

        if ( cabsf(err) > cabsf(err_max) )
            err_max = err;
    }

    printf("maximum error: %12.4e;\n", cabsf(err_max));


    // 
    // print autotest lines
    //

    printf("\n");
    printf("    float complex z[%u] = {\n      ", n);
    for (i=0; i<n; i++) {
        printf("%12.4e+_Complex_I*%12.4e", crealf(z[i]), cimagf(z[i]));

        if ( i == n-1)
            printf(" ");
        else if ( ((i+1)%d)==0 )
            printf(",\n      ");
        else
            printf(", ");
    }
    printf("};\n");

    printf("\n");
    printf("    float complex test[%u] = {\n      ", n);
    for (i=0; i<n; i++) {
        printf("%12.4e+_Complex_I*%12.4e", crealf(test[i]), cimagf(test[i]));

        if ( i == n-1)
            printf(" ");
        else if ( ((i+1)%d)==0 )
            printf(",\n      ");
        else
            printf(", ");
    }
    printf("};\n");
    printf("done.\n");
    return 0;
}
Exemple #4
0
 ld = cexpl(ld);
 TEST_TRACE(C99 7.3.7.2)
 d = clog(d);
 f = clogf(f);
 ld = clogl(ld);
 TEST_TRACE(C99 7.3.8.1)
 d = cabs(d);
 f = cabsf(f);
 ld = cabsl(ld);
 TEST_TRACE(C99 7.3.8.2)
 d = cpow(d, d);
 f = cpowf(f, f);
 ld = cpowl(ld, ld);
 TEST_TRACE(C99 7.3.8.3)
 d = csqrt(d);
 f = csqrtf(f);
 ld = csqrtl(ld);
 TEST_TRACE(C99 7.3.9.1)
 d = carg(d);
 f = cargf(f);
 ld = cargl(ld);
 TEST_TRACE(C99 7.3.9.2)
 d = cimag(d);
 f = cimagf(f);
 ld = cimagl(ld);
 TEST_TRACE(C99 7.3.9.3)
 d = conj(d);
 f = conjf(f);
 ld = conjl(ld);
 TEST_TRACE(C99 7.3.9.4)
 d = cproj(d);
Exemple #5
0
void
docomplexf (void)
{
#ifndef NO_FLOAT
  complex float ca, cb, cc;
  float f1;

  ca = 1.0 + 1.0 * I;
  cb = 1.0 - 1.0 * I;

  f1 = cabsf (ca);
  fprintf (stdout, "cabsf  : %f\n", f1);

  cc = cacosf (ca);
  fprintf (stdout, "cacosf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = cacoshf (ca);
  fprintf (stdout, "cacoshf: %f %fi\n", crealf (cc),
	   cimagf (cc));

  f1 = cargf (ca);
  fprintf (stdout, "cargf  : %f\n", f1);

  cc = casinf (ca);
  fprintf (stdout, "casinf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = casinhf (ca);
  fprintf (stdout, "casinhf: %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = catanf (ca);
  fprintf (stdout, "catanf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = catanhf (ca);
  fprintf (stdout, "catanhf: %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = ccosf (ca);
  fprintf (stdout, "ccosf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = ccoshf (ca);
  fprintf (stdout, "ccoshf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = cexpf (ca);
  fprintf (stdout, "cexpf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  f1 = cimagf (ca);
  fprintf (stdout, "cimagf : %f\n", f1);

  cc = clogf (ca);
  fprintf (stdout, "clogf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = conjf (ca);
  fprintf (stdout, "conjf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = cpowf (ca, cb);
  fprintf (stdout, "cpowf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = cprojf (ca);
  fprintf (stdout, "cprojf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  f1 = crealf (ca);
  fprintf (stdout, "crealf : %f\n", f1);

  cc = csinf (ca);
  fprintf (stdout, "csinf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = csinhf (ca);
  fprintf (stdout, "csinhf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = csqrtf (ca);
  fprintf (stdout, "csqrtf : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = ctanf (ca);
  fprintf (stdout, "ctanf  : %f %fi\n", crealf (cc),
	   cimagf (cc));

  cc = ctanhf (ca);
  fprintf (stdout, "ctanhf : %f %fi\n", crealf (cc),
	   cimagf (cc));
#endif
}
Exemple #6
0
int main(int argc, char* argv[])
{
    int job;
    float x,y, rads, theta;
    sf_complex cs, cz;
    const int nfat=1, ntheta= 271;
    const float eps=0.1, k2=0.05;

    vp_init();

    for (job=0; job < 5; job++) {
	vp_uorig ( -1.75-2.20*job, -1.5 );
	vp_uclip (-1.,-1.,1.3,1.1);
	vp_fat (nfat);

	vp_umove (0.,-.9);  
	vp_udraw (0.,4.9);
	vp_umove (-.5,0.);  
	vp_udraw (1.2,0.);

	vp_utext(  .1,  .9,  4,0, "Im");
	vp_utext( 1.05, -.2, 4,0, "Re");

	switch (job) {
	    case 0:
		vp_utext( .1, -.7 , 4,0, "\\F10 w=+p");
		vp_utext( .1,  .6 , 4,0, "\\F10 w=-p");
		vp_utext( .1,  .05, 4,0, "\\F10 w=0");
		break;
	    case 1:
		vp_utext( .4, -.65, 4,0, "\\F10 w=p/2");
		vp_utext( .4,  .55, 4,0, "\\F10 w=-p/2");
		vp_utext( .1,  .05, 4,0, "\\F10 w=0");
		break;
	    default:
		break;
	}

	vp_fat(0);
	vp_penup();

	for( theta = -180.; theta<180.1; theta += 360./ntheta )  {
	    rads = 2. * SF_PI * theta / 360.;
	    cz = cexpf( sf_cmplx(0.,rads) );
#ifdef SF_HAS_COMPLEX_H	 
	    cs = (1.+eps - cz )/2.;
#else
	    cs = sf_crmul(sf_cadd(sf_cmplx(1.+eps,0.),sf_cneg(cz)),0.5);
#endif
	    
	    switch (job) {
		case 0: cs = sf_cmplx( .05, .8*theta/180.); break;
		case 1: break;
#ifdef SF_HAS_COMPLEX_H	 
		case 2: cs *= cs; break;
		case 3: cs = cs*cs + k2; break;
		case 4: cs = csqrtf( cs*cs + k2 ); break;
#else
		case 2: cs = sf_cmul(cs,cs); 
		    break;
		case 3: cs = sf_cadd(sf_cmul(cs,cs),sf_cmplx(k2,0.)); 
		    break;
		case 4: cs = csqrtf(sf_cadd(sf_cmul(cs,cs),sf_cmplx(k2,0.))); 
		    break;
#endif 
		default: break;
	    }

	    x = crealf( cs ); 
	    y = cimagf( cs );

	    vp_upendn ( x, -y);
	}
    }

    return 0;
}
Exemple #7
0
complex float
cacoshf (complex float z)
{
  return clogf (z + csqrtf (z-1.0f) * csqrtf (z+1.0f));
}
Exemple #8
0
complex float
casinhf (complex float z)
{
  return clogf (z + csqrtf (z*z+1.0f));
}
Exemple #9
0
complex float
cacosf (complex float z)
{
  return -I*clogf (z + I*csqrtf (1.0f-z*z));
}
Exemple #10
0
complex float
casinf (complex float z)
{
  return -I*clogf (I*z + csqrtf (1.0f-z*z));
}