// 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 ); }
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; }
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);
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 }
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; }
complex float cacoshf (complex float z) { return clogf (z + csqrtf (z-1.0f) * csqrtf (z+1.0f)); }
complex float casinhf (complex float z) { return clogf (z + csqrtf (z*z+1.0f)); }
complex float cacosf (complex float z) { return -I*clogf (z + I*csqrtf (1.0f-z*z)); }
complex float casinf (complex float z) { return -I*clogf (I*z + csqrtf (1.0f-z*z)); }