#define _GNU_SOURCE #include #include #include #include #include #include static double randU(double a, double b) {return a + (b-a) * random() * (1. / RAND_MAX); } // Normal distribution via Box-Muller transform static double randN(double sigma, double mu) { double u1 = randU(0,1); double u2 = randU(0,1); return mu + sigma*sqrt(-2*log(u1))*cos(2.*M_PI*u2); } struct param { double *T0; double *T1; double *T2; }; int M_function(complex double *target, const size_t m, const complex double z, void *params) { struct param *p = params; for(size_t i = 0; i < m*m; ++i) target[i] = p->T0[i] + z*p->T1[i] + cexp( #ifdef VARIANTB // Also note that this case requires pretty large contour point number (>~ 3000) (1+3*I) #else // VARIANTA or VARIANTC (1+1*I) #endif *z*p->T2[i]) + #ifdef VARIANTC // Essential singularity at zero cexp(3/z); #elif defined VARIANTD // Essential singularity outside the contour cexp(3/(z-1)) #elif defined VARIANTE // High-order pole at zero 3/cpow(z,10); #elif defined VARIANTF // High-order pole at zero, higher order than dim .0003/cpow(z,12); #else // double pole at zero 3/z/z #endif ; return 0; } int main(int argc, char **argv) { feenableexcept(FE_INVALID | FE_OVERFLOW); complex double z0 = 0+3e-1*I; #ifdef RXSMALL double Rx = .1; #else double Rx = .3; // Variant B will fail in this case due to large number of eigenvalues (>30) #endif double Ry = .25; #ifdef VARIANTF int L = 10, N = 150, dim = 10; #else int L = 30, N = 150, dim = 60; #endif if (argc > 1) N = atoi(argv[1]); if (argc > 2) L = atoi(argv[2]); #ifdef IMPLUS beyn_contour_t *contour = beyn_contour_halfellipse(z0, Rx, Ry, N, BEYN_CONTOUR_HALFELLIPSE_IM_PLUS); #elif defined IMPLUS_KIDNEY beyn_contour_t *contour = beyn_contour_kidney(z0, Rx, Ry, 0.3, N, BEYN_CONTOUR_HALFELLIPSE_IM_PLUS); #else beyn_contour_t *contour = beyn_contour_ellipse(z0, Rx, Ry, N); #endif struct param p; p.T0 = malloc(dim*dim*sizeof(double)); p.T1 = malloc(dim*dim*sizeof(double)); p.T2 = malloc(dim*dim*sizeof(double)); for(size_t i = 0; i < dim*dim; ++i) { p.T0[i] = randN(1,0); p.T1[i] = randN(1,0); p.T2[i] = randN(1,0); } beyn_result_t *result = beyn_solve(dim, L, M_function, NULL /*M_inv_Vhat_function*/, &p /*params*/, contour, 1e-4, 1, 1e-4); printf("Found %zd eigenvalues:\n", result->neig); for (size_t i = 0; i < result->neig; ++i) { complex double eig = result->eigval[i]; printf("%zd: %g%+gj\n", i, creal(eig), cimag(eig)); } free(contour); beyn_result_free(result); free(p.T0); free(p.T1); free(p.T2); return 0; }