#include #include #include #include "arpackdef.h" // This test calls fortran from C the old-fashion cumbersome way. // Note: icb_arpack_c tests the same kind of things using ICB. #ifdef INCLUDE_FCMANGLE #include "FCMangle.h" #endif /* test program to solve for the 9 largest eigenvalues of * A*x = lambda*x where A is the diagonal matrix * with entries 1000, 999, ... , 2, 1 on the diagonal. * We're using the non symmetric routines dnaupd and dneupd. * This is not efficient since the problem is * symmetric but is done to exhibit the bug. */ extern void snaupd(a_int *, char *, a_int *, char *, a_int *, float *, float *, a_int *, float *, a_int *, a_int *, a_int *, float *, float *, a_int *, a_int *); extern void sneupd(a_int *, char *, a_int *, float *, float *, float *, a_int *, float *, float *, float *, char *, a_int *, char *, a_int *, float *, float *, a_int *, float *, a_int *, a_int *, a_int *, float *, float *, a_int *, a_int *); void matVec(float *x, float *y) { int i; for (i = 0; i < 1000; ++i) y[i] = ((float)(i + 1)) * x[i]; }; int main() { a_int ido = 0; char bmat[] = "I"; a_int N = 1000; char which[] = "LM"; a_int nev = 9; float tol = 0; float resid[N]; a_int ncv = 2 * nev + 1; float V[ncv * N]; a_int ldv = N; a_int iparam[11]; a_int ipntr[14]; float workd[3 * N]; a_int rvec = 1; char howmny[] = "A"; float *dr = (float *)malloc((nev + 1) * sizeof(float)); float *di = (float *)malloc((nev + 1) * sizeof(float)); a_int select[3 * ncv]; float z[(N + 1) * (nev + 1)]; a_int ldz = N + 1; float sigmar = 0; float sigmai = 0; float workev[3 * ncv]; int k; for (k = 0; k < 3 * N; ++k) workd[k] = 0; float workl[3 * (ncv * ncv) + 6 * ncv]; for (k = 0; k < 3 * (ncv * ncv) + 6 * ncv; ++k) workl[k] = 0; a_int lworkl = 3 * (ncv * ncv) + 6 * ncv; a_int info = 0; iparam[0] = 1; iparam[2] = 10 * N; iparam[3] = 1; iparam[6] = 1; snaupd(&ido, bmat, &N, which, &nev, &tol, resid, &ncv, V, &ldv, iparam, ipntr, workd, workl, &lworkl, &info); while (ido == -1 || ido == 1) { matVec(&(workd[ipntr[0] - 1]), &(workd[ipntr[1] - 1])); snaupd(&ido, bmat, &N, which, &nev, &tol, resid, &ncv, V, &ldv, iparam, ipntr, workd, workl, &lworkl, &info); } sneupd(&rvec, howmny, select, dr, di, z, &ldz, &sigmar, &sigmai, workev, bmat, &N, which, &nev, &tol, resid, &ncv, V, &ldv, iparam, ipntr, workd, workl, &lworkl, &info); int i; for (i = 0; i < nev; ++i) { printf("%f\n", dr[i]); if (fabs(dr[i] - (float)(1000 - i)) > 1e-2) { free(dr); free(di); exit(EXIT_FAILURE); } } free(dr); free(di); return 0; }