From 7d2097a1e07c4965e49e901a117acfccc4ed45a6 Mon Sep 17 00:00:00 2001 From: Ruslan Kabatsayev Date: Wed, 6 Jun 2018 23:05:54 +0300 Subject: [PATCH] Pass complex parameters by pointers to constant instead of by value, as Fortran-C bindings expect it This fixes opencollab/arpack-ng#123. Both C and C++ tests will no longer crash. But the C test will fail. This might be due to an error in the test itself. --- TESTS/icb_arpack_c.c | 4 ++-- arpack.h | 4 ++-- arpack.hpp | 10 ++++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/TESTS/icb_arpack_c.c b/TESTS/icb_arpack_c.c index 419227a25..84bfa55ae 100644 --- a/TESTS/icb_arpack_c.c +++ b/TESTS/icb_arpack_c.c @@ -116,7 +116,7 @@ int zn() { int select[ncv]; double _Complex z[(N+1)*(nev+1)]; BLASINT ldz = N+1; - double sigma=0; + double _Complex sigma=0; int k; for (k=0; k < 3*N; ++k ) workd[k] = 0; @@ -144,7 +144,7 @@ int zn() { if (iparam[4] != nev) return 1; // check number of ev found by arpack. /* call arpack like you would have, but, use zneupd_c instead of zneupd_ */ - zneupd_c(rvec, howmny, select, d, z, ldz, sigma, workev, + zneupd_c(rvec, howmny, select, d, z, ldz, &sigma, workev, bmat, N, which, nev, tol, resid, ncv, V, ldv, iparam, ipntr, workd, workl, lworkl, rwork, &info); int i; diff --git a/arpack.h b/arpack.h index f85ec7ba9..9cfaf40cc 100644 --- a/arpack.h +++ b/arpack.h @@ -55,7 +55,7 @@ extern void cnaupd_c(int * ido, char * bmat, int n, char * which, int nev, float _Complex * workl, int lworkl, float _Complex * rwork, int * info); extern void cneupd_c(bool rvec, char * howmny, int * select, - float _Complex * d, float _Complex * z, int ldz, float _Complex sigma, float _Complex * workev, + float _Complex * d, float _Complex * z, int ldz, float _Complex const* sigma, float _Complex * workev, char * bmat, int n, char * which, int nev, float tol, float _Complex * resid, int ncv, float _Complex * v, int ldv, int * iparam, int * ipntr, float _Complex * workd, @@ -67,7 +67,7 @@ extern void znaupd_c(int * ido, char * bmat, int n, char * which, int nev, double _Complex * workl, int lworkl, double _Complex * rwork, int * info); extern void zneupd_c(bool rvec, char * howmny, int * select, - double _Complex * d, double _Complex * z, int ldz, double _Complex sigma, double _Complex * workev, + double _Complex * d, double _Complex * z, int ldz, double _Complex const* sigma, double _Complex * workev, char * bmat, int n, char * which, int nev, double tol, double _Complex * resid, int ncv, double _Complex * v, int ldv, int * iparam, int * ipntr, double _Complex * workd, diff --git a/arpack.hpp b/arpack.hpp index 6ce800f57..ac2dd291e 100644 --- a/arpack.hpp +++ b/arpack.hpp @@ -94,7 +94,7 @@ void cnaupd_c(int& ido, const char* bmat, int n, const char* which, int nev, int& info); void cneupd_c(bool rvec, const char* howmny, int* select, float _Complex* d, - float _Complex* z, int ldz, float _Complex sigma, + float _Complex* z, int ldz, float _Complex const* sigma, float _Complex* workev, const char* bmat, int n, const char* which, int nev, float tol, float _Complex* resid, int ncv, float _Complex* v, int ldv, int* iparam, int* ipntr, @@ -108,7 +108,7 @@ void znaupd_c(int& ido, const char* bmat, int n, const char* which, int nev, int& info); void zneupd_c(bool rvec, const char* howmny, int* select, double _Complex* d, - double _Complex* z, int ldz, double _Complex sigma, + double _Complex* z, int ldz, double _Complex const* sigma, double _Complex* workev, const char* bmat, int n, const char* which, int nev, double tol, double _Complex* resid, int ncv, double _Complex* v, int ldv, int* iparam, int* ipntr, @@ -273,10 +273,11 @@ inline void neupd(bool rvec, howmny const howmny_option, int* select, std::complex* v, int ldv, int* iparam, int* ipntr, std::complex* workd, std::complex* workl, int lworkl, std::complex* rwork, int& info) { + const _Complex float csigma=std::real(sigma) + std::imag(sigma) * I; internal::cneupd_c(rvec, internal::convert_to_char(howmny_option), select, reinterpret_cast<_Complex float*>(d), reinterpret_cast<_Complex float*>(z), ldz, - std::real(sigma) + std::imag(sigma) * I, + &csigma, reinterpret_cast<_Complex float*>(workev), internal::convert_to_char(bmat_option), n, internal::convert_to_char(ritz_option), nev, tol, @@ -310,10 +311,11 @@ inline void neupd(bool rvec, howmny const howmny_option, int* select, std::complex* v, int ldv, int* iparam, int* ipntr, std::complex* workd, std::complex* workl, int lworkl, std::complex* rwork, int& info) { + const _Complex double csigma=std::real(sigma) + _Complex_I * std::imag(sigma); internal::zneupd_c(rvec, internal::convert_to_char(howmny_option), select, reinterpret_cast<_Complex double*>(d), reinterpret_cast<_Complex double*>(z), ldz, - std::real(sigma) + _Complex_I * std::imag(sigma), + &csigma, reinterpret_cast<_Complex double*>(workev), internal::convert_to_char(bmat_option), n, internal::convert_to_char(ritz_option), nev, tol,