New Upstream Release - arpack

Ready changes

Summary

Merged new upstream version: 3.9.0 (was: 3.8.0).

Diff

diff --git a/.github/workflows/jobs.yml b/.github/workflows/jobs.yml
new file mode 100644
index 0000000..a07d6fa
--- /dev/null
+++ b/.github/workflows/jobs.yml
@@ -0,0 +1,293 @@
+name: arpack-ng
+on: [push, pull_request]
+jobs:
+  ubuntu_latest_cmake:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Clone and check out repository code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+          ref: ${{github.event.pull_request.head.ref}} # Branch where changes are implemented.
+          repository: ${{github.event.pull_request.head.repo.full_name}} # Repo where changes are implemented.
+      - name: Check commit
+        run: |
+          git log -1
+      - name: Update OS
+        run: sudo apt-get update
+      - name: Install apt-get dependencies
+        run: sudo apt-get install -y gfortran gcc g++ openmpi-bin libopenmpi-dev libblas-dev liblapack-dev libeigen3-dev cmake
+      - name: Run job
+        run: |
+          mkdir build
+          cd build
+          cmake -DEXAMPLES=ON -DMPI=ON -DICB=ON -DICBEXMM=ON ..
+          make all
+          CTEST_OUTPUT_ON_FAILURE=1 make test
+          make package_source
+  ubuntu_latest_cmake_install:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Clone and check out repository code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+          ref: ${{github.event.pull_request.head.ref}} # Branch where changes are implemented.
+          repository: ${{github.event.pull_request.head.repo.full_name}} # Repo where changes are implemented.
+      - name: Check commit
+        run: |
+          git log -1
+      - name: Update OS
+        run: sudo apt-get update
+      - name: Install apt-get dependencies
+        run: sudo apt-get install -y gfortran gcc g++ openmpi-bin libopenmpi-dev libblas-dev liblapack-dev cmake
+      - name: Run job
+        run: |
+          mkdir build
+          cd build
+          cmake ..
+          bash ./tstCMakeInstall.sh
+          bash ./tstCMakeInstall.sh 64-
+          bash ./tstCMakeInstall.sh   -ILP64
+          bash ./tstCMakeInstall.sh 64-ILP64
+  ubuntu_latest_autotools:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Clone and check out repository code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+          ref: ${{github.event.pull_request.head.ref}} # Branch where changes are implemented.
+          repository: ${{github.event.pull_request.head.repo.full_name}} # Repo where changes are implemented.
+      - name: Check commit
+        run: |
+          git log -1
+      - name: Update OS
+        run: sudo apt-get update
+      - name: Install apt-get dependencies
+        run: sudo apt-get install -y gfortran gcc g++ openmpi-bin libopenmpi-dev libblas-dev liblapack-dev libeigen3-dev automake autoconf pkg-config libtool
+      - name: Run job
+        run: |
+          ./bootstrap
+          ./configure --enable-mpi --enable-icb --enable-icbexmm
+          make all
+          make check
+          make distcheck
+  ubuntu_latest_autotools_install:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Clone and check out repository code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+          ref: ${{github.event.pull_request.head.ref}} # Branch where changes are implemented.
+          repository: ${{github.event.pull_request.head.repo.full_name}} # Repo where changes are implemented.
+      - name: Check commit
+        run: |
+          git log -1
+      - name: Update OS
+        run: sudo apt-get update
+      - name: Install apt-get dependencies
+        run: sudo apt-get install -y gfortran gcc g++ openmpi-bin libopenmpi-dev libblas-dev liblapack-dev automake autoconf pkg-config libtool
+      - name: Run job
+        run: |
+          ./bootstrap
+          ./configure
+          bash ./tstAutotoolsInstall.sh
+          bash ./tstAutotoolsInstall.sh 64-
+          bash ./tstAutotoolsInstall.sh   -ILP64
+          bash ./tstAutotoolsInstall.sh 64-ILP64
+  ubuntu_latest_cmake_python:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Clone and check out repository code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+          ref: ${{github.event.pull_request.head.ref}} # Branch where changes are implemented.
+          repository: ${{github.event.pull_request.head.repo.full_name}} # Repo where changes are implemented.
+      - name: Check commit
+        run: |
+          git log -1
+      - name: Update OS
+        run: sudo apt-get update
+      - name: Install apt-get dependencies
+        run: sudo apt-get install -y gfortran gcc g++ openmpi-bin libopenmpi-dev libblas-dev liblapack-dev cmake libeigen3-dev
+      - name: Install python dependencies
+        run: sudo apt-get -y install python3-minimal python3-pip python3-numpy
+      - name: Build boost-python for python3 (not provided by apt-cache)
+        run : |
+          sudo apt-get -y install wget
+          wget https://sourceforge.net/projects/boost/files/boost/1.79.0/boost_1_79_0.tar.gz
+          tar -xf boost_1_79_0.tar.gz
+          cd boost_1_79_0
+          ./bootstrap.sh --with-libraries=python --with-python=/usr/bin/python3 --with-toolset=gcc
+          sudo ./b2 toolset=gcc install
+          sudo apt-get install locate
+          sudo updatedb
+      - name: Run job
+        run: |
+          mkdir build
+          cd build
+          cmake -DEXAMPLES=ON -DMPI=ON -DICB=ON -DICBEXMM=ON -DPYTHON3=ON ..
+          make all
+          CTEST_OUTPUT_ON_FAILURE=1 make test
+  ubuntu_latest_autotools_ilp64:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Clone and check out repository code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+          ref: ${{github.event.pull_request.head.ref}} # Branch where changes are implemented.
+          repository: ${{github.event.pull_request.head.repo.full_name}} # Repo where changes are implemented.
+      - name: Check commit
+        run: |
+          git log -1
+      - name: Update OS
+        run: sudo apt-get update
+      - name: Install apt-get dependencies
+        run: sudo apt-get install -y gfortran gcc g++ openmpi-bin libopenmpi-dev libblas-dev liblapack-dev automake autoconf pkg-config libtool libeigen3-dev
+      - name: Install Intel MKL (ILP64 blas/lapack)
+        run: echo yes | sudo apt-get -y install intel-mkl libmkl-dev
+      - name: Run job
+        run: |
+          ./bootstrap
+          ./configure --enable-icb --with-blas=mkl_gf_ilp64 --with-lapack=mkl_gf_ilp64
+          make all
+          make check
+        env:
+          FFLAGS: "-DMKL_ILP64 -I/usr/include/mkl"
+          FCFLAGS: "-DMKL_ILP64 -I/usr/include/mkl"
+          LIBS: "-Wl,--no-as-needed -L/usr/lib/x86_64-linux-gnu -lmkl_sequential -lmkl_core -lpthread -lm -ldl"
+          INTERFACE64: "1"
+  macos_latest_cmake:
+    runs-on: macos-latest
+    steps:
+      - name: Clone and check out repository code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+          ref: ${{github.event.pull_request.head.ref}} # Branch where changes are implemented.
+          repository: ${{github.event.pull_request.head.repo.full_name}} # Repo where changes are implemented.
+      - name: Check commit
+        run: |
+          git log -1
+      - name: Install brew dependencies
+        run: |
+          brew reinstall gcc # brings gfortran on path
+          brew install cmake mpich
+      - name: Run job
+        run: |
+          mkdir -p build
+          cd build
+          export FC=mpif90 # Uses gfortran.
+          export FFLAGS="-ff2c -fno-second-underscore"
+          export CC=mpicc # Uses clang.
+          export CFLAGS="-Qunused-arguments"
+          export CXX=mpic++ # Uses clang++.
+          export CXXFLAGS="-Qunused-arguments"
+          LIBS="-framework Accelerate" cmake -DBLA_VENDOR=Generic -DEXAMPLES=ON -DICB=ON -DMPI=ON ..
+          make all
+          CTEST_OUTPUT_ON_FAILURE=1 make test
+  macos_latest_cmake_python:
+    runs-on: macos-latest
+    steps:
+      - name: Clone and check out repository code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+          ref: ${{github.event.pull_request.head.ref}} # Branch where changes are implemented.
+          repository: ${{github.event.pull_request.head.repo.full_name}} # Repo where changes are implemented.
+      - name: Check commit
+        run: |
+          git log -1
+      - name: Install brew dependencies
+        run: |
+          # Unlink and re-link to prevent errors when github mac runner images
+          # install python outside of brew, for example:
+          # https://github.com/orgs/Homebrew/discussions/3895
+          # https://github.com/actions/setup-python/issues/577
+          # https://github.com/actions/runner-images/issues/6459
+          # https://github.com/actions/runner-images/issues/6507
+          # https://github.com/actions/runner-images/issues/2322
+          brew list -1 | grep python | while read formula; do brew unlink $formula; brew link --overwrite $formula; done
+          brew reinstall gcc # brings gfortran on path
+          brew install cmake eigen boost-python3 python3 
+          pip3 install numpy
+      - name: Run job
+        run: |
+          mkdir -p build
+          cd build
+          export FC=gfortran
+          export FFLAGS="-ff2c -fno-second-underscore"
+          export CC=clang
+          export CFLAGS="-Qunused-arguments"
+          export CXX=clang++
+          export CXXFLAGS="-Qunused-arguments"
+          LIBS="-framework Accelerate" cmake -DBLA_VENDOR=Generic -DEXAMPLES=ON -DICB=ON -DPYTHON3=ON ..
+          make all
+          CTEST_OUTPUT_ON_FAILURE=1 make test
+  macos_latest_autotools:
+    runs-on: macos-latest
+    steps:
+      - name: Clone and check out repository code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+          ref: ${{github.event.pull_request.head.ref}} # Branch where changes are implemented.
+          repository: ${{github.event.pull_request.head.repo.full_name}} # Repo where changes are implemented.
+      - name: Check commit
+        run: |
+          git log -1
+      - name: Install brew dependencies
+        run: |
+          brew reinstall gcc # brings gfortran on path
+          brew install autoconf automake libtool pkg-config mpich
+      - name: Run job
+        run: |
+          ./bootstrap
+          LIBS="-framework Accelerate" FFLAGS="-ff2c -fno-second-underscore" FCFLAGS="-ff2c -fno-second-underscore" ./configure --enable-icb --enable-mpi
+          make all
+          make check
+  windows_latest_cmake:
+    runs-on: windows-latest
+    defaults:
+      run:
+        # Use MSYS2 as default shell
+        shell: msys2 {0}
+    steps:
+      - name: Install MSYS2 build environment
+        uses: msys2/setup-msys2@v2
+        with:
+          update: true
+          msystem: MINGW64
+          install: >-
+            base-devel
+            git
+            mingw-w64-x86_64-cmake
+            mingw-w64-x86_64-ninja
+            mingw-w64-x86_64-gcc-fortran
+            mingw-w64-x86_64-openblas
+            mingw-w64-x86_64-msmpi
+      - name: Install MS-MPI (for mpiexec)
+        uses: mpi4py/setup-mpi@v1
+      - name: Clone and check out repository code
+        uses: actions/checkout@v2
+        with:
+          fetch-depth: 0
+          ref: ${{github.event.pull_request.head.ref}} # Branch where changes are implemented.
+          repository: ${{github.event.pull_request.head.repo.full_name}} # Repo where changes are implemented.
+      - name: Check commit
+        run: |
+          git log -1
+      - name: Run job
+        run: |
+          mkdir -p build && cd build
+          cmake -GNinja -DICB=ON -DEXAMPLES=ON -DMPI=ON ..
+          cmake --build . -v
+      - name: Run tests
+        run: |
+          export PATH="/c/Program Files/Microsoft MPI/Bin":$PATH # add mpiexec to msys2 path
+          cd build
+          ctest --output-on-failure
diff --git a/.gitignore b/.gitignore
index 61eca04..a8ebcfc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,13 +15,12 @@ config.log
 config.status
 libtool
 .deps/
-arpack.pc
-parpack.pc
-arpackSolver.pc
+arpack*.pc
+parpack*.pc
+arpackSolver*.pc
 arpackdef.h
 arpackicb.h
-arpack-ng-config.cmake
-arpack-ng-config-version.cmake
+tstAutotoolsInstall.sh
 
 # Generated by `make`
 .dirstamp
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 997ffab..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,288 +0,0 @@
-sudo: true
-
-language: c
-
-compiler:
-  - gcc
-
-addons:
-  apt:
-    packages:
-      - gfortran
-      - gcc
-      - g++
-      - openmpi-bin
-      - libopenmpi-dev
-      - cmake
-      - automake
-      - autoconf
-      - pkg-config
-      - libtool
-      - libblas-dev
-      - liblapack-dev
-      - diffutils
-      - findutils
-      - libeigen3-dev
-
-services:
-  - docker
-
-stages:
-  # order stages
-  - name: opensuse
-  - name: centos
-  - name: fedora
-  - name: osx
-  - name: ubuntu_precise
-  - name: ubuntu_trusty
-  - name: ubuntu_xenial
-  - name: ubuntu_bionic
-  - name: ubuntu_eoan
-  - name: ubuntu_focal
-  - name: coverage
-  - name: debian_interface64
-
-jobs:
-  include:
-  # opensuse: "recent" systems with ICB
-  #   note: when you PR, docker-cp provides, in the container, the branch associated with the PR (not master where there's nothing new)
-  #         1. docker create --name mobydick IMAGE CMD        <=> create a container (= instance of image) but container is NOT yet started
-  #         2. docker cp -a ${TRAVIS_BUILD_DIR} mobydick:/tmp <=> copy git repository (CI worker, checkout-ed on PR branch) into the container
-  #                                                               note: docker-cp works only if copy from/to containers (not images)
-  #         3. docker start -a mobydick                       <=> start to run the container (initialized with docker-cp)
-  - stage: opensuse
-    dist: bionic
-    script: |
-      sudo docker pull opensuse/tumbleweed                                                   \
-      &&                                                                                     \
-      sudo docker create --name mobydick opensuse/tumbleweed /bin/bash -c                    \
-      "zypper install -y git gcc gcc-fortran gcc-c++ openmpi2-devel                       && \
-       zypper install -y cmake                                                            && \
-       zypper install -y blas-devel lapack-devel                                          && \
-       cd /tmp                                                                            && \
-       cd arpack-ng                                                                       && \
-       git status                                                                         && \
-       git log -2                                                                         && \
-       sed -e 's/mpirun /mpirun --allow-run-as-root --oversubscribe /' -i CMakeLists.txt  && \
-       mkdir -p build && cd build                                                         && \
-       cmake -DEXAMPLES=ON -DMPI=ON -DICB=ON ..                                           && \
-       export PATH=/usr/lib64/mpi/gcc/openmpi2/bin:/usr/lib/mpi/gcc/openmpi2/bin/:$PATH   && \
-       make all && make test"                                                                \
-      &&                                                                                     \
-      sudo docker cp -a ${TRAVIS_BUILD_DIR} mobydick:/tmp                                    \
-      &&                                                                                     \
-      sudo docker start -a mobydick
-  # centos: "recent" systems with ICB
-  - stage: centos
-    dist: bionic
-    script: |
-      sudo docker pull centos                                                  \
-      &&                                                                       \
-      sudo docker create --name mobydick centos /bin/bash -c                   \
-      "dnf install -y dnf-plugins-core epel-release                         && \
-       dnf upgrade -y                                                       && \
-       dnf config-manager --set-enabled PowerTools                          && \
-       dnf install -y git make gcc gcc-gfortran gcc-c++ environment-modules && \
-       dnf install -y cmake                                                 && \
-       dnf install -y mpich-devel                                           && \
-       dnf --enablerepo=\"epel\" install -y openblas-devel lapack-devel     && \
-       . /etc/profile.d/modules.sh                                          && \
-       module avail && module load mpi && module list                       && \
-       cd /tmp                                                              && \
-       cd arpack-ng                                                         && \
-       git status                                                           && \
-       git log -2                                                           && \
-       mkdir -p build && cd build                                           && \
-       cmake -DEXAMPLES=ON -DMPI=ON -DICB=ON ..                             && \
-       make all && make test"                                                  \
-      &&                                                                       \
-      sudo docker cp -a ${TRAVIS_BUILD_DIR} mobydick:/tmp                      \
-      &&                                                                       \
-      sudo docker start -a mobydick
-  # fedora (released fedora with openmpi)
-  - stage: fedora
-    name: "Fedora latest with openmpi"
-    dist: bionic
-    script: ./scripts/travis_fedora.sh setup openmpi latest
-  # fedora (with gcc 10 and mpich)
-  - stage: fedora
-    name: "Fedora rawhide with mpich"
-    dist: bionic
-    script: ./scripts/travis_fedora.sh setup mpich rawhide
-  # osx
-  - stage: osx
-    os: osx
-    osx_image: xcode12
-    before_install:
-    - brew list -1 | while read line; do brew unlink $line; done;
-    - brew list gcc      || brew install gcc
-    - brew list autoconf || brew install autoconf
-    - brew list automake || brew install automake
-    - brew list mpich    || brew install mpich
-    - brew list -1 | while read line; do brew link --overwrite $line; done;
-    - softwareupdate --install -a
-    # full build and testing with Accelerate framework (xcode provides vecLib which stands for BLAS/LAPACK)
-    # note: -ff2c to convert fortran code to C, -fno-second-underscore to force underscoring of external symbols to link
-    script: |
-      ./bootstrap && LIBS="-framework Accelerate" FFLAGS="-ff2c -fno-second-underscore" FCFLAGS="-ff2c -fno-second-underscore" ./configure --enable-icb --enable-mpi && make VERBOSE=1 && make check
-  - stage: osx
-    os: osx
-    osx_image: xcode12
-    before_install:
-    - brew list -1 | while read line; do brew unlink $line; done;
-    - brew list gcc      || brew install gcc
-    - brew list cmake    || brew install cmake
-    - brew list openblas || brew install openblas
-    - brew list lapack   || brew install lapack
-    - brew list mpich    || brew install mpich
-    - brew list -1 | while read line; do brew link --overwrite $line; done;
-    # full build and testing with openblas and lapack
-    # note: -ff2c to convert fortran code to C, -fno-second-underscore to force underscoring of external symbols to link
-    script: |
-      mkdir -p build && cd build && FFLAGS="-ff2c -fno-second-underscore" FCFLAGS="-ff2c -fno-second-underscore" cmake -DEXAMPLES=ON -DICB=ON -DMPI=ON .. && make VERBOSE=1 && make test
-  - stage: osx
-    os: osx
-    osx_image: xcode11
-    before_install:
-    - brew list -1 | while read line; do brew unlink $line; done;
-    - brew list arpack   || brew install arpack # Test osx formula
-    - brew list -1 | while read line; do brew link --overwrite $line; done;
-    script: ls # Need fake script.
-  - stage: osx
-    os: osx
-    osx_image: xcode12
-    before_install:
-    - brew list -1 | while read line; do brew unlink $line; done;
-    - brew list arpack   || brew install arpack # Test osx formula
-    - brew list -1 | while read line; do brew link --overwrite $line; done;
-    script: ls # Need fake script.
-  # ubuntu_precise <=> test "older" systems, without ICB, without cmake (too old to be supported)
-  - stage: ubuntu_precise
-    dist: precise
-    script: ./bootstrap && ./configure                                                  && make VERBOSE=1 && make check && make distcheck;
-  - stage: ubuntu_precise
-    dist: precise
-    script: ./bootstrap && ./configure --enable-mpi                                     && make VERBOSE=1 && make check && make distcheck;
-  # ubuntu_trusty <=> test "older" systems, without ICB
-  - stage: ubuntu_trusty
-    dist: trusty
-    script: mkdir -p build && cd build && cmake -D EXAMPLES=ON -D MPI=ON  -D ICB=OFF .. && make VERBOSE=1 && make test  && make package_source;
-  - stage: ubuntu_trusty
-    dist: trusty
-    script: ./bootstrap && ./configure --enable-mpi                                     && make VERBOSE=1 && make check && make distcheck;
-  # ubuntu_xenial <=> test "recent" systems, with ICB
-  - stage: ubuntu_xenial
-    dist: xenial
-    script: mkdir -p build && cd build && cmake -D EXAMPLES=ON -D MPI=ON  -D ICB=ON  .. && make VERBOSE=1 && make test  && make package_source;
-  - stage: ubuntu_xenial
-    dist: xenial
-    script: ./bootstrap && ./configure --enable-mpi --enable-icb                        && make VERBOSE=1 && make check && make distcheck;
-  # ubuntu_bionic <=> test "recent" systems, with ICB
-  - stage: ubuntu_bionic
-    dist: bionic
-    script: ./bootstrap && ./configure --enable-icb --enable-icb-exmm --enable-mpi && export VERBOSE=1 && make all && make check
-  - stage: ubuntu_bionic
-    dist: bionic
-    before_install:
-    - sudo apt-get -y install python3-minimal python3-pip python3-numpy
-    - sudo pip3 install --system numpy
-    # need to build boost-python from source for python 3 (repository package is built for python 2)
-    - sudo apt-get -y install wget
-    - wget https://sourceforge.net/projects/boost/files/boost/1.67.0/boost_1_67_0.tar.gz
-    - tar -xf boost_1_67_0.tar.gz && cd boost_1_67_0
-    - ./bootstrap.sh --with-libraries=python --with-python=/usr/bin/python3
-    - sudo ./b2 install
-    - sudo apt-get install locate
-    - sudo updatedb
-    script: |
-      cd $TRAVIS_BUILD_DIR && mkdir -p build && cd build &&                                  \
-      cmake -DEXAMPLES=ON -DICB=ON -DICBEXMM=ON -DMPI=ON -DPYTHON3=ON -DBOOST_PYTHON_LIBSUFFIX='36' .. && \
-      export VERBOSE=1 && make all && make test
-  # ubuntu_eoan <=> test "recent" systems, with ICB
-  - stage: ubuntu_eoan
-    dist: bionic
-    script: ./scripts/travis_ubuntu.sh ubuntu :eoan
-  # ubuntu_focal <=> test "recent" systems, with ICB
-  - stage: ubuntu_focal
-    dist: bionic
-    script: ./scripts/travis_ubuntu.sh ubuntu :focal
-  # coverage: "recent" systems with ICB
-  - stage: coverage
-    dist: bionic
-    script: |
-      mkdir -p build && cd build                                                   \
-      &&                                                                           \
-      cmake -DEXAMPLES=ON -DMPI=ON -DICB=ON -DCOVERALLS=ON ..     &> cmake.log     \
-      &&                                                                           \
-      tail -n 50 cmake.log                                                         \
-      &&                                                                           \
-      make all                                                    &> compil.log    \
-      &&                                                                           \
-      tail -n 50 compil.log                                                        \
-      &&                                                                           \
-      make test                                                   &> test.log      \
-      &&                                                                           \
-      tail -n 50 test.log                                                          \
-      &&                                                                           \
-      make coveralls                                              &> coveralls.log \
-      &&                                                                           \
-      head -n 50 coveralls.log && tail -n 50 coveralls.log                         \
-      &&                                                                           \
-      head -n 50 coveralls.json && tail -n 50 coveralls.json
-  # debian_interface64: "recent" systems with ICB + MKL + ILP64 (need debian/testing to get MKL-ILP64)
-  #   note: when you PR, docker-cp provides, in the container, the branch associated with the PR (not master where there's nothing new)
-  #         1. docker create --name mobydick IMAGE CMD        <=> create a container (= instance of image) but container is NOT yet started
-  #         2. docker cp -a ${TRAVIS_BUILD_DIR} mobydick:/tmp <=> copy git repository (CI worker, checkout-ed on PR branch) into the container
-  #                                                               note: docker-cp works only if copy from/to containers (not images)
-  #         3. docker start -a mobydick                       <=> start to run the container (initialized with docker-cp)
-  - stage: debian_interface64
-    dist: xenial
-    script: |
-      sudo docker pull debian                                                                                           \
-      &&                                                                                                                \
-      sudo docker create --name mobydick debian /bin/bash -c                                                            \
-      "cat /etc/os-release                                                                                           && \
-       cat /etc/apt/sources.list                                                                                     && \
-       sed -e 's/stretch/testing/'            -i /etc/apt/sources.list                                               && \
-       sed -e 's/main/main non-free contrib/' -i /etc/apt/sources.list                                               && \
-       sed -e '/security.debian.org/d'        -i /etc/apt/sources.list                                               && \
-       cat /etc/apt/sources.list                                                                                     && \
-       export DEBIAN_FRONTEND=noninteractive                                                                         && \
-       apt-get -y                                                                 update                             && \
-       apt-get -y --allow-unauthenticated -o Dpkg::Options::=--force-confdef      upgrade                            && \
-       apt-get -y --allow-unauthenticated -o Dpkg::Options::=--force-confdef dist-upgrade                            && \
-       cat /etc/os-release                                                                                           && \
-       apt-get -y install dialog                                                                                     && \
-       echo yes | apt-get -y install intel-mkl libmkl-dev                                                            && \
-       apt-get -y install build-essential                                                                            && \
-       apt-get -y install git gfortran gcc g++ openmpi-bin libopenmpi-dev automake autoconf libtool pkg-config       && \
-       apt-get -y install libeigen3-dev                                                                              && \
-       cd /tmp                                                                                                       && \
-       cd arpack-ng                                                                                                  && \
-       git status                                                                                                    && \
-       git log -2                                                                                                    && \
-       sed -e 's/LOG_FLAGS = /LOG_FLAGS = --allow-run-as-root --oversubscribe /' -i PARPACK/EXAMPLES/MPI/Makefile.am && \
-       sed -e 's/LOG_FLAGS = /LOG_FLAGS = --allow-run-as-root --oversubscribe /' -i PARPACK/TESTS/MPI/Makefile.am    && \
-       ./bootstrap                                                                                                   && \
-       export FFLAGS='-DMKL_ILP64 -I/usr/include/mkl'                                                                && \
-       export FCFLAGS='-DMKL_ILP64 -I/usr/include/mkl'                                                               && \
-       export LIBS='-Wl,--no-as-needed -L/usr/lib/x86_64-linux-gnu -lmkl_sequential -lmkl_core -lpthread -lm -ldl'   && \
-       export INTERFACE64=1                                                                                          && \
-       ./configure --with-blas=mkl_gf_ilp64 --with-lapack=mkl_gf_ilp64 --enable-mpi --enable-icb-exmm                   \
-                   --disable-dependency-tracking                                                                     && \
-       export VERBOSE=1                                                                                              && \
-       make all                                                                                                      && \
-       make check                                                                                                    && \
-       find . -name test-suite.log | xargs tail -n 300"                                                                 \
-      &&                                                                                                                \
-      sudo docker cp -a ${TRAVIS_BUILD_DIR} mobydick:/tmp                                                               \
-      &&                                                                                                                \
-      sudo docker start -a mobydick
-
-
-after_failure:
-
-  # show build error or test log to know what is wrong if errors occured.
-  - if [[ -f $TRAVIS_BUILD_DIR/build/Testing/Temporary/LastTest.log ]]; then tail -n 300 $TRAVIS_BUILD_DIR/build/Testing/Temporary/LastTest.log; fi
-  - find . -name test-suite.log | xargs tail -n 300
-  - find . -name arpackmm.run.log | xargs tail -n 300
diff --git a/CHANGES b/CHANGES
index 63dea14..ee0ac71 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,73 @@
+ -- Franck Houssen <fghoussen@users.noreply.github.com> Sat, 11 Feb 2023 13:52:57 +0100
+
+arpack-ng - 3.9.0
+
+[ Vikas Sharma ]
+ * Improve README.
+
+[ Fabien Péan ]
+ * CI: Enable job `windows_latest_cmake` to run all tests
+ * CMake: Fix BLAS and LAPACK static library order needed to consume the library on Windows with static linkage
+ * Fix using ARPACK on Windows with MSVC compiler from C++17 onwards
+
+[ Zhentao Wang ]
+ * [BUG FIX] parpack.h and parpack.hpp: type of rwork should be real instead of complex.
+ * Allow ritz_option {"LR", "SR", "LI", "SI"} for complex eigenvalue problems in ICB.
+
+[ Jose E. Roman ]
+ * Avoid using isnan() in tests, since is GNU-specific
+
+[ Tom Payerle ]
+ * Change the continuation line format for stat.h, debug.h
+
+[ John Doe ]
+ * Avoid calling [c|z]dotc for better portability on macOS
+
+[ Dima Pasechnik ]
+ * [BUG FIX] autotools: replace obsolete AC_TRY_COMPILE macros.
+ * Support for NAG's nagfor Fortran compiler
+
+[ Franck Houssen ]
+ * Create one .cmake file per arpack-ng flavor (32-bits, 64-bits, ILP64).
+ * Test autotools pkg-config (*.pc files) with/without LIBSUFFIX/ITF64SUFFIX.
+ * Test CMake find_package (*.cmake files) with/without LIBSUFFIX/ITF64SUFFIX.
+ * [BUG FIX] autotools: ICB must be checked first (MPI changes compilers).
+ * [BUG FIX] BLAS/LAPACK: allow suffixes in case BLAS/LAPACK can not provide ICB.
+ * [BUG FIX] Compile C programs with ICB.
+ * arpackmm: command line bug fix.
+ * arpackmm: restart bug fix.
+ * pyarpack: fix compilation warning, test on macos and latest boost-python (1.79).
+ * arpackSolver: fix error messages.
+ * [BUG FIX] Make sure iseed is always initialized to values allowed by lapack ?larnv.
+ * [BUG FIX] According to lapack doc of ?larnv, iseed(4) must be odd.
+ * [BUG FIX] Use MPI ICB types (mpi_f08) instead of integer(kind=i_int).
+ * parpack: no ILP64 support.
+
+[ Haoyang Liu ]
+ * CMake: minimum required version changed to 3.0
+ * CMake: add C99 standard checking
+ * CI: Support for centos7 added.
+ * CI: Add `scripts/travis_centos.sh` for centos builds
+
+[ Robert Schütz ]
+ * use CMAKE_INSTALL_FULL_<dir> in arpack.pc
+
+[ Markus Mützel ]
+ * CMake: Handle libraries without "lib" prefix.
+ * CMake: Don't override BLAS/LAPACK/MPI flags. Directly use results from the Find* modules instead.
+
+[ Juan José García-Ripoll ]
+ * Adapt the C/C++ interface to accept also MSVC's non-standard complex types.
+ * Propagate dependencies to CMake targets that use arpack-ng:
+   - Create CMake-generated targets and configuration files that keep track of
+     arpack's dependencies (libraries, directories) and expose them to users.
+   - Install those files under ${prefix}/lib/cmake/arpackng* so that arpack can be
+     found using 'find_package(arpackng)' from CMake files.
+   - Add code to the arpackng-config.cmake to find required dependencies when this
+     module is loaded by find_package(arpackng).
+
+ -- Sylvestre Ledru <sylvestre@debian.org> Mon, 07 Dec 2020 11:37:40 +0100
+
 arpack-ng - 3.8.0
 
 [ Myron Oikonomakis ]
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9e4853b..f9a08ed 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 2.8.6)
+cmake_minimum_required(VERSION 3.0)
 
 if (NOT DEFINED CMAKE_BUILD_TYPE)
    set (CMAKE_BUILD_TYPE Release CACHE STRING "Build type")
@@ -7,12 +7,16 @@ endif ()
 project(arpack C Fortran)
 
 set(arpack_ng_MAJOR_VERSION 3)
-set(arpack_ng_MINOR_VERSION 8)
+set(arpack_ng_MINOR_VERSION 9)
 set(arpack_ng_PATCH_VERSION 0)
 set(arpack_ng_VERSION ${arpack_ng_MAJOR_VERSION}.${arpack_ng_MINOR_VERSION}.${arpack_ng_PATCH_VERSION})
 
 set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
 
+# set C99 standard
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_C_STANDARD_REQUIRED True)
+
 # Adopted from https://github.com/feymark/arpack.git
 
 if (POLICY CMP0042)
@@ -27,24 +31,24 @@ option(ICBEXMM "Enable support for matrix market example based on ICB" OFF)
 option(PYTHON3 "Enable python3 support" OFF)
 set(BOOST_PYTHON_LIBSUFFIX "" CACHE STRING "suffix to add to custom boost python libs")
 option(EXAMPLES "Compile ARPACK examples" OFF)
+option(TESTS "Compile ARPACK tests" ON)
+
+# Suffixes: LIBSUFFIX modify ONLY libraries names, ITF64SUFFIX modify BOTH libraries AND include directory names.
 set(LIBSUFFIX ""
     CACHE STRING "suffix to add to ARPACK libraries names")
+set(ITF64SUFFIX ""
+    CACHE STRING "suffix to add to ARPACK include directory and libraries names (use with INTERFACE64)")
 set(SYMBOLSUFFIX ""
     CACHE STRING "suffix to add to ARPACK, BLAS and LAPACK function names")
 option(INTERFACE64 "use the 64-bit integer interface (ILP64) for ARPACK, BLAS and LAPACK")
 
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
+# 'make install' to the correct location, and also define
+# paths for target_include_directories and target_link_libraries
+include(GNUInstallDirs)
+set(ARPACK_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}/arpack-ng${ITF64SUFFIX}")
+set(ARPACK_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/arpackng${LIBSUFFIX}${ITF64SUFFIX}")
 
-# We don't want this to run on every build.
-option(COVERALLS "Generate coveralls data" OFF)
-if (COVERALLS)
-    include(Coveralls)
-    set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
-    # The no space is by design: issue in cmake. See CMP0004.
-    set(EXTRA_LDFLAGS "${EXTRA_LDFLAGS}-lgcov")
-endif()
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
 
 function(prefixlist list_name prefix)
     set(${list_name}_TMP)
@@ -58,8 +62,8 @@ function(examples list_name)
     foreach(l ${${list_name}})
         get_filename_component(lwe ${l} NAME_WE)
         add_executable(${lwe} ${arpackexample_DIR}/${l} ${examples_EXTRA_SRCS})
-	target_link_libraries(${lwe} arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
-        add_test(NAME "${lwe}_ex" COMMAND ${lwe} WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+        target_link_libraries(${lwe} arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
+        add_test(NAME "${lwe}_ex" COMMAND ${lwe})
     endforeach()
 endfunction(examples)
 
@@ -68,14 +72,17 @@ function(pexamples list_name)
         get_filename_component(lwe ${l} NAME_WE)
         add_executable(${lwe} ${parpackexample_DIR}/${l} )
         target_link_libraries(${lwe} parpack arpack MPI::MPI_Fortran)
-        add_test(NAME "${lwe}_ex" COMMAND mpirun -n 2 ./${lwe} WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+        add_test(NAME "${lwe}_ex" COMMAND mpiexec -n 2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${lwe})
     endforeach()
 endfunction(pexamples)
 
 if (PYTHON3)
+    enable_language(C CXX) # Boost requirement.
+    set(CMAKE_CXX_STANDARD 14) # Boost requirement.
+
     find_package(PythonInterp 3 REQUIRED)
     find_package(PythonLibs 3 REQUIRED)
-    find_package(Boost COMPONENTS python${BOOST_PYTHON_LIBSUFFIX} numpy${BOOST_PYTHON_LIBSUFFIX} REQUIRED)
+    find_package(Boost 1.78 COMPONENTS python${BOOST_PYTHON_LIBSUFFIX} numpy${BOOST_PYTHON_LIBSUFFIX} REQUIRED)
 
     set(ICBEXMM "ON")
 endif ()
@@ -153,72 +160,49 @@ if (ICB)
       message("-- Fortran compiler does support iso_c_binding.")
     endif()
 else()
-    # ICB saves you from old-fashion-boring-cumbersome-fortran/C crap...
-
-    if ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
-      set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -cpp -ffixed-line-length-none")
-    elseif ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "Intel")
-      set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fpp -extend-source")
-    else ()
-      message(WARNING "build script does not know how to enable your Fortran compiler's preprocessor and support for lines longer than 72 characters: set them manually via FFLAGS.")
-    endif ()
-
-    set(SCALARFUNS naitr napps naup2 naupd nconv neigh neupd ngets statn saitr sapps saup2 saupd sconv seigt seupd sgets stats getv0 sortc sortr sesrt stqrb)
-    set(COMPLEXFUNS, naitr napps naup2 naupd neigh neupd ngets statn getv0 sortc)
-
-    set(BLASFUNS1 axpy copy gemv geqr2 lacpy lae2 lahqr lanhs larnv lartg lascl laset lasrt scal trevc trmm trsen gbmv gbtrf gbtrs gttrf gttrs pttrf pttrs)
-    set(BLASFUNS2 dot ger labad laev2 lamch lanst lanv2 lapy2 larf larfg lasr nrm2 orm2r rot steqr swap)
-    set(BLASFUNS3 dotc geru unm2r)
-    set(BLASFUNS4 COPY LABAD LAMCH LANHS LANV2 LARFG ROT GEMV)
-    set(BLASFUNS5 scnrm2 dznrm2 csscal zdscal)
+    # ICB saves you from old-fashion-boring-cumbersome-fortran/C crap... For arpack symbols (only).
 
     if (SYMBOLSUFFIX)
-        foreach (f IN LISTS SCALARFUNS BLASFUNS1 BLASFUNS2)
+        if ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+          set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -cpp -ffixed-line-length-none")
+        elseif ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "Intel")
+          set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fpp -extend-source")
+        else ()
+          message(WARNING "build script does not know how to enable your Fortran compiler's preprocessor and support for lines longer than 72 characters: set them manually via FFLAGS.")
+        endif ()
+
+        set(SCALARFUNS naitr napps naup2 naupd nconv neigh neupd ngets statn saitr sapps saup2 saupd sconv seigt seupd sgets stats getv0 sortc sortr sesrt stqrb)
+        set(COMPLEXFUNS, naitr napps naup2 naupd neigh neupd ngets statn getv0 sortc)
+
+        foreach (f IN LISTS SCALARFUNS)
             set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Ds${f}=s${f}${SYMBOLSUFFIX} -Dd${f}=d${f}${SYMBOLSUFFIX}")
         endforeach ()
 
-        foreach (f IN LISTS COMPLEXFUNS BLASFUNS1 BLASFUNS3)
+        foreach (f IN LISTS COMPLEXFUNS)
             set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Dc${f}=c${f}${SYMBOLSUFFIX} -Dz${f}=z${f}${SYMBOLSUFFIX}")
         endforeach ()
 
-        foreach (f IN LISTS BLASFUNS4)
-            set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -DS${f}=S${f}${SYMBOLSUFFIX} -DD${f}=D${f}${SYMBOLSUFFIX}")
+        set(CFUNS snaupd sneupd dnaupd dneupd)
+        foreach (f IN LISTS CFUNS)
+            set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D${f}=${f}${SYMBOLSUFFIX}")
+            list(APPEND CFUNS_SUFFIXED ${f}${SYMBOLSUFFIX})
         endforeach ()
 
-        foreach (f IN LISTS BLASFUNS5)
-            set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -D${f}=${f}${SYMBOLSUFFIX}")
-        endforeach ()
-    endif ()
+        include(FortranCInterface)
+        FortranCInterface_HEADER(FCMangle.h SYMBOLS ${CFUNS_SUFFIXED})
 
-    set(CFUNS sgemm snaupd sneupd dnaupd dneupd cheev)
-    foreach (f IN LISTS CFUNS)
-        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D${f}=${f}${SYMBOLSUFFIX}")
-        list(APPEND CFUNS_SUFFIXED ${f}${SYMBOLSUFFIX})
-    endforeach ()
+        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DINCLUDE_FCMANGLE")
 
-    include(FortranCInterface)
-    FortranCInterface_HEADER(FCMangle.h SYMBOLS ${CFUNS_SUFFIXED})
-
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DINCLUDE_FCMANGLE")
-
-    FortranCInterface_VERIFY()
+        FortranCInterface_VERIFY()
+    endif ()
 endif ()
 
-if (NOT TARGET BLAS::BLAS) # Search only if not already found by upper CMakeLists.txt
-    find_package(BLAS REQUIRED)
-
-    # BLAS::BLAS target was already created at this point by FindBLAS.cmake if cmake version >= 3.18
-    if (NOT TARGET BLAS::BLAS) # Create target "at hand" to ensure compatibility if cmake version < 3.18
-        add_library(BLAS::BLAS INTERFACE IMPORTED)
-        set_target_properties(BLAS::BLAS PROPERTIES INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}")
-    endif()
-endif()
-get_target_property(BLAS_LIBRARIES BLAS::BLAS INTERFACE_LINK_LIBRARIES) # Get variables from target (*.pc/cmake, msg).
+# Find MPI
 
 if (MPI)
     if (NOT TARGET MPI::MPI_Fortran) # Search only if not already found by upper CMakeLists.txt
         include(FindMPI)
-        find_package(MPI REQUIRED)
+        find_package(MPI REQUIRED COMPONENTS Fortran)
 
         # MPI::MPI_* target was already created at this point by FindMPI.cmake if cmake version >= 3.9
         if (NOT TARGET MPI::MPI_Fortran) # Create target "at hand" to ensure compatibility if cmake version < 3.9
@@ -226,27 +210,64 @@ if (MPI)
             set_target_properties(MPI::MPI_Fortran PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${MPI_Fortran_INCLUDE_DIRS}")
             set_target_properties(MPI::MPI_Fortran PROPERTIES INTERFACE_LINK_LIBRARIES      "${MPI_Fortran_LIBRARIES}")
         endif()
-        if (NOT TARGET MPI::MPI_C) # Create target "at hand" to ensure compatibility if cmake version < 3.9
-            add_library(MPI::MPI_C INTERFACE IMPORTED)
-            set_target_properties(MPI::MPI_C PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${MPI_C_INCLUDE_DIRS}")
-            set_target_properties(MPI::MPI_C PROPERTIES INTERFACE_LINK_LIBRARIES      "${MPI_C_LIBRARIES}")
-        endif()
-        if (NOT TARGET MPI::MPI_CXX) # Create target "at hand" to ensure compatibility if cmake version < 3.9
-            add_library(MPI::MPI_CXX INTERFACE IMPORTED)
-            set_target_properties(MPI::MPI_CXX PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${MPI_CXX_INCLUDE_DIRS}")
-            set_target_properties(MPI::MPI_CXX PROPERTIES INTERFACE_LINK_LIBRARIES      "${MPI_CXX_LIBRARIES}")
-        endif()
     endif()
-    get_target_property(MPI_Fortran_INCLUDE_DIRS MPI::MPI_Fortran INTERFACE_INCLUDE_DIRECTORIES) # Get variables from target (*.pc/cmake, msg).
-    get_target_property(MPI_Fortran_LIBRARIES    MPI::MPI_Fortran INTERFACE_LINK_LIBRARIES)      # Get variables from target (*.pc/cmake, msg).
 
     set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${MPI_Fortran_COMPILE_FLAG}")
+    if(CMAKE_SYSTEM_NAME MATCHES "Windows" AND CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
+        set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fallow-invalid-boz")
+    endif()
+
+    # Check if we can use ISO_C_BINDING provided by MPI.
+    file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/PROG_ICB.f90
+         "
+          PROGRAM PROG_ICB
+          USE :: mpi_f08
+          IMPLICIT NONE
+          type(MPI_Comm)    comm
+          type(MPI_Status)  status
+          END PROGRAM PROG_ICB
+         ")
+         try_compile(COMPILE_ICB ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/PROG_ICB.f90 LINK_LIBRARIES MPI::MPI_Fortran)
+    if(NOT ${COMPILE_ICB})
+      message("-- MPI library does not support iso_c_binding.")
+      set(HAVE_MPI_ICB 0)
+    else()
+      message("-- MPI library does support iso_c_binding.")
+      set(HAVE_MPI_ICB 1)
+      add_compile_definitions(HAVE_MPI_ICB=1)
+    endif()
+
+    # As MPI can be used with or without ISO_C_BINDING (#ifdef), we need to preprocess code before compiling.
+    if ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+      set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -cpp")
+    elseif ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "Intel")
+      set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fpp")
+    else ()
+      message(WARNING "build script does not know how to preprocess Fortran code: set it manually via FFLAGS.")
+    endif ()
 
     if(ICB)
-        get_target_property(MPI_C_INCLUDE_DIRS   MPI::MPI_C       INTERFACE_INCLUDE_DIRECTORIES) # Get variables from target (*.pc/cmake, msg).
-        get_target_property(MPI_C_LIBRARIES      MPI::MPI_C       INTERFACE_LINK_LIBRARIES)      # Get variables from target (*.pc/cmake, msg).
-        get_target_property(MPI_CXX_INCLUDE_DIRS MPI::MPI_CXX     INTERFACE_INCLUDE_DIRECTORIES) # Get variables from target (*.pc/cmake, msg).
-        get_target_property(MPI_CXX_LIBRARIES    MPI::MPI_CXX     INTERFACE_LINK_LIBRARIES)      # Get variables from target (*.pc/cmake, msg).
+        if (NOT TARGET MPI::MPI_C) # Search only if not already found by upper CMakeLists.txt
+            include(FindMPI)
+            find_package(MPI REQUIRED COMPONENTS C)
+
+            if (NOT TARGET MPI::MPI_C) # Create target "at hand" to ensure compatibility if cmake version < 3.9
+                add_library(MPI::MPI_C INTERFACE IMPORTED)
+                set_target_properties(MPI::MPI_C PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${MPI_C_INCLUDE_DIRS}")
+                set_target_properties(MPI::MPI_C PROPERTIES INTERFACE_LINK_LIBRARIES      "${MPI_C_LIBRARIES}")
+            endif()
+        endif()
+
+        if (NOT TARGET MPI::MPI_CXX) # Search only if not already found by upper CMakeLists.txt
+            include(FindMPI)
+            find_package(MPI REQUIRED COMPONENTS CXX)
+
+            if (NOT TARGET MPI::MPI_CXX) # Create target "at hand" to ensure compatibility if cmake version < 3.9
+                add_library(MPI::MPI_CXX INTERFACE IMPORTED)
+                set_target_properties(MPI::MPI_CXX PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${MPI_CXX_INCLUDE_DIRS}")
+                set_target_properties(MPI::MPI_CXX PROPERTIES INTERFACE_LINK_LIBRARIES      "${MPI_CXX_LIBRARIES}")
+            endif()
+        endif()
 
         include(CheckSymbolExists)
         check_symbol_exists(MPI_Comm_c2f "${MPI_C_INCLUDE_DIRS}/mpi.h" MPI_Comm_c2f_FOUND)
@@ -256,6 +277,20 @@ if (MPI)
     endif()
 endif()
 
+# Find BLAS
+
+if (NOT TARGET BLAS::BLAS) # Search only if not already found by upper CMakeLists.txt
+    find_package(BLAS REQUIRED)
+
+    # BLAS::BLAS target was already created at this point by FindBLAS.cmake if cmake version >= 3.18
+    if (NOT TARGET BLAS::BLAS) # Create target "at hand" to ensure compatibility if cmake version < 3.18
+        add_library(BLAS::BLAS INTERFACE IMPORTED)
+        set_target_properties(BLAS::BLAS PROPERTIES INTERFACE_LINK_LIBRARIES "${BLAS_LIBRARIES}")
+    endif()
+endif()
+
+# Find LAPACK
+
 if (NOT TARGET LAPACK::LAPACK) # Search only if not already found by upper CMakeLists.txt
     find_package(LAPACK REQUIRED)
 
@@ -265,7 +300,53 @@ if (NOT TARGET LAPACK::LAPACK) # Search only if not already found by upper CMake
         set_target_properties(LAPACK::LAPACK PROPERTIES INTERFACE_LINK_LIBRARIES "${LAPACK_LIBRARIES}")
     endif()
 endif()
-get_target_property(LAPACK_LIBRARIES LAPACK::LAPACK INTERFACE_LINK_LIBRARIES) # Get variables from target (*.pc/cmake, msg).
+
+# As BLAS/LAPACK does not provide ICB, we may have to deal with symbols the old-fashion-boring-cumbersome-fortran/C way...
+
+if (SYMBOLSUFFIX)
+    if ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "GNU")
+      set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -cpp -ffixed-line-length-none")
+    elseif ("${CMAKE_Fortran_COMPILER_ID}" MATCHES "Intel")
+      set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fpp -extend-source")
+    else ()
+      message(WARNING "build script does not know how to enable your Fortran compiler's preprocessor and support for lines longer than 72 characters: set them manually via FFLAGS.")
+    endif ()
+
+    set(BLASFUNS1 axpy copy gemv geqr2 lacpy lae2 lahqr lanhs larnv lartg lascl laset lasrt scal trevc trmm trsen gbmv gbtrf gbtrs gttrf gttrs pttrf pttrs)
+    set(BLASFUNS2 dot ger labad laev2 lamch lanst lanv2 lapy2 larf larfg lasr nrm2 orm2r rot steqr swap)
+    set(BLASFUNS3 dotc geru unm2r)
+    set(BLASFUNS4 COPY LABAD LAMCH LANHS LANV2 LARFG ROT GEMV)
+    set(BLASFUNS5 scnrm2 dznrm2 csscal zdscal)
+
+    foreach (f IN LISTS BLASFUNS1 BLASFUNS2)
+        set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Ds${f}=s${f}${SYMBOLSUFFIX} -Dd${f}=d${f}${SYMBOLSUFFIX}")
+    endforeach ()
+
+    foreach (f IN LISTS BLASFUNS1 BLASFUNS3)
+        set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Dc${f}=c${f}${SYMBOLSUFFIX} -Dz${f}=z${f}${SYMBOLSUFFIX}")
+    endforeach ()
+
+    foreach (f IN LISTS BLASFUNS4)
+        set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -DS${f}=S${f}${SYMBOLSUFFIX} -DD${f}=D${f}${SYMBOLSUFFIX}")
+    endforeach ()
+
+    foreach (f IN LISTS BLASFUNS5)
+        set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -D${f}=${f}${SYMBOLSUFFIX}")
+    endforeach ()
+
+    set(CFUNS sgemm cheev)
+    foreach (f IN LISTS CFUNS)
+        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D${f}=${f}${SYMBOLSUFFIX}")
+        list(APPEND CFUNS_SUFFIXED ${f}${SYMBOLSUFFIX})
+    endforeach ()
+
+    include(FortranCInterface)
+    FortranCInterface_HEADER(FCMangle.h SYMBOLS ${CFUNS_SUFFIXED})
+
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DINCLUDE_FCMANGLE")
+
+    FortranCInterface_VERIFY()
+endif ()
 
 if (MPI)
     set(parpackutil_DIR ${arpack_SOURCE_DIR}/PARPACK/UTIL/)
@@ -306,19 +387,38 @@ endif()
 # use -DBUILD_SHARED_LIBS=ON|OFF to control static/shared
 add_library(arpack ${arpackutil_STAT_SRCS} ${arpacksrc_STAT_SRCS} ${arpacksrc_ICB})
 
-target_link_libraries(arpack BLAS::BLAS)
-target_link_libraries(arpack LAPACK::LAPACK ${EXTRA_LDFLAGS})
-set_target_properties(arpack PROPERTIES OUTPUT_NAME arpack${LIBSUFFIX})
+target_link_libraries(arpack
+  PUBLIC
+  $<INSTALL_INTERFACE:$<IF:$<BOOL:${BUILD_SHARED_LIBS}>,,LAPACK::LAPACK>>
+  $<INSTALL_INTERFACE:$<IF:$<BOOL:${BUILD_SHARED_LIBS}>,,BLAS::BLAS>>
+  $<BUILD_INTERFACE:LAPACK::LAPACK>
+  $<BUILD_INTERFACE:BLAS::BLAS>
+)
+target_link_options(arpack PUBLIC "${EXTRA_LDFLAGS}")
+set_target_properties(arpack PROPERTIES OUTPUT_NAME arpack${LIBSUFFIX}${ITF64SUFFIX})
 set_target_properties(arpack PROPERTIES VERSION 2.1.0)
 set_target_properties(arpack PROPERTIES SOVERSION 2)
+target_include_directories(arpack
+  PUBLIC
+  # Exported location of headers
+  $<INSTALL_INTERFACE:${ARPACK_INSTALL_INCLUDEDIR}>
+  # Find arpackdef.h, arpackicb.h, stat*.h, debug*.h at build time
+  $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
+  $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
+  # For ICB interface
+  $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/ICB>
+)
 
 if (MPI)
     # use -DBUILD_SHARED_LIBS=ON|OFF to control static/shared
     add_library(parpack ${parpacksrc_STAT_SRCS} ${parpackutil_STAT_SRCS} ${parpacksrc_ICB})
-
-    target_link_libraries(parpack MPI::MPI_Fortran)
-    target_link_libraries(parpack arpack)
-    set_target_properties(parpack PROPERTIES OUTPUT_NAME parpack${LIBSUFFIX})
+    target_link_libraries(parpack
+      PUBLIC
+      arpack
+      $<INSTALL_INTERFACE:$<IF:$<BOOL:${BUILD_SHARED_LIBS}>,,MPI::MPI_Fortran>>
+      $<BUILD_INTERFACE:MPI::MPI_Fortran>
+    )
+    set_target_properties(parpack PROPERTIES OUTPUT_NAME parpack${LIBSUFFIX}${ITF64SUFFIX})
     set_target_properties(parpack PROPERTIES VERSION 2.1.0)
     set_target_properties(parpack PROPERTIES SOVERSION 2)
 endif ()
@@ -334,6 +434,11 @@ if (INTERFACE64)
     else ()
       message(WARNING "build script does not know how to make your Fortran compiler use 64-bit integers: set it manually via FFLAGS.")
     endif ()
+
+    # TODO: this needs full re-write of parpack to support ILP64...
+    if (MPI)
+      message(FATAL_ERROR "Parallel arpack does not support ILP64.")
+    endif()
 else ()
     set(INTERFACE64 0)
 endif ()
@@ -520,169 +625,180 @@ endif()
 ############################
 # TEST
 ############################
+function(build_tests)  
+  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/TESTS)
 
-enable_testing()
-
-set(CMAKE_CTEST_COMMAND ctest -V)
-
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/TESTS)
-
-add_executable(dnsimp_test TESTS/dnsimp.f TESTS/mmio.f TESTS/debug.h)
-set_target_properties( dnsimp_test PROPERTIES OUTPUT_NAME  dnsimp )
-target_link_libraries(dnsimp_test arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
-add_custom_command(TARGET dnsimp_test POST_BUILD
-  COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/TESTS/testA.mtx testA.mtx
-)
-add_test(dnsimp_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/dnsimp)
-
-if (NOT ICB)
-    add_executable(bug_1315_single TESTS/bug_1315_single.c)
-    target_link_libraries(bug_1315_single arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
-    add_test(bug_1315_single_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bug_1315_single)
-
-    add_executable(bug_1315_double TESTS/bug_1315_double.c)
-    target_link_libraries(bug_1315_double arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
-    add_test(bug_1315_double_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bug_1315_double)
-endif()
+  add_executable(dnsimp_test TESTS/dnsimp.f TESTS/mmio.f TESTS/debug.h)
+  set_target_properties( dnsimp_test PROPERTIES OUTPUT_NAME  dnsimp )
+  target_link_libraries(dnsimp_test arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
+  add_custom_command(TARGET dnsimp_test POST_BUILD
+    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/TESTS/testA.mtx testA.mtx
+  )
+  add_test(dnsimp_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/dnsimp)
+
+  if (ICB)
+      add_executable(bug_1315_single TESTS/bug_1315_single.c)
+      target_include_directories(bug_1315_single PUBLIC ${PROJECT_SOURCE_DIR}/ICB) # Get arpack.h
+      target_link_libraries(bug_1315_single arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
+      add_test(bug_1315_single_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bug_1315_single)
+
+      add_executable(bug_1315_double TESTS/bug_1315_double.c)
+      target_include_directories(bug_1315_double PUBLIC ${PROJECT_SOURCE_DIR}/ICB) # Get arpack.h
+      target_link_libraries(bug_1315_double arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
+      add_test(bug_1315_double_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bug_1315_double)
+  endif()
 
-add_executable(bug_1323 TESTS/bug_1323.f)
-target_link_libraries(bug_1323 arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
-add_test(bug_1323_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bug_1323)
+  add_executable(bug_1323 TESTS/bug_1323.f)
+  target_link_libraries(bug_1323 arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
+  add_test(bug_1323_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bug_1323)
 
-add_executable(bug_58_double TESTS/bug_58_double.f)
-target_link_libraries(bug_58_double arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
-add_test(bug_58_double_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bug_58_double)
+  add_executable(bug_58_double TESTS/bug_58_double.f)
+  target_link_libraries(bug_58_double arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
+  add_test(bug_58_double_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bug_58_double)
 
-add_executable(bug_79_double_complex TESTS/bug_79_double_complex.f)
-target_link_libraries(bug_79_double_complex arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
-add_test(bug_79_double_complex_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bug_79_double_complex)
+  add_executable(bug_79_double_complex TESTS/bug_79_double_complex.f)
+  target_link_libraries(bug_79_double_complex arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
+  add_test(bug_79_double_complex_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bug_79_double_complex)
 
-add_executable(bug_142 TESTS/bug_142.f)
-target_link_libraries(bug_142 arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
-add_test(bug_142_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bug_142)
+  add_executable(bug_142 TESTS/bug_142.f)
+  target_link_libraries(bug_142 arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
+  add_test(bug_142_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bug_142)
 
-add_executable(bug_142_gen TESTS/bug_142_gen.f)
-target_link_libraries(bug_142_gen arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
-add_test(bug_142_gen_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bug_142_gen)
+  add_executable(bug_142_gen TESTS/bug_142_gen.f)
+  target_link_libraries(bug_142_gen arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
+  add_test(bug_142_gen_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/bug_142_gen)
 
-if(MPI)
-  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/PARPACK/TESTS/MPI)
+  if(MPI)
+    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/PARPACK/TESTS/MPI)
 
-  add_executable(issue46 PARPACK/TESTS/MPI/issue46.f)
-  target_link_libraries(issue46 parpack arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
-  add_test(issue46_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/issue46)
-endif()
+    add_executable(issue46 PARPACK/TESTS/MPI/issue46.f)
+    target_link_libraries(issue46 parpack arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
+    add_test(issue46_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/issue46)
+  endif()
 
-if(ICB)
-  set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/TESTS)
+  if(ICB)
+    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/TESTS)
+
+    add_executable(icb_arpack_c TESTS/icb_arpack_c.c)
+    target_include_directories(icb_arpack_c PUBLIC ${PROJECT_SOURCE_DIR}/ICB) # Get arpack.h
+    target_link_libraries(icb_arpack_c arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
+    add_test(icb_arpack_c_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/icb_arpack_c)
+
+    add_executable(icb_arpack_cpp TESTS/icb_arpack_cpp.cpp)
+    target_include_directories(icb_arpack_cpp PUBLIC ${PROJECT_SOURCE_DIR}/ICB) # Get arpack.hpp
+    target_link_libraries(icb_arpack_cpp arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
+    add_test(icb_arpack_cpp_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/icb_arpack_cpp)
+
+    if (ICBEXMM)
+      set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/EXAMPLES/MATRIX_MARKET)
+
+      add_executable(arpackmm EXAMPLES/MATRIX_MARKET/arpackmm.cpp)
+      target_include_directories(arpackmm PUBLIC ${PROJECT_SOURCE_DIR}/ICB ${EIGEN3_INCLUDE_DIR}) # Get arpack.h + eigen
+      target_link_libraries(arpackmm arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
+      configure_file(EXAMPLES/MATRIX_MARKET/As.mtx ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/As.mtx)
+      configure_file(EXAMPLES/MATRIX_MARKET/An.mtx ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/An.mtx)
+      configure_file(EXAMPLES/MATRIX_MARKET/Az.mtx ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Az.mtx)
+      configure_file(EXAMPLES/MATRIX_MARKET/B.mtx  ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/B.mtx)
+      configure_file(EXAMPLES/MATRIX_MARKET/Bz.mtx ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Bz.mtx)
+      configure_file(EXAMPLES/MATRIX_MARKET/arpackmm.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/arpackmm.sh)
+      add_test(NAME arpackmm_tst WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${BASH_PROGRAM} arpackmm.sh)
+    endif()
 
-  add_executable(icb_arpack_c TESTS/icb_arpack_c.c)
-  target_include_directories(icb_arpack_c PUBLIC ${PROJECT_SOURCE_DIR}/ICB) # Get arpack.h
-  target_link_libraries(icb_arpack_c arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
-  add_test(icb_arpack_c_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/icb_arpack_c)
+    if (PYTHON3)
+      python_add_module(pyarpack ${arpackutil_STAT_SRCS} ${arpacksrc_STAT_SRCS} ${arpacksrc_ICB} ${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpack.cpp)
+      target_include_directories(pyarpack
+          PRIVATE
+          ${PROJECT_BINARY_DIR}
+          ${PROJECT_SOURCE_DIR}
+          ${PROJECT_SOURCE_DIR}/ICB
+          ${PROJECT_SOURCE_DIR}/EXAMPLES/MATRIX_MARKET
+          ${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK
+          ${EIGEN3_INCLUDE_DIR}
+          ${Boost_INCLUDE_DIRS}
+          ${PYTHON_INCLUDE_DIRS})
+      target_link_libraries(pyarpack
+          BLAS::BLAS LAPACK::LAPACK ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
+      install(TARGETS pyarpack
+              ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/pyarpack
+              LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/pyarpack)
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseBiCGDiag.py.in" "${CMAKE_BINARY_DIR}/pyarpackSparseBiCGDiag.py" @ONLY)
+      add_test(NAME pyarpackSparseBiCGDiag_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseBiCGDiag.py)
+      set_tests_properties(pyarpackSparseBiCGDiag_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseBiCGILU.py.in"  "${CMAKE_BINARY_DIR}/pyarpackSparseBiCGILU.py" @ONLY)
+      add_test(NAME pyarpackSparseBiCGILU_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseBiCGILU.py)
+      set_tests_properties(pyarpackSparseBiCGILU_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseCGDiag.py.in" "${CMAKE_BINARY_DIR}/pyarpackSparseCGDiag.py" @ONLY)
+      add_test(NAME pyarpackSparseCGDiag_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseCGDiag.py)
+      set_tests_properties(pyarpackSparseCGDiag_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseCGILU.py.in" "${CMAKE_BINARY_DIR}/pyarpackSparseCGILU.py" @ONLY)
+      add_test(NAME pyarpackSparseCGILU_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseCGILU.py)
+      set_tests_properties(pyarpackSparseCGILU_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseLLT.py.in" "${CMAKE_BINARY_DIR}/pyarpackSparseLLT.py" @ONLY)
+      add_test(NAME pyarpackSparseLLT_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseLLT.py)
+      set_tests_properties(pyarpackSparseLLT_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseLDLT.py.in" "${CMAKE_BINARY_DIR}/pyarpackSparseLDLT.py" @ONLY)
+      add_test(NAME pyarpackSparseLDLT_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseLDLT.py)
+      set_tests_properties(pyarpackSparseLDLT_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseLU.py.in" "${CMAKE_BINARY_DIR}/pyarpackSparseLU.py" @ONLY)
+      add_test(NAME pyarpackSparseLU_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseLU.py)
+      set_tests_properties(pyarpackSparseLU_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseQR.py.in" "${CMAKE_BINARY_DIR}/pyarpackSparseQR.py" @ONLY)
+      add_test(NAME pyarpackSparseQR_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseQR.py)
+      set_tests_properties(pyarpackSparseQR_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackDenseLLT.py.in" "${CMAKE_BINARY_DIR}/pyarpackDenseLLT.py" @ONLY)
+      add_test(NAME pyarpackDenseLLT_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackDenseLLT.py)
+      set_tests_properties(pyarpackDenseLLT_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackDenseLDLT.py.in" "${CMAKE_BINARY_DIR}/pyarpackDenseLDLT.py" @ONLY)
+      add_test(NAME pyarpackDenseLDLT_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackDenseLDLT.py)
+      set_tests_properties(pyarpackDenseLDLT_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackDenseLURR.py.in" "${CMAKE_BINARY_DIR}/pyarpackDenseLURR.py" @ONLY)
+      add_test(NAME pyarpackDenseLURR_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackDenseLURR.py)
+      set_tests_properties(pyarpackDenseLURR_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackDenseQRRR.py.in" "${CMAKE_BINARY_DIR}/pyarpackDenseQRRR.py" @ONLY)
+      add_test(NAME pyarpackDenseQRRR_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackDenseQRRR.py)
+      set_tests_properties(pyarpackDenseQRRR_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackDenseLUPP.py.in" "${CMAKE_BINARY_DIR}/pyarpackDenseLUPP.py" @ONLY)
+      add_test(NAME pyarpackDenseLUPP_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackDenseLUPP.py)
+      set_tests_properties(pyarpackDenseLUPP_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackDenseQRPP.py.in" "${CMAKE_BINARY_DIR}/pyarpackDenseQRPP.py" @ONLY)
+      add_test(NAME pyarpackDenseQRPP_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackDenseQRPP.py)
+      set_tests_properties(pyarpackDenseQRPP_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackRestart.py.in" "${CMAKE_BINARY_DIR}/pyarpackRestart.py" @ONLY)
+      add_test(NAME pyarpackRestart_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackRestart.py)
+      set_tests_properties(pyarpackRestart_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+    endif()
 
-  add_executable(icb_arpack_cpp TESTS/icb_arpack_cpp.cpp)
-  target_include_directories(icb_arpack_cpp PUBLIC ${PROJECT_SOURCE_DIR}/ICB) # Get arpack.hpp
-  target_link_libraries(icb_arpack_cpp arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
-  add_test(icb_arpack_cpp_tst ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/icb_arpack_cpp)
+    if (MPI)
+      set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/PARPACK/TESTS/MPI)
 
-  if (ICBEXMM)
-    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/EXAMPLES/MATRIX_MARKET)
-
-    add_executable(arpackmm EXAMPLES/MATRIX_MARKET/arpackmm.cpp)
-    target_include_directories(arpackmm PUBLIC ${PROJECT_SOURCE_DIR}/ICB ${EIGEN3_INCLUDE_DIR}) # Get arpack.h + eigen
-    target_link_libraries(arpackmm arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS})
-    configure_file(EXAMPLES/MATRIX_MARKET/As.mtx ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/As.mtx)
-    configure_file(EXAMPLES/MATRIX_MARKET/An.mtx ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/An.mtx)
-    configure_file(EXAMPLES/MATRIX_MARKET/Az.mtx ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Az.mtx)
-    configure_file(EXAMPLES/MATRIX_MARKET/B.mtx  ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/B.mtx)
-    configure_file(EXAMPLES/MATRIX_MARKET/Bz.mtx ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Bz.mtx)
-    configure_file(EXAMPLES/MATRIX_MARKET/arpackmm.sh ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/arpackmm.sh)
-    add_test(NAME arpackmm_tst WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} COMMAND ${BASH_PROGRAM} arpackmm.sh)
-  endif()
+      add_executable(icb_parpack_c PARPACK/TESTS/MPI/icb_parpack_c.c)
+      target_include_directories(icb_parpack_c PUBLIC ${PROJECT_SOURCE_DIR}/ICB MPI::MPI_C) # Get parpack.h mpi.h
+      target_link_libraries(icb_parpack_c parpack arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS} MPI::MPI_C)
+      add_test(icb_parpack_c_tst mpiexec -n 2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/icb_parpack_c)
 
-  if (PYTHON3)
-    python_add_module(pyarpack ${arpackutil_STAT_SRCS} ${arpacksrc_STAT_SRCS} ${arpacksrc_ICB} ${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpack.cpp)
-    target_compile_definitions(pyarpack PRIVATE PY_MAJOR_VERSION="3")
-    set(pyarpack_HDR ${PROJECT_SOURCE_DIR}/ICB ${PROJECT_SOURCE_DIR}/EXAMPLES/MATRIX_MARKET ${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK)
-    target_include_directories(pyarpack PUBLIC ${pyarpack_HDR} ${EIGEN3_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
-    target_link_libraries(pyarpack BLAS::BLAS LAPACK::LAPACK ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
-    install(TARGETS pyarpack
-            ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/pyarpack
-            LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/pyarpack)
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseBiCGDiag.py.in" "${CMAKE_BINARY_DIR}/pyarpackSparseBiCGDiag.py" @ONLY)
-    add_test(NAME pyarpackSparseBiCGDiag_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseBiCGDiag.py)
-    set_tests_properties(pyarpackSparseBiCGDiag_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseBiCGILU.py.in"  "${CMAKE_BINARY_DIR}/pyarpackSparseBiCGILU.py" @ONLY)
-    add_test(NAME pyarpackSparseBiCGILU_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseBiCGILU.py)
-    set_tests_properties(pyarpackSparseBiCGILU_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseCGDiag.py.in" "${CMAKE_BINARY_DIR}/pyarpackSparseCGDiag.py" @ONLY)
-    add_test(NAME pyarpackSparseCGDiag_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseCGDiag.py)
-    set_tests_properties(pyarpackSparseCGDiag_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseCGILU.py.in" "${CMAKE_BINARY_DIR}/pyarpackSparseCGILU.py" @ONLY)
-    add_test(NAME pyarpackSparseCGILU_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseCGILU.py)
-    set_tests_properties(pyarpackSparseCGILU_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseLLT.py.in" "${CMAKE_BINARY_DIR}/pyarpackSparseLLT.py" @ONLY)
-    add_test(NAME pyarpackSparseLLT_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseLLT.py)
-    set_tests_properties(pyarpackSparseLLT_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseLDLT.py.in" "${CMAKE_BINARY_DIR}/pyarpackSparseLDLT.py" @ONLY)
-    add_test(NAME pyarpackSparseLDLT_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseLDLT.py)
-    set_tests_properties(pyarpackSparseLDLT_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseLU.py.in" "${CMAKE_BINARY_DIR}/pyarpackSparseLU.py" @ONLY)
-    add_test(NAME pyarpackSparseLU_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseLU.py)
-    set_tests_properties(pyarpackSparseLU_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackSparseQR.py.in" "${CMAKE_BINARY_DIR}/pyarpackSparseQR.py" @ONLY)
-    add_test(NAME pyarpackSparseQR_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackSparseQR.py)
-    set_tests_properties(pyarpackSparseQR_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackDenseLLT.py.in" "${CMAKE_BINARY_DIR}/pyarpackDenseLLT.py" @ONLY)
-    add_test(NAME pyarpackDenseLLT_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackDenseLLT.py)
-    set_tests_properties(pyarpackDenseLLT_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackDenseLDLT.py.in" "${CMAKE_BINARY_DIR}/pyarpackDenseLDLT.py" @ONLY)
-    add_test(NAME pyarpackDenseLDLT_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackDenseLDLT.py)
-    set_tests_properties(pyarpackDenseLDLT_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackDenseLURR.py.in" "${CMAKE_BINARY_DIR}/pyarpackDenseLURR.py" @ONLY)
-    add_test(NAME pyarpackDenseLURR_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackDenseLURR.py)
-    set_tests_properties(pyarpackDenseLURR_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackDenseQRRR.py.in" "${CMAKE_BINARY_DIR}/pyarpackDenseQRRR.py" @ONLY)
-    add_test(NAME pyarpackDenseQRRR_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackDenseQRRR.py)
-    set_tests_properties(pyarpackDenseQRRR_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackDenseLUPP.py.in" "${CMAKE_BINARY_DIR}/pyarpackDenseLUPP.py" @ONLY)
-    add_test(NAME pyarpackDenseLUPP_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackDenseLUPP.py)
-    set_tests_properties(pyarpackDenseLUPP_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackDenseQRPP.py.in" "${CMAKE_BINARY_DIR}/pyarpackDenseQRPP.py" @ONLY)
-    add_test(NAME pyarpackDenseQRPP_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackDenseQRPP.py)
-    set_tests_properties(pyarpackDenseQRPP_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
-    configure_file("${PROJECT_SOURCE_DIR}/EXAMPLES/PYARPACK/pyarpackRestart.py.in" "${CMAKE_BINARY_DIR}/pyarpackRestart.py" @ONLY)
-    add_test(NAME pyarpackRestart_tst COMMAND ${PYTHON_EXECUTABLE} pyarpackRestart.py)
-    set_tests_properties(pyarpackRestart_tst PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_BINARY_DIR}/lib:$ENV{PYTHONPATH})
+      add_executable(icb_parpack_cpp PARPACK/TESTS/MPI/icb_parpack_cpp.cpp)
+      target_include_directories(icb_parpack_cpp PUBLIC ${PROJECT_SOURCE_DIR}/ICB MPI::MPI_CXX) # Get parpack.hpp mpi.h
+      target_link_libraries(icb_parpack_cpp parpack arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS} MPI::MPI_CXX)
+      add_test(icb_parpack_cpp_tst mpiexec -n 2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/icb_parpack_cpp)
+    endif()
   endif()
+endfunction(build_tests)
 
-  if (MPI)
-    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/PARPACK/TESTS/MPI)
-
-    add_executable(icb_parpack_c PARPACK/TESTS/MPI/icb_parpack_c.c)
-    target_include_directories(icb_parpack_c PUBLIC ${PROJECT_SOURCE_DIR}/ICB MPI::MPI_C) # Get parpack.h mpi.h
-    target_link_libraries(icb_parpack_c parpack arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS} MPI::MPI_C)
-    add_test(icb_parpack_c_tst mpirun -n 2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/icb_parpack_c)
-
-    add_executable(icb_parpack_cpp PARPACK/TESTS/MPI/icb_parpack_cpp.cpp)
-    target_include_directories(icb_parpack_cpp PUBLIC ${PROJECT_SOURCE_DIR}/ICB MPI::MPI_CXX) # Get parpack.hpp mpi.h
-    target_link_libraries(icb_parpack_cpp parpack arpack BLAS::BLAS LAPACK::LAPACK ${EXTRA_LDFLAGS} MPI::MPI_CXX)
-    add_test(icb_parpack_cpp_tst mpirun -n 2 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/icb_parpack_cpp)
-  endif()
+if(TESTS)
+    enable_testing()
+    set(CMAKE_CTEST_COMMAND ctest -V)   
+    build_tests()
 endif()
 
 ############################
 # install
 ############################
-# 'make install' to the correct location
-include(GNUInstallDirs)
 
 # Convert variable names to those expected by the .pc file.
 set(prefix ${CMAKE_INSTALL_PREFIX})
 set(exec_prefix \${prefix})
-set(libdir \${exec_prefix}/${CMAKE_INSTALL_LIBDIR})
-set(includedir \${prefix}/${CMAKE_INSTALL_INCLUDEDIR})
+set(libdir ${CMAKE_INSTALL_FULL_LIBDIR})
+set(includedir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR})
 set(PACKAGE_NAME ${PROJECT_NAME})
 set(PACKAGE_VERSION ${arpack_ng_VERSION})
 set(PACKAGE_URL "https://github.com/opencollab/arpack-ng/")
@@ -692,7 +808,7 @@ set(PACKAGE_URL "https://github.com/opencollab/arpack-ng/")
 set(ARPACK_PC_LIBS_PRIVATE)
 foreach(lib ${LAPACK_LIBRARIES})
     get_filename_component(libname ${lib} NAME)
-    string(REGEX REPLACE "^lib([^.]+).*$" "-l\\1" libname ${libname})
+    string(REGEX REPLACE "^(lib)?([^.]+).*$" "-l\\2" libname ${libname})
     list(APPEND ARPACK_PC_LIBS_PRIVATE "${libname}")
 endforeach()
 string(REPLACE ";" " " ARPACK_PC_LIBS_PRIVATE "${ARPACK_PC_LIBS_PRIVATE}")
@@ -700,68 +816,80 @@ string(REPLACE ";" " " ARPACK_PC_LIBS_PRIVATE "${ARPACK_PC_LIBS_PRIVATE}")
 set(PARPACK_PC_LIBS_PRIVATE)
 foreach(lib ${LAPACK_LIBRARIES} ${MPI_Fortran_LIBRARIES})
     get_filename_component(libname ${lib} NAME)
-    string(REGEX REPLACE "^lib([^.]+).*$" "-l\\1" libname ${libname})
+    string(REGEX REPLACE "^(lib)?([^.]+).*$" "-l\\2" libname ${libname})
     list(APPEND PARPACK_PC_LIBS_PRIVATE "${libname}")
 endforeach()
 string(REPLACE ";" " " PARPACK_PC_LIBS_PRIVATE "${PARPACK_PC_LIBS_PRIVATE}")
 
-configure_file(SRC/arpack.pc.in "${PROJECT_BINARY_DIR}/SRC/arpack${LIBSUFFIX}.pc" @ONLY)
-configure_file(PARPACK/SRC/MPI/parpack.pc.in "${PROJECT_BINARY_DIR}/PARPACK/SRC/MPI/parpack${LIBSUFFIX}.pc" @ONLY)
-configure_file(EXAMPLES/MATRIX_MARKET/arpackSolver.pc.in "${PROJECT_BINARY_DIR}/EXAMPLES/MATRIX_MARKET/arpackSolver.pc" @ONLY)
+configure_file(pkg-config/arpack.pc.in "${PROJECT_BINARY_DIR}/arpack${LIBSUFFIX}${ITF64SUFFIX}.pc" @ONLY)
+configure_file(pkg-config/parpack.pc.in "${PROJECT_BINARY_DIR}/parpack${LIBSUFFIX}${ITF64SUFFIX}.pc" @ONLY)
+configure_file(pkg-config/arpackSolver.pc.in "${PROJECT_BINARY_DIR}/arpackSolver${LIBSUFFIX}${ITF64SUFFIX}.pc" @ONLY)
 
 
 install(TARGETS arpack
+    EXPORT arpackngTargets
     ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
     LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
     RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
-install(FILES "${PROJECT_BINARY_DIR}/SRC/arpack${LIBSUFFIX}.pc"
+install(FILES "${PROJECT_BINARY_DIR}/arpack${LIBSUFFIX}${ITF64SUFFIX}.pc"
     DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
 
 if (MPI)
   install(TARGETS parpack
+      EXPORT arpackngTargets
       ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
       LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
       RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
-  install(FILES "${PROJECT_BINARY_DIR}/PARPACK/SRC/MPI/parpack${LIBSUFFIX}.pc"
+  install(FILES "${PROJECT_BINARY_DIR}/parpack${LIBSUFFIX}${ITF64SUFFIX}.pc"
       DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
 endif ()
 
 if(ICB)
-  install(FILES ICB/arpack.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arpack)
-  install(FILES ICB/arpack.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arpack)
+  install(FILES ICB/arpack.h DESTINATION "${ARPACK_INSTALL_INCLUDEDIR}")
+  install(FILES ICB/arpack.hpp DESTINATION ${ARPACK_INSTALL_INCLUDEDIR})
   if (MPI)
-    install(FILES ICB/parpack.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arpack)
-    install(FILES ICB/parpack.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arpack)
+    install(FILES ICB/parpack.h DESTINATION ${ARPACK_INSTALL_INCLUDEDIR})
+    install(FILES ICB/parpack.hpp DESTINATION ${ARPACK_INSTALL_INCLUDEDIR})
   endif()
   if (ICBEXMM)
-    install(FILES EXAMPLES/MATRIX_MARKET/arpackSolver.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arpack)
-    install(FILES "${PROJECT_BINARY_DIR}/EXAMPLES/MATRIX_MARKET/arpackSolver.pc" DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+    install(FILES EXAMPLES/MATRIX_MARKET/arpackSolver.hpp DESTINATION ${ARPACK_INSTALL_INCLUDEDIR})
+    install(FILES "${PROJECT_BINARY_DIR}/arpackSolver${LIBSUFFIX}${ITF64SUFFIX}.pc" DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
   endif()
 endif()
 
-install(FILES debug.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arpack)
+install(FILES debug.h DESTINATION ${ARPACK_INSTALL_INCLUDEDIR})
+install(FILES debugF90.h DESTINATION ${ARPACK_INSTALL_INCLUDEDIR})
 if(ICB)
-  install(FILES ICB/debug_c.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arpack)
-  install(FILES ICB/debug_c.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arpack)
+  install(FILES ICB/debug_c.h DESTINATION ${ARPACK_INSTALL_INCLUDEDIR})
+  install(FILES ICB/debug_c.hpp DESTINATION ${ARPACK_INSTALL_INCLUDEDIR})
 endif()
 
-install(FILES stat.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arpack)
+install(FILES stat.h DESTINATION ${ARPACK_INSTALL_INCLUDEDIR})
+install(FILES statF90.h DESTINATION ${ARPACK_INSTALL_INCLUDEDIR})
 if(ICB)
-  install(FILES ICB/stat_c.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arpack)
-  install(FILES ICB/stat_c.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arpack)
+  install(FILES ICB/stat_c.h DESTINATION ${ARPACK_INSTALL_INCLUDEDIR})
+  install(FILES ICB/stat_c.hpp DESTINATION ${ARPACK_INSTALL_INCLUDEDIR})
 endif()
 
 configure_file(arpackdef.h.in "${PROJECT_BINARY_DIR}/arpackdef.h" @ONLY)
-install(FILES "${PROJECT_BINARY_DIR}/arpackdef.h" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arpack)
+install(FILES "${PROJECT_BINARY_DIR}/arpackdef.h" DESTINATION ${ARPACK_INSTALL_INCLUDEDIR})
 
 configure_file(arpackicb.h.in "${PROJECT_BINARY_DIR}/arpackicb.h" @ONLY)
-install(FILES "${PROJECT_BINARY_DIR}/arpackicb.h" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/arpack)
+install(FILES "${PROJECT_BINARY_DIR}/arpackicb.h" DESTINATION ${ARPACK_INSTALL_INCLUDEDIR})
 
+install(EXPORT arpackngTargets
+  DESTINATION "${ARPACK_INSTALL_CMAKEDIR}"
+)
 # Provide find_package for arpack-ng to users.
-configure_file(arpack-ng-config.cmake.in "${PROJECT_BINARY_DIR}/arpack-ng-config.cmake" @ONLY)
-install(FILES "${PROJECT_BINARY_DIR}/arpack-ng-config.cmake" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/arpack-ng) # find_package(arpack-ng)
-configure_file(arpack-ng-config-version.cmake.in "${PROJECT_BINARY_DIR}/arpack-ng-config-version.cmake" @ONLY)
-install(FILES "${PROJECT_BINARY_DIR}/arpack-ng-config-version.cmake" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/arpack-ng)
+configure_file(cmake/arpackng-config.cmake.in "${PROJECT_BINARY_DIR}/arpackng-config.cmake" @ONLY)
+configure_file(cmake/arpackng-config-version.cmake.in "${PROJECT_BINARY_DIR}/arpackng-config-version.cmake" @ONLY)
+install(
+  FILES
+  "${PROJECT_BINARY_DIR}/arpackng-config.cmake"
+  "${PROJECT_BINARY_DIR}/arpackng-config-version.cmake"
+  DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/arpackng${LIBSUFFIX}${ITF64SUFFIX}) # find_package(arpackng)
+
+configure_file(cmake/tstCMakeInstall.sh.in ${PROJECT_BINARY_DIR}/tstCMakeInstall.sh @ONLY)
 
 # Packaging: ease arpack-ng distribution (precompiled binaries and sources tarballs).
 set(CPACK_VERSION_MAJOR "${arpack_ng_MAJOR_VERSION}")
@@ -771,38 +899,6 @@ set(CPACK_SOURCE_IGNORE_FILES "/BUILD/" "/Build/" "/build/" "/local/") # Do not
 set(CPACK_SOURCE_PACKAGE_FILE_NAME "arpack-ng-${CPACK_VERSION_MAJOR}.${CPACK_VERSION_MINOR}.${CPACK_VERSION_PATCH}")
 include(CPack)
 
-if (COVERALLS)
-    set(arpack_TST_SRC
-        ${arpack_SOURCE_DIR}/TESTS/bug_1323.f
-        ${arpack_SOURCE_DIR}/TESTS/bug_142.f
-        ${arpack_SOURCE_DIR}/TESTS/bug_142_gen.f
-        ${arpack_SOURCE_DIR}/TESTS/bug_58_double.f
-        ${arpack_SOURCE_DIR}/TESTS/bug_79_double_complex.f
-        ${arpack_SOURCE_DIR}/TESTS/dnsimp.f
-        ${arpack_SOURCE_DIR}/TESTS/mmio.f
-        ${arpack_SOURCE_DIR}/TESTS/bug_1315_single.c
-        ${arpack_SOURCE_DIR}/TESTS/bug_1315_double.c
-        ${arpack_SOURCE_DIR}/TESTS/icb_arpack_c.c
-        ${arpack_SOURCE_DIR}/TESTS/icb_arpack_cpp.cpp
-       )
-    file(GLOB_RECURSE arpack_EX_F_SRC "${arpack_SOURCE_DIR}/EXAMPLES/*/*.f")
-    set(arpack_EX_CPP_SRC ${arpack_SOURCE_DIR}/EXAMPLES/MATRIX_MARKET/arpackmm.cpp)
-
-    set(parpack_TST_SRC
-        ${arpack_SOURCE_DIR}/PARPACK/TESTS/MPI/issue46.f
-        ${arpack_SOURCE_DIR}/PARPACK/TESTS/MPI/icb_parpack_c.c
-        ${arpack_SOURCE_DIR}/PARPACK/TESTS/MPI/icb_parpack_cpp.cpp
-       )
-    file(GLOB_RECURSE parpack_EX_F_SRC "${arpack_SOURCE_DIR}/PARPACK/EXAMPLES/MPI/*.f")
-
-    # Create the coveralls target.
-    # Also lists the c/cpp files for test purposes
-    coveralls_setup(
-        "${arpacksrc_STAT_SRCS} ${arpackutil_STAT_SRCS} ${arpacksrc_ICB} ${arpack_TST_SRC} ${arpack_EX_F_SRC} ${arpack_EX_CPP_SRC} ${parpacksrc_STAT_SRCS} ${parpackutil_STAT_SRCS} ${parpacksrc_ICB} ${parpack_TST_SRC} ${parpack_EX_F_SRC}" # The source files.
-        ON                 # If we should upload.
-        "${PROJECT_SOURCE_DIR}/cmake/") # (Optional) Alternate project cmake module path.
-endif()
-
 function(libsummary title include libraries)
     message("   -- ${title}:")
     foreach(inc ${include})
@@ -831,7 +927,7 @@ endfunction(cprsummary)
 
 message("-- Configuration summary for arpack-ng-${arpack_ng_VERSION}:")
 message("   -- prefix: ${CMAKE_INSTALL_PREFIX}")
-message("   -- MPI: ${MPI}")
+message("   -- MPI: ${MPI} (ICB provided ${HAVE_MPI_ICB})")
 message("   -- ICB: ${ICB}")
 message("   -- INTERFACE64: ${INTERFACE64}")
 cprsummary("FC" "${CMAKE_Fortran_COMPILER}"
diff --git a/EXAMPLES/BAND/Makefile.am b/EXAMPLES/BAND/Makefile.am
index 04a750b..776d8b2 100644
--- a/EXAMPLES/BAND/Makefile.am
+++ b/EXAMPLES/BAND/Makefile.am
@@ -1,4 +1,4 @@
-LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
+LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX)$(ITF64SUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
 
 SSBDR = ssbdr1 ssbdr2 ssbdr3 ssbdr4 ssbdr5 ssbdr6
 DSBDR = dsbdr1 dsbdr2 dsbdr3 dsbdr4 dsbdr5 dsbdr6
diff --git a/EXAMPLES/COMPLEX/Makefile.am b/EXAMPLES/COMPLEX/Makefile.am
index 9cca488..6af33a0 100644
--- a/EXAMPLES/COMPLEX/Makefile.am
+++ b/EXAMPLES/COMPLEX/Makefile.am
@@ -1,4 +1,4 @@
-LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
+LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX)$(ITF64SUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
 
 CNDRV = cndrv1 cndrv2 cndrv3 cndrv4
 ZNDRV = zndrv1 zndrv2 zndrv3 zndrv4
diff --git a/EXAMPLES/MATRIX_MARKET/Makefile.am b/EXAMPLES/MATRIX_MARKET/Makefile.am
index cc2b7cc..3e8c528 100644
--- a/EXAMPLES/MATRIX_MARKET/Makefile.am
+++ b/EXAMPLES/MATRIX_MARKET/Makefile.am
@@ -1,8 +1,6 @@
-LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX).la
+LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX)$(ITF64SUFFIX).la
 AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)/ICB $(EIGEN3_CFLAGS)
 
-pkgincludedir = $(includedir)/arpack
-
 EXTRA_DIST = README
 
 check_PROGRAMS = arpackmm
@@ -14,7 +12,6 @@ arpackmm_SOURCES = arpackmm.cpp
 
 if ICBEXMM
 pkginclude_HEADERS = arpackSolver.hpp
-pkgconfig_DATA = arpackSolver.pc
 endif
 
 CLEANFILES = \
diff --git a/EXAMPLES/MATRIX_MARKET/arpackSolver.hpp b/EXAMPLES/MATRIX_MARKET/arpackSolver.hpp
index cec79a6..d8fc31f 100644
--- a/EXAMPLES/MATRIX_MARKET/arpackSolver.hpp
+++ b/EXAMPLES/MATRIX_MARKET/arpackSolver.hpp
@@ -437,18 +437,18 @@ class arpackSolver {
               a_int ldv, a_int * iparam, a_int * ipntr, complex<float> * workd, complex<float> * workl, a_int lworkl, float * & rwork,
               a_int * info) {
       if (!rwork) rwork = new float[nbCV];
-      cnaupd_c(ido, bMat, nbDim, which, nbEV, tol, reinterpret_cast<_Complex float*>(resid), nbCV,
-               reinterpret_cast<_Complex float*>(v), ldv, iparam, ipntr, reinterpret_cast<_Complex float*>(workd),
-               reinterpret_cast<_Complex float*>(workl), lworkl, rwork, info);
+      cnaupd_c(ido, bMat, nbDim, which, nbEV, tol, reinterpret_cast<a_fcomplex*>(resid), nbCV,
+               reinterpret_cast<a_fcomplex*>(v), ldv, iparam, ipntr, reinterpret_cast<a_fcomplex*>(workd),
+               reinterpret_cast<a_fcomplex*>(workl), lworkl, rwork, info);
     };
 
     void aupd(a_int * ido, char const * bMat, a_int nbDim, char const * which, complex<double> * resid, complex<double> * v,
               a_int ldv, a_int * iparam, a_int * ipntr, complex<double> * workd, complex<double> * workl, a_int lworkl, double * & rwork,
               a_int * info) {
       if (!rwork) rwork = new double[nbCV];
-      znaupd_c(ido, bMat, nbDim, which, nbEV, tol, reinterpret_cast<_Complex double*>(resid), nbCV,
-               reinterpret_cast<_Complex double*>(v), ldv, iparam, ipntr, reinterpret_cast<_Complex double*>(workd),
-               reinterpret_cast<_Complex double*>(workl), lworkl, rwork, info);
+      znaupd_c(ido, bMat, nbDim, which, nbEV, tol, reinterpret_cast<a_dcomplex*>(resid), nbCV,
+               reinterpret_cast<a_dcomplex*>(v), ldv, iparam, ipntr, reinterpret_cast<a_dcomplex*>(workd),
+               reinterpret_cast<a_dcomplex*>(workl), lworkl, rwork, info);
     };
 
     void spectrum(RC * d, RC * z, a_int nbDim, a_int * iparam) {
@@ -517,8 +517,8 @@ class arpackSolver {
 
         sseupd_c(rvec, howmny, select, d, z, ldz, sigmaReal,
                  bMat, nbDim, which, nbEV, tol, resid, nbCV, v, ldv, iparam, ipntr, workd, workl, lworkl, &info);
-        if (info == -14) cerr << "Error: dseupd - KO: dsaupd did not find any eigenvalues to sufficient accuracy" << endl;
-        if (info < 0 && info != -14 /*-14: don't break*/) {cerr << "Error: dseupd - KO with info " << info << endl; return 1;}
+        if (info == -14) cerr << "Error: sseupd - KO: ssaupd did not find any eigenvalues to sufficient accuracy" << endl;
+        if (info < 0 && info != -14 /*-14: don't break*/) {cerr << "Error: sseupd - KO with info " << info << endl; return 1;}
 
         spectrum(d, z, nbDim, iparam);
 
@@ -531,8 +531,8 @@ class arpackSolver {
 
         sneupd_c(rvec, howmny, select, dr, di, z, ldz, sigmaReal, sigmaImag, workev,
                  bMat, nbDim, which, nbEV, tol, resid, nbCV, v, ldv, iparam, ipntr, workd, workl, lworkl, &info);
-        if (info == -14) cerr << "Error: dneupd - KO: [dz]naupd did not find any eigenvalues to sufficient accuracy" << endl;
-        if (info < 0 && info != -14 /*-14: don't break*/) {cerr << "Error: dneupd - KO with info " << info << endl; return 1;}
+        if (info == -14) cerr << "Error: sneupd - KO: snaupd did not find any eigenvalues to sufficient accuracy" << endl;
+        if (info < 0 && info != -14 /*-14: don't break*/) {cerr << "Error: sneupd - KO with info " << info << endl; return 1;}
 
         halfSpectrum(dr, di, z, nbDim, iparam);
 
@@ -568,7 +568,7 @@ class arpackSolver {
 
         dneupd_c(rvec, howmny, select, dr, di, z, ldz, sigmaReal, sigmaImag, workev,
                  bMat, nbDim, which, nbEV, tol, resid, nbCV, v, ldv, iparam, ipntr, workd, workl, lworkl, &info);
-        if (info == -14) cerr << "Error: dneupd - KO: [dz]naupd did not find any eigenvalues to sufficient accuracy" << endl;
+        if (info == -14) cerr << "Error: dneupd - KO: dnaupd did not find any eigenvalues to sufficient accuracy" << endl;
         if (info < 0 && info != -14 /*-14: don't break*/) {cerr << "Error: dneupd - KO with info " << info << endl; return 1;}
 
         halfSpectrum(dr, di, z, nbDim, iparam);
@@ -589,13 +589,13 @@ class arpackSolver {
       complex<float> * workev = new complex<float>[2*nbCV];
 
       complex<float> sigma = complex<float>((float) sigmaReal, (float) sigmaImag);
-      cneupd_c(rvec, howmny, select, reinterpret_cast<_Complex float*>(d), reinterpret_cast<_Complex float*>(z), ldz,
-               reinterpret_cast<_Complex float &>(sigma), reinterpret_cast<_Complex float*>(workev),
-               bMat, nbDim, which, nbEV, tol, reinterpret_cast<_Complex float*>(resid), nbCV,
-               reinterpret_cast<_Complex float*>(v), ldv, iparam, ipntr,
-               reinterpret_cast<_Complex float*>(workd), reinterpret_cast<_Complex float*>(workl), lworkl, rwork, &info);
-      if (info == -14) cerr << "Error: zneupd - KO: dsaupd did not find any eigenvalues to sufficient accuracy" << endl;
-      if (info < 0 && info != -14 /*-14: don't break*/) {cerr << "Error: zneupd - KO with info " << info << endl; return 1;}
+      cneupd_c(rvec, howmny, select, reinterpret_cast<a_fcomplex*>(d), reinterpret_cast<a_fcomplex*>(z), ldz,
+               reinterpret_cast<a_fcomplex &>(sigma), reinterpret_cast<a_fcomplex*>(workev),
+               bMat, nbDim, which, nbEV, tol, reinterpret_cast<a_fcomplex*>(resid), nbCV,
+               reinterpret_cast<a_fcomplex*>(v), ldv, iparam, ipntr,
+               reinterpret_cast<a_fcomplex*>(workd), reinterpret_cast<a_fcomplex*>(workl), lworkl, rwork, &info);
+      if (info == -14) cerr << "Error: cneupd - KO: cnaupd did not find any eigenvalues to sufficient accuracy" << endl;
+      if (info < 0 && info != -14 /*-14: don't break*/) {cerr << "Error: cneupd - KO with info " << info << endl; return 1;}
 
       spectrum(d, z, nbDim, iparam);
 
@@ -613,12 +613,12 @@ class arpackSolver {
       complex<double> * workev = new complex<double>[2*nbCV];
 
       complex<double> sigma = complex<double>(sigmaReal, sigmaImag);
-      zneupd_c(rvec, howmny, select, reinterpret_cast<_Complex double*>(d), reinterpret_cast<_Complex double*>(z), ldz,
-               reinterpret_cast<_Complex double &>(sigma), reinterpret_cast<_Complex double*>(workev),
-               bMat, nbDim, which, nbEV, tol, reinterpret_cast<_Complex double*>(resid), nbCV,
-               reinterpret_cast<_Complex double*>(v), ldv, iparam, ipntr,
-               reinterpret_cast<_Complex double*>(workd), reinterpret_cast<_Complex double*>(workl), lworkl, rwork, &info);
-      if (info == -14) cerr << "Error: zneupd - KO: dsaupd did not find any eigenvalues to sufficient accuracy" << endl;
+      zneupd_c(rvec, howmny, select, reinterpret_cast<a_dcomplex*>(d), reinterpret_cast<a_dcomplex*>(z), ldz,
+               reinterpret_cast<a_dcomplex &>(sigma), reinterpret_cast<a_dcomplex*>(workev),
+               bMat, nbDim, which, nbEV, tol, reinterpret_cast<a_dcomplex*>(resid), nbCV,
+               reinterpret_cast<a_dcomplex*>(v), ldv, iparam, ipntr,
+               reinterpret_cast<a_dcomplex*>(workd), reinterpret_cast<a_dcomplex*>(workl), lworkl, rwork, &info);
+      if (info == -14) cerr << "Error: zneupd - KO: znaupd did not find any eigenvalues to sufficient accuracy" << endl;
       if (info < 0 && info != -14 /*-14: don't break*/) {cerr << "Error: zneupd - KO with info " << info << endl; return 1;}
 
       spectrum(d, z, nbDim, iparam);
@@ -659,7 +659,11 @@ class arpackSolver {
       if (restartFromFile) {
         ifstream ifs(fileName.c_str());
         if (ifs.is_open()) {
-          a_int nbCV = 1; if (readNbCV) {ifs >> nbCV; if (nbCV < nbCV) nbCV = nbCV;}
+          a_int nbCV = 1;
+          if (readNbCV) {
+            ifs >> nbCV;
+            if (nbCV < nbDim) nbCV = nbDim; // Cut-off in case previous run used different nbDim.
+          }
           for (a_int n = 0; rv && n < nbDim*nbCV; n++) ifs >> rv[n];
           if (verbose >= 1) {
             cout << endl << "arpackSolver:" << endl;
diff --git a/EXAMPLES/MATRIX_MARKET/arpackmm.cpp b/EXAMPLES/MATRIX_MARKET/arpackmm.cpp
index 8865bd8..e2451bc 100644
--- a/EXAMPLES/MATRIX_MARKET/arpackmm.cpp
+++ b/EXAMPLES/MATRIX_MARKET/arpackmm.cpp
@@ -316,6 +316,13 @@ class options {
       }
     }
 
+    // Sanity checks.
+
+    if (!stdPb && fileB.empty()) {
+      cerr << "Error: generalized problem without B matrix" << endl;
+      return usage();
+    }
+
     return 0;
   };
 
diff --git a/EXAMPLES/NONSYM/Makefile.am b/EXAMPLES/NONSYM/Makefile.am
index fbec7f0..fdd0b8c 100644
--- a/EXAMPLES/NONSYM/Makefile.am
+++ b/EXAMPLES/NONSYM/Makefile.am
@@ -1,4 +1,4 @@
-LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
+LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX)$(ITF64SUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
 
 SNDRV = sndrv1 sndrv2 sndrv3 sndrv4 sndrv5 sndrv6
 DNDRV = dndrv1 dndrv2 dndrv3 dndrv4 dndrv5 dndrv6
diff --git a/EXAMPLES/PYARPACK/README b/EXAMPLES/PYARPACK/README
index 1f5b37b..c136dd6 100644
--- a/EXAMPLES/PYARPACK/README
+++ b/EXAMPLES/PYARPACK/README
@@ -5,11 +5,18 @@ Installation:
 
 Python3: ~/arpack-ng/build> cmake -DCMAKE_INSTALL_PREFIX=/tmp/local -DPYTHON3=ON -DBOOST_PYTHON_LIBSUFFIX="3" ..
          ~/arpack-ng/build> make all test
+         ~/arpack-ng/build> make install
 Note: Boost must have been compiled for Python3.
+Note: installation will install libpyarpack.so in the install directory.
+Note: python3 minimal packages must be installed (apt-get install python3-minimal python3-pip).
+      numpy must be installed (apt-get install python3-numpy) as the A/B matrices used by arpack
+      solver must be numpy arrays.
 
 Usage:
 ------
 
+PYTHONPATH must include the directory where libpyarpack.so has been installed.
+
 >> export PYTHONPATH="/tmp/local/lib/pyarpack:${PYTHONPATH}"
 >> python
 >> import pyarpack
@@ -45,7 +52,7 @@ Note:
    1.1. create numpy arrays specifying explicitly the type:
         >> Aij = np.array([], dtype='complex128')
    1.2. filling numpy arrays casting value on append:
-        >> Aij = np.append(Aij, np.complex128(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+        >> Aij = np.append(Aij, np.complex128(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
    1.3. calling the solver flavor which is consistent with the numpy array data type:
         >> arpackSlv = pyarpackSlv.complexDouble() # Caution: complexDouble <=> np.array(..., dtype='complex128')
    note: NO data type check can be done at C++ side, the pyarpack user MUST insure data consistency.
diff --git a/EXAMPLES/PYARPACK/pyarpack.cpp b/EXAMPLES/PYARPACK/pyarpack.cpp
index 1eaf5ff..a705b2c 100644
--- a/EXAMPLES/PYARPACK/pyarpack.cpp
+++ b/EXAMPLES/PYARPACK/pyarpack.cpp
@@ -194,7 +194,7 @@ BOOST_PYTHON_MODULE(pyarpack) {
   doc << "   1.1. create numpy arrays specifying explicitly the type:" << std::endl;
   doc << "        >> Aij = np.array([], dtype='complex128')" << std::endl;
   doc << "   1.2. filling numpy arrays casting value on append:" << std::endl;
-  doc << "        >> Aij = np.append(Aij, np.complex128(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type." << std::endl;
+  doc << "        >> Aij = np.append(Aij, np.complex128(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type." << std::endl;
   doc << "   1.3. calling the solver flavor which is consistent with the numpy array data type:" << std::endl;
   doc << "        >> arpackSlv = pyarpackSlv.complexDouble() # Caution: complexDouble <=> np.array(..., dtype='complex128')" << std::endl;
   doc << "   note: NO data type check can be done at C++ side, the pyarpack user MUST insure data consistency." << std::endl;
diff --git a/EXAMPLES/PYARPACK/pyarpackDenseLDLT.py.in b/EXAMPLES/PYARPACK/pyarpackDenseLDLT.py.in
index bf3ecb9..00231bf 100644
--- a/EXAMPLES/PYARPACK/pyarpackDenseLDLT.py.in
+++ b/EXAMPLES/PYARPACK/pyarpackDenseLDLT.py.in
@@ -10,13 +10,13 @@ Aij = np.array([], dtype='complex128')
 for k in range(n):
     for l in range(n):
         if l == k:
-            Aij = np.append(Aij, np.complex128(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         elif l == k-1:
-            Aij = np.append(Aij, np.complex128(np.complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         elif l == k+1:
-            Aij = np.append(Aij, np.complex128(np.complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         else:
-            Aij = np.append(Aij, np.complex128(np.complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
 for idx, val in enumerate(Aij):
     print("A[", idx, "] =", val)
 A = (Aij, False) # raw format: Aij values, row ordered (or not).
@@ -65,17 +65,17 @@ Bij = np.array([], dtype='complex64')
 for k in range(n):
     for l in range(n):
         if l == k:
-            Aij = np.append(Aij, np.complex64(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 33.3,  33.3))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 33.3,  33.3))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         elif l == k-1:
-            Aij = np.append(Aij, np.complex64(np.complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         elif l == k+1:
-            Aij = np.append(Aij, np.complex64(np.complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         else:
-            Aij = np.append(Aij, np.complex64(np.complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
 for idx, val in enumerate(Aij):
     print("A[", idx, "] =", val)
 for idx, val in enumerate(Bij):
diff --git a/EXAMPLES/PYARPACK/pyarpackDenseQRPP.py.in b/EXAMPLES/PYARPACK/pyarpackDenseQRPP.py.in
index 148c350..b3d82b1 100644
--- a/EXAMPLES/PYARPACK/pyarpackDenseQRPP.py.in
+++ b/EXAMPLES/PYARPACK/pyarpackDenseQRPP.py.in
@@ -10,13 +10,13 @@ Aij = np.array([], dtype='complex128')
 for k in range(n):
     for l in range(n):
         if l == k:
-            Aij = np.append(Aij, np.complex128(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         elif l == k-1:
-            Aij = np.append(Aij, np.complex128(np.complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         elif l == k+1:
-            Aij = np.append(Aij, np.complex128(np.complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         else:
-            Aij = np.append(Aij, np.complex128(np.complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
 for idx, val in enumerate(Aij):
     print("A[", idx, "] =", val)
 A = (Aij, False) # raw format: Aij values, row ordered (or not).
@@ -64,17 +64,17 @@ Bij = np.array([], dtype='complex64')
 for k in range(n):
     for l in range(n):
         if l == k:
-            Aij = np.append(Aij, np.complex64(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 33.3,  33.3))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 33.3,  33.3))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         elif l == k-1:
-            Aij = np.append(Aij, np.complex64(np.complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         elif l == k+1:
-            Aij = np.append(Aij, np.complex64(np.complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         else:
-            Aij = np.append(Aij, np.complex64(np.complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
 for idx, val in enumerate(Aij):
     print("A[", idx, "] =", val)
 for idx, val in enumerate(Bij):
diff --git a/EXAMPLES/PYARPACK/pyarpackDenseQRRR.py.in b/EXAMPLES/PYARPACK/pyarpackDenseQRRR.py.in
index 0dec3ae..400851d 100644
--- a/EXAMPLES/PYARPACK/pyarpackDenseQRRR.py.in
+++ b/EXAMPLES/PYARPACK/pyarpackDenseQRRR.py.in
@@ -10,13 +10,13 @@ Aij = np.array([], dtype='complex128')
 for k in range(n):
     for l in range(n):
         if l == k:
-            Aij = np.append(Aij, np.complex128(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         elif l == k-1:
-            Aij = np.append(Aij, np.complex128(np.complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         elif l == k+1:
-            Aij = np.append(Aij, np.complex128(np.complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         else:
-            Aij = np.append(Aij, np.complex128(np.complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
 for idx, val in enumerate(Aij):
     print("A[", idx, "] =", val)
 A = (Aij, False) # raw format: Aij values, row ordered (or not).
@@ -64,17 +64,17 @@ Bij = np.array([], dtype='complex64')
 for k in range(n):
     for l in range(n):
         if l == k:
-            Aij = np.append(Aij, np.complex64(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 33.3,  33.3))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 33.3,  33.3))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         elif l == k-1:
-            Aij = np.append(Aij, np.complex64(np.complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         elif l == k+1:
-            Aij = np.append(Aij, np.complex64(np.complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         else:
-            Aij = np.append(Aij, np.complex64(np.complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex(   0.,    0.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
 for idx, val in enumerate(Aij):
     print("A[", idx, "] =", val)
 for idx, val in enumerate(Bij):
diff --git a/EXAMPLES/PYARPACK/pyarpackSparseBiCGILU.py.in b/EXAMPLES/PYARPACK/pyarpackSparseBiCGILU.py.in
index 2df9d40..04d9b07 100644
--- a/EXAMPLES/PYARPACK/pyarpackSparseBiCGILU.py.in
+++ b/EXAMPLES/PYARPACK/pyarpackSparseBiCGILU.py.in
@@ -16,11 +16,11 @@ for k in range(n):
         i = np.append(i, np.@PYINT@(k)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         j = np.append(j, np.@PYINT@(l)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k:
-            Aij = np.append(Aij, np.complex128(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k-1:
-            Aij = np.append(Aij, np.complex128(np.complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k+1:
-            Aij = np.append(Aij, np.complex128(np.complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
 for k, l, Akl in zip(i, j, Aij):
     print("A[", k, ",", l, "] =", Akl)
 A = (n, i, j, Aij) # coo format: dimension, i 0-based indices, j 0-based indices, Aij values.
@@ -77,14 +77,14 @@ for k in range(n):
         i = np.append(i, np.@PYINT@(k+1)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         j = np.append(j, np.@PYINT@(l+1)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k:
-            Aij = np.append(Aij, np.complex64(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 33.3,  33.3))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 33.3,  33.3))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k-1:
-            Aij = np.append(Aij, np.complex64(np.complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k+1:
-            Aij = np.append(Aij, np.complex64(np.complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
 for k, l, Akl in zip(i, j, Aij):
     print("A[", k, ",", l, "] =", Akl)
 for k, l, Bkl in zip(i, j, Bij):
diff --git a/EXAMPLES/PYARPACK/pyarpackSparseCGILU.py.in b/EXAMPLES/PYARPACK/pyarpackSparseCGILU.py.in
index 1e6b0df..0db211d 100644
--- a/EXAMPLES/PYARPACK/pyarpackSparseCGILU.py.in
+++ b/EXAMPLES/PYARPACK/pyarpackSparseCGILU.py.in
@@ -16,11 +16,11 @@ for k in range(n):
         i = np.append(i, np.@PYINT@(k)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         j = np.append(j, np.@PYINT@(l)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k:
-            Aij = np.append(Aij, np.complex128(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k-1:
-            Aij = np.append(Aij, np.complex128(np.complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k+1:
-            Aij = np.append(Aij, np.complex128(np.complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
 for k, l, Akl in zip(i, j, Aij):
     print("A[", k, ",", l, "] =", Akl)
 A = (n, i, j, Aij) # coo format: dimension, i 0-based indices, j 0-based indices, Aij values.
@@ -77,14 +77,14 @@ for k in range(n):
         i = np.append(i, np.@PYINT@(k+1)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         j = np.append(j, np.@PYINT@(l+1)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k:
-            Aij = np.append(Aij, np.complex64(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 33.3,  33.3))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 33.3,  33.3))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k-1:
-            Aij = np.append(Aij, np.complex64(np.complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k+1:
-            Aij = np.append(Aij, np.complex64(np.complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
 for k, l, Akl in zip(i, j, Aij):
     print("A[", k, ",", l, "] =", Akl)
 for k, l, Bkl in zip(i, j, Bij):
diff --git a/EXAMPLES/PYARPACK/pyarpackSparseLDLT.py.in b/EXAMPLES/PYARPACK/pyarpackSparseLDLT.py.in
index bda27dd..667d5b6 100644
--- a/EXAMPLES/PYARPACK/pyarpackSparseLDLT.py.in
+++ b/EXAMPLES/PYARPACK/pyarpackSparseLDLT.py.in
@@ -16,11 +16,11 @@ for k in range(n):
         i = np.append(i, np.@PYINT@(k)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         j = np.append(j, np.@PYINT@(l)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k:
-            Aij = np.append(Aij, np.complex128(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k-1:
-            Aij = np.append(Aij, np.complex128(np.complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k+1:
-            Aij = np.append(Aij, np.complex128(np.complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
 for k, l, Akl in zip(i, j, Aij):
     print("A[", k, ",", l, "] =", Akl)
 A = (n, i, j, Aij) # coo format: dimension, i 0-based indices, j 0-based indices, Aij values.
@@ -75,14 +75,14 @@ for k in range(n):
         i = np.append(i, np.@PYINT@(k+1)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         j = np.append(j, np.@PYINT@(l+1)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k:
-            Aij = np.append(Aij, np.complex64(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 33.3,  33.3))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 33.3,  33.3))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k-1:
-            Aij = np.append(Aij, np.complex64(np.complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k+1:
-            Aij = np.append(Aij, np.complex64(np.complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
 for k, l, Akl in zip(i, j, Aij):
     print("A[", k, ",", l, "] =", Akl)
 for k, l, Bkl in zip(i, j, Bij):
diff --git a/EXAMPLES/PYARPACK/pyarpackSparseQR.py.in b/EXAMPLES/PYARPACK/pyarpackSparseQR.py.in
index 62fd5c6..b41b4b8 100644
--- a/EXAMPLES/PYARPACK/pyarpackSparseQR.py.in
+++ b/EXAMPLES/PYARPACK/pyarpackSparseQR.py.in
@@ -16,11 +16,11 @@ for k in range(n):
         i = np.append(i, np.@PYINT@(k)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         j = np.append(j, np.@PYINT@(l)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k:
-            Aij = np.append(Aij, np.complex128(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k-1:
-            Aij = np.append(Aij, np.complex128(np.complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k+1:
-            Aij = np.append(Aij, np.complex128(np.complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex128(complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
 for k, l, Akl in zip(i, j, Aij):
     print("A[", k, ",", l, "] =", Akl)
 A = (n, i, j, Aij) # coo format: dimension, i 0-based indices, j 0-based indices, Aij values.
@@ -74,14 +74,14 @@ for k in range(n):
         i = np.append(i, np.@PYINT@(k+1)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         j = np.append(j, np.@PYINT@(l+1)) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k:
-            Aij = np.append(Aij, np.complex64(np.complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 33.3,  33.3))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex( 200.,  200.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 33.3,  33.3))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k-1:
-            Aij = np.append(Aij, np.complex64(np.complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex(-101., -101.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
         if l == k+1:
-            Aij = np.append(Aij, np.complex64(np.complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
-            Bij = np.append(Bij, np.complex64(np.complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Aij = np.append(Aij, np.complex64(complex( -99.,  -99.))) # Casting value on append is MANDATORY or C++ won't get the expected type.
+            Bij = np.append(Bij, np.complex64(complex( 16.6,  16.6))) # Casting value on append is MANDATORY or C++ won't get the expected type.
 for k, l, Akl in zip(i, j, Aij):
     print("A[", k, ",", l, "] =", Akl)
 for k, l, Bkl in zip(i, j, Bij):
diff --git a/EXAMPLES/SIMPLE/Makefile.am b/EXAMPLES/SIMPLE/Makefile.am
index a676d0d..a02dbdc 100644
--- a/EXAMPLES/SIMPLE/Makefile.am
+++ b/EXAMPLES/SIMPLE/Makefile.am
@@ -1,4 +1,4 @@
-LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
+LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX)$(ITF64SUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
 
 SIMPLE = sssimp dssimp snsimp dnsimp cnsimp znsimp
 
diff --git a/EXAMPLES/SVD/Makefile.am b/EXAMPLES/SVD/Makefile.am
index d4e1836..1e7a8cf 100644
--- a/EXAMPLES/SVD/Makefile.am
+++ b/EXAMPLES/SVD/Makefile.am
@@ -1,4 +1,4 @@
-LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
+LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX)$(ITF64SUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
 
 SVD = ssvd dsvd
 
diff --git a/EXAMPLES/SYM/Makefile.am b/EXAMPLES/SYM/Makefile.am
index 7432ccd..8207e6a 100644
--- a/EXAMPLES/SYM/Makefile.am
+++ b/EXAMPLES/SYM/Makefile.am
@@ -1,4 +1,4 @@
-LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
+LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX)$(ITF64SUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
 
 SSDRV = ssdrv1 ssdrv2 ssdrv3 ssdrv4 ssdrv5 ssdrv6
 DSDRV = dsdrv1 dsdrv2 dsdrv3 dsdrv4 dsdrv5 dsdrv6
diff --git a/ICB/Makefile.am b/ICB/Makefile.am
index 94dc376..8587e08 100644
--- a/ICB/Makefile.am
+++ b/ICB/Makefile.am
@@ -1,7 +1,5 @@
 AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)
 
-pkgincludedir = $(includedir)/arpack
-
 pkginclude_HEADERS = debug_c.h debug_c.hpp
 pkginclude_HEADERS += stat_c.h stat_c.hpp
 pkginclude_HEADERS += arpack.h arpack.hpp
diff --git a/ICB/arpack.h b/ICB/arpack.h
index 865e269..f9f1053 100644
--- a/ICB/arpack.h
+++ b/ICB/arpack.h
@@ -7,8 +7,8 @@
 extern "C" {
 #endif
 
-void cnaupd_c(a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, float tol, float _Complex* resid, a_int ncv, float _Complex* v, a_int ldv, a_int* iparam, a_int* ipntr, float _Complex* workd, float _Complex* workl, a_int lworkl, float* rwork, a_int* info);
-void cneupd_c(a_int rvec, char const* howmny, a_int const* select, float _Complex* d, float _Complex* z, a_int ldz, float _Complex sigma, float _Complex* workev, char const* bmat, a_int n, char const* which, a_int nev, float tol, float _Complex* resid, a_int ncv, float _Complex* v, a_int ldv, a_int* iparam, a_int* ipntr, float _Complex* workd, float _Complex* workl, a_int lworkl, float* rwork, a_int* info);
+void cnaupd_c(a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, float tol, a_fcomplex* resid, a_int ncv, a_fcomplex* v, a_int ldv, a_int* iparam, a_int* ipntr, a_fcomplex* workd, a_fcomplex* workl, a_int lworkl, float* rwork, a_int* info);
+void cneupd_c(a_int rvec, char const* howmny, a_int const* select, a_fcomplex* d, a_fcomplex* z, a_int ldz, a_fcomplex sigma, a_fcomplex* workev, char const* bmat, a_int n, char const* which, a_int nev, float tol, a_fcomplex* resid, a_int ncv, a_fcomplex* v, a_int ldv, a_int* iparam, a_int* ipntr, a_fcomplex* workd, a_fcomplex* workl, a_int lworkl, float* rwork, a_int* info);
 void dnaupd_c(a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, double tol, double* resid, a_int ncv, double* v, a_int ldv, a_int* iparam, a_int* ipntr, double* workd, double* workl, a_int lworkl, a_int* info);
 void dneupd_c(a_int rvec, char const* howmny, a_int const* select, double* dr, double* di, double* z, a_int ldz, double sigmar, double sigmai, double * workev, char const* bmat, a_int n, char const* which, a_int nev, double tol, double* resid, a_int ncv, double* v, a_int ldv, a_int* iparam, a_int* ipntr, double* workd, double* workl, a_int lworkl, a_int* info);
 void dsaupd_c(a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, double tol, double* resid, a_int ncv, double* v, a_int ldv, a_int* iparam, a_int* ipntr, double* workd, double* workl, a_int lworkl, a_int* info);
@@ -17,8 +17,8 @@ void snaupd_c(a_int* ido, char const* bmat, a_int n, char const* which, a_int ne
 void sneupd_c(a_int rvec, char const* howmny, a_int const* select, float* dr, float* di, float* z, a_int ldz, float sigmar, float sigmai, float * workev, char const* bmat, a_int n, char const* which, a_int nev, float tol, float* resid, a_int ncv, float* v, a_int ldv, a_int* iparam, a_int* ipntr, float* workd, float* workl, a_int lworkl, a_int* info);
 void ssaupd_c(a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, float tol, float* resid, a_int ncv, float* v, a_int ldv, a_int* iparam, a_int* ipntr, float* workd, float* workl, a_int lworkl, a_int* info);
 void sseupd_c(a_int rvec, char const* howmny, a_int const* select, float* d, float* z, a_int ldz, float sigma, char const* bmat, a_int n, char const* which, a_int nev, float tol, float* resid, a_int ncv, float* v, a_int ldv, a_int* iparam, a_int* ipntr, float* workd, float* workl, a_int lworkl, a_int* info);
-void znaupd_c(a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, double tol, double _Complex* resid, a_int ncv, double _Complex* v, a_int ldv, a_int* iparam, a_int* ipntr, double _Complex* workd, double _Complex* workl, a_int lworkl, double* rwork, a_int* info);
-void zneupd_c(a_int rvec, char const* howmny, a_int const* select, double _Complex* d, double _Complex* z, a_int ldz, double _Complex sigma, double _Complex* workev, char const* bmat, a_int n, char const* which, a_int nev, double tol, double _Complex* resid, a_int ncv, double _Complex* v, a_int ldv, a_int* iparam, a_int* ipntr, double _Complex* workd, double _Complex* workl, a_int lworkl, double* rwork, a_int* info);
+void znaupd_c(a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, double tol, a_dcomplex* resid, a_int ncv, a_dcomplex* v, a_int ldv, a_int* iparam, a_int* ipntr, a_dcomplex* workd, a_dcomplex* workl, a_int lworkl, double* rwork, a_int* info);
+void zneupd_c(a_int rvec, char const* howmny, a_int const* select, a_dcomplex* d, a_dcomplex* z, a_int ldz, a_dcomplex sigma, a_dcomplex* workev, char const* bmat, a_int n, char const* which, a_int nev, double tol, a_dcomplex* resid, a_int ncv, a_dcomplex* v, a_int ldv, a_int* iparam, a_int* ipntr, a_dcomplex* workd, a_dcomplex* workl, a_int lworkl, double* rwork, a_int* info);
 
 #ifdef  __cplusplus
 }
diff --git a/ICB/arpack.hpp b/ICB/arpack.hpp
index 4d753d1..8043867 100644
--- a/ICB/arpack.hpp
+++ b/ICB/arpack.hpp
@@ -16,6 +16,14 @@ enum class which : int {
   largest_magnitude,
   /// 'SM' - compute the NEV smallest (in magnitude) eigenvalues.
   smallest_magnitude,
+  /// 'LR' - compute the NEV largest (real part) eigenvalues.
+  largest_real,
+  /// 'SR' - compute the NEV smallest (real part) eigenvalues.
+  smallest_real,
+  /// 'LI' - compute the NEV largest (imaginary part) eigenvalues.
+  largest_imaginary,
+  /// 'SI' - compute the NEV smallest (imaginary part) eigenvalues.
+  smallest_imaginary,
   /// 'BE' - compute NEV eigenvalues, half from each end of the
   /// spectrum.  When NEV is odd, compute one more from the
   /// high end than from the low end.
@@ -60,6 +68,22 @@ inline char const* convert_to_char(which const option) {
       return "SM";
       break;
     }
+    case which::largest_real: {
+      return "LR";
+      break;
+    }
+    case which::smallest_real: {
+      return "SR";
+      break;
+    }
+    case which::largest_imaginary: {
+      return "LI";
+      break;
+    }
+    case which::smallest_imaginary: {
+      return "SI";
+      break;
+    }
     case which::both_ends: {
       return "BE";
       break;
@@ -186,10 +210,10 @@ inline void naupd(a_int& ido, bmat const bmat_option, a_int n,
                   float* rwork, a_int& info) {
   internal::cnaupd_c(&ido, internal::convert_to_char(bmat_option), n,
                      internal::convert_to_char(ritz_option), nev, tol,
-                     reinterpret_cast<_Complex float*>(resid), ncv,
-                     reinterpret_cast<_Complex float*>(v), ldv, iparam, ipntr,
-                     reinterpret_cast<_Complex float*>(workd),
-                     reinterpret_cast<_Complex float*>(workl), lworkl,
+                     reinterpret_cast<a_fcomplex*>(resid), ncv,
+                     reinterpret_cast<a_fcomplex*>(v), ldv, iparam, ipntr,
+                     reinterpret_cast<a_fcomplex*>(workd),
+                     reinterpret_cast<a_fcomplex*>(workl), lworkl,
                      rwork, &info);
 }
 
@@ -203,16 +227,16 @@ inline void neupd(a_int rvec, howmny const howmny_option, a_int* select,
                   a_int lworkl, float* rwork, a_int& info) {
   std::complex<float> sigma2 = sigma;
   internal::cneupd_c(rvec, internal::convert_to_char(howmny_option), select,
-                     reinterpret_cast<_Complex float*>(d),
-                     reinterpret_cast<_Complex float*>(z), ldz,
-                     *reinterpret_cast<_Complex float*>(&sigma2),
-                     reinterpret_cast<_Complex float*>(workev),
+                     reinterpret_cast<a_fcomplex*>(d),
+                     reinterpret_cast<a_fcomplex*>(z), ldz,
+                     *reinterpret_cast<a_fcomplex*>(&sigma2),
+                     reinterpret_cast<a_fcomplex*>(workev),
                      internal::convert_to_char(bmat_option), n,
                      internal::convert_to_char(ritz_option), nev, tol,
-                     reinterpret_cast<_Complex float*>(resid), ncv,
-                     reinterpret_cast<_Complex float*>(v), ldv, iparam, ipntr,
-                     reinterpret_cast<_Complex float*>(workd),
-                     reinterpret_cast<_Complex float*>(workl), lworkl,
+                     reinterpret_cast<a_fcomplex*>(resid), ncv,
+                     reinterpret_cast<a_fcomplex*>(v), ldv, iparam, ipntr,
+                     reinterpret_cast<a_fcomplex*>(workd),
+                     reinterpret_cast<a_fcomplex*>(workl), lworkl,
                      rwork, &info);
 }
 
@@ -224,10 +248,10 @@ inline void naupd(a_int& ido, bmat const bmat_option, a_int n,
                   double* rwork, a_int& info) {
   internal::znaupd_c(&ido, internal::convert_to_char(bmat_option), n,
                      internal::convert_to_char(ritz_option), nev, tol,
-                     reinterpret_cast<_Complex double*>(resid), ncv,
-                     reinterpret_cast<_Complex double*>(v), ldv, iparam, ipntr,
-                     reinterpret_cast<_Complex double*>(workd),
-                     reinterpret_cast<_Complex double*>(workl), lworkl,
+                     reinterpret_cast<a_dcomplex*>(resid), ncv,
+                     reinterpret_cast<a_dcomplex*>(v), ldv, iparam, ipntr,
+                     reinterpret_cast<a_dcomplex*>(workd),
+                     reinterpret_cast<a_dcomplex*>(workl), lworkl,
                      rwork, &info);
 }
 
@@ -241,16 +265,16 @@ inline void neupd(a_int rvec, howmny const howmny_option, a_int* select,
                   a_int lworkl, double* rwork, a_int& info) {
   std::complex<double> sigma2 = sigma;
   internal::zneupd_c(rvec, internal::convert_to_char(howmny_option), select,
-                     reinterpret_cast<_Complex double*>(d),
-                     reinterpret_cast<_Complex double*>(z), ldz,
-                     *reinterpret_cast<_Complex double*>(&sigma2),
-                     reinterpret_cast<_Complex double*>(workev),
+                     reinterpret_cast<a_dcomplex*>(d),
+                     reinterpret_cast<a_dcomplex*>(z), ldz,
+                     *reinterpret_cast<a_dcomplex*>(&sigma2),
+                     reinterpret_cast<a_dcomplex*>(workev),
                      internal::convert_to_char(bmat_option), n,
                      internal::convert_to_char(ritz_option), nev, tol,
-                     reinterpret_cast<_Complex double*>(resid), ncv,
-                     reinterpret_cast<_Complex double*>(v), ldv, iparam, ipntr,
-                     reinterpret_cast<_Complex double*>(workd),
-                     reinterpret_cast<_Complex double*>(workl), lworkl,
+                     reinterpret_cast<a_dcomplex*>(resid), ncv,
+                     reinterpret_cast<a_dcomplex*>(v), ldv, iparam, ipntr,
+                     reinterpret_cast<a_dcomplex*>(workd),
+                     reinterpret_cast<a_dcomplex*>(workl), lworkl,
                      rwork, &info);
 }
 }  // namespace arpack
diff --git a/ICB/debug_icb.F90 b/ICB/debug_icb.F90
index 5219716..6632117 100644
--- a/ICB/debug_icb.F90
+++ b/ICB/debug_icb.F90
@@ -12,7 +12,7 @@ subroutine debug_c(logfil_c, ndigit_c, mgetv0_c,
   integer(kind=i_int), value, intent(in) :: msaupd_c, msaup2_c, msaitr_c, mseigt_c, msapps_c, msgets_c, mseupd_c
   integer(kind=i_int), value, intent(in) :: mnaupd_c, mnaup2_c, mnaitr_c, mneigh_c, mnapps_c, mngets_c, mneupd_c
   integer(kind=i_int), value, intent(in) :: mcaupd_c, mcaup2_c, mcaitr_c, mceigh_c, mcapps_c, mcgets_c, mceupd_c
-  include 'debug.h'
+  include 'debugF90.h'
   logfil = logfil_c
   ndigit = ndigit_c
   mgetv0 = mgetv0_c
diff --git a/ICB/parpack.h b/ICB/parpack.h
index 23b14ee..93490bd 100644
--- a/ICB/parpack.h
+++ b/ICB/parpack.h
@@ -14,18 +14,23 @@
 extern "C" {
 #endif
 
-void pcnaupd_c(MPI_Fint comm, a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, float tol, float _Complex* resid, a_int ncv, float _Complex* v, a_int ldv, a_int* iparam, a_int* ipntr, float _Complex* workd, float _Complex* workl, a_int lworkl, float _Complex* rwork, a_int* info);
-void pcneupd_c(MPI_Fint comm, a_int rvec, char const* howmny, a_int const* select, float _Complex* d, float _Complex* z, a_int ldz, float _Complex sigma, float _Complex* workev, char const* bmat, a_int n, char const* which, a_int nev, float tol, float _Complex* resid, a_int ncv, float _Complex* v, a_int ldv, a_int* iparam, a_int* ipntr, float _Complex* workd, float _Complex* workl, a_int lworkl, float _Complex* rwork, a_int* info);
-void pdnaupd_c(MPI_Fint comm, a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, double tol, double* resid, a_int ncv, double* v, a_int ldv, a_int* iparam, a_int* ipntr, double* workd, double* workl, a_int lworkl, a_int* info);
-void pdneupd_c(MPI_Fint comm, a_int rvec, char const* howmny, a_int const* select, double* dr, double* di, double* z, a_int ldz, double sigmar, double sigmai, double * workev, char const* bmat, a_int n, char const* which, a_int nev, double tol, double* resid, a_int ncv, double* v, a_int ldv, a_int* iparam, a_int* ipntr, double* workd, double* workl, a_int lworkl, a_int* info);
+void pssaupd_c(MPI_Fint comm, a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, float tol, float* resid, a_int ncv, float* v, a_int ldv, a_int* iparam, a_int* ipntr, float* workd, float* workl, a_int lworkl, a_int* info);
+void psseupd_c(MPI_Fint comm, a_int rvec, char const* howmny, a_int const* select, float* d, float* z, a_int ldz, float sigma, char const* bmat, a_int n, char const* which, a_int nev, float tol, float* resid, a_int ncv, float* v, a_int ldv, a_int* iparam, a_int* ipntr, float* workd, float* workl, a_int lworkl, a_int* info);
+
 void pdsaupd_c(MPI_Fint comm, a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, double tol, double* resid, a_int ncv, double* v, a_int ldv, a_int* iparam, a_int* ipntr, double* workd, double* workl, a_int lworkl, a_int* info);
 void pdseupd_c(MPI_Fint comm, a_int rvec, char const* howmny, a_int const* select, double* d, double* z, a_int ldz, double sigma, char const* bmat, a_int n, char const* which, a_int nev, double tol, double* resid, a_int ncv, double* v, a_int ldv, a_int* iparam, a_int* ipntr, double* workd, double* workl, a_int lworkl, a_int* info);
+
 void psnaupd_c(MPI_Fint comm, a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, float tol, float* resid, a_int ncv, float* v, a_int ldv, a_int* iparam, a_int* ipntr, float* workd, float* workl, a_int lworkl, a_int* info);
 void psneupd_c(MPI_Fint comm, a_int rvec, char const* howmny, a_int const* select, float* dr, float* di, float* z, a_int ldz, float sigmar, float sigmai, float * workev, char const* bmat, a_int n, char const* which, a_int nev, float tol, float* resid, a_int ncv, float* v, a_int ldv, a_int* iparam, a_int* ipntr, float* workd, float* workl, a_int lworkl, a_int* info);
-void pssaupd_c(MPI_Fint comm, a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, float tol, float* resid, a_int ncv, float* v, a_int ldv, a_int* iparam, a_int* ipntr, float* workd, float* workl, a_int lworkl, a_int* info);
-void psseupd_c(MPI_Fint comm, a_int rvec, char const* howmny, a_int const* select, float* d, float* z, a_int ldz, float sigma, char const* bmat, a_int n, char const* which, a_int nev, float tol, float* resid, a_int ncv, float* v, a_int ldv, a_int* iparam, a_int* ipntr, float* workd, float* workl, a_int lworkl, a_int* info);
-void pznaupd_c(MPI_Fint comm, a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, double tol, double _Complex* resid, a_int ncv, double _Complex* v, a_int ldv, a_int* iparam, a_int* ipntr, double _Complex* workd, double _Complex* workl, a_int lworkl, double _Complex* rwork, a_int* info);
-void pzneupd_c(MPI_Fint comm, a_int rvec, char const* howmny, a_int const* select, double _Complex* d, double _Complex* z, a_int ldz, double _Complex sigma, double _Complex* workev, char const* bmat, a_int n, char const* which, a_int nev, double tol, double _Complex* resid, a_int ncv, double _Complex* v, a_int ldv, a_int* iparam, a_int* ipntr, double _Complex* workd, double _Complex* workl, a_int lworkl, double _Complex* rwork, a_int* info);
+
+void pdnaupd_c(MPI_Fint comm, a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, double tol, double* resid, a_int ncv, double* v, a_int ldv, a_int* iparam, a_int* ipntr, double* workd, double* workl, a_int lworkl, a_int* info);
+void pdneupd_c(MPI_Fint comm, a_int rvec, char const* howmny, a_int const* select, double* dr, double* di, double* z, a_int ldz, double sigmar, double sigmai, double * workev, char const* bmat, a_int n, char const* which, a_int nev, double tol, double* resid, a_int ncv, double* v, a_int ldv, a_int* iparam, a_int* ipntr, double* workd, double* workl, a_int lworkl, a_int* info);
+
+void pcnaupd_c(MPI_Fint comm, a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, float tol, a_fcomplex* resid, a_int ncv, a_fcomplex* v, a_int ldv, a_int* iparam, a_int* ipntr, a_fcomplex* workd, a_fcomplex* workl, a_int lworkl, float* rwork, a_int* info);
+void pcneupd_c(MPI_Fint comm, a_int rvec, char const* howmny, a_int const* select, a_fcomplex* d, a_fcomplex* z, a_int ldz, a_fcomplex sigma, a_fcomplex* workev, char const* bmat, a_int n, char const* which, a_int nev, float tol, a_fcomplex* resid, a_int ncv, a_fcomplex* v, a_int ldv, a_int* iparam, a_int* ipntr, a_fcomplex* workd, a_fcomplex* workl, a_int lworkl, float* rwork, a_int* info);
+
+void pznaupd_c(MPI_Fint comm, a_int* ido, char const* bmat, a_int n, char const* which, a_int nev, double tol, a_dcomplex* resid, a_int ncv, a_dcomplex* v, a_int ldv, a_int* iparam, a_int* ipntr, a_dcomplex* workd, a_dcomplex* workl, a_int lworkl, double* rwork, a_int* info);
+void pzneupd_c(MPI_Fint comm, a_int rvec, char const* howmny, a_int const* select, a_dcomplex* d, a_dcomplex* z, a_int ldz, a_dcomplex sigma, a_dcomplex* workev, char const* bmat, a_int n, char const* which, a_int nev, double tol, a_dcomplex* resid, a_int ncv, a_dcomplex* v, a_int ldv, a_int* iparam, a_int* ipntr, a_dcomplex* workd, a_dcomplex* workl, a_int lworkl, double* rwork, a_int* info);
 
 #ifdef  __cplusplus
 }
diff --git a/ICB/parpack.hpp b/ICB/parpack.hpp
index aa9360d..fe93a77 100644
--- a/ICB/parpack.hpp
+++ b/ICB/parpack.hpp
@@ -111,14 +111,14 @@ inline void naupd(MPI_Fint comm, a_int& ido, bmat const bmat_option, a_int n,
                   std::complex<float>* resid, a_int ncv, std::complex<float>* v,
                   a_int ldv, a_int* iparam, a_int* ipntr, std::complex<float>* workd,
                   std::complex<float>* workl, a_int lworkl,
-                  std::complex<float>* rwork, a_int& info) {
+                  float* rwork, a_int& info) {
   internal::pcnaupd_c(comm, &ido, internal::convert_to_char(bmat_option), n,
                       internal::convert_to_char(which_option), nev, tol,
-                      reinterpret_cast<_Complex float*>(resid), ncv,
-                      reinterpret_cast<_Complex float*>(v), ldv, iparam, ipntr,
-                      reinterpret_cast<_Complex float*>(workd),
-                      reinterpret_cast<_Complex float*>(workl), lworkl,
-                      reinterpret_cast<_Complex float*>(rwork), &info);
+                      reinterpret_cast<a_fcomplex*>(resid), ncv,
+                      reinterpret_cast<a_fcomplex*>(v), ldv, iparam, ipntr,
+                      reinterpret_cast<a_fcomplex*>(workd),
+                      reinterpret_cast<a_fcomplex*>(workl), lworkl,
+                      rwork, &info);
 }
 
 inline void neupd(MPI_Fint comm, a_int rvec, howmny const howmny_option,
@@ -129,22 +129,22 @@ inline void neupd(MPI_Fint comm, a_int rvec, howmny const howmny_option,
                   std::complex<float>* resid, a_int ncv, std::complex<float>* v,
                   a_int ldv, a_int* iparam, a_int* ipntr, std::complex<float>* workd,
                   std::complex<float>* workl, a_int lworkl,
-                  std::complex<float>* rwork, a_int& info)
+                  float* rwork, a_int& info)
 
 {
   std::complex<float> sigma2 = sigma;
   internal::pcneupd_c(comm, rvec, internal::convert_to_char(howmny_option),
-                      select, reinterpret_cast<_Complex float*>(d),
-                      reinterpret_cast<_Complex float*>(z), ldz,
-                      *reinterpret_cast<_Complex float*>(&sigma2),
-                      reinterpret_cast<_Complex float*>(workev),
+                      select, reinterpret_cast<a_fcomplex*>(d),
+                      reinterpret_cast<a_fcomplex*>(z), ldz,
+                      *reinterpret_cast<a_fcomplex*>(&sigma2),
+                      reinterpret_cast<a_fcomplex*>(workev),
                       internal::convert_to_char(bmat_option), n,
                       internal::convert_to_char(which_option), nev, tol,
-                      reinterpret_cast<_Complex float*>(resid), ncv,
-                      reinterpret_cast<_Complex float*>(v), ldv, iparam, ipntr,
-                      reinterpret_cast<_Complex float*>(workd),
-                      reinterpret_cast<_Complex float*>(workl), lworkl,
-                      reinterpret_cast<_Complex float*>(rwork), &info);
+                      reinterpret_cast<a_fcomplex*>(resid), ncv,
+                      reinterpret_cast<a_fcomplex*>(v), ldv, iparam, ipntr,
+                      reinterpret_cast<a_fcomplex*>(workd),
+                      reinterpret_cast<a_fcomplex*>(workl), lworkl,
+                      rwork, &info);
 }
 
 inline void naupd(MPI_Fint comm, a_int& ido, bmat const bmat_option, a_int n,
@@ -152,14 +152,14 @@ inline void naupd(MPI_Fint comm, a_int& ido, bmat const bmat_option, a_int n,
                   std::complex<double>* resid, a_int ncv, std::complex<double>* v,
                   a_int ldv, a_int* iparam, a_int* ipntr, std::complex<double>* workd,
                   std::complex<double>* workl, a_int lworkl,
-                  std::complex<double>* rwork, a_int& info) {
+                  double* rwork, a_int& info) {
   internal::pznaupd_c(comm, &ido, internal::convert_to_char(bmat_option), n,
                       internal::convert_to_char(which_option), nev, tol,
-                      reinterpret_cast<_Complex double*>(resid), ncv,
-                      reinterpret_cast<_Complex double*>(v), ldv, iparam, ipntr,
-                      reinterpret_cast<_Complex double*>(workd),
-                      reinterpret_cast<_Complex double*>(workl), lworkl,
-                      reinterpret_cast<_Complex double*>(rwork), &info);
+                      reinterpret_cast<a_dcomplex*>(resid), ncv,
+                      reinterpret_cast<a_dcomplex*>(v), ldv, iparam, ipntr,
+                      reinterpret_cast<a_dcomplex*>(workd),
+                      reinterpret_cast<a_dcomplex*>(workl), lworkl,
+                      rwork, &info);
 }
 
 inline void neupd(MPI_Fint comm, a_int rvec, howmny const howmny_option,
@@ -170,20 +170,20 @@ inline void neupd(MPI_Fint comm, a_int rvec, howmny const howmny_option,
                   std::complex<double>* resid, a_int ncv, std::complex<double>* v,
                   a_int ldv, a_int* iparam, a_int* ipntr, std::complex<double>* workd,
                   std::complex<double>* workl, a_int lworkl,
-                  std::complex<double>* rwork, a_int& info) {
+                  double* rwork, a_int& info) {
   std::complex<double> sigma2 = sigma;
   internal::pzneupd_c(comm, rvec, internal::convert_to_char(howmny_option),
-                      select, reinterpret_cast<_Complex double*>(d),
-                      reinterpret_cast<_Complex double*>(z), ldz,
-                      *reinterpret_cast<_Complex double*>(&sigma2),
-                      reinterpret_cast<_Complex double*>(workev),
+                      select, reinterpret_cast<a_dcomplex*>(d),
+                      reinterpret_cast<a_dcomplex*>(z), ldz,
+                      *reinterpret_cast<a_dcomplex*>(&sigma2),
+                      reinterpret_cast<a_dcomplex*>(workev),
                       internal::convert_to_char(bmat_option), n,
                       internal::convert_to_char(which_option), nev, tol,
-                      reinterpret_cast<_Complex double*>(resid), ncv,
-                      reinterpret_cast<_Complex double*>(v), ldv, iparam, ipntr,
-                      reinterpret_cast<_Complex double*>(workd),
-                      reinterpret_cast<_Complex double*>(workl), lworkl,
-                      reinterpret_cast<_Complex double*>(rwork), &info);
+                      reinterpret_cast<a_dcomplex*>(resid), ncv,
+                      reinterpret_cast<a_dcomplex*>(v), ldv, iparam, ipntr,
+                      reinterpret_cast<a_dcomplex*>(workd),
+                      reinterpret_cast<a_dcomplex*>(workl), lworkl,
+                      rwork, &info);
 }
 }  // namespace arpack
 #endif
diff --git a/ICB/stat_icb.F90 b/ICB/stat_icb.F90
index 62435f7..f057b4c 100644
--- a/ICB/stat_icb.F90
+++ b/ICB/stat_icb.F90
@@ -32,7 +32,7 @@ subroutine stat_c(  nopx_c,    nbx_c, nrorth_c, nitref_c, nrstrt_c,
                                       tnaupd_c, tnaup2_c, tnaitr_c, tneigh_c, tngets_c, tnapps_c, tnconv_c,&
                                       tcaupd_c, tcaup2_c, tcaitr_c, tceigh_c, tcgets_c, tcapps_c, tcconv_c,&
                                       tmvopx_c,  tmvbx_c, tgetv0_c, titref_c,  trvec_c
-  include 'stat.h'
+  include 'statF90.h'
     nopx_c =   nopx
      nbx_c =    nbx
   nrorth_c = nrorth
diff --git a/Makefile.am b/Makefile.am
index f71acd6..54a79d5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
 ACLOCAL_AMFLAGS = -I m4
 
-pkgincludedir = $(includedir)/arpack
-pkginclude_HEADERS = debug.h stat.h arpackdef.h
+pkgincludedir = $(includedir)/arpack-ng@ITF64SUFFIX@
+pkginclude_HEADERS = debug.h stat.h debugF90.h statF90.h arpackdef.h
 
 AM_DISTCHECK_CONFIGURE_FLAGS =
 if MPI
@@ -9,6 +9,7 @@ AM_DISTCHECK_CONFIGURE_FLAGS += --enable-mpi
 endif
 if ICB
 AM_DISTCHECK_CONFIGURE_FLAGS += --enable-icb
+pkginclude_HEADERS += arpackicb.h
 endif
 if ICBEXMM
 AM_DISTCHECK_CONFIGURE_FLAGS += --enable-icb-exmm
@@ -26,5 +27,7 @@ endif
 EXTRA_DIST = README.md PARPACK_CHANGES CHANGES DOCUMENTS VISUAL_STUDIO \
 detect_arpack_bug.m4 CMakeLists.txt
 
-cmakedir = $(libdir)/cmake/arpack-ng
-cmake_DATA = arpack-ng-config.cmake arpack-ng-config-version.cmake
+pkgconfig_DATA = arpack@LIBSUFFIX@@ITF64SUFFIX@.pc parpack@LIBSUFFIX@@ITF64SUFFIX@.pc arpackSolver@LIBSUFFIX@@ITF64SUFFIX@.pc
+
+# Due to the LIBSUFFIX/ITF64SUFFIX, configure doesn't automatically clean this file:
+DISTCLEANFILES = arpack@LIBSUFFIX@@ITF64SUFFIX@.pc parpack@LIBSUFFIX@@ITF64SUFFIX@.pc arpackSolver@LIBSUFFIX@@ITF64SUFFIX@.pc
diff --git a/PARPACK/EXAMPLES/BLACS/Makefile.am b/PARPACK/EXAMPLES/BLACS/Makefile.am
index b04ff6d..0c55ed6 100644
--- a/PARPACK/EXAMPLES/BLACS/Makefile.am
+++ b/PARPACK/EXAMPLES/BLACS/Makefile.am
@@ -1,4 +1,4 @@
-LDADD = $(top_builddir)/PARPACK/SRC/BLACS/libparpack$(LIBSUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
+LDADD = $(top_builddir)/PARPACK/SRC/BLACS/libparpack$(LIBSUFFIX)$(ITF64SUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
 
 SNDRV = psndrv1 psndrv3
 DNDRV = pdndrv1 pdndrv3
diff --git a/PARPACK/EXAMPLES/MPI/Makefile.am b/PARPACK/EXAMPLES/MPI/Makefile.am
index 66ccaf7..ecbd456 100644
--- a/PARPACK/EXAMPLES/MPI/Makefile.am
+++ b/PARPACK/EXAMPLES/MPI/Makefile.am
@@ -1,5 +1,5 @@
 F77 = $(MPIF77)
-LDADD = $(top_builddir)/PARPACK/SRC/MPI/libparpack$(LIBSUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
+LDADD = $(top_builddir)/PARPACK/SRC/MPI/libparpack$(LIBSUFFIX)$(ITF64SUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
 
 SNDRV = psndrv1 psndrv3
 DNDRV = pdndrv1 pdndrv3
diff --git a/PARPACK/SRC/BLACS/Makefile.am b/PARPACK/SRC/BLACS/Makefile.am
index ca804f1..39979af 100644
--- a/PARPACK/SRC/BLACS/Makefile.am
+++ b/PARPACK/SRC/BLACS/Makefile.am
@@ -14,10 +14,10 @@ ZSRC = pznaitr.f pznapps.f pznaup2.f pznaupd.f pzneigh.f pzneupd.f pzngets.f \
 
 EXTRA_DIST = debug.h stat.h
 
-lib_LTLIBRARIES = libparpack@LIBSUFFIX@.la
-libparpack@LIBSUFFIX@_la_SOURCES = $(SSRC) $(DSRC) $(CSRC) $(ZSRC)
-libparpack@LIBSUFFIX@_la_LIBADD = \
+lib_LTLIBRARIES = libparpack@LIBSUFFIX@@ITF64SUFFIX@.la
+libparpack@LIBSUFFIX@@ITF64SUFFIX@_la_SOURCES = $(SSRC) $(DSRC) $(CSRC) $(ZSRC)
+libparpack@LIBSUFFIX@@ITF64SUFFIX@_la_LIBADD = \
 	$(top_builddir)/PARPACK/UTIL/BLACS/libparpackutil.la \
-	$(top_builddir)/SRC/libarpack@LIBSUFFIX@.la \
+	$(top_builddir)/SRC/libarpack@LIBSUFFIX@@ITF64SUFFIX@.la \
 	$(LAPACK_LIBS) $(BLAS_LIBS)
-libparpack@LIBSUFFIX@_la_LDFLAGS = -no-undefined -version-info 3:0:1
+libparpack@LIBSUFFIX@@ITF64SUFFIX@_la_LDFLAGS = -no-undefined -version-info 3:0:1
diff --git a/PARPACK/SRC/BLACS/pcgetv0.f b/PARPACK/SRC/BLACS/pcgetv0.f
index 191d70f..e74fe56 100644
--- a/PARPACK/SRC/BLACS/pcgetv0.f
+++ b/PARPACK/SRC/BLACS/pcgetv0.f
@@ -197,8 +197,8 @@ c
       Real
      &           pscnorm2, slapy2
       Complex
-     &           cdotc
-      external   cdotc, pscnorm2, slapy2
+     &           ccdotc
+      external   ccdotc, pscnorm2, slapy2
 c
 c     %-----------------%
 c     | Data Statements |
@@ -335,7 +335,7 @@ c
 c
       first = .FALSE.
       if (bmat .eq. 'G') then
-          cnorm = cdotc (n, resid, 1, workd, 1)
+          cnorm = ccdotc (n, resid, 1, workd, 1)
           call cgsum2d( comm, 'All', ' ', 1, 1, cnorm, 1, -1, -1 )
           rnorm0 = sqrt(slapy2(real (cnorm),aimag(cnorm)))
       else if (bmat .eq. 'I') then
@@ -394,7 +394,7 @@ c
       end if
 c
       if (bmat .eq. 'G') then
-         cnorm = cdotc (n, resid, 1, workd, 1)
+         cnorm = ccdotc (n, resid, 1, workd, 1)
          call cgsum2d( comm, 'All', ' ', 1, 1, cnorm, 1, -1, -1 )
          rnorm = sqrt(slapy2(real (cnorm),aimag(cnorm)))
       else if (bmat .eq. 'I') then
diff --git a/PARPACK/SRC/BLACS/pcnaitr.f b/PARPACK/SRC/BLACS/pcnaitr.f
index 04fa1cb..3059481 100644
--- a/PARPACK/SRC/BLACS/pcnaitr.f
+++ b/PARPACK/SRC/BLACS/pcnaitr.f
@@ -303,10 +303,10 @@ c     | External Functions |
 c     %--------------------%
 c
       Complex
-     &           cdotc
+     &           ccdotc
       Real
      &           pslamch, pscnorm2, clanhs, slapy2
-      external   cdotc, pscnorm2, clanhs, pslamch, slapy2
+      external   ccdotc, pscnorm2, clanhs, pslamch, slapy2
 c
 c     %---------------------%
 c     | Intrinsic Functions |
@@ -573,7 +573,7 @@ c        | Compute the B-norm of OP*v_{j}.     |
 c        %-------------------------------------%
 c
          if (bmat .eq. 'G') then
-             cnorm = cdotc (n, resid, 1, workd(ipj), 1)
+             cnorm = ccdotc (n, resid, 1, workd(ipj), 1)
              call cgsum2d( comm, 'All', ' ', 1, 1, cnorm, 1, -1, -1 )
              wnorm = sqrt( slapy2(real(cnorm),aimag(cnorm)) )
          else if (bmat .eq. 'I') then
@@ -647,7 +647,7 @@ c        | Compute the B-norm of r_{j}. |
 c        %------------------------------%
 c
          if (bmat .eq. 'G') then
-            cnorm = cdotc (n, resid, 1, workd(ipj), 1)
+            cnorm = ccdotc (n, resid, 1, workd(ipj), 1)
             call cgsum2d( comm, 'All', ' ', 1, 1, cnorm, 1, -1, -1 )
             rnorm = sqrt( slapy2(real(cnorm),aimag(cnorm)) )
          else if (bmat .eq. 'I') then
@@ -749,7 +749,7 @@ c        | Compute the B-norm of the corrected residual r_{j}. |
 c        %-----------------------------------------------------%
 c
          if (bmat .eq. 'G') then
-             cnorm = cdotc (n, resid, 1, workd(ipj), 1)
+             cnorm = ccdotc (n, resid, 1, workd(ipj), 1)
              call cgsum2d( comm, 'All', ' ', 1, 1, cnorm, 1, -1, -1 )
              rnorm1 = sqrt( slapy2(real(cnorm),aimag(cnorm)) )
          else if (bmat .eq. 'I') then
diff --git a/PARPACK/SRC/BLACS/pcnaup2.f b/PARPACK/SRC/BLACS/pcnaup2.f
index 757b12c..bb57037 100644
--- a/PARPACK/SRC/BLACS/pcnaup2.f
+++ b/PARPACK/SRC/BLACS/pcnaup2.f
@@ -254,10 +254,10 @@ c     | External functions |
 c     %--------------------%
 c
       Complex
-     &           cdotc
+     &           ccdotc
       Real
      &           pscnorm2, pslamch, slapy2
-      external   cdotc, pscnorm2, pslamch, slapy2
+      external   ccdotc, pscnorm2, pslamch, slapy2
 c
 c     %---------------------%
 c     | Intrinsic Functions |
@@ -767,7 +767,7 @@ c
          end if
 c
          if (bmat .eq. 'G') then
-            cmpnorm = cdotc (n, resid, 1, workd, 1)
+            cmpnorm = ccdotc (n, resid, 1, workd, 1)
             call cgsum2d( comm, 'All', ' ', 1, 1, cmpnorm, 1, -1, -1 )
             rnorm = sqrt(slapy2(real(cmpnorm),aimag(cmpnorm)))
          else if (bmat .eq. 'I') then
diff --git a/PARPACK/SRC/BLACS/pcneupd.f b/PARPACK/SRC/BLACS/pcneupd.f
index da4a9ec..ad2a080 100644
--- a/PARPACK/SRC/BLACS/pcneupd.f
+++ b/PARPACK/SRC/BLACS/pcneupd.f
@@ -340,8 +340,8 @@ c
       external   scnrm2,pslamch,slapy2
 c
       Complex
-     &           cdotc
-      external   cdotc
+     &           ccdotc
+      external   ccdotc
 c
 c     %---------------------%
 c     | Intrinsic Functions |
@@ -743,7 +743,7 @@ c                 | upper triangular, thus the length of the |
 c                 | inner product can be set to j.           |
 c                 %------------------------------------------%
 c
-                  workev(j) = cdotc(j, workl(ihbds), 1,
+                  workev(j) = ccdotc(j, workl(ihbds), 1,
      &                        workl(invsub+(j-1)*ldq), 1)
  40         continue
 c
diff --git a/PARPACK/SRC/BLACS/pzgetv0.f b/PARPACK/SRC/BLACS/pzgetv0.f
index c1d173f..17354c1 100644
--- a/PARPACK/SRC/BLACS/pzgetv0.f
+++ b/PARPACK/SRC/BLACS/pzgetv0.f
@@ -197,8 +197,8 @@ c
       Double precision
      &           pdznorm2 , dlapy2
       Complex*16
-     &           zdotc
-      external   zdotc , pdznorm2 , dlapy2
+     &           zzdotc
+      external   zzdotc , pdznorm2 , dlapy2
 c
 c     %-----------------%
 c     | Data Statements |
@@ -335,7 +335,7 @@ c
 c
       first = .FALSE.
       if (bmat .eq. 'G') then
-          cnorm = zdotc  (n, resid, 1, workd, 1)
+          cnorm = zzdotc  (n, resid, 1, workd, 1)
           call zgsum2d ( comm, 'All', ' ', 1, 1, cnorm, 1, -1, -1 )
           rnorm0 = sqrt(dlapy2 (dble (cnorm),dimag (cnorm)))
       else if (bmat .eq. 'I') then
@@ -394,7 +394,7 @@ c
       end if
 c
       if (bmat .eq. 'G') then
-         cnorm = zdotc  (n, resid, 1, workd, 1)
+         cnorm = zzdotc  (n, resid, 1, workd, 1)
          call zgsum2d ( comm, 'All', ' ', 1, 1, cnorm, 1, -1, -1 )
          rnorm = sqrt(dlapy2 (dble (cnorm),dimag (cnorm)))
       else if (bmat .eq. 'I') then
diff --git a/PARPACK/SRC/BLACS/pznaitr.f b/PARPACK/SRC/BLACS/pznaitr.f
index 92db7fe..cd1ba01 100644
--- a/PARPACK/SRC/BLACS/pznaitr.f
+++ b/PARPACK/SRC/BLACS/pznaitr.f
@@ -303,10 +303,10 @@ c     | External Functions |
 c     %--------------------%
 c
       Complex*16
-     &           zdotc
+     &           zzdotc
       Double precision
      &           pdlamch, pdznorm2, zlanhs, dlapy2
-      external   zdotc, pdznorm2, zlanhs, pdlamch, dlapy2
+      external   zzdotc, pdznorm2, zlanhs, pdlamch, dlapy2
 c
 c     %---------------------%
 c     | Intrinsic Functions |
@@ -573,7 +573,7 @@ c        | Compute the B-norm of OP*v_{j}.     |
 c        %-------------------------------------%
 c
          if (bmat .eq. 'G') then
-             cnorm = zdotc (n, resid, 1, workd(ipj), 1)
+             cnorm = zzdotc (n, resid, 1, workd(ipj), 1)
              call zgsum2d( comm, 'All', ' ', 1, 1, cnorm, 1, -1, -1 )
              wnorm = sqrt( dlapy2(dble(cnorm),dimag(cnorm)) )
          else if (bmat .eq. 'I') then
@@ -647,7 +647,7 @@ c        | Compute the B-norm of r_{j}. |
 c        %------------------------------%
 c
          if (bmat .eq. 'G') then
-            cnorm = zdotc (n, resid, 1, workd(ipj), 1)
+            cnorm = zzdotc (n, resid, 1, workd(ipj), 1)
             call zgsum2d( comm, 'All', ' ', 1, 1, cnorm, 1, -1, -1 )
             rnorm = sqrt( dlapy2(dble(cnorm),dimag(cnorm)) )
          else if (bmat .eq. 'I') then
@@ -749,7 +749,7 @@ c        | Compute the B-norm of the corrected residual r_{j}. |
 c        %-----------------------------------------------------%
 c
          if (bmat .eq. 'G') then
-             cnorm = zdotc (n, resid, 1, workd(ipj), 1)
+             cnorm = zzdotc (n, resid, 1, workd(ipj), 1)
              call zgsum2d( comm, 'All', ' ', 1, 1, cnorm, 1, -1, -1 )
              rnorm1 = sqrt( dlapy2(dble(cnorm),dimag(cnorm)) )
          else if (bmat .eq. 'I') then
diff --git a/PARPACK/SRC/BLACS/pznaup2.f b/PARPACK/SRC/BLACS/pznaup2.f
index 1610a58..8fff22f 100644
--- a/PARPACK/SRC/BLACS/pznaup2.f
+++ b/PARPACK/SRC/BLACS/pznaup2.f
@@ -254,10 +254,10 @@ c     | External functions |
 c     %--------------------%
 c
       Complex*16
-     &           zdotc
+     &           zzdotc
       Double precision
      &           pdznorm2, pdlamch, dlapy2
-      external   zdotc, pdznorm2, pdlamch, dlapy2
+      external   zzdotc, pdznorm2, pdlamch, dlapy2
 c
 c     %---------------------%
 c     | Intrinsic Functions |
@@ -767,7 +767,7 @@ c
          end if
 c
          if (bmat .eq. 'G') then
-            cmpnorm = zdotc (n, resid, 1, workd, 1)
+            cmpnorm = zzdotc (n, resid, 1, workd, 1)
             call zgsum2d( comm, 'All', ' ', 1, 1, cmpnorm, 1, -1, -1 )
             rnorm = sqrt(dlapy2(dble(cmpnorm),dimag(cmpnorm)))
          else if (bmat .eq. 'I') then
diff --git a/PARPACK/SRC/BLACS/pzneupd.f b/PARPACK/SRC/BLACS/pzneupd.f
index c2f508f..af76f06 100644
--- a/PARPACK/SRC/BLACS/pzneupd.f
+++ b/PARPACK/SRC/BLACS/pzneupd.f
@@ -340,8 +340,8 @@ c
       external   dznrm2,pdlamch,dlapy2
 c
       Complex*16
-     &           zdotc
-      external   zdotc
+     &           zzdotc
+      external   zzdotc
 c
 c     %---------------------%
 c     | Intrinsic Functions |
@@ -743,7 +743,7 @@ c                 | upper triangular, thus the length of the |
 c                 | inner product can be set to j.           |
 c                 %------------------------------------------%
 c
-                  workev(j) = zdotc(j, workl(ihbds), 1,
+                  workev(j) = zzdotc(j, workl(ihbds), 1,
      &                        workl(invsub+(j-1)*ldq), 1)
  40         continue
 c
diff --git a/PARPACK/SRC/MPI/Makefile.am b/PARPACK/SRC/MPI/Makefile.am
index 72b0a85..b574a82 100644
--- a/PARPACK/SRC/MPI/Makefile.am
+++ b/PARPACK/SRC/MPI/Makefile.am
@@ -28,26 +28,21 @@ endif
 
 EXTRA_DIST = debug.h stat.h pcontext.h
 
-noinst_LTLIBRARIES = libparpack@LIBSUFFIX@_noopt.la
-libparpack@LIBSUFFIX@_noopt_la_SOURCES = pslamch10.f pdlamch10.f
-libparpack@LIBSUFFIX@_noopt_la_FFLAGS = -O0
-
-lib_LTLIBRARIES = libparpack@LIBSUFFIX@.la
-libparpack@LIBSUFFIX@_la_SOURCES = $(PSRC) $(SSRC) $(DSRC) $(CSRC) $(ZSRC)
-libparpack@LIBSUFFIX@_la_SOURCES += $(top_builddir)/dbgini.f
-libparpack@LIBSUFFIX@_la_SOURCES += $(top_builddir)/staini.f
-libparpack@LIBSUFFIX@_la_FFLAGS = $(FFLAGS_SAV)
-libparpack@LIBSUFFIX@_la_LIBADD = libparpack@LIBSUFFIX@_noopt.la \
+noinst_LTLIBRARIES = libparpack@LIBSUFFIX@@ITF64SUFFIX@_noopt.la
+libparpack@LIBSUFFIX@@ITF64SUFFIX@_noopt_la_SOURCES = pslamch10.f pdlamch10.f
+libparpack@LIBSUFFIX@@ITF64SUFFIX@_noopt_la_FFLAGS = -O0
+
+lib_LTLIBRARIES = libparpack@LIBSUFFIX@@ITF64SUFFIX@.la
+libparpack@LIBSUFFIX@@ITF64SUFFIX@_la_SOURCES = $(PSRC) $(SSRC) $(DSRC) $(CSRC) $(ZSRC)
+libparpack@LIBSUFFIX@@ITF64SUFFIX@_la_SOURCES += $(top_builddir)/dbgini.f
+libparpack@LIBSUFFIX@@ITF64SUFFIX@_la_SOURCES += $(top_builddir)/staini.f
+libparpack@LIBSUFFIX@@ITF64SUFFIX@_la_FFLAGS = $(FFLAGS_SAV)
+libparpack@LIBSUFFIX@@ITF64SUFFIX@_la_LIBADD = libparpack@LIBSUFFIX@@ITF64SUFFIX@_noopt.la \
 	$(top_builddir)/PARPACK/UTIL/MPI/libparpackutil.la \
-	$(top_builddir)/SRC/libarpack@LIBSUFFIX@.la \
+	$(top_builddir)/SRC/libarpack@LIBSUFFIX@@ITF64SUFFIX@.la \
 	$(LAPACK_LIBS) $(BLAS_LIBS) $(MPI_Fortran_LIBS)
-libparpack@LIBSUFFIX@_la_LDFLAGS = -no-undefined -version-info 3:0:1
+libparpack@LIBSUFFIX@@ITF64SUFFIX@_la_LDFLAGS = -no-undefined -version-info 3:0:1
 if ICB
-libparpack@LIBSUFFIX@_la_LIBADD += $(top_builddir)/ICB/libdbgicb.la $(top_builddir)/ICB/libstaicb.la
-libparpack@LIBSUFFIX@_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)
+libparpack@LIBSUFFIX@@ITF64SUFFIX@_la_LIBADD += $(top_builddir)/ICB/libdbgicb.la $(top_builddir)/ICB/libstaicb.la
+libparpack@LIBSUFFIX@@ITF64SUFFIX@_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)
 endif
-
-pkgconfig_DATA = parpack@LIBSUFFIX@.pc
-
-# Due to the LIBSUFFIX, configure doesn't automatically clean this file:
-DISTCLEANFILES = parpack@LIBSUFFIX@.pc
diff --git a/PARPACK/SRC/MPI/icbpcn.F90 b/PARPACK/SRC/MPI/icbpcn.F90
index 8bbaf0e..cc175ec 100644
--- a/PARPACK/SRC/MPI/icbpcn.F90
+++ b/PARPACK/SRC/MPI/icbpcn.F90
@@ -4,9 +4,16 @@ subroutine pcnaupd_c(comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,&
                      iparam, ipntr, workd, workl, lworkl, rwork, info)       &
                      bind(c, name="pcnaupd_c")
   use :: iso_c_binding
+#ifdef HAVE_MPI_ICB
+  use :: mpi_f08
+#endif
   implicit none
 #include "arpackicb.h"
+#ifdef HAVE_MPI_ICB
+  type(MPI_Comm),               value,              intent(in)    :: comm
+#else
   integer(kind=i_int),          value,              intent(in)    :: comm
+#endif
   integer(kind=i_int),                              intent(inout) :: ido
   character(kind=c_char),                           intent(in)    :: bmat
   integer(kind=i_int),          value,              intent(in)    :: n
@@ -22,7 +29,7 @@ subroutine pcnaupd_c(comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,&
   complex(kind=c_float_complex),dimension(3*n),     intent(out)   :: workd
   complex(kind=c_float_complex),dimension(lworkl),  intent(out)   :: workl
   integer(kind=i_int),          value,              intent(in)    :: lworkl
-  complex(kind=c_float_complex),dimension(ncv),     intent(out)   :: rwork
+  real(kind=c_float),           dimension(ncv),     intent(out)   :: rwork
   integer(kind=i_int),                              intent(inout) :: info
 
   character(len=2):: w
@@ -41,9 +48,16 @@ subroutine pcneupd_c(comm, rvec, howmny, select, d, z, ldz, sigma, workev,&
                      iparam, ipntr, workd, workl, lworkl, rwork, info)    &
                      bind(c, name="pcneupd_c")
   use :: iso_c_binding
+#ifdef HAVE_MPI_ICB
+  use :: mpi_f08
+#endif
   implicit none
 #include "arpackicb.h"
+#ifdef HAVE_MPI_ICB
+  type(MPI_Comm),               value,              intent(in)    :: comm
+#else
   integer(kind=i_int),          value,              intent(in)    :: comm
+#endif
   integer(kind=i_int),          value,              intent(in)    :: rvec
   character(kind=c_char),                           intent(in)    :: howmny
   integer(kind=i_int),          dimension(ncv),     intent(in)    :: select
@@ -66,7 +80,7 @@ subroutine pcneupd_c(comm, rvec, howmny, select, d, z, ldz, sigma, workev,&
   complex(kind=c_float_complex),dimension(3*n),     intent(out)   :: workd
   complex(kind=c_float_complex),dimension(lworkl),  intent(out)   :: workl
   integer(kind=i_int),          value,              intent(in)    :: lworkl
-  complex(kind=c_float_complex),dimension(ncv),     intent(out)   :: rwork
+  real(kind=c_float),           dimension(ncv),     intent(out)   :: rwork
   integer(kind=i_int),                              intent(inout) :: info
 
   ! convert parameters if needed.
diff --git a/PARPACK/SRC/MPI/icbpdn.F90 b/PARPACK/SRC/MPI/icbpdn.F90
index 1828e49..21a03cd 100644
--- a/PARPACK/SRC/MPI/icbpdn.F90
+++ b/PARPACK/SRC/MPI/icbpdn.F90
@@ -4,9 +4,16 @@ subroutine pdnaupd_c(comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,&
                      iparam, ipntr, workd, workl, lworkl, info)              &
                      bind(c, name="pdnaupd_c")
   use :: iso_c_binding
+#ifdef HAVE_MPI_ICB
+  use :: mpi_f08
+#endif
   implicit none
 #include "arpackicb.h"
+#ifdef HAVE_MPI_ICB
+  type(MPI_Comm),         value,               intent(in)    :: comm
+#else
   integer(kind=i_int),    value,               intent(in)    :: comm
+#endif
   integer(kind=i_int),                         intent(inout) :: ido
   character(kind=c_char),                      intent(in)    :: bmat
   integer(kind=i_int),    value,               intent(in)    :: n
@@ -41,9 +48,16 @@ subroutine pdneupd_c(comm, rvec, howmny, select,                  &
                      iparam, ipntr, workd, workl, lworkl, info)   &
                      bind(c, name="pdneupd_c")
   use :: iso_c_binding
+#ifdef HAVE_MPI_ICB
+  use :: mpi_f08
+#endif
   implicit none
 #include "arpackicb.h"
+#ifdef HAVE_MPI_ICB
+  type(MPI_Comm),         value,               intent(in)    :: comm
+#else
   integer(kind=i_int),    value,               intent(in)    :: comm
+#endif
   integer(kind=i_int),    value,               intent(in)    :: rvec
   character(kind=c_char),                      intent(in)    :: howmny
   integer(kind=i_int),    dimension(ncv),      intent(in)    :: select
diff --git a/PARPACK/SRC/MPI/icbpds.F90 b/PARPACK/SRC/MPI/icbpds.F90
index 78fe202..f0eeaaf 100644
--- a/PARPACK/SRC/MPI/icbpds.F90
+++ b/PARPACK/SRC/MPI/icbpds.F90
@@ -4,9 +4,16 @@ subroutine pdsaupd_c(comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,&
                      iparam, ipntr, workd, workl, lworkl, info)              &
                      bind(c, name="pdsaupd_c")
   use :: iso_c_binding
+#ifdef HAVE_MPI_ICB
+  use :: mpi_f08
+#endif
   implicit none
 #include "arpackicb.h"
+#ifdef HAVE_MPI_ICB
+  type(MPI_Comm),         value,               intent(in)    :: comm
+#else
   integer(kind=i_int),    value,               intent(in)    :: comm
+#endif
   integer(kind=i_int),                         intent(inout) :: ido
   character(kind=c_char),                      intent(in)    :: bmat
   integer(kind=i_int),    value,               intent(in)    :: n
@@ -40,9 +47,16 @@ subroutine pdseupd_c(comm, rvec, howmny, select, d, z, ldz, sigma,&
                      iparam, ipntr, workd, workl, lworkl, info)   &
                      bind(c, name="pdseupd_c")
   use :: iso_c_binding
+#ifdef HAVE_MPI_ICB
+  use :: mpi_f08
+#endif
   implicit none
 #include "arpackicb.h"
+#ifdef HAVE_MPI_ICB
+  type(MPI_Comm),         value,               intent(in)    :: comm
+#else
   integer(kind=i_int),    value,               intent(in)    :: comm
+#endif
   integer(kind=i_int),    value,               intent(in)    :: rvec
   character(kind=c_char),                      intent(in)    :: howmny
   integer(kind=i_int),    dimension(ncv),      intent(in)    :: select
diff --git a/PARPACK/SRC/MPI/icbpsn.F90 b/PARPACK/SRC/MPI/icbpsn.F90
index 5ca0c89..3effc01 100644
--- a/PARPACK/SRC/MPI/icbpsn.F90
+++ b/PARPACK/SRC/MPI/icbpsn.F90
@@ -4,9 +4,16 @@ subroutine psnaupd_c(comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,&
                      iparam, ipntr, workd, workl, lworkl, info)              &
                      bind(c, name="psnaupd_c")
   use :: iso_c_binding
+#ifdef HAVE_MPI_ICB
+  use :: mpi_f08
+#endif
   implicit none
 #include "arpackicb.h"
+#ifdef HAVE_MPI_ICB
+  type(MPI_Comm),         value,               intent(in)    :: comm
+#else
   integer(kind=i_int),    value,               intent(in)    :: comm
+#endif
   integer(kind=i_int),                         intent(inout) :: ido
   character(kind=c_char),                      intent(in)    :: bmat
   integer(kind=i_int),    value,               intent(in)    :: n
@@ -41,9 +48,16 @@ subroutine psneupd_c(comm, rvec, howmny, select,                  &
                      iparam, ipntr, workd, workl, lworkl, info)   &
                      bind(c, name="psneupd_c")
   use :: iso_c_binding
+#ifdef HAVE_MPI_ICB
+  use :: mpi_f08
+#endif
   implicit none
 #include "arpackicb.h"
+#ifdef HAVE_MPI_ICB
+  type(MPI_Comm),         value,               intent(in)    :: comm
+#else
   integer(kind=i_int),    value,               intent(in)    :: comm
+#endif
   integer(kind=i_int),    value,               intent(in)    :: rvec
   character(kind=c_char),                      intent(in)    :: howmny
   integer(kind=i_int),    dimension(ncv),      intent(in)    :: select
diff --git a/PARPACK/SRC/MPI/icbpss.F90 b/PARPACK/SRC/MPI/icbpss.F90
index ae2b2aa..73a7e4a 100644
--- a/PARPACK/SRC/MPI/icbpss.F90
+++ b/PARPACK/SRC/MPI/icbpss.F90
@@ -4,9 +4,16 @@ subroutine pssaupd_c(comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,&
                      iparam, ipntr, workd, workl, lworkl, info)              &
                      bind(c, name="pssaupd_c")
   use :: iso_c_binding
+#ifdef HAVE_MPI_ICB
+  use :: mpi_f08
+#endif
   implicit none
 #include "arpackicb.h"
+#ifdef HAVE_MPI_ICB
+  type(MPI_Comm),         value,               intent(in)    :: comm
+#else
   integer(kind=i_int),    value,               intent(in)    :: comm
+#endif
   integer(kind=i_int),                         intent(inout) :: ido
   character(kind=c_char),                      intent(in)    :: bmat
   integer(kind=i_int),    value,               intent(in)    :: n
@@ -40,9 +47,16 @@ subroutine psseupd_c(comm, rvec, howmny, select, d, z, ldz, sigma,&
                      iparam, ipntr, workd, workl, lworkl, info)   &
                      bind(c, name="psseupd_c")
   use :: iso_c_binding
+#ifdef HAVE_MPI_ICB
+  use :: mpi_f08
+#endif
   implicit none
 #include "arpackicb.h"
+#ifdef HAVE_MPI_ICB
+  type(MPI_Comm),         value,               intent(in)    :: comm
+#else
   integer(kind=i_int),    value,               intent(in)    :: comm
+#endif
   integer(kind=i_int),    value,               intent(in)    :: rvec
   character(kind=c_char),                      intent(in)    :: howmny
   integer(kind=i_int),    dimension(ncv),      intent(in)    :: select
diff --git a/PARPACK/SRC/MPI/icbpzn.F90 b/PARPACK/SRC/MPI/icbpzn.F90
index 2c8cf61..c2f81a6 100644
--- a/PARPACK/SRC/MPI/icbpzn.F90
+++ b/PARPACK/SRC/MPI/icbpzn.F90
@@ -4,9 +4,16 @@ subroutine pznaupd_c(comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,&
                      iparam, ipntr, workd, workl, lworkl, rwork, info)       &
                      bind(c, name="pznaupd_c")
   use :: iso_c_binding
+#ifdef HAVE_MPI_ICB
+  use :: mpi_f08
+#endif
   implicit none
 #include "arpackicb.h"
+#ifdef HAVE_MPI_ICB
+  type(MPI_Comm),                   value,              intent(in)    :: comm
+#else
   integer(kind=i_int),              value,              intent(in)    :: comm
+#endif
   integer(kind=i_int),                                  intent(inout) :: ido
   character(kind=c_char),                               intent(in)    :: bmat
   integer(kind=i_int),              value,              intent(in)    :: n
@@ -22,7 +29,7 @@ subroutine pznaupd_c(comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,&
   complex(kind=c_double_complex),   dimension(3*n),     intent(out)   :: workd
   complex(kind=c_double_complex),   dimension(lworkl),  intent(out)   :: workl
   integer(kind=i_int),              value,              intent(in)    :: lworkl
-  complex(kind=c_double_complex),   dimension(ncv),     intent(out)   :: rwork
+  real(kind=c_double),              dimension(ncv),     intent(out)   :: rwork
   integer(kind=i_int),                                  intent(inout) :: info
   
   character(len=2):: w
@@ -41,9 +48,16 @@ subroutine pzneupd_c(comm, rvec, howmny, select, d, z, ldz, sigma, workev,&
                      iparam, ipntr, workd, workl, lworkl, rwork, info)    &
                      bind(c, name="pzneupd_c")
   use :: iso_c_binding
+#ifdef HAVE_MPI_ICB
+  use :: mpi_f08
+#endif
   implicit none
 #include "arpackicb.h"
+#ifdef HAVE_MPI_ICB
+  type(MPI_Comm),                   value,              intent(in)    :: comm
+#else
   integer(kind=i_int),              value,              intent(in)    :: comm
+#endif
   integer(kind=i_int),              value,              intent(in)    :: rvec
   character(kind=c_char),                               intent(in)    :: howmny
   integer(kind=i_int),              dimension(ncv),     intent(in)    :: select
@@ -66,7 +80,7 @@ subroutine pzneupd_c(comm, rvec, howmny, select, d, z, ldz, sigma, workev,&
   complex(kind=c_double_complex),   dimension(3*n),     intent(out)   :: workd
   complex(kind=c_double_complex),   dimension(lworkl),  intent(out)   :: workl
   integer(kind=i_int),              value,              intent(in)    :: lworkl
-  complex(kind=c_double_complex),   dimension(ncv),     intent(out)   :: rwork
+  real(kind=c_double),              dimension(ncv),     intent(out)   :: rwork
   integer(kind=i_int),                                  intent(inout) :: info
 
   ! convert parameters if needed.
diff --git a/PARPACK/SRC/MPI/pcgetv0.f b/PARPACK/SRC/MPI/pcgetv0.f
index 72677a5..59e3d16 100644
--- a/PARPACK/SRC/MPI/pcgetv0.f
+++ b/PARPACK/SRC/MPI/pcgetv0.f
@@ -176,13 +176,13 @@ c     %------------------------%
 c     | Local Scalars & Arrays |
 c     %------------------------%
 c
-      logical    first, inits, orth
+      logical    first, orth
       integer    idist, iseed(4), iter, msglvl, jj, myid, igen
       Real
      &           rnorm0
       Complex
      &           cnorm, cnorm2
-      save       first, iseed, inits, iter, msglvl, orth, rnorm0
+      save       first, iseed, iter, msglvl, orth, rnorm0
 c
       Complex
      &           cnorm_buf, buf2(1)
@@ -200,14 +200,8 @@ c
       Real
      &           pscnorm2, slapy2
       Complex
-     &           cdotc
-      external   cdotc, pscnorm2, slapy2
-c
-c     %-----------------%
-c     | Data Statements |
-c     %-----------------%
-c
-      data       inits /.true./
+     &           ccdotc
+      external   ccdotc, pscnorm2, slapy2
 c
 c     %-----------------------%
 c     | Executable Statements |
@@ -219,30 +213,26 @@ c     | Initialize the seed of the LAPACK |
 c     | random number generator           |
 c     %-----------------------------------%
 c
-      if (inits) then
-c
-c        %-----------------------------------%
-c        | Generate a seed on each processor |
-c        | using process id (myid).          |
-c        | Note: the seed must be between 1  |
-c        | and 4095.  iseed(4) must be odd.  |
-c        %-----------------------------------%
-c
-         call MPI_COMM_RANK(comm, myid, ierr)
-         igen = 1000 + 2*myid + 1
-         if (igen .gt. 4095) then
-            write(0,*) 'Error in p_getv0: seed exceeds 4095!'
-         end if
 c
-         iseed(1) = igen/1000
-         igen     = mod(igen,1000)
-         iseed(2) = igen/100
-         igen     = mod(igen,100)
-         iseed(3) = igen/10
-         iseed(4) = mod(igen,10)
+c     %-----------------------------------%
+c     | Generate a seed on each processor |
+c     | using process id (myid).          |
+c     | Note: the seed must be between 1  |
+c     | and 4095.  iseed(4) must be odd.  |
+c     %-----------------------------------%
 c
-         inits = .false.
+      call MPI_COMM_RANK(comm, myid, ierr)
+      igen = 1000 + 2*myid + 1
+      if (igen .gt. 4095) then
+         write(0,*) 'Error in p_getv0: seed exceeds 4095!'
       end if
+c
+      iseed(1) = igen/1000
+      igen     = mod(igen,1000)
+      iseed(2) = igen/100
+      igen     = mod(igen,100)
+      iseed(3) = igen/10
+      iseed(4) = 7
 c
       if (ido .eq.  0) then
 c
@@ -331,7 +321,7 @@ c
 c
       first = .FALSE.
       if (bmat .eq. 'G') then
-          cnorm_buf = cdotc (n, resid, 1, workd, 1)
+          cnorm_buf = ccdotc (n, resid, 1, workd, 1)
           call MPI_ALLREDUCE( [cnorm_buf], buf2, 1,
      &          MPI_COMPLEX, MPI_SUM, comm, ierr )
           cnorm = buf2(1)
@@ -393,7 +383,7 @@ c
       end if
 c
       if (bmat .eq. 'G') then
-         cnorm_buf = cdotc (n, resid, 1, workd, 1)
+         cnorm_buf = ccdotc (n, resid, 1, workd, 1)
          call MPI_ALLREDUCE( [cnorm_buf], buf2, 1,
      &            MPI_COMPLEX, MPI_SUM, comm, ierr )
          cnorm = buf2(1)
diff --git a/PARPACK/SRC/MPI/pcnaitr.f b/PARPACK/SRC/MPI/pcnaitr.f
index fe246ea..6e3cd98 100644
--- a/PARPACK/SRC/MPI/pcnaitr.f
+++ b/PARPACK/SRC/MPI/pcnaitr.f
@@ -307,10 +307,10 @@ c     | External Functions |
 c     %--------------------%
 c
       Complex
-     &           cdotc
+     &           ccdotc
       Real
      &           pslamch10, pscnorm2, clanhs, slapy2
-      external   cdotc, pscnorm2, clanhs, pslamch10, slapy2
+      external   ccdotc, pscnorm2, clanhs, pslamch10, slapy2
 c
 c     %---------------------%
 c     | Intrinsic Functions |
@@ -576,7 +576,7 @@ c        | Compute the B-norm of OP*v_{j}.     |
 c        %-------------------------------------%
 c
          if (bmat .eq. 'G') then
-             cnorm_buf = cdotc (n, resid, 1, workd(ipj), 1)
+             cnorm_buf = ccdotc (n, resid, 1, workd(ipj), 1)
             call MPI_ALLREDUCE( [cnorm_buf], buf2, 1,
      &           MPI_COMPLEX, MPI_SUM, comm, ierr )
              cnorm = buf2(1)
@@ -653,7 +653,7 @@ c        | Compute the B-norm of r_{j}. |
 c        %------------------------------%
 c
          if (bmat .eq. 'G') then
-            cnorm_buf = cdotc (n, resid, 1, workd(ipj), 1)
+            cnorm_buf = ccdotc (n, resid, 1, workd(ipj), 1)
             call MPI_ALLREDUCE( [cnorm_buf], buf2, 1,
      &           MPI_COMPLEX, MPI_SUM, comm, ierr )
             cnorm = buf2(1)
@@ -758,7 +758,7 @@ c        | Compute the B-norm of the corrected residual r_{j}. |
 c        %-----------------------------------------------------%
 c
          if (bmat .eq. 'G') then
-             cnorm_buf = cdotc (n, resid, 1, workd(ipj), 1)
+             cnorm_buf = ccdotc (n, resid, 1, workd(ipj), 1)
             call MPI_ALLREDUCE( [cnorm_buf], buf2, 1,
      &           MPI_COMPLEX, MPI_SUM, comm, ierr )
              cnorm = buf2(1)
diff --git a/PARPACK/SRC/MPI/pcnaup2.f b/PARPACK/SRC/MPI/pcnaup2.f
index 4b0d6ce..acff483 100644
--- a/PARPACK/SRC/MPI/pcnaup2.f
+++ b/PARPACK/SRC/MPI/pcnaup2.f
@@ -257,10 +257,10 @@ c     | External functions |
 c     %--------------------%
 c
       Complex
-     &           cdotc
+     &           ccdotc
       Real
      &           pscnorm2, pslamch10, slapy2
-      external   cdotc, pscnorm2, pslamch10, slapy2
+      external   ccdotc, pscnorm2, pslamch10, slapy2
 c
 c     %---------------------%
 c     | Intrinsic Functions |
@@ -770,7 +770,7 @@ c
          end if
 c
          if (bmat .eq. 'G') then
-            cmpnorm_buf = cdotc (n, resid, 1, workd, 1)
+            cmpnorm_buf = ccdotc (n, resid, 1, workd, 1)
             call MPI_ALLREDUCE( [cmpnorm_buf], buf2, 1,
      &               MPI_COMPLEX, MPI_SUM, comm, ierr )
             cmpnorm = buf2(1)
diff --git a/PARPACK/SRC/MPI/pcnaupd.f b/PARPACK/SRC/MPI/pcnaupd.f
index 0bd6eb6..2ceab52 100644
--- a/PARPACK/SRC/MPI/pcnaupd.f
+++ b/PARPACK/SRC/MPI/pcnaupd.f
@@ -54,11 +54,11 @@ c  COMM    MPI  Communicator for the processor grid.  (INPUT)
 c
 c  IDO     Integer.  (INPUT/OUTPUT)
 c          Reverse communication flag.  IDO must be zero on the first
-c          call to pcnaupd.  IDO will be set internally to
+c          call to pcnaupd. IDO will be set internally to
 c          indicate the type of operation to be performed.  Control is
 c          then given back to the calling routine which has the
 c          responsibility to carry out the requested operation and call
-c          pcnaupd with the result.  The operand is given in
+c          pcnaupd with the result. The operand is given in
 c          WORKD(IPNTR(1)), the result must be put in WORKD(IPNTR(2)).
 c          -------------------------------------------------------------
 c          IDO =  0: first call to the reverse communication interface
@@ -312,7 +312,7 @@ c\Data Distribution Note:
 c
 c  Fortran-D syntax:
 c  ================
-c  Complex  resid(n), v(ldv,ncv), workd(3*n), workl(lworkl)
+c  Complex    resid(n), v(ldv,ncv), workd(3*n), workl(lworkl)
 c  decompose  d1(n), d2(n,ncv)
 c  align      resid(i) with d1(i)
 c  align      v(i,j)   with d2(i,j)
@@ -324,7 +324,7 @@ c  replicated workl(lworkl)
 c
 c  Cray MPP syntax:
 c  ===============
-c  Complex  resid(n), v(ldv,ncv), workd(n,3), workl(lworkl)
+c  Complex    resid(n), v(ldv,ncv), workd(n,3), workl(lworkl)
 c  shared     resid(block), v(block,:), workd(block,:)
 c  replicated workl(lworkl)
 c
@@ -354,13 +354,13 @@ c     _Real_ Matrices", Linear Algebra and its Applications, vol 88/89,
 c     pp 575-595, (1987).
 c
 c\Routines called:
-c     pcnaup2  Parallel ARPACK routine that implements the Implicitly Restarted
-c              Arnoldi Iteration.
-c     cstatn   ARPACK routine that initializes the timing variables.
-c     pivout   Parallel ARPACK utility routine that prints integers.
-c     pcvout   Parallel ARPACK utility routine that prints vectors.
-c     arscnd   ARPACK utility routine for timing.
-c     pslamch10  ScaLAPACK routine that determines machine constants.
+c     pcnaup2   Parallel ARPACK routine that implements the Implicitly Restarted
+c               Arnoldi Iteration.
+c     cstatn    ARPACK routine that initializes the timing variables.
+c     pivout    Parallel ARPACK utility routine that prints integers.
+c     pcvout    Parallel ARPACK utility routine that prints vectors.
+c     arscnd    ARPACK utility routine for timing.
+c     pslamch10 ScaLAPACK routine that determines machine constants.
 c
 c\Author
 c     Danny Sorensen               Phuong Vu
@@ -389,7 +389,7 @@ c
      &   ( comm, ido, bmat, n, which, nev, tol, resid, ncv, v, ldv,
      &     iparam, ipntr, workd, workl, lworkl, rwork, info )
 c
-      include   'pcontext.h'
+      include  'pcontext.h'
       include  'mpif.h'
 c
 c     %------------------%
diff --git a/PARPACK/SRC/MPI/pcneupd.f b/PARPACK/SRC/MPI/pcneupd.f
index 8ced1df..2618a6f 100644
--- a/PARPACK/SRC/MPI/pcneupd.f
+++ b/PARPACK/SRC/MPI/pcneupd.f
@@ -340,8 +340,8 @@ c
       external   scnrm2,pslamch10,slapy2
 c
       Complex
-     &           cdotc
-      external   cdotc
+     &           ccdotc
+      external   ccdotc
 c
 c     %---------------------%
 c     | Intrinsic Functions |
@@ -743,7 +743,7 @@ c                 | upper triangular, thus the length of the |
 c                 | inner product can be set to j.           |
 c                 %------------------------------------------%
 c
-                  workev(j) = cdotc(j, workl(ihbds), 1,
+                  workev(j) = ccdotc(j, workl(ihbds), 1,
      &                        workl(invsub+(j-1)*ldq), 1)
  40         continue
 c
diff --git a/PARPACK/SRC/MPI/pdgetv0.f b/PARPACK/SRC/MPI/pdgetv0.f
index 54ed850..0f348b8 100644
--- a/PARPACK/SRC/MPI/pdgetv0.f
+++ b/PARPACK/SRC/MPI/pdgetv0.f
@@ -177,11 +177,11 @@ c     %------------------------%
 c     | Local Scalars & Arrays |
 c     %------------------------%
 c
-      logical    first, inits, orth
+      logical    first, orth
       integer    idist, iseed(4), iter, msglvl, jj
       Double precision
      &           rnorm0, buf2(1)
-      save       first, iseed, inits, iter, msglvl, orth, rnorm0
+      save       first, iseed, iter, msglvl, orth, rnorm0
 c
       Double precision
      &           rnorm_buf
@@ -206,12 +206,6 @@ c     %---------------------%
 c
       intrinsic    abs, sqrt
 c
-c     %-----------------%
-c     | Data Statements |
-c     %-----------------%
-c
-      data       inits /.true./
-c
 c     %-----------------------%
 c     | Executable Statements |
 c     %-----------------------%
@@ -222,13 +216,10 @@ c     | Initialize the seed of the LAPACK |
 c     | random number generator           |
 c     %-----------------------------------%
 c
-      if (inits) then
-          iseed(1) = 1
-          iseed(2) = 3
-          iseed(3) = 5
-          iseed(4) = 7
-          inits = .false.
-      end if
+      iseed(1) = 1
+      iseed(2) = 3
+      iseed(3) = 5
+      iseed(4) = 7
 c
       if (ido .eq.  0) then
 c
diff --git a/PARPACK/SRC/MPI/psgetv0.f b/PARPACK/SRC/MPI/psgetv0.f
index 597212b..d79a513 100644
--- a/PARPACK/SRC/MPI/psgetv0.f
+++ b/PARPACK/SRC/MPI/psgetv0.f
@@ -177,11 +177,11 @@ c     %------------------------%
 c     | Local Scalars & Arrays |
 c     %------------------------%
 c
-      logical    first, inits, orth
+      logical    first, orth
       integer    idist, iseed(4), iter, msglvl, jj
       Real
      &           rnorm0
-      save       first, iseed, inits, iter, msglvl, orth, rnorm0
+      save       first, iseed, iter, msglvl, orth, rnorm0
 c
       Real
      &           rnorm_buf
@@ -206,12 +206,6 @@ c     %---------------------%
 c
       intrinsic    abs, sqrt
 c
-c     %-----------------%
-c     | Data Statements |
-c     %-----------------%
-c
-      data       inits /.true./
-c
 c     %-----------------------%
 c     | Executable Statements |
 c     %-----------------------%
@@ -222,13 +216,10 @@ c     | Initialize the seed of the LAPACK |
 c     | random number generator           |
 c     %-----------------------------------%
 c
-      if (inits) then
-          iseed(1) = 1
-          iseed(2) = 3
-          iseed(3) = 5
-          iseed(4) = 7
-          inits = .false.
-      end if
+      iseed(1) = 1
+      iseed(2) = 3
+      iseed(3) = 5
+      iseed(4) = 7
 c
       if (ido .eq.  0) then
 c
diff --git a/PARPACK/SRC/MPI/pzgetv0.f b/PARPACK/SRC/MPI/pzgetv0.f
index 29f18f5..731fb31 100644
--- a/PARPACK/SRC/MPI/pzgetv0.f
+++ b/PARPACK/SRC/MPI/pzgetv0.f
@@ -176,13 +176,13 @@ c     %------------------------%
 c     | Local Scalars & Arrays |
 c     %------------------------%
 c
-      logical    first, inits, orth
+      logical    first, orth
       integer    idist, iseed(4), iter, msglvl, jj, myid, igen
       Double precision
      &           rnorm0
       Complex*16
      &           cnorm, cnorm2
-      save       first, iseed, inits, iter, msglvl, orth, rnorm0
+      save       first, iseed, iter, msglvl, orth, rnorm0
 c
       Complex*16
      &           cnorm_buf, buf2(1)
@@ -200,14 +200,8 @@ c
       Double precision
      &           pdznorm2 , dlapy2
       Complex*16
-     &           zdotc
-      external   zdotc , pdznorm2 , dlapy2
-c
-c     %-----------------%
-c     | Data Statements |
-c     %-----------------%
-c
-      data       inits /.true./
+     &           zzdotc
+      external   zzdotc , pdznorm2 , dlapy2
 c
 c     %-----------------------%
 c     | Executable Statements |
@@ -219,30 +213,26 @@ c     | Initialize the seed of the LAPACK |
 c     | random number generator           |
 c     %-----------------------------------%
 c
-      if (inits) then
-c
-c        %-----------------------------------%
-c        | Generate a seed on each processor |
-c        | using process id (myid).          |
-c        | Note: the seed must be between 1  |
-c        | and 4095.  iseed(4) must be odd.  |
-c        %-----------------------------------%
-c
-         call MPI_COMM_RANK(comm, myid, ierr)
-         igen = 1000 + 2*myid + 1
-         if (igen .gt. 4095) then
-            write(0,*) 'Error in p_getv0: seed exceeds 4095!'
-         end if
 c
-         iseed(1) = igen/1000
-         igen     = mod(igen,1000)
-         iseed(2) = igen/100
-         igen     = mod(igen,100)
-         iseed(3) = igen/10
-         iseed(4) = mod(igen,10)
+c     %-----------------------------------%
+c     | Generate a seed on each processor |
+c     | using process id (myid).          |
+c     | Note: the seed must be between 1  |
+c     | and 4095.  iseed(4) must be odd.  |
+c     %-----------------------------------%
 c
-         inits = .false.
+      call MPI_COMM_RANK(comm, myid, ierr)
+      igen = 1000 + 2*myid + 1
+      if (igen .gt. 4095) then
+         write(0,*) 'Error in p_getv0: seed exceeds 4095!'
       end if
+c
+      iseed(1) = igen/1000
+      igen     = mod(igen,1000)
+      iseed(2) = igen/100
+      igen     = mod(igen,100)
+      iseed(3) = igen/10
+      iseed(4) = 7
 c
       if (ido .eq.  0) then
 c
@@ -331,7 +321,7 @@ c
 c
       first = .FALSE.
       if (bmat .eq. 'G') then
-          cnorm_buf = zdotc  (n, resid, 1, workd, 1)
+          cnorm_buf = zzdotc  (n, resid, 1, workd, 1)
           call MPI_ALLREDUCE( [cnorm_buf], buf2, 1,
      &          MPI_DOUBLE_COMPLEX , MPI_SUM, comm, ierr )
           cnorm = buf2(1)
@@ -393,7 +383,7 @@ c
       end if
 c
       if (bmat .eq. 'G') then
-         cnorm_buf = zdotc  (n, resid, 1, workd, 1)
+         cnorm_buf = zzdotc  (n, resid, 1, workd, 1)
          call MPI_ALLREDUCE( [cnorm_buf], buf2, 1,
      &            MPI_DOUBLE_COMPLEX , MPI_SUM, comm, ierr )
          cnorm = buf2(1)
diff --git a/PARPACK/SRC/MPI/pznaitr.f b/PARPACK/SRC/MPI/pznaitr.f
index 4ec77e4..29a757f 100644
--- a/PARPACK/SRC/MPI/pznaitr.f
+++ b/PARPACK/SRC/MPI/pznaitr.f
@@ -307,10 +307,10 @@ c     | External Functions |
 c     %--------------------%
 c
       Complex*16
-     &           zdotc
+     &           zzdotc
       Double precision
      &           pdlamch10, pdznorm2, zlanhs, dlapy2
-      external   zdotc, pdznorm2, zlanhs, pdlamch10, dlapy2
+      external   zzdotc, pdznorm2, zlanhs, pdlamch10, dlapy2
 c
 c     %---------------------%
 c     | Intrinsic Functions |
@@ -576,7 +576,7 @@ c        | Compute the B-norm of OP*v_{j}.     |
 c        %-------------------------------------%
 c
          if (bmat .eq. 'G') then
-             cnorm_buf = zdotc (n, resid, 1, workd(ipj), 1)
+             cnorm_buf = zzdotc (n, resid, 1, workd(ipj), 1)
             call MPI_ALLREDUCE( [cnorm_buf], buf2, 1,
      &           MPI_DOUBLE_COMPLEX, MPI_SUM, comm, ierr )
             cnorm = buf2(1)
@@ -653,7 +653,7 @@ c        | Compute the B-norm of r_{j}. |
 c        %------------------------------%
 c
          if (bmat .eq. 'G') then
-            cnorm_buf = zdotc (n, resid, 1, workd(ipj), 1)
+            cnorm_buf = zzdotc (n, resid, 1, workd(ipj), 1)
             call MPI_ALLREDUCE( [cnorm_buf], buf2, 1,
      &           MPI_DOUBLE_COMPLEX, MPI_SUM, comm, ierr )
             cnorm = buf2(1)
@@ -758,7 +758,7 @@ c        | Compute the B-norm of the corrected residual r_{j}. |
 c        %-----------------------------------------------------%
 c
          if (bmat .eq. 'G') then
-             cnorm_buf = zdotc (n, resid, 1, workd(ipj), 1)
+             cnorm_buf = zzdotc (n, resid, 1, workd(ipj), 1)
             call MPI_ALLREDUCE( [cnorm_buf], buf2, 1,
      &           MPI_DOUBLE_COMPLEX, MPI_SUM, comm, ierr )
             cnorm = buf2(1)
diff --git a/PARPACK/SRC/MPI/pznaup2.f b/PARPACK/SRC/MPI/pznaup2.f
index 7852197..7ea1198 100644
--- a/PARPACK/SRC/MPI/pznaup2.f
+++ b/PARPACK/SRC/MPI/pznaup2.f
@@ -257,10 +257,10 @@ c     | External functions |
 c     %--------------------%
 c
       Complex*16
-     &           zdotc
+     &           zzdotc
       Double precision
      &           pdznorm2, pdlamch10, dlapy2
-      external   zdotc, pdznorm2, pdlamch10, dlapy2
+      external   zzdotc, pdznorm2, pdlamch10, dlapy2
 c
 c     %---------------------%
 c     | Intrinsic Functions |
@@ -770,7 +770,7 @@ c
          end if
 c
          if (bmat .eq. 'G') then
-            cmpnorm_buf = zdotc (n, resid, 1, workd, 1)
+            cmpnorm_buf = zzdotc (n, resid, 1, workd, 1)
             call MPI_ALLREDUCE( [cmpnorm_buf], buf2, 1,
      &               MPI_DOUBLE_COMPLEX, MPI_SUM, comm, ierr )
             cmpnorm = buf2(1)
diff --git a/PARPACK/SRC/MPI/pznaupd.f b/PARPACK/SRC/MPI/pznaupd.f
index 7d6ea4c..d0f03de 100644
--- a/PARPACK/SRC/MPI/pznaupd.f
+++ b/PARPACK/SRC/MPI/pznaupd.f
@@ -9,14 +9,14 @@ c  Reverse communication interface for the Implicitly Restarted Arnoldi
 c  iteration. This is intended to be used to find a few eigenpairs of a
 c  complex linear operator OP with respect to a semi-inner product defined
 c  by a hermitian positive semi-definite real matrix B. B may be the identity
-c  matrix.  NOTE: if both OP and B are real, then dsaupd  or dnaupd  should
+c  matrix.  NOTE: if both OP and B are real, then dsaupd or dnaupd should
 c  be used.
 c
 c
 c  The computed approximate eigenvalues are called Ritz values and
 c  the corresponding approximate eigenvectors are called Ritz vectors.
 c
-c  pznaupd  is usually called iteratively to solve one of the
+c  pznaupd is usually called iteratively to solve one of the
 c  following problems:
 c
 c  Mode 1:  A*x = lambda*x.
@@ -54,11 +54,11 @@ c  COMM    MPI  Communicator for the processor grid.  (INPUT)
 c
 c  IDO     Integer.  (INPUT/OUTPUT)
 c          Reverse communication flag.  IDO must be zero on the first
-c          call to pznaupd .  IDO will be set internally to
+c          call to pznaupd. IDO will be set internally to
 c          indicate the type of operation to be performed.  Control is
 c          then given back to the calling routine which has the
 c          responsibility to carry out the requested operation and call
-c          pznaupd  with the result.  The operand is given in
+c          pznaupd with the result. The operand is given in
 c          WORKD(IPNTR(1)), the result must be put in WORKD(IPNTR(2)).
 c          -------------------------------------------------------------
 c          IDO =  0: first call to the reverse communication interface
@@ -108,8 +108,8 @@ c  TOL     Double precision   scalar.  (INPUT)
 c          Stopping criteria: the relative accuracy of the Ritz value
 c          is considered acceptable if BOUNDS(I) .LE. TOL*ABS(RITZ(I))
 c          where ABS(RITZ(I)) is the magnitude when RITZ(I) is complex.
-c          DEFAULT = pdlamch10 (comm, 'EPS')  (machine precision as computed
-c                    by the ScaLAPACK auxiliary subroutine pdlamch ).
+c          DEFAULT = pdlamch10(comm, 'EPS')  (machine precision as computed
+c                    by the ScaLAPACK auxiliary subroutine pdlamch10).
 c
 c  RESID   Complex*16  array of length N.  (INPUT/OUTPUT)
 c          On INPUT:
@@ -171,7 +171,7 @@ c          No longer referenced. Implicit restarting is ALWAYS used.
 c
 c          IPARAM(7) = MODE
 c          On INPUT determines what type of eigenproblem is being solved.
-c          Must be 1,2,3; See under \Description of pznaupd  for the
+c          Must be 1,2,3; See under \Description of pznaupd for the
 c          four modes available.
 c
 c          IPARAM(8) = NP
@@ -201,7 +201,7 @@ c          IPNTR(7): pointer to the (projected) ritz vector array Q
 c          IPNTR(8): pointer to the error BOUNDS array in WORKL.
 c          IPNTR(14): pointer to the NP shifts in WORKL. See Remark 5 below.
 c
-c          Note: IPNTR(9:13) is only referenced by pzneupd . See Remark 2 below.
+c          Note: IPNTR(9:13) is only referenced by pzneupd. See Remark 2 below.
 c
 c          IPNTR(9):  pointer to the NCV RITZ values of the
 c                     original system.
@@ -211,7 +211,7 @@ c          IPNTR(12): pointer to the NCV by NCV upper triangular
 c                     Schur matrix for H.
 c          IPNTR(13): pointer to the NCV by NCV matrix of eigenvectors
 c                     of the upper Hessenberg matrix H. Only referenced by
-c                     zneupd  if RVEC = .TRUE. See Remark 2 below.
+c                     zneupd if RVEC = .TRUE. See Remark 2 below.
 c          -------------------------------------------------------------
 c
 c  WORKD   Complex*16  work array of length 3*N.  (REVERSE COMMUNICATION)
@@ -272,11 +272,11 @@ c     selection of WHICH should be made with this in mind when using
 c     Mode = 3.  When operating in Mode = 3 setting WHICH = 'LM' will
 c     compute the NEV eigenvalues of the original problem that are
 c     closest to the shift SIGMA . After convergence, approximate eigenvalues
-c     of the original problem may be obtained with the ARPACK subroutine pzneupd .
+c     of the original problem may be obtained with the ARPACK subroutine pzneupd.
 c
 c  2. If a basis for the invariant subspace corresponding to the converged Ritz
-c     values is needed, the user must call pzneupd  immediately following
-c     completion of pznaupd . This is new starting with release 2 of ARPACK.
+c     values is needed, the user must call pzneupd immediately following
+c     completion of pznaupd. This is new starting with release 2 of ARPACK.
 c
 c  3. If M can be factored into a Cholesky factorization M = LL`
 c     then Mode = 2 should not be selected.  Instead one should use
@@ -312,7 +312,7 @@ c\Data Distribution Note:
 c
 c  Fortran-D syntax:
 c  ================
-c  Complex*16  resid(n), v(ldv,ncv), workd(3*n), workl(lworkl)
+c  Complex*16 resid(n), v(ldv,ncv), workd(3*n), workl(lworkl)
 c  decompose  d1(n), d2(n,ncv)
 c  align      resid(i) with d1(i)
 c  align      v(i,j)   with d2(i,j)
@@ -324,7 +324,7 @@ c  replicated workl(lworkl)
 c
 c  Cray MPP syntax:
 c  ===============
-c  Complex*16  resid(n), v(ldv,ncv), workd(n,3), workl(lworkl)
+c  Complex*16 resid(n), v(ldv,ncv), workd(n,3), workl(lworkl)
 c  shared     resid(block), v(block,:), workd(block,:)
 c  replicated workl(lworkl)
 c
@@ -355,12 +355,12 @@ c     pp 575-595, (1987).
 c
 c\Routines called:
 c     pznaup2   Parallel ARPACK routine that implements the Implicitly Restarted
-c              Arnoldi Iteration.
+c               Arnoldi Iteration.
 c     zstatn    ARPACK routine that initializes the timing variables.
-c     pivout   Parallel ARPACK utility routine that prints integers.
+c     pivout    Parallel ARPACK utility routine that prints integers.
 c     pzvout    Parallel ARPACK utility routine that prints vectors.
-c     arscnd   ARPACK utility routine for timing.
-c     pdlamch10   ScaLAPACK routine that determines machine constants.
+c     arscnd    ARPACK utility routine for timing.
+c     pdlamch10 ScaLAPACK routine that determines machine constants.
 c
 c\Author
 c     Danny Sorensen               Phuong Vu
@@ -570,8 +570,8 @@ c        | workl(ncv*ncv+1:ncv*ncv+ncv) := the ritz values             |
 c        | workl(ncv*ncv+ncv+1:ncv*ncv+2*ncv)   := error bounds        |
 c        | workl(ncv*ncv+2*ncv+1:2*ncv*ncv+2*ncv) := rotation matrix Q |
 c        | workl(2*ncv*ncv+2*ncv+1:3*ncv*ncv+5*ncv) := workspace       |
-c        | The final workspace is needed by subroutine pzneigh  called  |
-c        | by pznaup2 . Subroutine pzneigh  calls LAPACK routines for    |
+c        | The final workspace is needed by subroutine pzneigh called  |
+c        | by pznaup2. Subroutine pzneigh calls LAPACK routines for    |
 c        | calculating eigenvalues and the last row of the eigenvector |
 c        | matrix.                                                     |
 c        %-------------------------------------------------------------%
@@ -619,7 +619,7 @@ c
 c
 c     %------------------------------------%
 c     | Exit if there was an informational |
-c     | error within pznaup2 .              |
+c     | error within pznaup2.              |
 c     %------------------------------------%
 c
       if (info .lt. 0) go to 9000
diff --git a/PARPACK/SRC/MPI/pzneupd.f b/PARPACK/SRC/MPI/pzneupd.f
index 7b6e7fe..395cfee 100644
--- a/PARPACK/SRC/MPI/pzneupd.f
+++ b/PARPACK/SRC/MPI/pzneupd.f
@@ -340,8 +340,8 @@ c
       external   dznrm2,pdlamch10,dlapy2
 c
       Complex*16
-     &           zdotc
-      external   zdotc
+     &           zzdotc
+      external   zzdotc
 c
 c     %---------------------%
 c     | Intrinsic Functions |
@@ -743,7 +743,7 @@ c                 | upper triangular, thus the length of the |
 c                 | inner product can be set to j.           |
 c                 %------------------------------------------%
 c
-                  workev(j) = zdotc(j, workl(ihbds), 1,
+                  workev(j) = zzdotc(j, workl(ihbds), 1,
      &                        workl(invsub+(j-1)*ldq), 1)
  40         continue
 c
diff --git a/PARPACK/TESTS/MPI/Makefile.am b/PARPACK/TESTS/MPI/Makefile.am
index 0b6e624..cb34b80 100644
--- a/PARPACK/TESTS/MPI/Makefile.am
+++ b/PARPACK/TESTS/MPI/Makefile.am
@@ -1,5 +1,5 @@
 F77 = $(MPIF77)
-LDADD = $(top_builddir)/PARPACK/SRC/MPI/libparpack$(LIBSUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
+LDADD = $(top_builddir)/PARPACK/SRC/MPI/libparpack$(LIBSUFFIX)$(ITF64SUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
 
 # Run MPI tests with "mpirun -n 2"
 LOG_COMPILER = mpirun
@@ -19,11 +19,11 @@ issue46_SOURCES= issue46.f
 
 if ICB
 icb_parpack_c_SOURCES = icb_parpack_c.c
-icb_parpack_c_LDADD = $(top_builddir)/PARPACK/SRC/MPI/libparpack$(LIBSUFFIX).la $(MPI_C_LIBS)
+icb_parpack_c_LDADD = $(top_builddir)/PARPACK/SRC/MPI/libparpack$(LIBSUFFIX)$(ITF64SUFFIX).la $(MPI_C_LIBS)
 icb_parpack_c_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir) -I$(top_srcdir)/ICB
 
 icb_parpack_cpp_SOURCES = icb_parpack_cpp.cpp
-icb_parpack_cpp_LDADD = $(top_builddir)/PARPACK/SRC/MPI/libparpack$(LIBSUFFIX).la $(MPI_CXX_LIBS)
+icb_parpack_cpp_LDADD = $(top_builddir)/PARPACK/SRC/MPI/libparpack$(LIBSUFFIX)$(ITF64SUFFIX).la $(MPI_CXX_LIBS)
 icb_parpack_cpp_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir) -I$(top_srcdir)/ICB
 endif
 
diff --git a/PARPACK/TESTS/MPI/icb_parpack_c.c b/PARPACK/TESTS/MPI/icb_parpack_c.c
index 94c6162..b35fcb9 100644
--- a/PARPACK/TESTS/MPI/icb_parpack_c.c
+++ b/PARPACK/TESTS/MPI/icb_parpack_c.c
@@ -13,149 +13,151 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "debug_c.h"  // debug parpack.
-#include "mpi.h"
 #include "parpack.h"
-#include "stat_c.h"  // arpack statistics.
+#include "debug_c.h"  // debug parpack.
+#include "stat_c.h"   // arpack statistics.
 
 /* 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.
  * */
 
-void dMatVec(double* x, double* y) {
+void dMatVec(const double* x, double* y) {
   int i;
   for (i = 0; i < 1000; ++i) y[i] = ((double)(i + 1)) * x[i];
 };
 
 int ds() {
-  a_int ido = 0;
-  char bmat[] = "I";
-  a_int N = 1000;
-  char which[] = "LM";
-  a_int nev = 3;
-  double tol = 0.000001; // small tol => more stable checks after EV computation.
+  const a_int N      = 1000;
+  const a_int nev    = 9;
+  const a_int ncv    = 2 * nev + 1;
+  const a_int ldv    = N;
+  const a_int ldz    = N;
+  const a_int lworkl = ncv * (ncv + 8);
+  const a_int rvec   = 1;        // need eigenvectors
+
+  const double tol   = 0.000001; // small tol => more stable checks after EV computation.
+  const double sigma = 0;        // not referenced in this mode
+
   double resid[N];
-  a_int ncv = 2 * nev + 1;
-  double V[ncv * N];
-  a_int ldv = N;
-  a_int iparam[11];
-  a_int ipntr[14];
+  double V[ldv * ncv];
+  double z[ldz * nev];
+  double d[nev];
   double workd[3 * N];
-  a_int rvec = 1;
-  char howmny[] = "A";
-  double* d = (double*)malloc((nev + 1) * sizeof(double));
+  double workl[lworkl];
   a_int select[ncv];
-  for (int i = 0; i < ncv; i++) select[i] = 1;
-  double z[(N + 1) * (nev + 1)];
-  a_int ldz = N + 1;
-  double sigma = 0;
-  int k;
-  for (k = 0; k < 3 * N; ++k) workd[k] = 0;
-  double 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;
-  int rank;
-  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
 
-  iparam[0] = 1;
-  iparam[2] = 10 * N;
-  iparam[3] = 1;
-  iparam[4] = 0;  // number of ev found by arpack.
-  iparam[6] = 1;
+  a_int iparam[11], ipntr[11];
+  iparam[0] = 1;       // ishift
+  iparam[2] = 10 * N;  // on input: maxit; on output: actual iteration
+  iparam[3] = 1;       // NB, only 1 allowed
+  iparam[6] = 1;       // mode
 
+  char bmat[]   = "I";
+  char which[]  = "LM";
+  char howmny[] = "A";
+  
+  int rank;
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   MPI_Fint MCW = MPI_Comm_c2f(MPI_COMM_WORLD);
-  while (ido != 99) {
-    /* call arpack like you would have, but, use dsaupd_c instead of dsaupd_ */
+  
+  a_int info = 0, ido = 0;
+  do {
     pdsaupd_c(MCW, &ido, bmat, N, which, nev, tol, resid, ncv, V, ldv, iparam,
               ipntr, workd, workl, lworkl, &info);
 
     dMatVec(&(workd[ipntr[0] - 1]), &(workd[ipntr[1] - 1]));
+  } while (ido == 1 || ido == -1);
+
+  // check info and number of ev found by arpack.
+  if (info < 0 || iparam[4] < nev) {
+    printf("Error in saupd: iparam[4] %d, nev %d, info %d\n", iparam[4], nev, info);
+    return 1;
   }
-  if (iparam[4] != nev) {printf("Error: iparam[4] %d, nev %d\n", iparam[4], nev); return 1;} // check number of ev found by arpack.
 
-  /* call arpack like you would have, but, use dseupd_c instead of dseupd_ */
   pdseupd_c(MCW, rvec, howmny, select, d, z, ldz, sigma, bmat, N, which, nev,
-            tol, resid, ncv, V, ldv, iparam, ipntr, workd, workl, lworkl,
-            &info);
-  int i;
+            tol, resid, ncv, V, ldv, iparam, ipntr, workd, workl, lworkl, &info);
+  if (info < 0) {
+    printf("Error in seupd: info %d\n", info);
+    return 1;
+  }
+
+  int i; // C99 compliant.
   for (i = 0; i < nev; ++i) {
     double val = d[i];
     double ref = (N-(nev-1)+i);
     double eps = fabs(val - ref);
     printf("rank %d : %f - %f - %f\n", rank, val, ref, eps);
 
-    /*eigen value order: smallest -> biggest*/
-    if(eps>1.e-05){
-      free(d);
-      return 1;
-    }
+    if (eps > 1.e-05) return 1;
   }
-  free(d);
   return 0;
 }
 
-void zMatVec(double _Complex* x, double _Complex* y) {
+void zMatVec(const a_dcomplex* x, a_dcomplex* y) {
   int i;
-  for (i = 0; i < 1000; ++i) y[i] = x[i] * (i + 1.0 + _Complex_I * (i + 1.0));
+  for (i = 0; i < 1000; ++i) y[i] = x[i] * CMPLXF(i + 1.0, i + 1.0);
 };
 
 int zn() {
-  a_int ido = 0;
-  char bmat[] = "I";
-  a_int N = 1000;
-  char which[] = "LM";
-  a_int nev = 1;
-  double tol = 0.000001; // small tol => more stable checks after EV computation.
-  double _Complex resid[N];
-  a_int ncv = 2 * nev + 1;
-  double _Complex V[ncv * N];
-  a_int ldv = N;
-  a_int iparam[11];
-  a_int ipntr[14];
-  double _Complex workd[3 * N];
-  a_int rvec = 0;
-  char howmny[] = "A";
-  double _Complex* d =
-      (double _Complex*)malloc((nev + 1) * sizeof(double _Complex));
+  const a_int N      = 1000;
+  const a_int nev    = 9;
+  const a_int ncv    = 2 * nev + 1;
+  const a_int ldv    = N;
+  const a_int ldz    = N;
+  const a_int lworkl = ncv * (3 * ncv + 5);
+  const a_int rvec   = 0;                 // eigenvectors omitted
+
+  const double tol = 0.000001;            // small tol => more stable checks after EV computation.
+  const a_dcomplex sigma = CMPLX(0., 0.); // not referenced in this mode
+
+  a_dcomplex resid[N];
+  a_dcomplex V[ldv * ncv];
+  a_dcomplex z[ldz * nev];
+  a_dcomplex d[nev];
+  a_dcomplex workd[3 * N];
+  a_dcomplex workl[lworkl];
+  a_dcomplex workev[2 * ncv];
+  double rwork[ncv];
   a_int select[ncv];
-  for (int i = 0; i < ncv; i++) select[i] = 1;
-  double _Complex z[(N + 1) * (nev + 1)];
-  a_int ldz = N + 1;
-  double _Complex sigma = 0. + I * 0.;
-  int k;
-  for (k = 0; k < 3 * N; ++k) workd[k] = 0. + I * 0.;
-  double _Complex workl[3 * (ncv * ncv) + 6 * ncv];
-  for (k = 0; k < 3 * (ncv * ncv) + 6 * ncv; ++k) workl[k] = 0. + I * 0.;
-  a_int lworkl = 3 * (ncv * ncv) + 6 * ncv;
-  double _Complex rwork[ncv];
-  double _Complex workev[2 * ncv];
-  a_int info = 0;
+
+  a_int iparam[11], ipntr[14];
+  iparam[0] = 1;       // ishift
+  iparam[2] = 10 * N;  // on input: maxit; on output: actual iteration
+  iparam[3] = 1;       // NB, only 1 allowed
+  iparam[6] = 1;       // mode
+  
+  char bmat[]   = "I";
+  char which[]  = "LM";
+  char howmny[] = "A";
+  
   int rank;
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-
-  iparam[0] = 1;
-  iparam[2] = 10 * N;
-  iparam[3] = 1;
-  iparam[4] = 0;  // number of ev found by arpack.
-  iparam[6] = 1;
-
   MPI_Fint MCW = MPI_Comm_c2f(MPI_COMM_WORLD);
-  while (ido != 99) {
-    /* call arpack like you would have, but, use znaupd_c instead of znaupd_ */
+
+  a_int info = 0, ido = 0;
+  do {
     pznaupd_c(MCW, &ido, bmat, N, which, nev, tol, resid, ncv, V, ldv, iparam,
               ipntr, workd, workl, lworkl, rwork, &info);
 
     zMatVec(&(workd[ipntr[0] - 1]), &(workd[ipntr[1] - 1]));
+  } while (ido == 1 || ido == -1);
+  
+  // check info and number of ev found by arpack.
+  if (info < 0 || iparam[4] < nev) {
+    printf("Error in naupd: iparam[4] %d, nev %d, info %d\n", iparam[4], nev, info);
+    return 1;
   }
-  if (iparam[4] != nev) {printf("Error: iparam[4] %d, nev %d\n", 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_ */
   pzneupd_c(MCW, 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;
+  if (info < 0) {
+    printf("Error in neupd: info %d\n", info);
+    return 1;
+  }
+            
+  int i; // C99 compliant.
   for (i = 0; i < nev; ++i) {
     double rval = creal(d[i]);
     double rref = (N-(nev-1)+i);
@@ -165,13 +167,8 @@ int zn() {
     double ieps = fabs(ival - iref);
     printf("rank %d : %f %f - %f %f - %f %f\n", rank, rval, ival, rref, iref, reps, ieps);
 
-    /*eigen value order: smallest -> biggest*/
-    if(reps>1.e-05 || ieps>1.e-05){
-      free(d);
-      return 1;
-    }
+    if (reps > 1.e-05 || ieps > 1.e-05) return 1;
   }
-  free(d);
   return 0;
 }
 
diff --git a/PARPACK/TESTS/MPI/icb_parpack_cpp.cpp b/PARPACK/TESTS/MPI/icb_parpack_cpp.cpp
index c480b71..f554877 100644
--- a/PARPACK/TESTS/MPI/icb_parpack_cpp.cpp
+++ b/PARPACK/TESTS/MPI/icb_parpack_cpp.cpp
@@ -6,190 +6,187 @@
  * Just use arpack as you would have normally done but use [ae]upd instead
  * of *[ae]upd_. The main advantage is that checks of the arguments are
  * performed at compile time. Note: to debug parpack, call debug_c.
- * This test program solves for the 9 largest eigenvalues of
+ * This test program solves for the 9 eigenvalues of
  * A*x = lambda*x where A is the diagonal matrix
  * with entries 1000, 999, ... , 2, 1 on the diagonal.
  */
 
-#include <array>
 #include <cmath>
 #include <iostream>
 #include <vector>
 
-#include "debug_c.hpp"  // debug parpack.
 #include "parpack.hpp"
-#include "stat_c.hpp"  // arpack statistics.
+#include "debug_c.hpp"  // debug parpack.
+#include "stat_c.hpp"   // arpack statistics.
 
-void diagonal_matrix_vector_product(float const* const x, float* const y) {
+template <typename Real>
+void diagonal_matrix_vector_product(const Real* x, Real* y) {
   for (int i = 0; i < 1000; ++i) {
     y[i] = static_cast<float>(i + 1) * x[i];
   }
 }
 
-void real_symmetric_runner() {
-  a_int N = 1000;
-  a_int nev = 3;
-  a_int ncv = 2 * nev + 1;
-  a_int ldz = N + 1;
-  a_int lworkl = 3 * (ncv * ncv) + 6 * ncv;
-  a_int ldv = N;
-
-  a_int rvec = 1;
-  float tol = 0.000001; // small tol => more stable checks after EV computation.
-  float sigma = 0.0f;
-
-  std::array<a_int, 14> ipntr;
-
-  std::vector<float> workd(3 * N, 0.0f);
-  std::vector<float> workl(3 * (ncv * ncv) + 6 * ncv, 0.0f);
-  std::vector<float> V(ncv * N);
-  std::vector<float> d(nev + 1);
-  std::vector<float> z((N + 1) * (nev + 1));
-  std::vector<float> resid(N);
-  std::vector<a_int> select(ncv);
-  for (int i = 0; i < ncv; i++) select[i] = 1;
-
-  a_int info = 0;
+template <typename Real>
+void real_symmetric_runner(double const& tol_check, arpack::which const& ritz_option) {
+  const a_int N      = 1000;
+  const a_int nev    = 9;
+  const a_int ncv    = 2 * nev + 1;
+  const a_int ldv    = N;
+  const a_int ldz    = N;
+  const a_int lworkl = ncv * (ncv + 8);
+  const a_int rvec   = 1;     // need eigenvectors
+
+  const Real tol = 0.000001; // small tol => more stable checks after EV computation.
+  const Real sigma = 0.0f;   // not referenced in this mode
+
+  std::vector<Real> resid(N);
+  std::vector<Real> V(ldv * ncv);
+  std::vector<Real> z(ldz * nev);
+  std::vector<Real> d(nev);
+  std::vector<Real> workd(3 * N);
+  std::vector<Real> workl(lworkl);
+  std::vector<a_int> select(ncv); // since HOWMNY = 'A', only used as workspace here
+
+  a_int iparam[11], ipntr[11];
+  iparam[0] = 1;      // ishift
+  iparam[2] = 10 * N; // on input: maxit; on output: actual iteration
+  iparam[3] = 1;      // NB, only 1 allowed
+  iparam[6] = 1;      // mode
 
   int rank;
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-
-  std::array<a_int, 11> iparam;
-  iparam[0] = 1;
-  iparam[2] = 10 * N;
-  iparam[3] = 1;
-  iparam[4] = 0;  // number of ev found by arpack.
-  iparam[6] = 1;
-
   MPI_Fint MCW = MPI_Comm_c2f(MPI_COMM_WORLD);
 
-  a_int ido = 0;
-
-  while (ido != 99) {
+  a_int info = 0, ido = 0;
+  do {
     arpack::saupd(MCW, ido, arpack::bmat::identity, N,
-                  arpack::which::largest_magnitude, nev, tol, resid.data(), ncv,
-                  V.data(), ldv, iparam.data(), ipntr.data(), workd.data(),
+                  ritz_option, nev, tol, resid.data(), ncv,
+                  V.data(), ldv, iparam, ipntr, workd.data(),
                   workl.data(), lworkl, info);
 
-    diagonal_matrix_vector_product(&(workd[ipntr[0] - 1]),
-                                   &(workd[ipntr[1] - 1]));
-  }
-  // check number of ev found by arpack.
-  if (iparam[4] < nev /*arpack may succeed to compute more EV than expected*/ ||
-      info != 0) {
-    std::cout << "ERROR: iparam[4] " << iparam[4] << ", nev " << nev
+    diagonal_matrix_vector_product(&(workd[ipntr[0] - 1]), &(workd[ipntr[1] - 1]));
+  } while  (ido == 1 || ido == -1);
+
+  // check info and number of ev found by arpack.
+  if (info < 0 || iparam[4] < nev) { /*arpack may succeed to compute more EV than expected*/
+    std::cout << "ERROR in saupd: iparam[4] " << iparam[4] << ", nev " << nev
               << ", info " << info << std::endl;
     throw std::domain_error("Error inside ARPACK routines");
   }
 
   arpack::seupd(MCW, rvec, arpack::howmny::ritz_vectors, select.data(),
                 d.data(), z.data(), ldz, sigma, arpack::bmat::identity, N,
-                arpack::which::largest_magnitude, nev, tol, resid.data(), ncv,
-                V.data(), ldv, iparam.data(), ipntr.data(), workd.data(),
+                ritz_option, nev, tol, resid.data(), ncv,
+                V.data(), ldv, iparam, ipntr, workd.data(),
                 workl.data(), lworkl, info);
+  if (info < 0) throw std::runtime_error("Error in seupd, info " + std::to_string(info));
 
   for (int i = 0; i < nev; ++i) {
-    float val = d[i];
-    float ref = (N - (nev - 1) + i);
-    float eps = std::fabs(val - ref);
+    Real val = d[i];
+    Real ref = (N - (nev - 1) + i);
+    Real eps = std::fabs(val - ref);
     std::cout << "rank " << rank  << " : " << val << " - " << ref << " - " << eps << std::endl;
 
     /*eigen value order: smallest -> biggest*/
-    if (eps > 1.) {
-      throw std::domain_error("Correct eigenvalues not computed");
-    }
+    if (eps > tol_check) throw std::domain_error("Correct eigenvalues not computed");
   }
+  std::cout << "------" << std::endl;
 }
 
-void diagonal_matrix_vector_product(std::complex<float> const* const x,
-                                    std::complex<float>* const y) {
+template <typename Real>
+void diagonal_matrix_vector_product(const std::complex<Real>* x, std::complex<Real>* y) {
   for (int i = 0; i < 1000; ++i) {
-    y[i] = x[i] * std::complex<float>{i + 1.0f, i + 1.0f};
+    // Use complex matrix (i, -i) instead of (i, i): this way "largest_magnitude"
+    // and "largest_imaginary" options produce different results that can be checked.
+    y[i] = x[i] * std::complex<Real>{Real(i + 1), -Real(i + 1)};
   }
 }
 
-void complex_symmetric_runner() {
-  a_int N = 1000;
-  a_int nev = 1;
-  a_int ncv = 2 * nev + 1;
-  a_int ldv = N;
-  a_int ldz = N + 1;
-
-  float tol = 0.000001; // small tol => more stable checks after EV computation.
-  a_int rvec = 0;
-  std::complex<float> sigma(0.0f, 0.0f);
-
-  std::vector<std::complex<float>> resid(N);
-  std::vector<std::complex<float>> V(ncv * N);
-  std::vector<std::complex<float>> workd(3 * N);
-  std::vector<std::complex<float>> d(nev + 1);
-  std::vector<std::complex<float>> z((N + 1) * (nev + 1));
-  std::vector<a_int> select(ncv);
-  for (int i = 0; i < ncv; i++) select[i] = 1;
-
-  a_int lworkl = 3 * (ncv * ncv) + 6 * ncv;
-  std::vector<std::complex<float>> workl(lworkl);
-
-  std::vector<std::complex<float>> rwork(ncv);
-  std::vector<std::complex<float>> workev(2 * ncv);
-
-  a_int info = 0;
+template <typename Real>
+void complex_nonsymmetric_runner(double const& tol_check, arpack::which const& ritz_option) {
+  const a_int N = 1000;
+  const a_int nev = 9;
+  const a_int ncv = 2 * nev + 1;
+  const a_int ldv = N;
+  const a_int ldz = N;
+  const a_int lworkl = ncv * (3 * ncv + 5);
+  const a_int rvec = 0;                       // eigenvectors omitted
+
+  const Real tol = 0.000001;                  // small tol => more stable checks after EV computation.
+  const std::complex<Real> sigma(0.0f, 0.0f); // not referenced in this mode
+
+  std::vector<std::complex<Real>> resid(N);
+  std::vector<std::complex<Real>> V(ldv * ncv);
+  std::vector<std::complex<Real>> z(ldz * nev);
+  std::vector<std::complex<Real>> d(nev);
+  std::vector<std::complex<Real>> workd(3 * N);
+  std::vector<std::complex<Real>> workl(lworkl);
+  std::vector<std::complex<Real>> workev(2 * ncv);
+  std::vector<Real> rwork(ncv);
+  std::vector<a_int> select(ncv); // since HOWMNY = 'A', only used as workspace here
+
+  a_int iparam[11], ipntr[14];
+  iparam[0] = 1;       // ishift
+  iparam[2] = 10 * N;  // on input: maxit; on output: actual iteration
+  iparam[3] = 1;       // NB, only 1 allowed
+  iparam[6] = 1;       // mode
 
   int rank;
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-
-  std::array<a_int, 11> iparam;
-  iparam[0] = 1;
-  iparam[2] = 10 * N;
-  iparam[3] = 1;
-  iparam[4] = 0;  // number of ev found by arpack.
-  iparam[6] = 1;
-
-  std::array<a_int, 14> ipntr;
-
   MPI_Fint MCW = MPI_Comm_c2f(MPI_COMM_WORLD);
 
-  a_int ido = 0;
-
-  while (ido != 99) {
+  a_int info = 0, ido = 0;
+  do {
     arpack::naupd(MCW, ido, arpack::bmat::identity, N,
-                  arpack::which::largest_magnitude, nev, tol, resid.data(), ncv,
-                  V.data(), ldv, iparam.data(), ipntr.data(), workd.data(),
+                  ritz_option, nev, tol, resid.data(), ncv,
+                  V.data(), ldv, iparam, ipntr, workd.data(),
                   workl.data(), lworkl, rwork.data(), info);
 
-    diagonal_matrix_vector_product(&(workd[ipntr[0] - 1]),
-                                   &(workd[ipntr[1] - 1]));
-  }
+    diagonal_matrix_vector_product(&(workd[ipntr[0] - 1]), &(workd[ipntr[1] - 1]));
+  } while (ido == 1 || ido == -1);
 
-  // check number of ev found by arpack
-  if (iparam[4] < nev /*arpack may succeed to compute more EV than expected*/ ||
-      info != 0) {
-    std::cout << "ERROR: iparam[4] " << iparam[4] << ", nev " << nev
+  // check info and number of ev found by arpack
+  if (info < 0 || iparam[4] < nev) { /*arpack may succeed to compute more EV than expected*/
+    std::cout << "ERROR in naupd: iparam[4] " << iparam[4] << ", nev " << nev
               << ", info " << info << std::endl;
     throw std::domain_error("Error inside ARPACK routines");
   }
 
   arpack::neupd(MCW, rvec, arpack::howmny::ritz_vectors, select.data(),
                 d.data(), z.data(), ldz, sigma, workev.data(),
-                arpack::bmat::identity, N, arpack::which::largest_magnitude,
-                nev, tol, resid.data(), ncv, V.data(), ldv, iparam.data(),
-                ipntr.data(), workd.data(), workl.data(), lworkl, rwork.data(),
-                info);
-
-  for (int i = 0; i < nev; ++i) {
-    float rval = std::real(d[i]);
-    float rref = (N-(nev-1)+i);
-    float reps = std::fabs(rval - rref);
-    float ival = std::imag(d[i]);
-    float iref = (N-(nev-1)+i);
-    float ieps = std::fabs(ival - iref);
-    std::cout << "rank " << rank << " : " << rval << " " << ival << " - " << rref << " " << iref << " - " << reps << " " << ieps << std::endl;
-
-    /*eigen value order: smallest -> biggest*/
-    if (reps > 1. || ieps > 1.) {
-      throw std::domain_error("Correct eigenvalues not computed");
+                arpack::bmat::identity, N, ritz_option,
+                nev, tol, resid.data(), ncv, V.data(), ldv, iparam,
+                ipntr, workd.data(), workl.data(), lworkl, rwork.data(), info);
+  if (info < 0) throw std::runtime_error("Error in neupd, info " + std::to_string(info));
+
+  if (ritz_option == arpack::which::largest_magnitude) {
+    for (int i = 0; i < nev; ++i) {
+      Real rval = std::real(d[i]);
+      Real rref = static_cast<Real>(N - (nev - 1) + i);
+      Real reps = std::fabs(rval - rref);
+      Real ival = std::imag(d[i]);
+      Real iref = -static_cast<Real>(N - (nev - 1) + i);
+      Real ieps = std::fabs(ival - iref);
+      std::cout << rval << " " << ival << " - " << rref << " " << iref << " - " << reps << " " << ieps << std::endl;
+
+      if (reps > tol_check || ieps > tol_check) throw std::domain_error("Correct eigenvalues not computed");
+    }
+  } else if (ritz_option == arpack::which::largest_imaginary) {
+    for (int i = 0; i < nev; ++i) {
+      Real rval = std::real(d[i]);
+      Real rref = static_cast<Real>(nev - i);
+      Real reps = std::fabs(rval - rref);
+      Real ival = std::imag(d[i]);
+      Real iref = -static_cast<Real>(nev - i);
+      Real ieps = std::fabs(ival - iref);
+      std::cout << rval << " " << ival << " - " << rref << " " << iref << " - " << reps << " " << ieps << std::endl;
+
+      if (reps > tol_check || ieps > tol_check) throw std::domain_error("Correct eigenvalues not computed");
     }
+  } else {
+    throw std::domain_error("The input Ritz option is not allowed in this test file.");
   }
+  std::cout << "------" << std::endl;
 }
 
 int main() {
@@ -199,9 +196,12 @@ int main() {
 
   try {
     // parpack without debug
-    real_symmetric_runner();
+    real_symmetric_runner<float>(1., arpack::which::largest_magnitude);
+    real_symmetric_runner<float>(1., arpack::which::largest_algebraic);
+    real_symmetric_runner<double>(1.e-05, arpack::which::largest_magnitude);
+    real_symmetric_runner<double>(1.e-05, arpack::which::largest_algebraic);
   } catch (std::domain_error& e) {
-    std::cout << e.what() << '\n';
+    std::cout << e.what() << std::endl;
     MPI_Abort(MPI_COMM_WORLD, 1);
   }
 
@@ -231,7 +231,10 @@ int main() {
           1);
 
   try {
-    complex_symmetric_runner();
+    complex_nonsymmetric_runner<float>(1., arpack::which::largest_magnitude);
+    complex_nonsymmetric_runner<float>(1., arpack::which::largest_imaginary);
+    complex_nonsymmetric_runner<double>(1.e-05, arpack::which::largest_magnitude);
+    complex_nonsymmetric_runner<double>(1.e-05, arpack::which::largest_imaginary);
   } catch (std::domain_error& e) {
     std::cout << e.what() << '\n';
     MPI_Abort(MPI_COMM_WORLD, 1);
diff --git a/README.md b/README.md
index 0da371d..cab9927 100644
--- a/README.md
+++ b/README.md
@@ -1,167 +1,326 @@
-ARPACK-NG is a collection of Fortran77 subroutines designed to solve large scale
-eigenvalue problems.
-
-<a href="https://travis-ci.org/opencollab/arpack-ng"><img src="https://travis-ci.org/opencollab/arpack-ng.svg"/></a><br/>
-[![Coverage Status](https://coveralls.io/repos/github/opencollab/arpack-ng/badge.svg?branch=master)](https://coveralls.io/github/opencollab/arpack-ng?branch=master)
-
-Important Features:
-
-* Reverse Communication Interface.
-* Single and Double Precision Real Arithmetic Versions for Symmetric,
-  Non-symmetric, Standard or Generalized Problems.
-* Single and Double Precision Complex Arithmetic Versions for Standard or
-  Generalized Problems.
-* Routines for Banded Matrices - Standard or Generalized Problems.
-* Routines for The Singular Value Decomposition.
-* Example driver routines that may be used as templates to implement numerous
-  Shift-Invert strategies for all problem types, data types and precision.
-* arpackmm: utility to test arpack with matrix market files.
-  Note: to run this utility, you need the eigen library (to handle RCI).
-* ILP64 support:
-  * reminder: you can NOT mix ILP64 with LP64. If you compile arpack-ng with ILP64
-    (resp. LP64) support, you MUST insure your BLAS/LAPACK is compliant with ILP64
-    (resp. LP64).
-  * users: set INTERFACE64 at configure time.
-  * F77/F90 developers:
-    * all files which needs ILP64 support must include "arpackicb.h".
-    * when coding, use i_int (defined in arpackicb.h) instead of c_int.
-      i_int stands for "iso_c_binding int": it's #defined to c_int or c_int64_t
-      according to the architecture.
-  * C/C++ developers:
-    * all files which needs ILP64 support must include "arpackdef.h".
-    * when coding, use a_int (defined in arpackdef.h) instead of int.
-      a_int stands for "architecture int": it's #defined to int or int64_t according
-      to the architecture.
-  * example: to test arpack with sequential ILP64 MKL assuming you use gnu compilers
-    ```$ ./bootstrap
-    $ export FFLAGS='-DMKL_ILP64 -I/usr/include/mkl'
-    $ export FCFLAGS='-DMKL_ILP64 -I/usr/include/mkl'
-    $ export LIBS='-Wl,--no-as-needed -L/usr/lib/x86_64-linux-gnu -lmkl_sequential -lmkl_core -lpthread -lm -ldl'
-    $ export INTERFACE64=1
-    $ ./configure --with-blas=mkl_gf_ilp64 --with-lapack=mkl_gf_ilp64
-    $ make all check```
-* pyarpack: python support based on Boost.Python.Numpy exposing C++ API.
-
-This project started as a joint project between Debian, Octave and Scilab in order to
-provide a common and maintained version of arpack.
+# arpack-ng [![arpack-ng CI/CD](https://github.com/opencollab/arpack-ng/actions/workflows/jobs.yml/badge.svg)](https://github.com/opencollab/arpack-ng/actions/workflows/jobs.yml)
+
+ARPACK-NG is a collection of Fortran77 subroutines designed to solve large scale eigenvalue problems.
+| mandatory dependencies | optional dependencies     | category      |
+|------------------------|---------------------------|---------------|
+| BLAS, LAPACK           | MPI, Eigen3, Boost.Python | LinearAlgebra |
+
+## About the project
+
+This project started as a joint project between Debian, Octave and Scilab in order to provide a common and maintained version of arpack.
 This is now a community project maintained by a few volunteers.
+Indeed, no single release has been published by Rice university for the last few years and since many software (Octave, Scilab, R, Matlab...)
+forked it and implemented their own modifications, arpack-ng aims to tackle this by providing a common repository, maintained versions with a testsuite.
+`arpack-ng` is replacing arpack almost everywhere.
+
+## Important Features
+
+- Reverse Communication Interface (RCI).
+- Single and Double Precision Real Arithmetic Versions for Symmetric, Non-symmetric, Standard or Generalized Problems.
+- Single and Double Precision Complex Arithmetic Versions for Standard or Generalized Problems.
+- Routines for Banded Matrices - Standard or Generalized Problems.
+- Routines for The Singular Value Decomposition.
+- Example driver routines that may be used as templates to implement numerous
+- Shift-Invert strategies for all problem types, data types and precision.
+- `arpackmm`: utility to test arpack with matrix market files. Note: to run this utility, you need the eigen library (to handle RCI).
+
+## Documentation
+
+Within DOCUMENTS directory there are three files for templates on how to invoke the computational modes of ARPACK.
+
+- ex-sym.doc
+- ex-nonsym.doc and
+- ex-complex.doc
+
+Also look in the README.MD file for explanations concerning the
+other documents.
+
+## ILP64 support
+
+About ILP64 support:
+
+- Sequential arpack supports [ILP64](https://www.intel.com/content/www/us/en/develop/documentation/onemkl-linux-developer-guide/top/linking-your-application-with-onemkl/linking-in-detail/linking-with-interface-libraries/using-the-ilp64-interface-vs-lp64-interface.html), but, parallel arpack doesn't.
+- Reminder: you can NOT mix `ILP64` with `LP64`. If you compile `arpack-ng` with `ILP64` (resp. `LP64`) support, you MUST insure your BLAS/LAPACK is compliant with `ILP64` (resp. `LP64`).
+- Set `INTERFACE64` at configure time.
+
+Note for F77/F90 developers:
+
+- All files which needs `ILP64` support must include `"arpackicb.h"`.
+- When coding, use `i_int` (defined in `arpackicb.h`) instead of `c_int`. `i_int` stands for `iso_c_binding int`: it's `#defined` to `c_int` or `c_int64_t` according to the architecture.
+
+Note for C/C++ developers:
+
+- All files which needs `ILP64` support must include `"arpackdef.h"`.
+- When coding, use `a_int` (defined in `arpackdef.h`) instead of `int`. Here, `a_int` stands for "architecture int": it's `#defined` to `int` or `int64_t` according to the architecture.
+
+**Example**: to test arpack with sequential `ILP64` MKL assuming you use gnu compilers
+
+```bash
+$ ./bootstrap
+$ export FFLAGS='-DMKL_ILP64 -I/usr/include/mkl'
+$ export FCFLAGS='-DMKL_ILP64 -I/usr/include/mkl'
+$ export LIBS='-Wl,--no-as-needed -L/usr/lib/x86_64-linux-gnu -lmkl_sequential -lmkl_core -lpthread -lm -ldl'
+$ export INTERFACE64=1
+$ ./configure --with-blas=mkl_gf_ilp64 --with-lapack=mkl_gf_ilp64
+$ make all check
+```
+
+## ISO_C_BINDING support
+
+About ISO_C_BINDING support:
+
+- The install will now provide `arpack.h/hpp`, `parpack.h/hpp` and friends.
+- Examples of use can be found in `./TESTS` and` ./PARPACK/TESTS/MPI`.
+
+Those who are interested in `ISO_C_BINDING` support can checkout following links for more informations.
+
+- <http://fortranwiki.org/fortran/show/ISO_C_BINDING>
+- <http://fortranwiki.org/fortran/show/Generating+C+Interfaces>
+- <https://www.roguewave.com/sites/rw/files/attachments/StandardizedMixedLanguageProgrammingforCandFortran.pdf>
+
+**Example**: to test arpack with ISO_C_BINDING
+
+```bash
+$ ./configure --enable-icb
+$ cmake -D ICB=ON
+```
+
+## Eigen support
+
+`arpack-ng` provides C++ eigensolver based on `eigen`.
+
+Check out `./EXAMPLES/MATRIX_MARKET/README` for more details.
+
+**Example**: to test arpack with `eigen`
+
+```bash
+$ mkdir build
+$ cd build
+$ cmake -D EXAMPLES=ON -D ICB=ON -D ICBEXMM=ON ..
+$ make all check
+```
+
+## Python support
+
+`pyarpack`: python support based on `Boost.Python.Numpy` exposing C++ API.
+`pyarpack` exposes in python the `arpack-ng` C++ eigensolver (based on `eigen`).
+
+Check out `./EXAMPLES/PYARPACK/README` for more details.
+
+**Example**: to test arpack with python3
+
+```bash
+$ mkdir build
+$ cd build
+$ cmake -D EXAMPLES=ON -D ICB=ON -D ICBEXMM=ON -D PYTHON3=ON ..
+$ make all check
+```
+
+## 📁 Directory structure
+
+- You have successfully unbundled ARPACK-NG` and are now in the ARPACK-NG directory that was created for you.
+
+- The directory SRC contains the top level routines including the highest level **reverse communication interface** routines
+
+  - `ssaupd`, `dsaupd`: symmetric single and double precision
+  - `snaupd`, `dnaupd`: non-symmetric single and double precision
+  - `cnaupd`, `znaupd`: complex non-symmetric single and double precision
+  - The headers of these routines contain full documentation of calling sequence and usage.
+  - Additional information is given in the `/DOCUMENTS` directory.
+
+- The directory `PARPACK` contains the Parallel ARPACK routines.
 
-Indeed, no single release has been published by Rice university for the last
-few years and since many software (Octave, Scilab, R, Matlab...) forked it and
-implemented their own modifications, arpack-ng aims to tackle this by providing
-a common repository, maintained versions with a testsuite.
+- Example driver programs that illustrate all the computational modes, data types and precisions may be found in the EXAMPLES directory. Upon executing the `ls EXAMPLES` command you should see the following directories
 
-arpack-ng is replacing arpack almost everywhere.
+  ```bash
+  ├── BAND
+  ├── COMPLEX
+  ├── Makefile.am
+  ├── MATRIX_MARKET
+  ├── NONSYM
+  ├── PYARPACK
+  ├── README
+  ├── SIMPLE
+  ├── SVD
+  └── SYM
+  ```
 
-1. You have successfully unbundled ARPACK-NG and are now in the ARPACK-NG
-   directory that was created for you.
+  - Example programs for banded, complex, nonsymmetric, symmetric, and singular value decomposition may be found in the directories BAND, COMPLEX, NONSYM, SYM, SVD respectively.
+  - Look at the README file for further information.
+  - To get started, get into the SIMPLE directory to see example programs that illustrate the use of ARPACK in the simplest modes of operation for the most commonly posed standard eigenvalue problems.
 
-2. The directory SRC contains the top level routines including
-   the highest level reverse communication interface routines
+> Example programs for Parallel ARPACK may be found in the directory `PARPACK/EXAMPLES`. Look at the README file for further information.
 
-* ssaupd, dsaupd - symmetric single and double precision
-* snaupd, dnaupd - non-symmetric single and double precision
-* cnaupd, znaupd - complex non-symmetric single and double precision
+## Install 🚀
 
-   The headers of these routines contain full documentation of calling
-   sequence and usage.  Additional information is in the DOCUMENTS directory.
+### Getting arpack-ng
 
-   The directory PARPACK contains the Parallel ARPACK routines.
+Unlike ARPACK, ARPACK-NG is providing autotools and cmake based build system. In addition, `ARPACK-NG` also provides
+`iso_c_binding` support, which enables to call fortran subroutines natively from C or C++.
 
+First, obtain the source code 📥 from github:
 
-3. Example driver programs that illustrate all the computational modes,
-   data types and precisions may be found in the EXAMPLES directory.
-   Upon executing the 'ls EXAMPLES' command you should see
+```bash
+$ git clone https://github.com/opencollab/arpack-ng.git
+$ cd ./arpack-ng
+```
 
-* BAND
-* COMPLEX
-* NONSYM
-* README
-* SIMPLE
-* SVD
-* SYM
+If you prefer the ssh to obtain the source code, then use:
 
-   Example programs for banded, complex, nonsymmetric, symmetric,
-   and singular value decomposition may be found in the directories
-   BAND, COMPLEX, NONSYM, SYM, SVD respectively.  Look at the README
-   file for further information.  To get started, get into the SIMPLE
-   directory to see example programs that illustrate the use of ARPACK in
-   the simplest modes of operation for the most commonly posed
-   standard eigenvalue problems.
+```bash
+$ git clone git@github.com:opencollab/arpack-ng.git
+$ cd ./arpack-ng
+```
 
+> Note, It is recommended to install `arpack` at standard location on your system by using your root privilege.
 
-   Example programs for Parallel ARPACK may be found in the directory
-   PARPACK/EXAMPLES. Look at the README file for further information.
+### Using autotools
 
-   The following instructions explain how to make the ARPACK library.
+In the source directory, use the following commands to configure, build and install `arpack-ng`.
 
-4. Unlike ARPACK, ARPACK-NG is providing autotools and cmake based build
-   system and iso_c_binding support (which enables to call fortran 
-   subroutines natively from C or C++).
+```bash
+$ sh bootstrap
+$ ./configure --enable-mpi
+$ make
+$ make check
+$ sudo make install
+```
 
-Therefore, the classical commands should work as expected:
-   
-   
-    $ sh bootstrap
-    $ ./configure
-    $ make
-    $ make check
-    $ make install
+Congratulations 🎉, you have installed `arpack` lib using autotools (caution: you need `sudo` to install in your system).
 
-Furthermore, ARPACK-NG now provides CMake functionality:
-   
-    $ mkdir build
-    $ cd build
-    $ cmake -D EXAMPLES=ON -D MPI=ON -D BUILD_SHARED_LIBS=ON ..
-    $ make
-    $ make install
-   builds everything including examples and parallel support (with MPI).
+The above-mentioned process will build everything including the examples and parallel support using MPI.
 
-To use arpack from CMake, use ARPACK::ARPACK target:
+### Using cmake
 
-    find_package(arpack-ng)
-    add_executable(main main.f)
-    target_include_directories(main PUBLIC ARPACK::ARPACK)
-    target_link_libraries(main ARPACK::ARPACK)
+You can install `ARPACK-NG` by using cmake. If you do not have cmake, then please download the binary from `pip` using:
 
-To use parpack from CMake, use PARPACK::PARPACK target:
+```bash
+$ python3 -m pip install cmake
+$ which cmake && cmake --version
+```
 
-    find_package(arpack-ng)
-    add_executable(main main.f)
-    target_include_directories(main PUBLIC PARPACK::PARPACK)
-    target_link_libraries(main PARPACK::PARPACK)
+After installing cmake, follow the instruction given below.
+
+Caution: Make sure you are in source directory of ARPACK-NG.
+
+```bash
+$ mkdir build
+$ cd build
+$ cmake -D EXAMPLES=ON -D MPI=ON -D BUILD_SHARED_LIBS=ON ..
+$ make
+$ sudo make install
+```
+
+✨ Congratulations, you have installed `arpack` lib using cmake (caution: you need `sudo` to install in your system).
+
+The above-mentioned process will build everything including the examples and parallel support using MPI.
+
+### Customize build / install
+
+You can also customize the installation of `arpack` using the autotools.
+
+To customize the install directories:
+
+```bash
+$ LIBSUFFIX="64" ./configure
+$ make all install
+```
+
+To enable ILP64 support:
+
+```bash
+$ INTERFACE64="1" ITF64SUFFIX="ILP64" ./configure
+$ make all install
+```
+
+To enable ISO_C_BINDING support:
+
+```bash
+$ ./configure --enable-icb
+```
+
+You can customize the build by declaring the cmake options during configuration.
+
+To customize the install directories:
+
+```bash
+$ cmake -D LIBSUFFIX="64" ..
+$ make all install
+```
+
+To enable ILP64 support:
+
+```bash
+$ cmake -D INTERFACE64=ON -D ITF64SUFFIX="ILP64" ..
+$ make all install
+```
+
+To enable ISO_C_BINDING support:
+
+```bash
+$ cmake -D ICB=ON
+```
+
+## Supported Operating Systems:
+
+### Linux support
+
+`arpack-ng` runs on debian-based distros.
+
+### Mac OS support
 
 On mac OS, with GNU compilers, you may need to customize options:
 
-    $ LIBS="-framework Accelerate" FFLAGS="-ff2c -fno-second-underscore" FCFLAGS="-ff2c -fno-second-underscore" ./configure
-
-To build with code coverage:
-   
-    $ mkdir build
-    $ cd build
-    $ cmake -DCOVERALLS=ON -DCMAKE_BUILD_TYPE=Debug ..
-    $ make all check test coveralls
-
-To get iso_c_binding support:
-   
-    $ ./configure --enable-icb
-    $ cmake -D ICB=ON
-   The install will now provide arpack.h/hpp, parpack.h/hpp and friends.
-   Examples of use can be found in ./TESTS and ./PARPACK/TESTS/MPI.
-   A few related links can be found here:
-
-   * http://fortranwiki.org/fortran/show/ISO_C_BINDING
-   * http://fortranwiki.org/fortran/show/Generating+C+Interfaces
-   * https://www.roguewave.com/sites/rw/files/attachments/StandardizedMixedLanguageProgrammingforCandFortran.pdf
-
-5. Within DOCUMENTS directory there are three files
-
-* ex-sym.doc
-* ex-nonsym.doc and
-* ex-complex.doc
-
-   for templates on how to invoke the computational modes of ARPACK.
-   Also look in the README.MD file for explanations concerning the
-   other documents.
- 
- Good luck and enjoy.
+```bash
+$ LIBS="-framework Accelerate" FFLAGS="-ff2c -fno-second-underscore" FCFLAGS="-ff2c -fno-second-underscore" ./configure
+```
+
+### Windows support
+
+`arpack-ng` runs on windows using `mingw64`.
+
+## Using arpack-ng from your own codebase
+
+### With autotools
+
+First, set `PKG_CONFIG_PATH` to the location in the installation directory where `arpack.pc` lies.
+
+Then, insert the following lines in your `configure.ac`:
+```
+PKG_CHECK_MODULES([ARPACK], [arpack])
+AC_SUBST([ARPACK_CFLAGS])
+AC_SUBST([ARPACK_LIBS])
+```
+
+Note: make sure you have installed `pkg-config`.
+
+### With CMake
+
+You can use arpack in your CMake builds by using `ARPACK::ARPACK` target. For example,
+
+```cmake
+FIND_PACKAGE(arpack-ng)
+ADD_EXECUTABLE(main main.f)
+TARGET_INCLUDE_DIRECTORIES(main PUBLIC ARPACK::ARPACK)
+TARGET_LINK_LIBRARIES(main ARPACK::ARPACK)
+```
+
+To use PARPACK in your Cmake builds, use `PARPACK::PARPACK` target:
+
+```cmake
+FIND_PACKAGE(arpack-ng)
+ADD_EXECUTABLE(main main.f)
+TARGET_INCLUDE_DIRECTORIES(main PUBLIC PARPACK::PARPACK)
+TARGET_LINK_LIBRARIES(main PARPACK::PARPACK)
+```
+
+Note: Make sure to update `CMAKE_MODULE_PATH` env variable (otheriwse, `find_package` won't find arpack-ng cmake file).
+
+## Using MKL instead of BLAS / LAPACK
+
+How to use arpack-ng with Intel MKL:
+
+- Let autotools/cmake find MKL for you based on pkg-config files (setting `PKG_CONFIG_PATH`) or cmake options (`BLA_VENDOR=Intel`).
+- Refers to the Intel Link Advisor: <https://www.intel.com/content/www/us/en/developer/tools/oneapi/onemkl-link-line-advisor.html>.
+
+## Good luck and enjoy 🎊
diff --git a/SRC/Makefile.am b/SRC/Makefile.am
index 8471035..afc48c0 100644
--- a/SRC/Makefile.am
+++ b/SRC/Makefile.am
@@ -9,10 +9,10 @@ DSRC = dnaitr.f dnapps.f dnaup2.f dnaupd.f dnconv.f dneigh.f dneupd.f dngets.f d
        dgetv0.f dsortc.f dsortr.f dsesrt.f dstqrb.f
 
 CSRC = cnaitr.f cnapps.f cnaup2.f cnaupd.f cneigh.f cneupd.f cngets.f cstatn.f \
-       cgetv0.f csortc.f
+       cgetv0.f csortc.f ccdotc.f
 
 ZSRC = znaitr.f znapps.f znaup2.f znaupd.f zneigh.f zneupd.f zngets.f zstatn.f \
-       zgetv0.f zsortc.f
+       zgetv0.f zsortc.f zzdotc.f
 
 if ICB
 SSRC += icbass.F90 icbasn.F90
@@ -23,18 +23,13 @@ endif
 
 EXTRA_DIST = debug.h stat.h version.h
 
-lib_LTLIBRARIES = libarpack@LIBSUFFIX@.la
-libarpack@LIBSUFFIX@_la_SOURCES = $(SSRC) $(DSRC) $(CSRC) $(ZSRC)
-libarpack@LIBSUFFIX@_la_SOURCES += $(top_builddir)/dbgini.f
-libarpack@LIBSUFFIX@_la_SOURCES += $(top_builddir)/staini.f
-libarpack@LIBSUFFIX@_la_LIBADD = $(top_builddir)/UTIL/libarpackutil.la $(LAPACK_LIBS) $(BLAS_LIBS)
-libarpack@LIBSUFFIX@_la_LDFLAGS = -no-undefined -version-info 3:0:1
+lib_LTLIBRARIES = libarpack@LIBSUFFIX@@ITF64SUFFIX@.la
+libarpack@LIBSUFFIX@@ITF64SUFFIX@_la_SOURCES = $(SSRC) $(DSRC) $(CSRC) $(ZSRC)
+libarpack@LIBSUFFIX@@ITF64SUFFIX@_la_SOURCES += $(top_builddir)/dbgini.f
+libarpack@LIBSUFFIX@@ITF64SUFFIX@_la_SOURCES += $(top_builddir)/staini.f
+libarpack@LIBSUFFIX@@ITF64SUFFIX@_la_LIBADD = $(top_builddir)/UTIL/libarpackutil.la $(LAPACK_LIBS) $(BLAS_LIBS)
+libarpack@LIBSUFFIX@@ITF64SUFFIX@_la_LDFLAGS = -no-undefined -version-info 3:0:1
 if ICB
-libarpack@LIBSUFFIX@_la_LIBADD += $(top_builddir)/ICB/libdbgicb.la $(top_builddir)/ICB/libstaicb.la
-libarpack@LIBSUFFIX@_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)
+libarpack@LIBSUFFIX@@ITF64SUFFIX@_la_LIBADD += $(top_builddir)/ICB/libdbgicb.la $(top_builddir)/ICB/libstaicb.la
+libarpack@LIBSUFFIX@@ITF64SUFFIX@_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)
 endif
-
-pkgconfig_DATA = arpack@LIBSUFFIX@.pc
-
-# Due to the LIBSUFFIX, configure doesn't automatically clean this file:
-DISTCLEANFILES = arpack@LIBSUFFIX@.pc
diff --git a/SRC/ccdotc.f b/SRC/ccdotc.f
new file mode 100644
index 0000000..f0f94f4
--- /dev/null
+++ b/SRC/ccdotc.f
@@ -0,0 +1,36 @@
+      complex function ccdotc(n,zx,incx,zy,incy)
+c
+c     forms the dot product of a vector.
+c     jack dongarra, 3/11/78.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      complex zx(*),zy(*),ztemp
+      integer i,incx,incy,ix,iy,n
+      ztemp = (0.0d0,0.0d0)
+      ccdotc = (0.0d0,0.0d0)
+      if(n.le.0)return
+      if(incx.eq.1.and.incy.eq.1)go to 20
+c
+c        code for unequal increments or equal increments
+c          not equal to 1
+c
+      ix = 1
+      iy = 1
+      if(incx.lt.0)ix = (-n+1)*incx + 1
+      if(incy.lt.0)iy = (-n+1)*incy + 1
+      do 10 i = 1,n
+        ztemp = ztemp + conjg(zx(ix))*zy(iy)
+        ix = ix + incx
+        iy = iy + incy
+   10 continue
+      ccdotc = ztemp
+      return
+c
+c        code for both increments equal to 1
+c
+   20 do 30 i = 1,n
+        ztemp = ztemp + conjg(zx(i))*zy(i)
+   30 continue
+      ccdotc = ztemp
+      return
+      end
diff --git a/SRC/cgetv0.f b/SRC/cgetv0.f
index a91ef92..b49e667 100644
--- a/SRC/cgetv0.f
+++ b/SRC/cgetv0.f
@@ -156,13 +156,13 @@ c     %------------------------%
 c     | Local Scalars & Arrays |
 c     %------------------------%
 c
-      logical    first, inits, orth
+      logical    first, orth
       integer    idist, iseed(4), iter, msglvl, jj
       Real
      &           rnorm0
       Complex
      &           cnorm
-      save       first, iseed, inits, iter, msglvl, orth, rnorm0
+      save       first, iseed, iter, msglvl, orth, rnorm0
 c
 c     %----------------------%
 c     | External Subroutines |
@@ -177,14 +177,8 @@ c
       Real
      &           scnrm2, slapy2
       Complex
-     &           cdotc
-      external   cdotc, scnrm2, slapy2
-c
-c     %-----------------%
-c     | Data Statements |
-c     %-----------------%
-c
-      data       inits /.true./
+     &           ccdotc
+      external   ccdotc, scnrm2, slapy2
 c
 c     %-----------------------%
 c     | Executable Statements |
@@ -196,13 +190,10 @@ c     | Initialize the seed of the LAPACK |
 c     | random number generator           |
 c     %-----------------------------------%
 c
-      if (inits) then
-          iseed(1) = 1
-          iseed(2) = 3
-          iseed(3) = 5
-          iseed(4) = 7
-          inits = .false.
-      end if
+      iseed(1) = 1
+      iseed(2) = 3
+      iseed(3) = 5
+      iseed(4) = 7
 c
       if (ido .eq.  0) then
 c
@@ -293,7 +284,7 @@ c
 c
       first = .FALSE.
       if (bmat .eq. 'G') then
-          cnorm  = cdotc (n, resid, 1, workd, 1)
+          cnorm  = ccdotc (n, resid, 1, workd, 1)
           rnorm0 = sqrt(slapy2(real(cnorm),aimag(cnorm)))
       else if (bmat .eq. 'I') then
            rnorm0 = scnrm2(n, resid, 1)
@@ -350,7 +341,7 @@ c
       end if
 c
       if (bmat .eq. 'G') then
-         cnorm = cdotc (n, resid, 1, workd, 1)
+         cnorm = ccdotc (n, resid, 1, workd, 1)
          rnorm = sqrt(slapy2(real(cnorm),aimag(cnorm)))
       else if (bmat .eq. 'I') then
          rnorm = scnrm2(n, resid, 1)
diff --git a/SRC/cnaitr.f b/SRC/cnaitr.f
index bebd823..3759760 100644
--- a/SRC/cnaitr.f
+++ b/SRC/cnaitr.f
@@ -280,10 +280,10 @@ c     | External Functions |
 c     %--------------------%
 c
       Complex
-     &           cdotc
+     &           ccdotc
       Real
      &           slamch,  scnrm2, clanhs, slapy2
-      external   cdotc, scnrm2, clanhs, slamch, slapy2
+      external   ccdotc, scnrm2, clanhs, slamch, slapy2
 c
 c     %---------------------%
 c     | Intrinsic Functions |
@@ -550,7 +550,7 @@ c        | Compute the B-norm of OP*v_{j}.     |
 c        %-------------------------------------%
 c
          if (bmat .eq. 'G') then
-             cnorm = cdotc (n, resid, 1, workd(ipj), 1)
+             cnorm = ccdotc (n, resid, 1, workd(ipj), 1)
              wnorm = sqrt( slapy2(real(cnorm),aimag(cnorm)) )
          else if (bmat .eq. 'I') then
              wnorm = scnrm2(n, resid, 1)
@@ -622,7 +622,7 @@ c        | Compute the B-norm of r_{j}. |
 c        %------------------------------%
 c
          if (bmat .eq. 'G') then
-            cnorm = cdotc (n, resid, 1, workd(ipj), 1)
+            cnorm = ccdotc (n, resid, 1, workd(ipj), 1)
             rnorm = sqrt( slapy2(real(cnorm),aimag(cnorm)) )
          else if (bmat .eq. 'I') then
             rnorm = scnrm2(n, resid, 1)
@@ -722,7 +722,7 @@ c        | Compute the B-norm of the corrected residual r_{j}. |
 c        %-----------------------------------------------------%
 c
          if (bmat .eq. 'G') then
-             cnorm  = cdotc (n, resid, 1, workd(ipj), 1)
+             cnorm  = ccdotc (n, resid, 1, workd(ipj), 1)
              rnorm1 = sqrt( slapy2(real(cnorm),aimag(cnorm)) )
          else if (bmat .eq. 'I') then
              rnorm1 = scnrm2(n, resid, 1)
diff --git a/SRC/cnaup2.f b/SRC/cnaup2.f
index 3f106f0..e361542 100644
--- a/SRC/cnaup2.f
+++ b/SRC/cnaup2.f
@@ -247,10 +247,10 @@ c     | External functions |
 c     %--------------------%
 c
       Complex
-     &           cdotc
+     &           ccdotc
       Real
      &           scnrm2, slamch, slapy2
-      external   cdotc, scnrm2, slamch, slapy2
+      external   ccdotc, scnrm2, slamch, slapy2
 c
 c     %---------------------%
 c     | Intrinsic Functions |
@@ -754,7 +754,7 @@ c
          end if
 c
          if (bmat .eq. 'G') then
-            cmpnorm = cdotc (n, resid, 1, workd, 1)
+            cmpnorm = ccdotc (n, resid, 1, workd, 1)
             rnorm = sqrt(slapy2(real (cmpnorm),aimag(cmpnorm)))
          else if (bmat .eq. 'I') then
             rnorm = scnrm2(n, resid, 1)
diff --git a/SRC/cneupd.f b/SRC/cneupd.f
index 34a78f7..29154ce 100644
--- a/SRC/cneupd.f
+++ b/SRC/cneupd.f
@@ -325,8 +325,8 @@ c
       external   scnrm2, slamch, slapy2
 c
       Complex
-     &           cdotc
-      external   cdotc
+     &           ccdotc
+      external   ccdotc
 c
 c     %-----------------------%
 c     | Executable Statements |
@@ -731,7 +731,7 @@ c                 | upper triangular, thus the length of the |
 c                 | inner product can be set to j.           |
 c                 %------------------------------------------%
 c
-                  workev(j) = cdotc(j, workl(ihbds), 1,
+                  workev(j) = ccdotc(j, workl(ihbds), 1,
      &                        workl(invsub+(j-1)*ldq), 1)
  40         continue
 c
diff --git a/SRC/dgetv0.f b/SRC/dgetv0.f
index 1d6dc01..8be4fa2 100644
--- a/SRC/dgetv0.f
+++ b/SRC/dgetv0.f
@@ -157,11 +157,11 @@ c     %------------------------%
 c     | Local Scalars & Arrays |
 c     %------------------------%
 c
-      logical    first, inits, orth
+      logical    first, orth
       integer    idist, iseed(4), iter, msglvl, jj
       Double precision
      &           rnorm0
-      save       first, iseed, inits, iter, msglvl, orth, rnorm0
+      save       first, iseed, iter, msglvl, orth, rnorm0
 c
 c     %----------------------%
 c     | External Subroutines |
@@ -183,12 +183,6 @@ c     %---------------------%
 c
       intrinsic    abs, sqrt
 c
-c     %-----------------%
-c     | Data Statements |
-c     %-----------------%
-c
-      data       inits /.true./
-c
 c     %-----------------------%
 c     | Executable Statements |
 c     %-----------------------%
@@ -199,13 +193,10 @@ c     | Initialize the seed of the LAPACK |
 c     | random number generator           |
 c     %-----------------------------------%
 c
-      if (inits) then
-          iseed(1) = 1
-          iseed(2) = 3
-          iseed(3) = 5
-          iseed(4) = 7
-          inits = .false.
-      end if
+      iseed(1) = 1
+      iseed(2) = 3
+      iseed(3) = 5
+      iseed(4) = 7
 c
       if (ido .eq.  0) then
 c
diff --git a/SRC/dnapps.f b/SRC/dnapps.f
index 7fb37d8..1cf3725 100644
--- a/SRC/dnapps.f
+++ b/SRC/dnapps.f
@@ -13,7 +13,7 @@ c
 c     A*(V_{k}*Q) - (V_{k}*Q)*(Q^T* H_{k}*Q) = r_{k+p}*e_{k+p}^T * Q
 c
 c  where Q is an orthogonal matrix which is the product of rotations
-c  and reflections resulting from the NP bulge chage sweeps.
+c  and reflections resulting from the NP bulge change sweeps.
 c  The updated Arnoldi factorization becomes:
 c
 c     A*VNEW_{k} - VNEW_{k}*HNEW_{k} = rnew_{k}*e_{k}^T.
diff --git a/SRC/dnaup2.f b/SRC/dnaup2.f
index 18ad20a..86375a6 100644
--- a/SRC/dnaup2.f
+++ b/SRC/dnaup2.f
@@ -598,7 +598,7 @@ c
 c
 c           %----------------------------------------------------%
 c           | Sort the Ritz values according to the scaled Ritz  |
-c           | esitmates.  This will push all the converged ones  |
+c           | estimates.  This will push all the converged ones  |
 c           | towards the front of ritzr, ritzi, bounds          |
 c           | (in the case when NCONV < NEV.)                    |
 c           %----------------------------------------------------%
diff --git a/SRC/dnaupd.f b/SRC/dnaupd.f
index dcf1f77..0b4cbb0 100644
--- a/SRC/dnaupd.f
+++ b/SRC/dnaupd.f
@@ -298,7 +298,7 @@ c     eigenvector z of the original problem is recovered by solving
 c     L`z = x  where x is a Ritz vector of OP.
 c
 c  4. At present there is no a-priori analysis to guide the selection
-c     of NCV relative to NEV.  The only formal requrement is that NCV > NEV + 2.
+c     of NCV relative to NEV.  The only formal requirement is that NCV > NEV + 2.
 c     However, it is recommended that NCV .ge. 2*NEV+1.  If many problems of
 c     the same type are to be solved, one should experiment with increasing
 c     NCV while keeping NEV fixed for a given test problem.  This will
diff --git a/SRC/dneupd.f b/SRC/dneupd.f
index 9c2ece0..860ceb8 100644
--- a/SRC/dneupd.f
+++ b/SRC/dneupd.f
@@ -994,9 +994,9 @@ c
 c
       if (type .eq. 'SHIFTI' .and. msglvl .gt. 1) then
          call dvout (logfil, nconv, dr, ndigit,
-     &   '_neupd: Untransformed real part of the Ritz valuess.')
+     &   '_neupd: Untransformed real part of the Ritz values.')
          call dvout  (logfil, nconv, di, ndigit,
-     &   '_neupd: Untransformed imag part of the Ritz valuess.')
+     &   '_neupd: Untransformed imag part of the Ritz values.')
          call dvout (logfil, nconv, workl(ihbds), ndigit,
      &   '_neupd: Ritz estimates of untransformed Ritz values.')
       else if (type .eq. 'REGULR' .and. msglvl .gt. 1) then
diff --git a/SRC/dsaup2.f b/SRC/dsaup2.f
index f7d4a11..fd4143f 100644
--- a/SRC/dsaup2.f
+++ b/SRC/dsaup2.f
@@ -588,7 +588,7 @@ c
 c
 c           %----------------------------------------------------%
 c           | Sort the Ritz values according to the scaled Ritz  |
-c           | esitmates.  This will push all the converged ones  |
+c           | estimates.  This will push all the converged ones  |
 c           | towards the front of ritzr, ritzi, bounds          |
 c           | (in the case when NCONV < NEV.)                    |
 c           %----------------------------------------------------%
diff --git a/SRC/dsaupd.f b/SRC/dsaupd.f
index c5b08d6..81a0ce5 100644
--- a/SRC/dsaupd.f
+++ b/SRC/dsaupd.f
@@ -297,7 +297,7 @@ c     eigenvector z of the original problem is recovered by solving
 c     L`z = x  where x is a Ritz vector of OP.
 c
 c  4. At present there is no a-priori analysis to guide the selection
-c     of NCV relative to NEV.  The only formal requrement is that NCV > NEV.
+c     of NCV relative to NEV.  The only formal requirement is that NCV > NEV.
 c     However, it is recommended that NCV .ge. 2*NEV.  If many problems of
 c     the same type are to be solved, one should experiment with increasing
 c     NCV while keeping NEV fixed for a given test problem.  This will
diff --git a/SRC/dstqrb.f b/SRC/dstqrb.f
index f69067c..d55a59a 100644
--- a/SRC/dstqrb.f
+++ b/SRC/dstqrb.f
@@ -93,7 +93,7 @@ c
 c\Remarks
 c     1. Starting with version 2.5, this routine is a modified version
 c        of LAPACK version 2.0 subroutine SSTEQR. No lines are deleted,
-c        only commeted out and new lines inserted.
+c        only commented out and new lines inserted.
 c        All lines commented out have "c$$$" at the beginning.
 c        Note that the LAPACK version 1.0 subroutine SSTEQR contained
 c        bugs.
diff --git a/SRC/sgetv0.f b/SRC/sgetv0.f
index d861b2d..26130a0 100644
--- a/SRC/sgetv0.f
+++ b/SRC/sgetv0.f
@@ -157,11 +157,11 @@ c     %------------------------%
 c     | Local Scalars & Arrays |
 c     %------------------------%
 c
-      logical    first, inits, orth
+      logical    first, orth
       integer    idist, iseed(4), iter, msglvl, jj
       Real
      &           rnorm0
-      save       first, iseed, inits, iter, msglvl, orth, rnorm0
+      save       first, iseed, iter, msglvl, orth, rnorm0
 c
 c     %----------------------%
 c     | External Subroutines |
@@ -183,12 +183,6 @@ c     %---------------------%
 c
       intrinsic    abs, sqrt
 c
-c     %-----------------%
-c     | Data Statements |
-c     %-----------------%
-c
-      data       inits /.true./
-c
 c     %-----------------------%
 c     | Executable Statements |
 c     %-----------------------%
@@ -199,13 +193,10 @@ c     | Initialize the seed of the LAPACK |
 c     | random number generator           |
 c     %-----------------------------------%
 c
-      if (inits) then
-          iseed(1) = 1
-          iseed(2) = 3
-          iseed(3) = 5
-          iseed(4) = 7
-          inits = .false.
-      end if
+      iseed(1) = 1
+      iseed(2) = 3
+      iseed(3) = 5
+      iseed(4) = 7
 c
       if (ido .eq.  0) then
 c
diff --git a/SRC/snapps.f b/SRC/snapps.f
index 9b76728..33b0361 100644
--- a/SRC/snapps.f
+++ b/SRC/snapps.f
@@ -13,7 +13,7 @@ c
 c     A*(V_{k}*Q) - (V_{k}*Q)*(Q^T* H_{k}*Q) = r_{k+p}*e_{k+p}^T * Q
 c
 c  where Q is an orthogonal matrix which is the product of rotations
-c  and reflections resulting from the NP bulge chage sweeps.
+c  and reflections resulting from the NP bulge change sweeps.
 c  The updated Arnoldi factorization becomes:
 c
 c     A*VNEW_{k} - VNEW_{k}*HNEW_{k} = rnew_{k}*e_{k}^T.
diff --git a/SRC/snaup2.f b/SRC/snaup2.f
index 12b2cfe..e3be754 100644
--- a/SRC/snaup2.f
+++ b/SRC/snaup2.f
@@ -598,7 +598,7 @@ c
 c
 c           %----------------------------------------------------%
 c           | Sort the Ritz values according to the scaled Ritz  |
-c           | esitmates.  This will push all the converged ones  |
+c           | estimates.  This will push all the converged ones  |
 c           | towards the front of ritzr, ritzi, bounds          |
 c           | (in the case when NCONV < NEV.)                    |
 c           %----------------------------------------------------%
diff --git a/SRC/snaupd.f b/SRC/snaupd.f
index e0be1bf..d6fad33 100644
--- a/SRC/snaupd.f
+++ b/SRC/snaupd.f
@@ -298,7 +298,7 @@ c     eigenvector z of the original problem is recovered by solving
 c     L`z = x  where x is a Ritz vector of OP.
 c
 c  4. At present there is no a-priori analysis to guide the selection
-c     of NCV relative to NEV.  The only formal requrement is that NCV > NEV + 2.
+c     of NCV relative to NEV.  The only formal requirement is that NCV > NEV + 2.
 c     However, it is recommended that NCV .ge. 2*NEV+1.  If many problems of
 c     the same type are to be solved, one should experiment with increasing
 c     NCV while keeping NEV fixed for a given test problem.  This will
diff --git a/SRC/sneupd.f b/SRC/sneupd.f
index 4c472fe..1c2c7ce 100644
--- a/SRC/sneupd.f
+++ b/SRC/sneupd.f
@@ -993,9 +993,9 @@ c
 c
       if (type .eq. 'SHIFTI' .and. msglvl .gt. 1) then
          call svout(logfil, nconv, dr, ndigit,
-     &   '_neupd: Untransformed real part of the Ritz valuess.')
+     &   '_neupd: Untransformed real part of the Ritz values.')
          call svout (logfil, nconv, di, ndigit,
-     &   '_neupd: Untransformed imag part of the Ritz valuess.')
+     &   '_neupd: Untransformed imag part of the Ritz values.')
          call svout(logfil, nconv, workl(ihbds), ndigit,
      &   '_neupd: Ritz estimates of untransformed Ritz values.')
       else if (type .eq. 'REGULR' .and. msglvl .gt. 1) then
diff --git a/SRC/ssaup2.f b/SRC/ssaup2.f
index 8cc0463..504f28f 100644
--- a/SRC/ssaup2.f
+++ b/SRC/ssaup2.f
@@ -587,7 +587,7 @@ c
 c
 c           %----------------------------------------------------%
 c           | Sort the Ritz values according to the scaled Ritz  |
-c           | esitmates.  This will push all the converged ones  |
+c           | estimates.  This will push all the converged ones  |
 c           | towards the front of ritzr, ritzi, bounds          |
 c           | (in the case when NCONV < NEV.)                    |
 c           %----------------------------------------------------%
diff --git a/SRC/ssaupd.f b/SRC/ssaupd.f
index a8d2f2d..9756815 100644
--- a/SRC/ssaupd.f
+++ b/SRC/ssaupd.f
@@ -297,7 +297,7 @@ c     eigenvector z of the original problem is recovered by solving
 c     L`z = x  where x is a Ritz vector of OP.
 c
 c  4. At present there is no a-priori analysis to guide the selection
-c     of NCV relative to NEV.  The only formal requrement is that NCV > NEV.
+c     of NCV relative to NEV.  The only formal requirement is that NCV > NEV.
 c     However, it is recommended that NCV .ge. 2*NEV.  If many problems of
 c     the same type are to be solved, one should experiment with increasing
 c     NCV while keeping NEV fixed for a given test problem.  This will
diff --git a/SRC/sstqrb.f b/SRC/sstqrb.f
index 63c5e45..9697c36 100644
--- a/SRC/sstqrb.f
+++ b/SRC/sstqrb.f
@@ -93,7 +93,7 @@ c
 c\Remarks
 c     1. Starting with version 2.5, this routine is a modified version
 c        of LAPACK version 2.0 subroutine SSTEQR. No lines are deleted,
-c        only commeted out and new lines inserted.
+c        only commented out and new lines inserted.
 c        All lines commented out have "c$$$" at the beginning.
 c        Note that the LAPACK version 1.0 subroutine SSTEQR contained
 c        bugs.
diff --git a/SRC/zgetv0.f b/SRC/zgetv0.f
index ff5c2b1..cc13c3c 100644
--- a/SRC/zgetv0.f
+++ b/SRC/zgetv0.f
@@ -156,13 +156,13 @@ c     %------------------------%
 c     | Local Scalars & Arrays |
 c     %------------------------%
 c
-      logical    first, inits, orth
+      logical    first, orth
       integer    idist, iseed(4), iter, msglvl, jj
       Double precision
      &           rnorm0
       Complex*16
      &           cnorm
-      save       first, iseed, inits, iter, msglvl, orth, rnorm0
+      save       first, iseed, iter, msglvl, orth, rnorm0
 c
 c     %----------------------%
 c     | External Subroutines |
@@ -177,14 +177,8 @@ c
       Double precision
      &           dznrm2, dlapy2
       Complex*16
-     &           zdotc
-      external   zdotc, dznrm2, dlapy2
-c
-c     %-----------------%
-c     | Data Statements |
-c     %-----------------%
-c
-      data       inits /.true./
+     &           zzdotc
+      external   zzdotc, dznrm2, dlapy2
 c
 c     %-----------------------%
 c     | Executable Statements |
@@ -196,13 +190,10 @@ c     | Initialize the seed of the LAPACK |
 c     | random number generator           |
 c     %-----------------------------------%
 c
-      if (inits) then
-          iseed(1) = 1
-          iseed(2) = 3
-          iseed(3) = 5
-          iseed(4) = 7
-          inits = .false.
-      end if
+      iseed(1) = 1
+      iseed(2) = 3
+      iseed(3) = 5
+      iseed(4) = 7
 c
       if (ido .eq.  0) then
 c
@@ -293,8 +284,8 @@ c
 c
       first = .FALSE.
       if (bmat .eq. 'G') then
-          cnorm  = zdotc (n, resid, 1, workd, 1)
-          rnorm0 = sqrt(dlapy2(dble(cnorm),dimag(cnorm)))
+          cnorm  = zzdotc (n, resid, 1, workd, 1)
+          rnorm0 = sqrt(dlapy2(dble(cnorm),aimag(cnorm)))
       else if (bmat .eq. 'I') then
            rnorm0 = dznrm2(n, resid, 1)
       end if
@@ -350,8 +341,8 @@ c
       end if
 c
       if (bmat .eq. 'G') then
-         cnorm = zdotc (n, resid, 1, workd, 1)
-         rnorm = sqrt(dlapy2(dble(cnorm),dimag(cnorm)))
+         cnorm = zzdotc (n, resid, 1, workd, 1)
+         rnorm = sqrt(dlapy2(dble(cnorm),aimag(cnorm)))
       else if (bmat .eq. 'I') then
          rnorm = dznrm2(n, resid, 1)
       end if
diff --git a/SRC/znaitr.f b/SRC/znaitr.f
index 1c5aa57..240412c 100644
--- a/SRC/znaitr.f
+++ b/SRC/znaitr.f
@@ -280,16 +280,16 @@ c     | External Functions |
 c     %--------------------%
 c
       Complex*16
-     &           zdotc
+     &           zzdotc
       Double precision
      &           dlamch,  dznrm2, zlanhs, dlapy2
-      external   zdotc, dznrm2, zlanhs, dlamch, dlapy2
+      external   zzdotc, dznrm2, zlanhs, dlamch, dlapy2
 c
 c     %---------------------%
 c     | Intrinsic Functions |
 c     %---------------------%
 c
-      intrinsic  dimag, dble, max, sqrt
+      intrinsic  aimag, dble, max, sqrt
 c
 c     %-----------------%
 c     | Data statements |
@@ -550,8 +550,8 @@ c        | Compute the B-norm of OP*v_{j}.     |
 c        %-------------------------------------%
 c
          if (bmat .eq. 'G') then
-             cnorm = zdotc (n, resid, 1, workd(ipj), 1)
-             wnorm = sqrt( dlapy2(dble(cnorm),dimag(cnorm)) )
+             cnorm = zzdotc (n, resid, 1, workd(ipj), 1)
+             wnorm = sqrt( dlapy2(dble(cnorm),aimag(cnorm)) )
          else if (bmat .eq. 'I') then
              wnorm = dznrm2(n, resid, 1)
          end if
@@ -581,7 +581,7 @@ c
          call zgemv ('N', n, j, -one, v, ldv, h(1,j), 1,
      &               one, resid, 1)
 c
-         if (j .gt. 1) h(j,j-1) = dcmplx(betaj, rzero)
+         if (j .gt. 1) h(j,j-1) = cmplx(betaj, rzero, Kind=Kind(0d0))
 c
          call arscnd (t4)
 c
@@ -622,8 +622,8 @@ c        | Compute the B-norm of r_{j}. |
 c        %------------------------------%
 c
          if (bmat .eq. 'G') then
-            cnorm = zdotc (n, resid, 1, workd(ipj), 1)
-            rnorm = sqrt( dlapy2(dble(cnorm),dimag(cnorm)) )
+            cnorm = zzdotc (n, resid, 1, workd(ipj), 1)
+            rnorm = sqrt( dlapy2(dble(cnorm),aimag(cnorm)) )
          else if (bmat .eq. 'I') then
             rnorm = dznrm2(n, resid, 1)
          end if
@@ -722,8 +722,8 @@ c        | Compute the B-norm of the corrected residual r_{j}. |
 c        %-----------------------------------------------------%
 c
          if (bmat .eq. 'G') then
-             cnorm  = zdotc (n, resid, 1, workd(ipj), 1)
-             rnorm1 = sqrt( dlapy2(dble(cnorm),dimag(cnorm)) )
+             cnorm  = zzdotc (n, resid, 1, workd(ipj), 1)
+             rnorm1 = sqrt( dlapy2(dble(cnorm),aimag(cnorm)) )
          else if (bmat .eq. 'I') then
              rnorm1 = dznrm2(n, resid, 1)
          end if
@@ -811,11 +811,11 @@ c              | Use a standard test as in the QR algorithm |
 c              | REFERENCE: LAPACK subroutine zlahqr        |
 c              %--------------------------------------------%
 c
-               tst1 = dlapy2(dble(h(i,i)),dimag(h(i,i)))
-     &              + dlapy2(dble(h(i+1,i+1)), dimag(h(i+1,i+1)))
+               tst1 = dlapy2(dble(h(i,i)),aimag(h(i,i)))
+     &              + dlapy2(dble(h(i+1,i+1)), aimag(h(i+1,i+1)))
                if( tst1.eq.dble(zero) )
      &              tst1 = zlanhs( '1', k+np, h, ldh, workd(n+1) )
-               if( dlapy2(dble(h(i+1,i)),dimag(h(i+1,i))) .le.
+               if( dlapy2(dble(h(i+1,i)),aimag(h(i+1,i))) .le.
      &                    max( ulp*tst1, smlnum ) )
      &             h(i+1,i) = zero
  110        continue
diff --git a/SRC/znapps.f b/SRC/znapps.f
index 6d8d12a..792fe61 100644
--- a/SRC/znapps.f
+++ b/SRC/znapps.f
@@ -198,7 +198,7 @@ c     %----------------------%
 c     | Intrinsics Functions |
 c     %----------------------%
 c
-      intrinsic  abs, dimag, conjg, dcmplx, max, min, dble
+      intrinsic  abs, aimag, conjg, cmplx, max, min, dble
 c
 c     %---------------------%
 c     | Statement Functions |
@@ -206,7 +206,7 @@ c     %---------------------%
 c
       Double precision
      &           zabs1
-      zabs1( cdum ) = abs( dble( cdum ) ) + abs( dimag( cdum ) )
+      zabs1( cdum ) = abs( dble( cdum ) ) + abs( aimag( cdum ) )
 c
 c     %----------------%
 c     | Data statements |
@@ -405,12 +405,12 @@ c     %---------------------------------------------------%
 c
       do 120 j=1,kev
          if ( dble( h(j+1,j) ) .lt. rzero .or.
-     &        dimag( h(j+1,j) ) .ne. rzero ) then
-            t = h(j+1,j) / dlapy2(dble(h(j+1,j)),dimag(h(j+1,j)))
+     &        aimag( h(j+1,j) ) .ne. rzero ) then
+            t = h(j+1,j) / dlapy2(dble(h(j+1,j)),aimag(h(j+1,j)))
             call zscal( kplusp-j+1, conjg(t), h(j+1,j), ldh )
             call zscal( min(j+2, kplusp), t, h(1,j+1), 1 )
             call zscal( min(j+np+1,kplusp), t, q(1,j+1), 1 )
-            h(j+1,j) = dcmplx( dble( h(j+1,j) ), rzero )
+            h(j+1,j) = cmplx( dble( h(j+1,j) ), rzero, Kind=Kind(0d0) )
          end if
   120 continue
 c
diff --git a/SRC/znaup2.f b/SRC/znaup2.f
index b814cf1..0ab01dd 100644
--- a/SRC/znaup2.f
+++ b/SRC/znaup2.f
@@ -247,16 +247,16 @@ c     | External functions |
 c     %--------------------%
 c
       Complex*16
-     &           zdotc
+     &           zzdotc
       Double precision
      &           dznrm2 , dlamch , dlapy2
-      external   zdotc , dznrm2 , dlamch , dlapy2
+      external   zzdotc , dznrm2 , dlamch , dlapy2
 c
 c     %---------------------%
 c     | Intrinsic Functions |
 c     %---------------------%
 c
-      intrinsic  dimag , dble , min, max
+      intrinsic  aimag , dble , min, max
 c
 c     %-----------------------%
 c     | Executable Statements |
@@ -489,8 +489,8 @@ c
 c
          do 25 i = 1, nev
             rtemp = max( eps23, dlapy2 ( dble (ritz(np+i)),
-     &                                  dimag (ritz(np+i)) ) )
-            if ( dlapy2 (dble (bounds(np+i)),dimag (bounds(np+i)))
+     &                                  aimag (ritz(np+i)) ) )
+            if ( dlapy2 (dble (bounds(np+i)),aimag (bounds(np+i)))
      &                 .le. tol*rtemp ) then
                nconv = nconv + 1
             end if
@@ -550,7 +550,7 @@ c           |  Use h( 3,1 ) as storage to communicate  |
 c           |  rnorm to zneupd  if needed               |
 c           %------------------------------------------%
 
-            h(3,1) = dcmplx (rnorm,rzero)
+            h(3,1) = cmplx (rnorm,rzero,Kind=Kind(0d0))
 c
 c           %----------------------------------------------%
 c           | Sort Ritz values so that converged Ritz      |
@@ -575,7 +575,7 @@ c           %--------------------------------------------------%
 c
             do 35 j = 1, nev0
                 rtemp = max( eps23, dlapy2 ( dble (ritz(j)),
-     &                                       dimag (ritz(j)) ) )
+     &                                       aimag (ritz(j)) ) )
                 bounds(j) = bounds(j)/rtemp
  35         continue
 c
@@ -596,7 +596,7 @@ c           %----------------------------------------------%
 c
             do 40 j = 1, nev0
                 rtemp = max( eps23, dlapy2 ( dble (ritz(j)),
-     &                                       dimag (ritz(j)) ) )
+     &                                       aimag (ritz(j)) ) )
                 bounds(j) = bounds(j)*rtemp
  40         continue
 c
@@ -754,8 +754,8 @@ c
          end if
 c
          if (bmat .eq. 'G') then
-            cmpnorm = zdotc  (n, resid, 1, workd, 1)
-            rnorm = sqrt(dlapy2 (dble (cmpnorm),dimag (cmpnorm)))
+            cmpnorm = zzdotc  (n, resid, 1, workd, 1)
+            rnorm = sqrt(dlapy2 (dble (cmpnorm),aimag (cmpnorm)))
          else if (bmat .eq. 'I') then
             rnorm = dznrm2 (n, resid, 1)
          end if
diff --git a/SRC/zneupd.f b/SRC/zneupd.f
index 9889e30..92e7dc9 100644
--- a/SRC/zneupd.f
+++ b/SRC/zneupd.f
@@ -325,8 +325,8 @@ c
       external   dznrm2, dlamch, dlapy2
 c
       Complex*16
-     &           zdotc
-      external   zdotc
+     &           zzdotc
+      external   zzdotc
 c
 c     %-----------------------%
 c     | Executable Statements |
@@ -516,11 +516,11 @@ c
          do 11 j = 1,ncv
             rtemp = max(eps23,
      &                 dlapy2 ( dble(workl(irz+ncv-j)),
-     &                          dimag(workl(irz+ncv-j)) ))
+     &                          aimag(workl(irz+ncv-j)) ))
             jj = workl(bounds + ncv - j)
             if (numcnv .lt. nconv .and.
      &          dlapy2( dble(workl(ibd+jj-1)),
-     &          dimag(workl(ibd+jj-1)) )
+     &          aimag(workl(ibd+jj-1)) )
      &          .le. tol*rtemp) then
                select(jj) = .true.
                numcnv = numcnv + 1
@@ -731,7 +731,7 @@ c                 | upper triangular, thus the length of the |
 c                 | inner product can be set to j.           |
 c                 %------------------------------------------%
 c
-                  workev(j) = zdotc(j, workl(ihbds), 1,
+                  workev(j) = zzdotc(j, workl(ihbds), 1,
      &                        workl(invsub+(j-1)*ldq), 1)
  40         continue
 c
diff --git a/SRC/zsortc.f b/SRC/zsortc.f
index 2db8bf3..6ea37a4 100644
--- a/SRC/zsortc.f
+++ b/SRC/zsortc.f
@@ -96,7 +96,7 @@ c     %--------------------%
 c     | Intrinsic Functions |
 c     %--------------------%
        Intrinsic
-     &           dble, dimag
+     &           dble, aimag
 c
 c     %-----------------------%
 c     | Executable Statements |
@@ -119,8 +119,8 @@ c
 c
             if (j.lt.0) go to 30
 c
-            temp1 = dlapy2(dble(x(j)),dimag(x(j)))
-            temp2 = dlapy2(dble(x(j+igap)),dimag(x(j+igap)))
+            temp1 = dlapy2(dble(x(j)),aimag(x(j)))
+            temp2 = dlapy2(dble(x(j+igap)),aimag(x(j+igap)))
 c
             if (temp1.gt.temp2) then
                 temp = x(j)
@@ -156,8 +156,8 @@ c
 c
             if (j .lt. 0) go to 60
 c
-            temp1 = dlapy2(dble(x(j)),dimag(x(j)))
-            temp2 = dlapy2(dble(x(j+igap)),dimag(x(j+igap)))
+            temp1 = dlapy2(dble(x(j)),aimag(x(j)))
+            temp2 = dlapy2(dble(x(j+igap)),aimag(x(j+igap)))
 c
             if (temp1.lt.temp2) then
                temp = x(j)
@@ -259,7 +259,7 @@ c
 c
             if (j.lt.0) go to 150
 c
-            if (dimag(x(j)).gt.dimag(x(j+igap))) then
+            if (aimag(x(j)).gt.aimag(x(j+igap))) then
                temp = x(j)
                x(j) = x(j+igap)
                x(j+igap) = temp
@@ -292,7 +292,7 @@ c
 c
             if (j.lt.0) go to 180
 c
-            if (dimag(x(j)).lt.dimag(x(j+igap))) then
+            if (aimag(x(j)).lt.aimag(x(j+igap))) then
                temp = x(j)
                x(j) = x(j+igap)
                x(j+igap) = temp
diff --git a/SRC/zzdotc.f b/SRC/zzdotc.f
new file mode 100644
index 0000000..a98c342
--- /dev/null
+++ b/SRC/zzdotc.f
@@ -0,0 +1,36 @@
+      double complex function zzdotc(n,zx,incx,zy,incy)
+c
+c     forms the dot product of a vector.
+c     jack dongarra, 3/11/78.
+c     modified 12/3/93, array(1) declarations changed to array(*)
+c
+      double complex zx(*),zy(*),ztemp
+      integer i,incx,incy,ix,iy,n
+      ztemp = (0.0d0,0.0d0)
+      zzdotc = (0.0d0,0.0d0)
+      if(n.le.0)return
+      if(incx.eq.1.and.incy.eq.1)go to 20
+c
+c        code for unequal increments or equal increments
+c          not equal to 1
+c
+      ix = 1
+      iy = 1
+      if(incx.lt.0)ix = (-n+1)*incx + 1
+      if(incy.lt.0)iy = (-n+1)*incy + 1
+      do 10 i = 1,n
+        ztemp = ztemp + conjg(zx(ix))*zy(iy)
+        ix = ix + incx
+        iy = iy + incy
+   10 continue
+      zzdotc = ztemp
+      return
+c
+c        code for both increments equal to 1
+c
+   20 do 30 i = 1,n
+        ztemp = ztemp + conjg(zx(i))*zy(i)
+   30 continue
+      zzdotc = ztemp
+      return
+      end
diff --git a/TESTS/Makefile.am b/TESTS/Makefile.am
index 4af6d45..224b68a 100644
--- a/TESTS/Makefile.am
+++ b/TESTS/Makefile.am
@@ -1,10 +1,9 @@
-LDADD=$(top_builddir)/SRC/libarpack$(LIBSUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
+LDADD=$(top_builddir)/SRC/libarpack$(LIBSUFFIX)$(ITF64SUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
 
 check_PROGRAMS = dnsimp bug_1323 bug_58_double bug_79_double_complex bug_142 bug_142_gen
 if ICB
 check_PROGRAMS += icb_arpack_c
 check_PROGRAMS += icb_arpack_cpp
-else
 check_PROGRAMS += bug_1315_single
 check_PROGRAMS += bug_1315_double
 endif
@@ -25,17 +24,17 @@ bug_142_gen_SOURCES = bug_142_gen.f
 
 if ICB
 icb_arpack_c_SOURCES = icb_arpack_c.c
-icb_arpack_c_LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX).la
+icb_arpack_c_LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX)$(ITF64SUFFIX).la
 icb_arpack_c_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir) -I$(top_srcdir)/ICB
 
 icb_arpack_cpp_SOURCES = icb_arpack_cpp.cpp
-icb_arpack_cpp_LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX).la
+icb_arpack_cpp_LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX)$(ITF64SUFFIX).la
 icb_arpack_cpp_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir) -I$(top_srcdir)/ICB
-else
+
 bug_1315_single_SOURCES = bug_1315_single.c
 bug_1315_double_SOURCES = bug_1315_double.c
-bug_1315_single_LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX).la
-bug_1315_double_LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX).la
-bug_1315_single_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)
-bug_1315_double_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)
+bug_1315_single_LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX)$(ITF64SUFFIX).la
+bug_1315_double_LDADD = $(top_builddir)/SRC/libarpack$(LIBSUFFIX)$(ITF64SUFFIX).la
+bug_1315_single_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir) -I$(top_srcdir)/ICB
+bug_1315_double_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir) -I$(top_srcdir)/ICB
 endif
diff --git a/TESTS/bug_1315_double.c b/TESTS/bug_1315_double.c
index 66703e8..a1d69c7 100644
--- a/TESTS/bug_1315_double.c
+++ b/TESTS/bug_1315_double.c
@@ -2,15 +2,11 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "arpackdef.h"
+#include "arpack.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.
@@ -19,16 +15,6 @@
  * symmetric but is done to exhibit the bug.
  * */
 
-extern void dnaupd(a_int *, char *, a_int *, char *, a_int *, double *,
-                   double *, a_int *, double *, a_int *, a_int *, a_int *,
-                   double *, double *, a_int *, a_int *);
-
-extern void dneupd(a_int *, char *, a_int *, double *, double *, double *,
-                   a_int *, double *, double *, double *, char *, a_int *,
-                   char *, a_int *, double *, double *, a_int *, double *,
-                   a_int *, a_int *, a_int *, double *, double *, a_int *,
-                   a_int *);
-
 void matVec(double *x, double *y) {
   int i;
   for (i = 0; i < 1000; ++i) y[i] = ((double)(i + 1)) * x[i];
@@ -70,19 +56,19 @@ int main() {
   iparam[3] = 1;
   iparam[6] = 1;
 
-  dnaupd(&ido, bmat, &N, which, &nev, &tol, resid, &ncv, V, &ldv, iparam, ipntr,
-         workd, workl, &lworkl, &info);
+  dnaupd_c(&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]));
 
-    dnaupd(&ido, bmat, &N, which, &nev, &tol, resid, &ncv, V, &ldv, iparam,
-           ipntr, workd, workl, &lworkl, &info);
+    dnaupd_c(&ido, bmat, N, which, nev, tol, resid, ncv, V, ldv, iparam,
+           ipntr, workd, workl, lworkl, &info);
   }
 
-  dneupd(&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);
+  dneupd_c(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]);
diff --git a/TESTS/bug_1315_single.c b/TESTS/bug_1315_single.c
index c469974..f7fc633 100644
--- a/TESTS/bug_1315_single.c
+++ b/TESTS/bug_1315_single.c
@@ -2,15 +2,11 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "arpackdef.h"
+#include "arpack.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.
@@ -19,15 +15,6 @@
  * 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];
@@ -69,23 +56,23 @@ int main() {
   iparam[3] = 1;
   iparam[6] = 1;
 
-  snaupd(&ido, bmat, &N, which, &nev, &tol, resid, &ncv, V, &ldv, iparam, ipntr,
-         workd, workl, &lworkl, &info);
+  snaupd_c(&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);
+    snaupd_c(&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);
+  sneupd_c(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) {
+    if (fabs(dr[i] - (float)(1000 - i)) > 1e-1) { // Easy tolerance as we deal with float.
       free(dr);
       free(di);
       exit(EXIT_FAILURE);
diff --git a/TESTS/bug_58_double.f b/TESTS/bug_58_double.f
index e2a1a23..45966ed 100644
--- a/TESTS/bug_58_double.f
+++ b/TESTS/bug_58_double.f
@@ -417,7 +417,7 @@ c
          print *, ' '
 c
       end if
-      if (isnan(v(1,1))) then
+      if (v(1,1) /= v(1,1)) then   ! result is NaN
          stop 1
       end if
 c
diff --git a/TESTS/icb_arpack_c.c b/TESTS/icb_arpack_c.c
index 40fa2fd..bdf78ce 100644
--- a/TESTS/icb_arpack_c.c
+++ b/TESTS/icb_arpack_c.c
@@ -21,59 +21,63 @@
  * with entries 1000, 999, ... , 2, 1 on the diagonal.
  * */
 
-void dMatVec(double* x, double* y) {
+void dMatVec(const double* x, double* y) {
   int i;
   for (i = 0; i < 1000; ++i) y[i] = ((double)(i + 1)) * x[i];
 };
 
 int ds() {
-  a_int ido = 0;
-  char bmat[] = "I";
-  a_int N = 1000;
-  char which[] = "LM";
-  a_int nev = 9;
-  double tol = 0.000001; // small tol => more stable checks after EV computation.
+  const a_int N      = 1000;
+  const a_int nev    = 9;
+  const a_int ncv    = 2 * nev + 1;
+  const a_int ldv    = N;
+  const a_int ldz    = N;
+  const a_int lworkl = ncv * (ncv + 8);
+  const a_int rvec   = 1;      // need eigenvectors
+
+  const double tol = 0.000001; // small tol => more stable checks after EV computation.
+  const double sigma = 0;      // not referenced in this mode
+  
   double resid[N];
-  a_int ncv = 2 * nev + 1;
-  double V[ncv * N];
-  a_int ldv = N;
-  a_int iparam[11];
-  a_int ipntr[14];
+  double V[ldv * ncv];
+  double z[ldz * nev];
+  double d[nev];
   double workd[3 * N];
-  a_int rvec = 1;
+  double workl[lworkl];
+  a_int select[ncv]; // since HOWMNY = 'A', only used as workspace here
+
+  a_int iparam[11], ipntr[11];
+  iparam[0] = 1;       // ishift
+  iparam[2] = 10 * N;  // on input: maxit; on output: actual iteration
+  iparam[3] = 1;       // NB, only 1 allowed
+  iparam[6] = 1;       // mode
+
+  char bmat[]   = "I";
+  char which[]  = "LM";
   char howmny[] = "A";
-  double* d = (double*)malloc((nev + 1) * sizeof(double));
-  a_int select[ncv];
-  for (int i = 0; i < ncv; i++) select[i] = 1;
-  double z[(N + 1) * (nev + 1)];
-  a_int ldz = N + 1;
-  double sigma = 0;
-  int k;
-  for (k = 0; k < 3 * N; ++k) workd[k] = 0;
-  double 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[4] = 0;  // number of ev found by arpack.
-  iparam[6] = 1;
-
-  while (ido != 99) {
-    /* call arpack like you would have, but, use dsaupd_c instead of dsaupd_ */
+
+  a_int info = 0, ido = 0;
+  do {
     dsaupd_c(&ido, bmat, N, which, nev, tol, resid, ncv, V, ldv, iparam, ipntr,
              workd, workl, lworkl, &info);
 
     dMatVec(&(workd[ipntr[0] - 1]), &(workd[ipntr[1] - 1]));
+  } while (ido == 1 || ido == -1);
+
+  // check info and number of ev found by arpack.
+  if (info < 0 || iparam[4] < nev) {
+    printf("Error in saupd: iparam[4] %d, nev %d, info %d\n", iparam[4], nev, info);
+    return 1;
   }
-  if (iparam[4] != nev) {printf("Error: iparam[4] %d, nev %d\n", iparam[4], nev); return 1;} // check number of ev found by arpack.
 
-  /* call arpack like you would have, but, use dseupd_c instead of dseupd_ */
   dseupd_c(rvec, howmny, select, d, z, ldz, sigma, bmat, N, which, nev, tol,
            resid, ncv, V, ldv, iparam, ipntr, workd, workl, lworkl, &info);
-  int i;
+  if (info < 0) {
+    printf("Error in seupd: info %d\n", info);
+    return 1;
+  }
+
+  int i; // C99 compliant.
   for (i = 0; i < nev; ++i) {
     double val = d[i];
     double ref = (N-(nev-1)+i);
@@ -81,72 +85,70 @@ int ds() {
     printf("%f - %f - %f\n", val, ref, eps);
 
     /*eigen value order: smallest -> biggest*/
-    if(eps>1.e-05){
-      free(d);
-      return 1;
-    }
+    if (eps > 1.e-05) return 1;
   }
-  free(d);
   return 0;
 }
 
-void zMatVec(double _Complex* x, double _Complex* y) {
+void zMatVec(const a_dcomplex* x, a_dcomplex* y) {
   int i;
-  for (i = 0; i < 1000; ++i) y[i] = x[i] * (i + 1.0 + _Complex_I * (i + 1.0));
+  for (i = 0; i < 1000; ++i) y[i] = x[i] * CMPLX(i + 1.0, i + 1.0);
 };
 
 int zn() {
-  a_int ido = 0;
-  char bmat[] = "I";
-  a_int N = 1000;
-  char which[] = "LM";
-  a_int nev = 9;
-  double tol = 0.000001; // small tol => more stable checks after EV computation.
-  double _Complex resid[N];
-  a_int ncv = 2 * nev + 1;
-  double _Complex V[ncv * N];
-  a_int ldv = N;
-  a_int iparam[11];
-  a_int ipntr[14];
-  double _Complex workd[3 * N];
-  a_int rvec = 0;
-  char howmny[] = "A";
-  double _Complex* d =
-      (double _Complex*)malloc((nev + 1) * sizeof(double _Complex));
-  a_int select[ncv];
-  for (int i = 0; i < ncv; i++) select[i] = 1;
-  double _Complex z[(N + 1) * (nev + 1)];
-  a_int ldz = N + 1;
-  double _Complex sigma = 0. + I * 0.;
-  int k;
-  for (k = 0; k < 3 * N; ++k) workd[k] = 0;
-  double _Complex 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;
+  const a_int N      = 1000;
+  const a_int nev    = 9;
+  const a_int ncv    = 2 * nev + 1;
+  const a_int ldv    = N;
+  const a_int ldz    = N;
+  const a_int lworkl = ncv * (3 * ncv + 5);
+  const a_int rvec   = 0;                 // eigenvectors omitted
+
+  const double tol = 0.000001;            // small tol => more stable checks after EV computation.
+  const a_dcomplex sigma = CMPLX(0., 0.); // not referenced in this mode
+
+  a_dcomplex resid[N];
+  a_dcomplex V[ldv * ncv];
+  a_dcomplex z[ldz * nev];
+  a_dcomplex d[nev];
+  a_dcomplex workd[3 * N];
+  a_dcomplex workl[lworkl];
+  a_dcomplex workev[2 * ncv];
   double rwork[ncv];
-  double _Complex workev[2 * ncv];
-  a_int info = 0;
+  a_int select[ncv]; // since HOWMNY = 'A', only used as workspace here
 
-  iparam[0] = 1;
-  iparam[2] = 10 * N;
-  iparam[3] = 1;
-  iparam[4] = 0;  // number of ev found by arpack.
-  iparam[6] = 1;
+  a_int iparam[11], ipntr[14];
+  iparam[0] = 1;       // ishift
+  iparam[2] = 10 * N;  // on input: maxit; on output: actual iteration
+  iparam[3] = 1;       // NB, only 1 allowed
+  iparam[6] = 1;       // mode
 
-  while (ido != 99) {
-    /* call arpack like you would have, but, use znaupd_c instead of znaupd_ */
+  char bmat[]   = "I";
+  char which[]  = "LM";
+  char howmny[] = "A";
+  
+  a_int info = 0, ido = 0;
+  do {
     znaupd_c(&ido, bmat, N, which, nev, tol, resid, ncv, V, ldv, iparam, ipntr,
              workd, workl, lworkl, rwork, &info);
 
     zMatVec(&(workd[ipntr[0] - 1]), &(workd[ipntr[1] - 1]));
+  } while (ido == 1 || ido == -1);
+
+  // check info and number of ev found by arpack
+  if (info < 0 || iparam[4] < nev) {
+    printf("Error in naupd: iparam[4] %d, nev %d, info %d\n", iparam[4], nev, info);
+    return 1;
   }
-  if (iparam[4] != nev) {printf("Error: iparam[4] %d, nev %d\n", 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, bmat, N, which, nev,
-           tol, resid, ncv, V, ldv, iparam, ipntr, workd, workl, lworkl, rwork,
-           &info);
-  int i;
+           tol, resid, ncv, V, ldv, iparam, ipntr, workd, workl, lworkl, rwork, &info);
+  if (info < 0) {
+    printf("Error in neupd: info %d\n", info);
+    return 1;
+  }
+           
+  int i; // C99 compliant.
   for (i = 0; i < nev; ++i) {
     double rval = creal(d[i]);
     double rref = (N-(nev-1)+i);
@@ -157,12 +159,9 @@ int zn() {
     printf("%f %f - %f %f - %f %f\n", rval, ival, rref, iref, reps, ieps);
 
     /*eigen value order: smallest -> biggest*/
-    if(reps>1.e-05 || ieps>1.e-05){
-      free(d);
-      return 1;
-    }
+    if (reps > 1.e-05 || ieps > 1.e-05) return 1;
   }
-  free(d);
+  
   return 0;
 }
 
diff --git a/TESTS/icb_arpack_cpp.cpp b/TESTS/icb_arpack_cpp.cpp
index 1423aa2..00b6d43 100644
--- a/TESTS/icb_arpack_cpp.cpp
+++ b/TESTS/icb_arpack_cpp.cpp
@@ -5,11 +5,10 @@
  * of *[ae]upd_. The main advantage is that compiler checks the argument types
  * and the correct function is called based on the type (float vs double vs
  * complex). Note: to debug arpack, call debug_c. This is a test program to
- * solve for the 9 largest eigenvalues of A*x = lambda*x where A is the diagonal
+ * solve for the 9 eigenvalues of A*x = lambda*x where A is the diagonal
  * matrix with entries 1000, 999, ... , 2, 1 on the diagonal.
  */
 
-#include <array>
 #include <cmath>
 #include <iostream>
 #include <vector>
@@ -19,73 +18,62 @@
 #include "stat_c.hpp"   // arpack statistics.
 
 template <typename Real>
-void diagonal_matrix_vector_product(Real const* const x, Real* const y) {
+void diagonal_matrix_vector_product(const Real* x, Real* y) {
   for (int i = 0; i < 1000; ++i) {
     y[i] = static_cast<Real>(i + 1) * x[i];
   }
 }
 
 template <typename Real>
-void real_symmetric_runner(double const& tol_check) {
-  a_int const N = 1000;
-  a_int const nev = 9;
-
-  a_int const ncv = 2 * nev + 1;
-  a_int const ldv = N;
-
-  a_int const ldz = N + 1;
-
-  a_int const lworkl = 3 * (ncv * ncv) + 6 * ncv;
-
-  Real const tol = 0.000001; // small tol => more stable checks after EV computation.
-  Real const sigma = 0.0;
-
-  a_int const rvec = 1;
+void real_symmetric_runner(double const& tol_check, arpack::which const& ritz_option) {
+  const a_int N      = 1000;
+  const a_int nev    = 9;
+  const a_int ncv    = 2 * nev + 1;
+  const a_int ldv    = N;
+  const a_int ldz    = N;
+  const a_int lworkl = ncv * (ncv + 8);
+  const a_int rvec   = 1;      // need eigenvectors
+
+  const Real tol   = 0.000001; // small tol => more stable checks after EV computation.
+  const Real sigma = 0.0;      // not referenced in this mode
 
   std::vector<Real> resid(N);
-  std::vector<Real> V(ncv * N);
-  std::vector<Real> workd(3 * N, 0.0);
-  std::vector<Real> workl(lworkl, 0.0);
-  std::vector<Real> d((nev + 1));
-  std::vector<Real> z((N + 1) * (nev + 1));
-
-  std::array<a_int, 11> iparam{};
-
-  iparam[0] = 1;
-  iparam[2] = 10 * N;
-  iparam[3] = 1;
-  iparam[4] = 0;  // number of ev found by arpack.
-  iparam[6] = 1;
-
-  std::array<a_int, 14> ipntr{};
+  std::vector<Real> V(ldv * ncv);
+  std::vector<Real> z(ldz * nev);
+  std::vector<Real> d(nev);
+  std::vector<Real> workd(3 * N);
+  std::vector<Real> workl(lworkl);
+  std::vector<a_int> select(ncv); // since HOWMNY = 'A', only used as workspace here
+
+  a_int iparam[11], ipntr[11];
+  iparam[0] = 1;      // ishift
+  iparam[2] = 10 * N; // on input: maxit; on output: actual iteration
+  iparam[3] = 1;      // NB, only 1 allowed
+  iparam[6] = 1;      // mode
 
   a_int info = 0, ido = 0;
-
-  while (ido != 99) {
+  do {
     arpack::saupd(ido, arpack::bmat::identity, N,
-                  arpack::which::largest_magnitude, nev, tol, resid.data(), ncv,
-                  V.data(), ldv, iparam.data(), ipntr.data(), workd.data(),
+                  ritz_option, nev, tol, resid.data(), ncv,
+                  V.data(), ldv, iparam, ipntr, workd.data(),
                   workl.data(), lworkl, info);
 
-    diagonal_matrix_vector_product(&(workd[ipntr[0] - 1]),
-                                   &(workd[ipntr[1] - 1]));
-  }
+    diagonal_matrix_vector_product(&(workd[ipntr[0] - 1]), &(workd[ipntr[1] - 1]));
+  } while (ido == 1 || ido == -1);
 
-  // check number of ev found by arpack.
-  if (iparam[4] < nev) { /*arpack may succeed to compute more EV than expected*/
-    std::cout << "ERROR: iparam[4] " << iparam[4] << ", nev " << nev
+  // check info and number of ev found by arpack.
+  if (info < 0 || iparam[4] < nev) { /*arpack may succeed to compute more EV than expected*/
+    std::cout << "ERROR in saupd: iparam[4] " << iparam[4] << ", nev " << nev
               << ", info " << info << std::endl;
     throw std::domain_error("Error inside ARPACK routines");
   }
 
-  std::vector<a_int> select(ncv);
-  for (int i = 0; i < ncv; i++) select[i] = 1;
-
   arpack::seupd(rvec, arpack::howmny::ritz_vectors, select.data(), d.data(),
                 z.data(), ldz, sigma, arpack::bmat::identity, N,
-                arpack::which::largest_magnitude, nev, tol, resid.data(), ncv,
-                V.data(), ldv, iparam.data(), ipntr.data(), workd.data(),
+                ritz_option, nev, tol, resid.data(), ncv,
+                V.data(), ldv, iparam, ipntr, workd.data(),
                 workl.data(), lworkl, info);
+  if (info < 0) throw std::runtime_error("Error in seupd, info " + std::to_string(info));
 
   for (int i = 0; i < nev; ++i) {
     Real val = d[i];
@@ -94,106 +82,111 @@ void real_symmetric_runner(double const& tol_check) {
     std::cout << val << " - " << ref << " - " << eps << std::endl;
 
     /*eigen value order: smallest -> biggest*/
-    if (eps > tol_check) {
-      throw std::domain_error("Correct eigenvalues not computed");
-    }
+    if (eps > tol_check) throw std::domain_error("Correct eigenvalues not computed");
   }
-  std::cout << "------\n";
+  std::cout << "------" << std::endl;
 }
 
 template <typename Real>
-void diagonal_matrix_vector_product(std::complex<Real> const* const x,
-                                    std::complex<Real>* const y) {
+void diagonal_matrix_vector_product(const std::complex<Real>* x, std::complex<Real>* y) {
   for (int i = 0; i < 1000; ++i) {
-    y[i] = x[i] * std::complex<Real>{Real(i + 1), Real(i + 1)};
+    // Use complex matrix (i, -i) instead of (i, i): this way "largest_magnitude"
+    // and "largest_imaginary" options produce different results that can be checked.
+    y[i] = x[i] * std::complex<Real>{Real(i + 1), -Real(i + 1)};
   }
 }
 
 template <typename Real>
-void complex_symmetric_runner(double const& tol_check) {
-  a_int const N = 1000;
-  a_int const nev = 9;
-
-  a_int const ncv = 2 * nev + 1;
-  a_int const ldv = N;
-
-  a_int const ldz = N + 1;
-
-  a_int const lworkl = 3 * (ncv * ncv) + 6 * ncv;
-
-  Real const tol = 0.000001; // small tol => more stable checks after EV computation.
-  std::complex<Real> const sigma(0.0, 0.0);
-
-  a_int const rvec = 0;
+void complex_nonsymmetric_runner(double const& tol_check, arpack::which const& ritz_option) {
+  const a_int N      = 1000;
+  const a_int nev    = 9;
+  const a_int ncv    = 2 * nev + 1;
+  const a_int ldv    = N;
+  const a_int ldz    = N;
+  const a_int lworkl = ncv * (3 * ncv + 5);
+  const a_int rvec   = 0;                   // eigenvectors omitted
+
+  const Real tol = 0.000001;                // small tol => more stable checks after EV computation.
+  const std::complex<Real> sigma(0.0, 0.0); // not referenced in this mode
 
   std::vector<std::complex<Real>> resid(N);
-  std::vector<std::complex<Real>> V(ncv * N);
+  std::vector<std::complex<Real>> V(ldv * ncv);
+  std::vector<std::complex<Real>> z(ldz * nev);
+  std::vector<std::complex<Real>> d(nev);
   std::vector<std::complex<Real>> workd(3 * N);
   std::vector<std::complex<Real>> workl(lworkl);
-  std::vector<std::complex<Real>> d(nev + 1);
-  std::vector<std::complex<Real>> z((N + 1) * (nev + 1));
-  std::vector<Real> rwork(ncv);
   std::vector<std::complex<Real>> workev(2 * ncv);
+  std::vector<Real> rwork(ncv);
+  std::vector<a_int> select(ncv); // since HOWMNY = 'A', only used as workspace here
 
-  std::array<a_int, 11> iparam{};
-  iparam[0] = 1;
-  iparam[2] = 10 * N;
-  iparam[3] = 1;
-  iparam[4] = 0;  // number of ev found by arpack.
-  iparam[6] = 1;
-
-  std::array<a_int, 14> ipntr{};
+  a_int iparam[11], ipntr[14];
+  iparam[0] = 1;       // ishift
+  iparam[2] = 10 * N;  // on input: maxit; on output: actual iteration
+  iparam[3] = 1;       // NB, only 1 allowed
+  iparam[6] = 1;       // mode
 
   a_int info = 0, ido = 0;
-
-  while (ido != 99) {
+  do {
     arpack::naupd(ido, arpack::bmat::identity, N,
-                  arpack::which::largest_magnitude, nev, tol, resid.data(), ncv,
-                  V.data(), ldv, iparam.data(), ipntr.data(), workd.data(),
+                  ritz_option, nev, tol, resid.data(), ncv,
+                  V.data(), ldv, iparam, ipntr, workd.data(),
                   workl.data(), lworkl, rwork.data(), info);
 
-    diagonal_matrix_vector_product(&(workd[ipntr[0] - 1]),
-                                   &(workd[ipntr[1] - 1]));
-  }
+    diagonal_matrix_vector_product(&(workd[ipntr[0] - 1]), &(workd[ipntr[1] - 1]));
+  } while (ido == 1 || ido == -1);
 
-  // check number of ev found by arpack.
-  if (iparam[4] < nev) { /*arpack may succeed to compute more EV than expected*/
-    std::cout << "ERROR: iparam[4] " << iparam[4] << ", nev " << nev
+  // check info and number of ev found by arpack.
+  if (info < 0 || iparam[4] < nev) { /*arpack may succeed to compute more EV than expected*/
+    std::cout << "ERROR in naupd: iparam[4] " << iparam[4] << ", nev " << nev
               << ", info " << info << std::endl;
     throw std::domain_error("Error inside ARPACK routines");
   }
 
-  std::vector<a_int> select(ncv);
-  for (int i = 0; i < ncv; i++) select[i] = 1;
-
   arpack::neupd(rvec, arpack::howmny::ritz_vectors, select.data(), d.data(),
                 z.data(), ldz, sigma, workev.data(), arpack::bmat::identity, N,
-                arpack::which::largest_magnitude, nev, tol, resid.data(), ncv,
-                V.data(), ldv, iparam.data(), ipntr.data(), workd.data(),
+                ritz_option, nev, tol, resid.data(), ncv,
+                V.data(), ldv, iparam, ipntr, workd.data(),
                 workl.data(), lworkl, rwork.data(), info);
-
-  for (int i = 0; i < nev; ++i) {
-    Real rval = std::real(d[i]);
-    Real rref = static_cast<Real>(N - (nev - 1) + i);
-    Real reps = std::fabs(rval - rref);
-    Real ival = std::imag(d[i]);
-    Real iref = static_cast<Real>(N - (nev - 1) + i);
-    Real ieps = std::fabs(ival - iref);
-    std::cout << rval << " " << ival << " - " << rref << " " << iref << " - " << reps << " " << ieps << std::endl;
-
-    /*eigen value order: smallest -> biggest*/
-    if (reps > tol_check || ieps > tol_check) {
-      throw std::domain_error("Correct eigenvalues not computed");
+  if (info < 0) throw std::runtime_error("Error in neupd, info " + std::to_string(info));
+
+  if (ritz_option == arpack::which::largest_magnitude) {
+    for (int i = 0; i < nev; ++i) {
+      Real rval = std::real(d[i]);
+      Real rref = static_cast<Real>(N - (nev - 1) + i);
+      Real reps = std::fabs(rval - rref);
+      Real ival = std::imag(d[i]);
+      Real iref = -static_cast<Real>(N - (nev - 1) + i);
+      Real ieps = std::fabs(ival - iref);
+      std::cout << rval << " " << ival << " - " << rref << " " << iref << " - " << reps << " " << ieps << std::endl;
+
+      if (reps > tol_check || ieps > tol_check) throw std::domain_error("Correct eigenvalues not computed");
     }
+  } else if (ritz_option == arpack::which::largest_imaginary) {
+    for (int i = 0; i < nev; ++i) {
+      Real rval = std::real(d[i]);
+      Real rref = static_cast<Real>(nev - i);
+      Real reps = std::fabs(rval - rref);
+      Real ival = std::imag(d[i]);
+      Real iref = -static_cast<Real>(nev - i);
+      Real ieps = std::fabs(ival - iref);
+      std::cout << rval << " " << ival << " - " << rref << " " << iref << " - " << reps << " " << ieps << std::endl;
+
+      if (reps > tol_check || ieps > tol_check) throw std::domain_error("Correct eigenvalues not computed");
+    }
+  } else {
+    throw std::domain_error("The input Ritz option is not allowed in this test file.");
   }
+  std::cout << "------" << std::endl;
 }
 
 int main() {
   sstats_c();
 
   // arpack without debug
-  real_symmetric_runner<float>(1.);
-  real_symmetric_runner<double>(1.e-05);
+  real_symmetric_runner<float>(1., arpack::which::largest_magnitude);
+  real_symmetric_runner<float>(1., arpack::which::largest_algebraic);
+  real_symmetric_runner<double>(1.e-05, arpack::which::largest_magnitude);
+  real_symmetric_runner<double>(1.e-05, arpack::which::largest_algebraic);
 
   a_int nopx_c, nbx_c, nrorth_c, nitref_c, nrstrt_c;
   float tsaupd_c, tsaup2_c, tsaitr_c, tseigt_c, tsgets_c, tsapps_c, tsconv_c;
@@ -215,8 +208,11 @@ int main() {
           1);
 
   // arpack with debug
-  complex_symmetric_runner<float>(1.);
-  complex_symmetric_runner<double>(1.e-05);
+  complex_nonsymmetric_runner<float>(1., arpack::which::largest_magnitude);
+  complex_nonsymmetric_runner<float>(1., arpack::which::largest_imaginary);
+  complex_nonsymmetric_runner<double>(1.e-05, arpack::which::largest_magnitude);
+  complex_nonsymmetric_runner<double>(1.e-05, arpack::which::largest_imaginary);
 
   return 0;
 }
+
diff --git a/arpack-ng-config.cmake.in b/arpack-ng-config.cmake.in
deleted file mode 100644
index b8c011b..0000000
--- a/arpack-ng-config.cmake.in
+++ /dev/null
@@ -1,25 +0,0 @@
-# Config file for the arpack-ng package.
-#
-# To use arpack from CMake, use ARPACK::ARPACK target:
-#   find_package(arpack-ng)
-#   add_executable(main main.f)
-#   target_include_directories(main PRIVATE ARPACK::ARPACK)
-#   target_link_libraries(main ARPACK::ARPACK)
-#
-# To use parpack from CMake, use PARPACK::PARPACK target:
-#   find_package(arpack-ng)
-#   add_executable(main main.f)
-#   target_link_libraries(main PARPACK::PARPACK)
-
-# Create local variables.
-set(prefix "@prefix@")
-set(exec_prefix "@exec_prefix@")
-set(libdir "@libdir@")
-set(includedir "@includedir@")
-
-# Create arpack targets.
-add_library(ARPACK::ARPACK INTERFACE IMPORTED)
-set_target_properties(ARPACK::ARPACK PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${includedir}/arpack")
-set_target_properties(ARPACK::ARPACK PROPERTIES INTERFACE_LINK_LIBRARIES      "arpack")
-add_library(PARPACK::PARPACK INTERFACE IMPORTED)
-set_target_properties(PARPACK::PARPACK PROPERTIES INTERFACE_LINK_LIBRARIES    "parpack")
diff --git a/arpackdef.h.in b/arpackdef.h.in
index d9e0143..56ba199 100644
--- a/arpackdef.h.in
+++ b/arpackdef.h.in
@@ -7,11 +7,37 @@
 
 #if INTERFACE64
 #include <stdint.h> /* Include this header for int64_t, uint64_t definition. */
-#define a_int    int64_t
-#define a_uint  uint64_t
+#define a_int int64_t
+#define a_uint uint64_t
 #else
-#define a_int            int
-#define a_uint  unsigned int
+#define a_int int
+#define a_uint unsigned int
+#endif
+#ifdef _MSC_VER
+#ifndef _CRT_USE_C_COMPLEX_H
+#define _CRT_USE_C_COMPLEX_H
+#include <complex.h>
+#undef _CRT_USE_C_COMPLEX_H
+#else
+#include <complex.h>
+#endif
+#define a_fcomplex _Fcomplex
+#define a_dcomplex _Dcomplex
+#ifndef CMPLXF
+#define CMPLXF(r,i) _FCbuild(r,i)
+#endif
+#ifndef CMPLX
+#define CMPLX(r,i) _Cbuild(r,i)
+#endif
+#else
+#ifndef CMPLXF
+#define CMPLXF(r,i) ((float _Complex)((float)(r) + _Complex_I * (float)(i)))
+#endif
+#ifndef CMPLX
+#define CMPLX(r,i) ((double _Complex)((double)(r) + _Complex_I * (double)(i)))
+#endif
+#define a_fcomplex float _Complex
+#define a_dcomplex double _Complex
 #endif
 
 #endif
diff --git a/cmake/Coveralls.cmake b/cmake/Coveralls.cmake
deleted file mode 100644
index 4250397..0000000
--- a/cmake/Coveralls.cmake
+++ /dev/null
@@ -1,128 +0,0 @@
-#
-# The MIT License (MIT)
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Copyright (C) 2014 Joakim Söderberg <joakim.soderberg@gmail.com>
-#
-
-set(_CMAKE_SCRIPT_PATH ${CMAKE_CURRENT_LIST_DIR}) # must be outside coveralls_setup() to get correct path
-
-#
-# Param _COVERAGE_SRCS	A list of source files that coverage should be collected for.
-# Param _COVERALLS_UPLOAD Upload the result to coveralls?
-#
-
-function(coveralls_setup _COVERAGE_SRCS _COVERALLS_UPLOAD)
-
-	if (ARGC GREATER 2)
-		set(_CMAKE_SCRIPT_PATH ${ARGN})
-		message(STATUS "Coveralls: Using alternate CMake script dir: ${_CMAKE_SCRIPT_PATH}")
-	endif()
-
-	if (NOT EXISTS "${_CMAKE_SCRIPT_PATH}/CoverallsClear.cmake")
-		message(FATAL_ERROR "Coveralls: Missing ${_CMAKE_SCRIPT_PATH}/CoverallsClear.cmake")
-	endif()
-
-	if (NOT EXISTS "${_CMAKE_SCRIPT_PATH}/CoverallsGenerateGcov.cmake")
-		message(FATAL_ERROR "Coveralls: Missing ${_CMAKE_SCRIPT_PATH}/CoverallsGenerateGcov.cmake")
-	endif()
-
-	# When passing a CMake list to an external process, the list
-	# will be converted from the format "1;2;3" to "1 2 3".
-	# This means the script we're calling won't see it as a list
-	# of sources, but rather just one long path. We remedy this
-	# by replacing ";" with "*" and then reversing that in the script
-	# that we're calling.
-	# http://cmake.3232098.n2.nabble.com/Passing-a-CMake-list-quot-as-is-quot-to-a-custom-target-td6505681.html
-	set(COVERAGE_SRCS_TMP ${_COVERAGE_SRCS})
-	set(COVERAGE_SRCS "")
-	foreach (COVERAGE_SRC ${COVERAGE_SRCS_TMP})
-		set(COVERAGE_SRCS "${COVERAGE_SRCS}*${COVERAGE_SRC}")
-	endforeach()
-
-	#message("Coverage sources: ${COVERAGE_SRCS}")
-	set(COVERALLS_FILE ${PROJECT_BINARY_DIR}/coveralls.json)
-
-	add_custom_target(coveralls_generate
-
-		# Zero the coverage counters.
-		COMMAND ${CMAKE_COMMAND} -DPROJECT_BINARY_DIR="${PROJECT_BINARY_DIR}" -P "${_CMAKE_SCRIPT_PATH}/CoverallsClear.cmake"
-
-		# Run regress tests.
-		COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
-
-		# Generate Gcov and translate it into coveralls JSON.
-		# We do this by executing an external CMake script.
-		# (We don't want this to run at CMake generation time, but after compilation and everything has run).
-		COMMAND ${CMAKE_COMMAND}
-				-DCOVERAGE_SRCS="${COVERAGE_SRCS}" # TODO: This is passed like: "a b c", not "a;b;c"
-				-DCOVERALLS_OUTPUT_FILE="${COVERALLS_FILE}"
-				-DCOV_PATH="${PROJECT_BINARY_DIR}"
-				-DPROJECT_ROOT="${PROJECT_SOURCE_DIR}"
-				-P "${_CMAKE_SCRIPT_PATH}/CoverallsGenerateGcov.cmake"
-
-		WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
-		COMMENT "Generating coveralls output..."
-		)
-
-	if (_COVERALLS_UPLOAD)
-		message("COVERALLS UPLOAD: ON")
-
-		find_program(CURL_EXECUTABLE curl)
-
-		if (NOT CURL_EXECUTABLE)
-			message(FATAL_ERROR "Coveralls: curl not found! Aborting")
-		endif()
-
-		add_custom_target(coveralls_upload
-			# Upload the JSON to coveralls.
-			COMMAND ${CURL_EXECUTABLE}
-					-S -F json_file=@${COVERALLS_FILE}
-					https://coveralls.io/api/v1/jobs
-
-			DEPENDS coveralls_generate
-
-			WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
-			COMMENT "Uploading coveralls output...")
-
-		add_custom_target(coveralls DEPENDS coveralls_upload)
-	else()
-		message("COVERALLS UPLOAD: OFF")
-		add_custom_target(coveralls DEPENDS coveralls_generate)
-	endif()
-
-endfunction()
-
-macro(coveralls_turn_on_coverage)
-	if(NOT (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
-		AND (NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang"))
-		message(FATAL_ERROR "Coveralls: Compiler ${CMAKE_C_COMPILER_ID} is not GNU gcc! Aborting... You can set this on the command line using CC=/usr/bin/gcc CXX=/usr/bin/g++ cmake <options> ..")
-	endif()
-
-	if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
-		message(FATAL_ERROR "Coveralls: Code coverage results with an optimised (non-Debug) build may be misleading! Add -DCMAKE_BUILD_TYPE=Debug")
-	endif()
-
-	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
-	set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
-endmacro()
-
-
-
diff --git a/cmake/CoverallsClear.cmake b/cmake/CoverallsClear.cmake
deleted file mode 100644
index eb68695..0000000
--- a/cmake/CoverallsClear.cmake
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Copyright (C) 2014 Joakim Söderberg <joakim.soderberg@gmail.com>
-#
-
-file(REMOVE_RECURSE ${PROJECT_BINARY_DIR}/*.gcda)
-
diff --git a/cmake/CoverallsGenerateGcov.cmake b/cmake/CoverallsGenerateGcov.cmake
deleted file mode 100644
index d04cdf4..0000000
--- a/cmake/CoverallsGenerateGcov.cmake
+++ /dev/null
@@ -1,430 +0,0 @@
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in all
-# copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Copyright (C) 2014 Joakim Söderberg <joakim.soderberg@gmail.com>
-#
-# This is intended to be run by a custom target in a CMake project like this.
-# 0. Compile program with coverage support.
-# 1. Clear coverage data. (Recursively delete *.gcda in build dir)
-# 2. Run the unit tests.
-# 3. Run this script specifying which source files the coverage should be performed on.
-#
-# This script will then use gcov to generate .gcov files in the directory specified
-# via the COV_PATH var. This should probably be the same as your cmake build dir.
-#
-# It then parses the .gcov files to convert them into the Coveralls JSON format:
-# https://coveralls.io/docs/api
-#
-# Example for running as standalone CMake script from the command line:
-# (Note it is important the -P is at the end...)
-# $ cmake -DCOV_PATH=$(pwd)
-#         -DCOVERAGE_SRCS="catcierge_rfid.c;catcierge_timer.c"
-#         -P ../cmake/CoverallsGcovUpload.cmake
-#
-CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
-
-
-#
-# Make sure we have the needed arguments.
-#
-if (NOT COVERALLS_OUTPUT_FILE)
-	message(FATAL_ERROR "Coveralls: No coveralls output file specified. Please set COVERALLS_OUTPUT_FILE")
-endif()
-
-if (NOT COV_PATH)
-	message(FATAL_ERROR "Coveralls: Missing coverage directory path where gcov files will be generated. Please set COV_PATH")
-endif()
-
-if (NOT COVERAGE_SRCS)
-	message(FATAL_ERROR "Coveralls: Missing the list of source files that we should get the coverage data for COVERAGE_SRCS")
-endif()
-
-if (NOT PROJECT_ROOT)
-	message(FATAL_ERROR "Coveralls: Missing PROJECT_ROOT.")
-endif()
-
-# Since it's not possible to pass a CMake list properly in the
-# "1;2;3" format to an external process, we have replaced the
-# ";" with "*", so reverse that here so we get it back into the
-# CMake list format.
-string(REGEX REPLACE "\\*" ";" COVERAGE_SRCS "${COVERAGE_SRCS}")
-
-find_program(GCOV_EXECUTABLE gcov)
-
-if (NOT GCOV_EXECUTABLE)
-	message(FATAL_ERROR "gcov not found! Aborting...")
-endif()
-
-find_package(Git)
-
-# TODO: Add these git things to the coveralls json.
-if (GIT_FOUND)
-	# Branch.
-	execute_process(
-		COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
-		WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
-		OUTPUT_VARIABLE GIT_BRANCH
-		OUTPUT_STRIP_TRAILING_WHITESPACE
-	)
-
-	macro (git_log_format FORMAT_CHARS VAR_NAME)
-		execute_process(
-			COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:%${FORMAT_CHARS}
-			WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
-			OUTPUT_VARIABLE ${VAR_NAME}
-			OUTPUT_STRIP_TRAILING_WHITESPACE
-		)
-	endmacro()
-
-	git_log_format(an GIT_AUTHOR_EMAIL)
-	git_log_format(ae GIT_AUTHOR_EMAIL)
-	git_log_format(cn GIT_COMMITTER_NAME)
-	git_log_format(ce GIT_COMMITTER_EMAIL)
-	git_log_format(B GIT_COMMIT_MESSAGE)
-
-	message("Git exe: ${GIT_EXECUTABLE}")
-	message("Git branch: ${GIT_BRANCH}")
-	message("Git author: ${GIT_AUTHOR_NAME}")
-	message("Git e-mail: ${GIT_AUTHOR_EMAIL}")
-	message("Git committer name: ${GIT_COMMITTER_NAME}")
-	message("Git committer e-mail: ${GIT_COMMITTER_EMAIL}")
-	message("Git commit message: ${GIT_COMMIT_MESSAGE}")
-
-endif()
-
-############################# Macros #########################################
-
-#
-# This macro converts from the full path format gcov outputs:
-#
-#    /path/to/project/root/build/#path#to#project#root#subdir#the_file.c.gcov
-#
-# to the original source file path the .gcov is for:
-#
-#   /path/to/project/root/subdir/the_file.c
-#
-macro(get_source_path_from_gcov_filename _SRC_FILENAME _GCOV_FILENAME)
-
-	# /path/to/project/root/build/#path#to#project#root#subdir#the_file.c.gcov
-	# ->
-	# #path#to#project#root#subdir#the_file.c.gcov
-	get_filename_component(_GCOV_FILENAME_WEXT ${_GCOV_FILENAME} NAME)
-
-	# #path#to#project#root#subdir#the_file.c.gcov -> /path/to/project/root/subdir/the_file.c
-	string(REGEX REPLACE "\\.gcov$" "" SRC_FILENAME_TMP "${_GCOV_FILENAME_WEXT}")
-	string(REGEX REPLACE "\#" "/" SRC_FILENAME_TMP "${SRC_FILENAME_TMP}")
-	set(${_SRC_FILENAME} "${SRC_FILENAME_TMP}")
-endmacro()
-
-##############################################################################
-
-# Get the coverage data.
-file(GLOB_RECURSE GCDA_FILES "${COV_PATH}/*.gcda")
-message("GCDA files:")
-
-# Get a list of all the object directories needed by gcov
-# (The directories the .gcda files and .o files are found in)
-# and run gcov on those.
-foreach(GCDA ${GCDA_FILES})
-	message("Process: ${GCDA}")
-	message("------------------------------------------------------------------------------")
-	get_filename_component(GCDA_DIR ${GCDA} PATH)
-
-	#
-	# The -p below refers to "Preserve path components",
-	# This means that the generated gcov filename of a source file will
-	# keep the original files entire filepath, but / is replaced with #.
-	# Example:
-	#
-	# /path/to/project/root/build/CMakeFiles/the_file.dir/subdir/the_file.c.gcda
-	# ------------------------------------------------------------------------------
-	# File '/path/to/project/root/subdir/the_file.c'
-	# Lines executed:68.34% of 199
-	# /path/to/project/root/subdir/the_file.c:creating '#path#to#project#root#subdir#the_file.c.gcov'
-	#
-	# If -p is not specified then the file is named only "the_file.c.gcov"
-	#
-	execute_process(
-		COMMAND ${GCOV_EXECUTABLE} -p -o ${GCDA_DIR} ${GCDA}
-		WORKING_DIRECTORY ${COV_PATH}
-	)
-endforeach()
-
-# TODO: Make these be absolute path
-file(GLOB ALL_GCOV_FILES ${COV_PATH}/*.gcov)
-
-# Get only the filenames to use for filtering.
-#set(COVERAGE_SRCS_NAMES "")
-#foreach (COVSRC ${COVERAGE_SRCS})
-#	get_filename_component(COVSRC_NAME ${COVSRC} NAME)
-#	message("${COVSRC} -> ${COVSRC_NAME}")
-#	list(APPEND COVERAGE_SRCS_NAMES "${COVSRC_NAME}")
-#endforeach()
-
-#
-# Filter out all but the gcov files we want.
-#
-# We do this by comparing the list of COVERAGE_SRCS filepaths that the
-# user wants the coverage data for with the paths of the generated .gcov files,
-# so that we only keep the relevant gcov files.
-#
-# Example:
-# COVERAGE_SRCS =
-#				/path/to/project/root/subdir/the_file.c
-#
-# ALL_GCOV_FILES =
-#				/path/to/project/root/build/#path#to#project#root#subdir#the_file.c.gcov
-#				/path/to/project/root/build/#path#to#project#root#subdir#other_file.c.gcov
-#
-# Result should be:
-# GCOV_FILES =
-#				/path/to/project/root/build/#path#to#project#root#subdir#the_file.c.gcov
-#
-set(GCOV_FILES "")
-#message("Look in coverage sources: ${COVERAGE_SRCS}")
-message("\nFilter out unwanted GCOV files:")
-message("===============================")
-
-set(COVERAGE_SRCS_REMAINING ${COVERAGE_SRCS})
-
-foreach (GCOV_FILE ${ALL_GCOV_FILES})
-
-	#
-	# /path/to/project/root/build/#path#to#project#root#subdir#the_file.c.gcov
-	# ->
-	# /path/to/project/root/subdir/the_file.c
-	get_source_path_from_gcov_filename(GCOV_SRC_PATH ${GCOV_FILE})
-
-	# Is this in the list of source files?
-	# TODO: We want to match against relative path filenames from the source file root...
-	list(FIND COVERAGE_SRCS ${GCOV_SRC_PATH} WAS_FOUND)
-
-	if (NOT WAS_FOUND EQUAL -1)
-		message("YES: ${GCOV_FILE}")
-		list(APPEND GCOV_FILES ${GCOV_FILE})
-
-		# We remove it from the list, so we don't bother searching for it again.
-		# Also files left in COVERAGE_SRCS_REMAINING after this loop ends should
-		# have coverage data generated from them (no lines are covered).
-		list(REMOVE_ITEM COVERAGE_SRCS_REMAINING ${GCOV_SRC_PATH})
-	else()
-		message("NO:  ${GCOV_FILE}")
-	endif()
-endforeach()
-
-# TODO: Enable setting these
-set(JSON_SERVICE_NAME "travis-ci")
-set(JSON_SERVICE_JOB_ID $ENV{TRAVIS_JOB_ID})
-
-set(JSON_TEMPLATE
-"{
-  \"service_name\": \"\@JSON_SERVICE_NAME\@\",
-  \"service_job_id\": \"\@JSON_SERVICE_JOB_ID\@\",
-  \"source_files\": \@JSON_GCOV_FILES\@
-}"
-)
-
-set(SRC_FILE_TEMPLATE
-"{
-      \"name\": \"\@GCOV_SRC_REL_PATH\@\",
-      \"source_digest\": \"\@GCOV_CONTENTS_MD5\@\",
-      \"coverage\": \@GCOV_FILE_COVERAGE\@
-  }"
-)
-
-message("\nGenerate JSON for files:")
-message("=========================")
-
-set(JSON_GCOV_FILES "[")
-
-# Read the GCOV files line by line and get the coverage data.
-foreach (GCOV_FILE ${GCOV_FILES})
-
-	get_source_path_from_gcov_filename(GCOV_SRC_PATH ${GCOV_FILE})
-	file(RELATIVE_PATH GCOV_SRC_REL_PATH "${PROJECT_ROOT}" "${GCOV_SRC_PATH}")
-
-	# The new coveralls API doesn't need the entire source (Yay!)
-	# However, still keeping that part for now. Will cleanup in the future.
-	file(MD5 "${GCOV_SRC_PATH}" GCOV_CONTENTS_MD5)
-	message("MD5: ${GCOV_SRC_PATH} = ${GCOV_CONTENTS_MD5}")
-
-	# Loads the gcov file as a list of lines.
-	# (We first open the file and replace all occurrences of [] with _
-	#  because CMake will fail to parse a line containing unmatched brackets...
-	#  also the \ to escaped \n in macros screws up things.)
-	# https://public.kitware.com/Bug/view.php?id=15369
-	file(READ ${GCOV_FILE} GCOV_CONTENTS)
-	string(REPLACE "[" "_" GCOV_CONTENTS "${GCOV_CONTENTS}")
-	string(REPLACE "]" "_" GCOV_CONTENTS "${GCOV_CONTENTS}")
-	string(REPLACE "\\" "_" GCOV_CONTENTS "${GCOV_CONTENTS}")
-	file(WRITE ${GCOV_FILE}_tmp "${GCOV_CONTENTS}")
-
-	file(STRINGS ${GCOV_FILE}_tmp GCOV_LINES)
-	list(LENGTH GCOV_LINES LINE_COUNT)
-
-	# Instead of trying to parse the source from the
-	# gcov file, simply read the file contents from the source file.
-	# (Parsing it from the gcov is hard because C-code uses ; in many places
-	#  which also happens to be the same as the CMake list delimiter).
-	file(READ ${GCOV_SRC_PATH} GCOV_FILE_SOURCE)
-
-	string(REPLACE "\\" "\\\\" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
-	string(REGEX REPLACE "\"" "\\\\\"" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
-	string(REPLACE "\t" "\\\\t" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
-	string(REPLACE "\r" "\\\\r" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
-	string(REPLACE "\n" "\\\\n" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
-	# According to http://json.org/ these should be escaped as well.
-	# Don't know how to do that in CMake however...
-	#string(REPLACE "\b" "\\\\b" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
-	#string(REPLACE "\f" "\\\\f" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
-	#string(REGEX REPLACE "\u([a-fA-F0-9]{4})" "\\\\u\\1" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
-
-	# We want a json array of coverage data as a single string
-	# start building them from the contents of the .gcov
-	set(GCOV_FILE_COVERAGE "[")
-
-	set(GCOV_LINE_COUNT 1) # Line number for the .gcov.
-	set(DO_SKIP 0)
-	foreach (GCOV_LINE ${GCOV_LINES})
-		#message("${GCOV_LINE}")
-		# Example of what we're parsing:
-		# Hitcount  |Line | Source
-		# "        8:   26:        if (!allowed || (strlen(allowed) == 0))"
-		string(REGEX REPLACE
-			"^([^:]*):([^:]*):(.*)$"
-			"\\1;\\2;\\3"
-			RES
-			"${GCOV_LINE}")
-
-		# Check if we should exclude lines using the Lcov syntax.
-		string(REGEX MATCH "LCOV_EXCL_START" START_SKIP "${GCOV_LINE}")
-		string(REGEX MATCH "LCOV_EXCL_END" END_SKIP "${GCOV_LINE}")
-		string(REGEX MATCH "LCOV_EXCL_LINE" LINE_SKIP "${GCOV_LINE}")
-
-		set(RESET_SKIP 0)
-		if (LINE_SKIP AND NOT DO_SKIP)
-			set(DO_SKIP 1)
-			set(RESET_SKIP 1)
-		endif()
-
-		if (START_SKIP)
-			set(DO_SKIP 1)
-			message("${GCOV_LINE_COUNT}: Start skip")
-		endif()
-
-		if (END_SKIP)
-			set(DO_SKIP 0)
-		endif()
-
-		list(LENGTH RES RES_COUNT)
-
-		if (RES_COUNT GREATER 2)
-			list(GET RES 0 HITCOUNT)
-			list(GET RES 1 LINE)
-			list(GET RES 2 SOURCE)
-
-			string(STRIP ${HITCOUNT} HITCOUNT)
-			string(STRIP ${LINE} LINE)
-
-			# Lines with 0 line numbers are metadata and can be ignored.
-			if (NOT ${LINE} EQUAL 0)
-
-				if (DO_SKIP)
-					set(GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}null, ")
-				else()
-					# Translate the hitcount into valid JSON values.
-					if (${HITCOUNT} STREQUAL "#####")
-						set(GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}0, ")
-					elseif (${HITCOUNT} STREQUAL "-")
-						set(GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}null, ")
-					else()
-						set(GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}${HITCOUNT}, ")
-					endif()
-				endif()
-			endif()
-		else()
-			message(WARNING "Failed to properly parse line (RES_COUNT = ${RES_COUNT}) ${GCOV_FILE}:${GCOV_LINE_COUNT}\n-->${GCOV_LINE}")
-		endif()
-
-		if (RESET_SKIP)
-			set(DO_SKIP 0)
-		endif()
-		math(EXPR GCOV_LINE_COUNT "${GCOV_LINE_COUNT}+1")
-	endforeach()
-
-	message("${GCOV_LINE_COUNT} of ${LINE_COUNT} lines read!")
-
-	# Advanced way of removing the trailing comma in the JSON array.
-	# "[1, 2, 3, " -> "[1, 2, 3"
-	string(REGEX REPLACE ",[ ]*$" "" GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}")
-
-	# Append the trailing ] to complete the JSON array.
-	set(GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}]")
-
-	# Generate the final JSON for this file.
-	message("Generate JSON for file: ${GCOV_SRC_REL_PATH}...")
-	string(CONFIGURE ${SRC_FILE_TEMPLATE} FILE_JSON)
-
-	set(JSON_GCOV_FILES "${JSON_GCOV_FILES}${FILE_JSON}, ")
-endforeach()
-
-# Loop through all files we couldn't find any coverage for
-# as well, and generate JSON for those as well with 0% coverage.
-string(REPLACE "\\ " ";" COVERAGE_SRCS_REMAINING "${COVERAGE_SRCS_REMAINING}")
-string(REPLACE "\\" "" COVERAGE_SRCS_REMAINING "${COVERAGE_SRCS_REMAINING}")
-foreach(NOT_COVERED_SRC ${COVERAGE_SRCS_REMAINING})
-	# Loads the source file as a list of lines.
-	file(STRINGS ${NOT_COVERED_SRC} SRC_LINES)
-
-	set(GCOV_FILE_COVERAGE "[")
-	set(GCOV_FILE_SOURCE "")
-
-	foreach (SOURCE ${SRC_LINES})
-		set(GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}0, ")
-
-		string(REPLACE "\\" "\\\\" SOURCE "${SOURCE}")
-		string(REGEX REPLACE "\"" "\\\\\"" SOURCE "${SOURCE}")
-		string(REPLACE "\t" "\\\\t" SOURCE "${SOURCE}")
-		string(REPLACE "\r" "\\\\r" SOURCE "${SOURCE}")
-		set(GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}${SOURCE}\\n")
-	endforeach()
-
-	# Remove trailing comma, and complete JSON array with ]
-	string(REGEX REPLACE ",[ ]*$" "" GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}")
-	set(GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}]")
-
-	# Generate the final JSON for this file.
-	message("Generate JSON for non-gcov file: ${NOT_COVERED_SRC}...")
-	string(CONFIGURE ${SRC_FILE_TEMPLATE} FILE_JSON)
-	set(JSON_GCOV_FILES "${JSON_GCOV_FILES}${FILE_JSON}, ")
-endforeach()
-
-# Get rid of trailing comma.
-string(REGEX REPLACE ",[ ]*$" "" JSON_GCOV_FILES "${JSON_GCOV_FILES}")
-set(JSON_GCOV_FILES "${JSON_GCOV_FILES}]")
-
-# Generate the final complete JSON!
-message("Generate final JSON...")
-string(CONFIGURE ${JSON_TEMPLATE} JSON)
-
-file(WRITE "${COVERALLS_OUTPUT_FILE}" "${JSON}")
-message("###########################################################################")
-message("Generated coveralls JSON containing coverage data:")
-message("${COVERALLS_OUTPUT_FILE}")
-message("###########################################################################")
diff --git a/arpack-ng-config-version.cmake.in b/cmake/arpackng-config-version.cmake.in
similarity index 100%
rename from arpack-ng-config-version.cmake.in
rename to cmake/arpackng-config-version.cmake.in
diff --git a/cmake/arpackng-config.cmake.in b/cmake/arpackng-config.cmake.in
new file mode 100644
index 0000000..bafa3fe
--- /dev/null
+++ b/cmake/arpackng-config.cmake.in
@@ -0,0 +1,40 @@
+# Config file for the arpack-ng package.
+#
+# To use arpack from CMake, use ARPACK::ARPACK target:
+#   find_package(arpackng)
+#   add_executable(main main.f)
+#   target_include_directories(main INTERFACE ARPACK::ARPACK)
+#   target_link_libraries(main ARPACK::ARPACK)
+#
+# To use parpack from CMake, use PARPACK::PARPACK target:
+#   find_package(arpackng)
+#   add_executable(main main.f)
+#   target_include_directories(main INTERFACE PARPACK::PARPACK)
+#   target_link_libraries(main PARPACK::PARPACK)
+
+if (NOT @BUILD_SHARED_LIBS@)
+	include(CMakeFindDependencyMacro)
+	# Find dependencies
+	if (NOT TARGET BLAS::BLAS)
+		find_dependency(BLAS REQUIRED)
+	endif()
+	if (NOT TARGET LAPACK::LAPACK)
+		find_dependency(LAPACK REQUIRED)
+	endif()
+	if (@ICB@)
+		enable_language(Fortran)
+	endif()
+	if (@MPI@)
+		include(FindMPI)
+		if (NOT TARGET MPI::Fortran)
+			find_dependency(MPI REQUIRED COMPONENTS Fortran)
+		endif()
+	endif()
+endif()
+
+include("${CMAKE_CURRENT_LIST_DIR}/arpackngTargets.cmake")
+
+add_library(ARPACK::ARPACK ALIAS arpack)
+if (TARGET parpack)
+	add_library(PARPACK::PARPACK ALIAS parpack)
+endif()
diff --git a/cmake/tstCMakeInstall.sh.in b/cmake/tstCMakeInstall.sh.in
new file mode 100755
index 0000000..747b5ee
--- /dev/null
+++ b/cmake/tstCMakeInstall.sh.in
@@ -0,0 +1,111 @@
+#!/bin/bash -eu
+# Testing that find_package works.
+# Note: this script must not be added to the test suite as it will change cmake options.
+echo "***************************************************************************************"
+
+# 1. Define temporary directory.
+
+export TMP_DIR="/tmp/tstCMakeInstall"
+rm -fr "${TMP_DIR}" # Make sure we restart from scratch.
+mkdir -p "${TMP_DIR}"
+
+# 2. Rerun cmake with prefix, install arpack-ng.
+#    Note: this script must not be added to the test suite as it will change cmake options.
+
+export TMP_PREFIX="${TMP_DIR}/local"
+export LIBSUFFIX="${1%-*}"
+echo "LIBSUFFIX: $LIBSUFFIX"
+export ITF64SUFFIX="${1#*-}"
+echo "ITF64SUFFIX: $ITF64SUFFIX"
+cmake -DCMAKE_INSTALL_PREFIX="${TMP_PREFIX}" -DMPI=ON -DLIBSUFFIX="${LIBSUFFIX}" -DITF64SUFFIX="${ITF64SUFFIX}" .
+make all install
+tree "${TMP_PREFIX}"
+
+# 3. Setup environment for find_package to work (what you typically in module-environment files).
+
+cd "${TMP_DIR}"
+export PKG_CONFIG_PATH="$(find ${TMP_PREFIX} -name arpack${LIBSUFFIX}${ITF64SUFFIX}.pc)"
+export PKG_CONFIG_PATH="${PKG_CONFIG_PATH%/*}" # Same as dirname.
+echo "PKG_CONFIG_PATH: $PKG_CONFIG_PATH"
+# find the prefix directory where CMake files are installed
+# this way we test find_package(arpackng) finds arpack in standard locations
+arpack_cmake_dir="$(find ${TMP_PREFIX} -name arpackng-config.cmake)"
+arpack_cmake_dir="${arpack_cmake_dir%/*}" # Same as dirname
+CMAKE_PREFIX_PATH="${arpack_cmake_dir%/*}" # cmake directory
+
+# 4. Create new cmake project, in temporary directory, with files from arpack-ng.
+
+mkdir -p tstCMakeInstall
+cd tstCMakeInstall
+
+cp "@PROJECT_SOURCE_DIR@/EXAMPLES/BAND/dnband.f" .
+cp "@PROJECT_SOURCE_DIR@/EXAMPLES/BAND/dnbdr1.f" .
+cp "@PROJECT_SOURCE_DIR@/EXAMPLES/BAND/dnbdr3.f" .
+cp "@PROJECT_SOURCE_DIR@/PARPACK/EXAMPLES/MPI/pdndrv1.f" .
+cp "@PROJECT_SOURCE_DIR@/PARPACK/EXAMPLES/MPI/pdndrv3.f" .
+
+echo "cmake_minimum_required(VERSION 3.0)"                               > CMakeLists.txt
+echo ""                                                                 >> CMakeLists.txt
+echo "project(tstCMakeInstall Fortran)"                                 >> CMakeLists.txt
+echo ""                                                                 >> CMakeLists.txt
+echo "find_package(BLAS REQUIRED)"                                      >> CMakeLists.txt
+echo "find_package(LAPACK REQUIRED)"                                    >> CMakeLists.txt
+echo "find_package(MPI REQUIRED COMPONENTS Fortran)"                    >> CMakeLists.txt
+echo "find_package(arpackng REQUIRED)"                                  >> CMakeLists.txt
+echo ""                                                                 >> CMakeLists.txt
+echo "add_executable(dnbdr1 dnband.f dnbdr1.f)"                         >> CMakeLists.txt
+echo "target_include_directories(dnbdr1 INTERFACE BLAS::BLAS)"          >> CMakeLists.txt
+echo "target_link_libraries(dnbdr1 BLAS::BLAS)"                         >> CMakeLists.txt
+echo "target_include_directories(dnbdr1 INTERFACE LAPACK::LAPACK)"      >> CMakeLists.txt
+echo "target_link_libraries(dnbdr1 LAPACK::LAPACK)"                     >> CMakeLists.txt
+echo "target_include_directories(dnbdr1 INTERFACE ARPACK::ARPACK)"      >> CMakeLists.txt
+echo "target_link_libraries(dnbdr1 ARPACK::ARPACK)"                     >> CMakeLists.txt
+echo ""                                                                 >> CMakeLists.txt
+echo "add_executable(pdndrv1 dnband.f pdndrv1.f)"                       >> CMakeLists.txt
+echo "target_include_directories(pdndrv1 INTERFACE BLAS::BLAS)"         >> CMakeLists.txt
+echo "target_link_libraries(pdndrv1 BLAS::BLAS)"                        >> CMakeLists.txt
+echo "target_include_directories(pdndrv1 INTERFACE LAPACK::LAPACK)"     >> CMakeLists.txt
+echo "target_link_libraries(pdndrv1 LAPACK::LAPACK)"                    >> CMakeLists.txt
+echo "target_include_directories(pdndrv1 INTERFACE MPI::MPI_Fortran)"   >> CMakeLists.txt
+echo "target_link_libraries(pdndrv1 MPI::MPI_Fortran)"                  >> CMakeLists.txt
+echo "target_include_directories(pdndrv1 INTERFACE ARPACK::ARPACK)"     >> CMakeLists.txt
+echo "target_link_libraries(pdndrv1 ARPACK::ARPACK)"                    >> CMakeLists.txt
+echo "target_include_directories(pdndrv1 INTERFACE PARPACK::PARPACK)"   >> CMakeLists.txt
+echo "target_link_libraries(pdndrv1 PARPACK::PARPACK)"                  >> CMakeLists.txt
+echo ""                                                                 >> CMakeLists.txt
+echo "find_package(PkgConfig REQUIRED)"                                 >> CMakeLists.txt
+echo "pkg_check_modules(ARPACK IMPORTED_TARGET REQUIRED arpack${LIBSUFFIX}${ITF64SUFFIX})"   >> CMakeLists.txt
+echo "pkg_check_modules(PARPACK IMPORTED_TARGET REQUIRED parpack${LIBSUFFIX}${ITF64SUFFIX})" >> CMakeLists.txt
+echo ""                                                                 >> CMakeLists.txt
+echo "add_executable(dnbdr3 dnband.f dnbdr3.f)"                         >> CMakeLists.txt
+echo "target_include_directories(dnbdr3 INTERFACE BLAS::BLAS)"          >> CMakeLists.txt
+echo "target_link_libraries(dnbdr3 BLAS::BLAS)"                         >> CMakeLists.txt
+echo "target_include_directories(dnbdr3 INTERFACE LAPACK::LAPACK)"      >> CMakeLists.txt
+echo "target_link_libraries(dnbdr3 LAPACK::LAPACK)"                     >> CMakeLists.txt
+echo "target_include_directories(dnbdr3 INTERFACE PkgConfig::ARPACK)"   >> CMakeLists.txt
+echo "target_link_libraries(dnbdr3 PkgConfig::ARPACK)"                  >> CMakeLists.txt
+echo ""                                                                 >> CMakeLists.txt
+echo "add_executable(pdndrv3 dnband.f pdndrv3.f)"                       >> CMakeLists.txt
+echo "target_include_directories(pdndrv3 INTERFACE BLAS::BLAS)"         >> CMakeLists.txt
+echo "target_link_libraries(pdndrv3 BLAS::BLAS)"                        >> CMakeLists.txt
+echo "target_include_directories(pdndrv3 INTERFACE LAPACK::LAPACK)"     >> CMakeLists.txt
+echo "target_link_libraries(pdndrv3 LAPACK::LAPACK)"                    >> CMakeLists.txt
+echo "target_include_directories(pdndrv3 INTERFACE MPI::MPI_Fortran)"   >> CMakeLists.txt
+echo "target_link_libraries(pdndrv3 MPI::MPI_Fortran)"                  >> CMakeLists.txt
+echo "target_include_directories(pdndrv3 INTERFACE PkgConfig::ARPACK)"  >> CMakeLists.txt
+echo "target_link_libraries(pdndrv3 PkgConfig::ARPACK)"                 >> CMakeLists.txt
+echo "target_include_directories(pdndrv3 INTERFACE PkgConfig::PARPACK)" >> CMakeLists.txt
+echo "target_link_libraries(pdndrv3 PkgConfig::PARPACK)"                >> CMakeLists.txt
+
+# 5. Build and test this new project with cmake: for this to be possible, find_package must work.
+
+mkdir -p build
+cd build
+
+cmake .. -DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH" || exit 1
+make all VERBOSE=1 || exit 1
+
+./dnbdr1 || exit 1
+mpirun -n 2 ./pdndrv1 || exit 1
+./dnbdr3 || exit 1
+mpirun -n 2 ./pdndrv3 || exit 1
diff --git a/configure.ac b/configure.ac
index 803c6a8..52e0a87 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 AC_PREREQ(2.67)
-AC_INIT([ARPACK-NG],[3.8.0],[https://github.com/opencollab/arpack-ng/issues/],[arpack-ng],[https://github.com/opencollab/arpack-ng/])
+AC_INIT([ARPACK-NG],[3.9.0],[https://github.com/opencollab/arpack-ng/issues/],[arpack-ng],[https://github.com/opencollab/arpack-ng/])
 AC_CONFIG_SRCDIR([SRC/version.h])
 AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_MACRO_DIR([m4])
@@ -36,7 +36,9 @@ else
   INTERFACE64=0
 fi
 
+dnl Suffixes: LIBSUFFIX modify ONLY libraries names, ITF64SUFFIX modify BOTH libraries AND include directory names.
 AC_ARG_VAR(LIBSUFFIX, [suffix to add to ARPACK libraries names])
+AC_ARG_VAR(ITF64SUFFIX, [suffix to add to ARPACK include directory and libraries names (use with INTERFACE64)])
 AC_ARG_VAR(SYMBOLSUFFIX, [suffix to add to ARPACK, BLAS and LAPACK function names])
 
 ifdef([LT_INIT], [], [
@@ -47,28 +49,7 @@ ifdef([LT_INIT], [], [
 LT_PREREQ([2.4.2])
 LT_INIT([win32-dll disable-static])
 
-dnl See if compiling parpack
-AC_ARG_ENABLE([mpi],
-	[AS_HELP_STRING(
-		[--enable-mpi],
-		[build parallel version of arpack with MPI])],
-	[],
-	[AS_VAR_SET([enable_mpi], [no])])
-AS_IF([test x"$enable_mpi" != x"no"], [
-	FCFLAGS_SAVE=$FCFLAGS
-	FCFLAGS=""
-	FFLAGS_SAVE=$FFLAGS
-	FFLAGS=""
-
-	AC_LANG_PUSH([Fortran 77])
-	AX_MPI([], AC_MSG_ERROR([could not compile a Fortran MPI test program]))
-	AC_SUBST([MPI_Fortran_LIBS], [$MPILIBS])
-	F77=$MPIF77
-	AC_LANG_POP([Fortran 77])
-
-	FCFLAGS=$FCFLAGS_SAVE
-	FFLAGS=$FFLAGS_SAVE
-])
+dnl Reminder: checking for ISO_C_BINDING must be done before MPI as MPI changes compilers.
 
 dnl See if compiling with ISO_C_BINDING support
 AC_ARG_ENABLE([icb],
@@ -77,6 +58,30 @@ AC_ARG_ENABLE([icb],
               [],
               [AS_VAR_SET([enable_icb], [no])])
 
+if test x"$enable_icb" != x"no"; then
+  AC_LANG_PUSH([Fortran])
+  AC_MSG_CHECKING([for iso_c_binding module compilation])
+  AC_LINK_IFELSE(
+                 [
+                  AC_LANG_PROGRAM(
+                                  [],
+                                  [
+                                   USE iso_c_binding
+                                   IMPLICIT NONE
+                                   INTEGER(C_INT) :: a
+                                   a = 1
+                                  ]
+                                 )
+                 ],
+                 [AC_MSG_RESULT([yes])],
+                 [
+                  AC_MSG_RESULT([no])
+                  AC_MSG_ERROR([Fortran compiler does not support iso_c_binding])
+                 ]
+                )
+  AC_LANG_POP([Fortran])
+fi
+
 dnl See if compiling matrix market example based on ICB
 AC_ARG_ENABLE([icb-exmm],
               [AS_HELP_STRING([--enable-icb-exmm],
@@ -120,29 +125,79 @@ if test x"$enable_icb_exmm" != x"no"; then
 	AC_LANG_POP([C++])
 fi
 
-if test x"$enable_icb" != x"no"; then
-  AC_LANG_PUSH([Fortran])
-  AC_MSG_CHECKING([for iso_c_binding module compilation])
+dnl See if compiling parpack
+AC_ARG_ENABLE([mpi],
+	[AS_HELP_STRING(
+		[--enable-mpi],
+		[build parallel version of arpack with MPI])],
+	[],
+	[AS_VAR_SET([enable_mpi], [no])])
+AS_IF([test x"$enable_mpi" != x"no"], [
+	FCFLAGS_SAVE=$FCFLAGS
+	FCFLAGS=""
+	FFLAGS_SAVE=$FFLAGS
+	FFLAGS=""
+
+	AC_LANG_PUSH([Fortran 77])
+	AX_MPI([], AC_MSG_ERROR([could not compile a Fortran MPI test program]))
+	AC_SUBST([MPI_Fortran_LIBS], [$MPILIBS])
+	F77=$MPIF77
+	AC_LANG_POP([Fortran 77])
+
+	FCFLAGS=$FCFLAGS_SAVE
+	FFLAGS=$FFLAGS_SAVE
+
+  dnl Check if we can use ISO_C_BINDING provided by MPI.
+  AC_LANG_PUSH([Fortran 77])
+  AC_MSG_CHECKING([for MPI support for iso_c_binding])
   AC_LINK_IFELSE(
                  [
                   AC_LANG_PROGRAM(
                                   [],
                                   [
-                                   USE iso_c_binding
+                                   USE :: mpi_f08
                                    IMPLICIT NONE
-                                   INTEGER(C_INT) :: a
-                                   a = 1
+                                   type(MPI_Comm)    comm
+                                   type(MPI_Status)  status
                                   ]
                                  )
                  ],
-                 [AC_MSG_RESULT([yes])],
+                 [
+                  AC_MSG_RESULT([yes])
+                  FCFLAGS=$FCFLAGS" -DHAVE_MPI_ICB"
+                  FFLAGS=$FFLAGS" -DHAVE_MPI_ICB"
+                  AS_VAR_SET([enable_mpi_icb], [yes])
+                 ],
                  [
                   AC_MSG_RESULT([no])
-                  AC_MSG_ERROR([Fortran compiler does not support iso_c_binding])
+                  AC_MSG_WARN([MPI library does not support iso_c_binding])
+                  AS_VAR_SET([enable_mpi_icb], [no])
                  ]
                 )
+  AC_LANG_POP([Fortran 77])
+
+  dnl As MPI can be used with or without ISO_C_BINDING (#ifdef), we need to preprocess code before compiling.
+  AC_LANG_PUSH([Fortran 77])
+  AX_CHECK_COMPILE_FLAG(-cpp, FFLAGS="$FFLAGS -cpp",
+                        AX_CHECK_COMPILE_FLAG(-fpp, FFLAGS="$FFLAGS -fpp",
+                                              AC_MSG_WARN([configure does not know how to preprocess Fortran code: set it manually via FFLAGS.])))
+  AC_LANG_POP([Fortran 77])
+
+  AC_LANG_PUSH([Fortran])
+  AX_CHECK_COMPILE_FLAG(-cpp, FCFLAGS="$FCFLAGS -cpp",
+                        AX_CHECK_COMPILE_FLAG(-fpp, FCFLAGS="$FCFLAGS -fpp",
+                                              AC_MSG_WARN([configure does not know how to preprocess Fortran code: set it manually via FCFLAGS.])))
   AC_LANG_POP([Fortran])
+])
+
+dnl TODO: this needs full re-write of parpack to support ILP64...
+if test x"$INTERFACE64" == x"1"; then
+  if test x"$enable_mpi" != x"no"; then
+    AC_MSG_ERROR([Parallel arpack does not support ILP64.])
+  fi
+fi
 
+if test x"$enable_icb" != x"no"; then
   if test x"$enable_mpi" != x"no"; then
     FCFLAGS_SAVE=$FCFLAGS
     FCFLAGS=""
@@ -190,7 +245,7 @@ if test x"$enable_icb" != x"no"; then
   fi
   AX_CXX_COMPILE_STDCXX(11)
 else
-  # ICB saves you from old-fashion-boring-cumbersome-fortran/C crap...
+  # ICB saves you from old-fashion-boring-cumbersome-fortran/C crap... For arpack symbols (only).
 
   if test x"$SYMBOLSUFFIX" != x""; then
     dnl Need to rely on non-F77 features
@@ -206,48 +261,82 @@ else
     SCALARFUNS="naitr napps naup2 naupd nconv neigh neupd ngets statn saitr sapps saup2 saupd sconv seigt seupd sgets stats getv0 sortc sortr sesrt stqrb"
     COMPLEXFUNS="naitr napps naup2 naupd neigh neupd ngets statn getv0 sortc"
 
-    BLASFUNS1="axpy copy gemv geqr2 lacpy lae2 lahqr lanhs larnv lartg lascl laset lasrt scal trevc trmm trsen gbmv gbtrf gbtrs gttrf gttrs pttrf pttrs"
-    BLASFUNS2="dot ger labad laev2 lamch lanst lanv2 lapy2 larf larfg lasr nrm2 orm2r rot steqr swap"
-    BLASFUNS3="dotc geru unm2r"
-    BLASFUNS4="COPY LABAD LAMCH LANHS LANV2 LARFG ROT GEMV"
-    BLASFUNS5="scnrm2 dznrm2 csscal zdscal"
-
-    FUNS1="$SCALARFUNS $BLASFUNS1 $BLASFUNS2"
+    FUNS1="$SCALARFUNS"
     for f in $FUNS1
     do
       FFLAGS="$FFLAGS -Ds$f=s$f$SYMBOLSUFFIX -Dd$f=d$f$SYMBOLSUFFIX"
     done
 
-    FUNS2="$COMPLEXFUNS $BLASFUNS1 $BLASFUNS3"
+    FUNS2="$COMPLEXFUNS"
     for f in $FUNS2
     do
       FFLAGS="$FFLAGS -Dc$f=c$f$SYMBOLSUFFIX -Dz$f=z$f$SYMBOLSUFFIX"
     done
-
-    for f in $BLASFUNS4
-    do
-      FFLAGS="$FFLAGS -DS$f=S$f$SYMBOLSUFFIX -DD$f=D$f$SYMBOLSUFFIX"
-    done
-
-    for f in $BLASFUNS5
-    do
-      FFLAGS="$FFLAGS -D$f=$f$SYMBOLSUFFIX -D$f=$f$SYMBOLSUFFIX"
-    done
   fi
 
   dnl Both a lowercase and uppercase variable are needed
   dnl since the macro changes the case of the whole expression
   symbolsuffix=$SYMBOLSUFFIX
-  AC_F77_FUNC(sgemm$SYMBOLSUFFIX, sgemmsuff)
   AC_F77_FUNC(snaupd$SYMBOLSUFFIX, snaupdsuff)
   AC_F77_FUNC(sneupd$SYMBOLSUFFIX, sneupdsuff)
   AC_F77_FUNC(dnaupd$SYMBOLSUFFIX, dnaupdsuff)
   AC_F77_FUNC(dneupd$SYMBOLSUFFIX, dneupdsuff)
+  dnl Needed for BLAS check and for tests (even when suffix is empty)
+  CPPFLAGS="$CPPFLAGS -Dsnaupd=$snaupdsuff -Dsneupd=$sneupdsuff -Ddnaupd=$dnaupdsuff -Ddneupd=$dneupdsuff"
+fi
+
+dnl As BLAS/LAPACK does not provide ICB, we may have to deal with symbols the old-fashion-boring-cumbersome-fortran/C way...
+
+if test x"$SYMBOLSUFFIX" != x""; then
+  dnl Need to rely on non-F77 features
+  AC_FC_LINE_LENGTH(unlimited)
+  FFLAGS="$FFLAGS $ac_cv_fc_line_length"
+
+  AC_LANG_PUSH([Fortran 77])
+  AX_CHECK_COMPILE_FLAG(-cpp, FFLAGS="$FFLAGS -cpp",
+                        AX_CHECK_COMPILE_FLAG(-fpp, FFLAGS="$FFLAGS -fpp",
+                                              AC_MSG_WARN([configure does not know how to enable your Fortran compiler's preprocessor: set it manually via FFLAGS.])))
+  AC_LANG_POP([Fortran 77])
+
+  BLASFUNS1="axpy copy gemv geqr2 lacpy lae2 lahqr lanhs larnv lartg lascl laset lasrt scal trevc trmm trsen gbmv gbtrf gbtrs gttrf gttrs pttrf pttrs"
+  BLASFUNS2="dot ger labad laev2 lamch lanst lanv2 lapy2 larf larfg lasr nrm2 orm2r rot steqr swap"
+  BLASFUNS3="dotc geru unm2r"
+  BLASFUNS4="COPY LABAD LAMCH LANHS LANV2 LARFG ROT GEMV"
+  BLASFUNS5="scnrm2 dznrm2 csscal zdscal"
+
+  FUNS1="$BLASFUNS1 $BLASFUNS2"
+  for f in $FUNS1
+  do
+    FFLAGS="$FFLAGS -Ds$f=s$f$SYMBOLSUFFIX -Dd$f=d$f$SYMBOLSUFFIX"
+  done
+
+  FUNS2="$BLASFUNS1 $BLASFUNS3"
+  for f in $FUNS2
+  do
+    FFLAGS="$FFLAGS -Dc$f=c$f$SYMBOLSUFFIX -Dz$f=z$f$SYMBOLSUFFIX"
+  done
+
+  for f in $BLASFUNS4
+  do
+    FFLAGS="$FFLAGS -DS$f=S$f$SYMBOLSUFFIX -DD$f=D$f$SYMBOLSUFFIX"
+  done
+
+  for f in $BLASFUNS5
+  do
+    FFLAGS="$FFLAGS -D$f=$f$SYMBOLSUFFIX -D$f=$f$SYMBOLSUFFIX"
+  done
+
+  dnl Both a lowercase and uppercase variable are needed
+  dnl since the macro changes the case of the whole expression
+  symbolsuffix=$SYMBOLSUFFIX
+  AC_F77_FUNC(sgemm$SYMBOLSUFFIX, sgemmsuff)
   AC_F77_FUNC(cheev$SYMBOLSUFFIX, cheevsuff)
   dnl Needed for BLAS check and for tests (even when suffix is empty)
-  CPPFLAGS="$CPPFLAGS -Dsgemm=$sgemmsuff -Dsnaupd=$snaupdsuff -Dsneupd=$sneupdsuff -Ddnaupd=$dnaupdsuff -Ddneupd=$dneupdsuff -Dcheev=$cheevsuff"
+  CPPFLAGS="$CPPFLAGS -Dsgemm=$sgemmsuff -Dcheev=$cheevsuff"
 fi
 
+dnl Set conditional for Makefiles.
+
 AM_CONDITIONAL([MPI], [test x"$enable_mpi" != x"no"])
 AM_CONDITIONAL([BLACS], [false])
 AM_CONDITIONAL([ICB], [test x"$enable_icb" != x"no"])
@@ -256,17 +345,21 @@ AM_CONDITIONAL([ICBEXMM], [test x"$enable_icb_exmm" != x"no"])
 m4_ifdef([PKG_INSTALLDIR], [PKG_INSTALLDIR], [AC_SUBST([pkgconfigdir], [${libdir}/pkgconfig])])
 AC_SUBST([ARPACK_PC_LIBS_PRIVATE], ["$LAPACK_LIBS $BLAS_LIBS"])
 AC_SUBST([PARPACK_PC_LIBS_PRIVATE], ["$LAPACK_LIBS $BLAS_LIBS $MPI_Fortran_LIBS"])
+
+AC_CONFIG_FILES([
+	arpack$LIBSUFFIX$ITF64SUFFIX.pc:pkg-config/arpack.pc.in
+	parpack$LIBSUFFIX$ITF64SUFFIX.pc:pkg-config/parpack.pc.in
+	arpackSolver$LIBSUFFIX$ITF64SUFFIX.pc:pkg-config/arpackSolver.pc.in
+], [], [LIBSUFFIX="$LIBSUFFIX"; ITF64SUFFIX="$ITF64SUFFIX"])
+
+dnl We do NOT want arpackng*.cmake files to be created: @MPI@ can not be replaced.
 AC_CONFIG_FILES([
-	SRC/arpack$LIBSUFFIX.pc:SRC/arpack.pc.in
-	PARPACK/SRC/MPI/parpack$LIBSUFFIX.pc:PARPACK/SRC/MPI/parpack.pc.in
-], [], [LIBSUFFIX="$LIBSUFFIX"])
+	tstAutotoolsInstall.sh:pkg-config/tstAutotoolsInstall.sh.in
+], [], [abs_top_builddir="$abs_top_builddir"])
 
 AC_CONFIG_FILES([
-	EXAMPLES/MATRIX_MARKET/arpackSolver.pc
 	arpackdef.h
 	arpackicb.h
-	arpack-ng-config-version.cmake
-	arpack-ng-config.cmake
 	Makefile
 	ICB/Makefile
 	UTIL/Makefile
@@ -304,7 +397,7 @@ AC_MSG_RESULT([
 Configuration summary for $PACKAGE_STRING
 --------------------------------------------------
 Installation prefix : $prefix
-MPI enabled         : $enable_mpi
+MPI enabled         : $enable_mpi (ICB provided $enable_mpi_icb)
 ICB enabled         : $enable_icb
 INTERFACE64         : $INTERFACE64
 F77                 : $F77
diff --git a/debian/changelog b/debian/changelog
index c8f9c8c..74d2240 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+arpack (3.9.0-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Fri, 24 Feb 2023 22:15:50 -0000
+
 arpack (3.8.0-3) unstable; urgency=medium
 
   * Team upload.
diff --git a/debian/patches/0001-Run-MPI-tests-on-a-single-cpu.patch b/debian/patches/0001-Run-MPI-tests-on-a-single-cpu.patch
index 0c7de47..3c74a40 100644
--- a/debian/patches/0001-Run-MPI-tests-on-a-single-cpu.patch
+++ b/debian/patches/0001-Run-MPI-tests-on-a-single-cpu.patch
@@ -7,10 +7,10 @@ Subject: Run MPI tests on a single cpu
  PARPACK/TESTS/MPI/Makefile.am    | 4 ++--
  2 files changed, 4 insertions(+), 4 deletions(-)
 
-diff --git a/PARPACK/EXAMPLES/MPI/Makefile.am b/PARPACK/EXAMPLES/MPI/Makefile.am
-index 66ccaf7..65d7fb3 100644
---- a/PARPACK/EXAMPLES/MPI/Makefile.am
-+++ b/PARPACK/EXAMPLES/MPI/Makefile.am
+Index: arpack.git/PARPACK/EXAMPLES/MPI/Makefile.am
+===================================================================
+--- arpack.git.orig/PARPACK/EXAMPLES/MPI/Makefile.am
++++ arpack.git/PARPACK/EXAMPLES/MPI/Makefile.am
 @@ -10,9 +10,9 @@ ZNDRV = pzndrv1
  
  check_PROGRAMS = $(SNDRV) $(DNDRV) $(SSDRV) $(DSDRV) $(CNDRV) $(ZNDRV)
@@ -23,13 +23,13 @@ index 66ccaf7..65d7fb3 100644
  
  TESTS = $(check_PROGRAMS)
  
-diff --git a/PARPACK/TESTS/MPI/Makefile.am b/PARPACK/TESTS/MPI/Makefile.am
-index 862a4c1..26ee9a6 100644
---- a/PARPACK/TESTS/MPI/Makefile.am
-+++ b/PARPACK/TESTS/MPI/Makefile.am
+Index: arpack.git/PARPACK/TESTS/MPI/Makefile.am
+===================================================================
+--- arpack.git.orig/PARPACK/TESTS/MPI/Makefile.am
++++ arpack.git/PARPACK/TESTS/MPI/Makefile.am
 @@ -1,9 +1,9 @@
  F77 = $(MPIF77)
- LDADD = $(top_builddir)/PARPACK/SRC/MPI/libparpack$(LIBSUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
+ LDADD = $(top_builddir)/PARPACK/SRC/MPI/libparpack$(LIBSUFFIX)$(ITF64SUFFIX).la $(LAPACK_LIBS) $(BLAS_LIBS)
  
 -# Run MPI tests with "mpirun -n 2"
 +# Run MPI tests with "mpirun -n 1"
diff --git a/debug.h b/debugF90.h
similarity index 100%
rename from debug.h
rename to debugF90.h
diff --git a/m4/ax_mpi.m4 b/m4/ax_mpi.m4
index 5b13376..8a9e9df 100644
--- a/m4/ax_mpi.m4
+++ b/m4/ax_mpi.m4
@@ -80,7 +80,7 @@
 
 AU_ALIAS([ACX_MPI], [AX_MPI])
 AC_DEFUN([AX_MPI], [
-AC_PREREQ(2.50) dnl for AC_LANG_CASE
+AC_PREREQ([2.50]) dnl for AC_LANG_CASE
 
 AC_LANG_CASE([C], [
 	AC_REQUIRE([AC_PROG_CC])
@@ -151,16 +151,16 @@ if test x = x"$MPILIBS"; then
 	AC_CHECK_LIB(mpich, MPI_Init, [MPILIBS="-lmpich"])
 fi
 
-dnl We have to use AC_TRY_COMPILE and not AC_CHECK_HEADER because the
+dnl We have to use AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[],[]) and not AC_CHECK_HEADER because the
 dnl latter uses $CPP, not $CC (which may be mpicc).
 AC_LANG_CASE([C], [if test x != x"$MPILIBS"; then
 	AC_MSG_CHECKING([for mpi.h])
-	AC_TRY_COMPILE([#include <mpi.h>],[],[AC_MSG_RESULT(yes)], [MPILIBS=""
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <mpi.h>]], [[]])],[AC_MSG_RESULT(yes)],[MPILIBS=""
 		AC_MSG_RESULT(no)])
 fi],
 [C++], [if test x != x"$MPILIBS"; then
 	AC_MSG_CHECKING([for mpi.h])
-	AC_TRY_COMPILE([#include <mpi.h>],[],[AC_MSG_RESULT(yes)], [MPILIBS=""
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <mpi.h>]], [[]])],[AC_MSG_RESULT(yes)],[MPILIBS=""
 		AC_MSG_RESULT(no)])
 fi],
 [Fortran 77], [if test x != x"$MPILIBS"; then
diff --git a/SRC/arpack.pc.in b/pkg-config/arpack.pc.in
similarity index 68%
rename from SRC/arpack.pc.in
rename to pkg-config/arpack.pc.in
index a5550ce..7168c5b 100644
--- a/SRC/arpack.pc.in
+++ b/pkg-config/arpack.pc.in
@@ -1,12 +1,12 @@
 prefix=@prefix@
 exec_prefix=@exec_prefix@
 libdir=@libdir@
-includedir=@includedir@
+includedir=@includedir@/arpack-ng@ITF64SUFFIX@
 
 Name: @PACKAGE_NAME@
 Description: Collection of Fortran77 subroutines designed to solve large scale eigenvalue problems
 Version: @PACKAGE_VERSION@
 URL: @PACKAGE_URL@
-Libs: -L${libdir} -larpack@LIBSUFFIX@
+Libs: -L${libdir} -larpack@LIBSUFFIX@@ITF64SUFFIX@
 Libs.private: @ARPACK_PC_LIBS_PRIVATE@
-Cflags: -I${includedir}/arpack
+Cflags: -I${includedir}
diff --git a/EXAMPLES/MATRIX_MARKET/arpackSolver.pc.in b/pkg-config/arpackSolver.pc.in
similarity index 73%
rename from EXAMPLES/MATRIX_MARKET/arpackSolver.pc.in
rename to pkg-config/arpackSolver.pc.in
index 5f92aeb..d6f1b5b 100644
--- a/EXAMPLES/MATRIX_MARKET/arpackSolver.pc.in
+++ b/pkg-config/arpackSolver.pc.in
@@ -1,10 +1,10 @@
 prefix=@prefix@
 exec_prefix=@exec_prefix@
-includedir=@includedir@
+includedir=@includedir@/arpack-ng@ITF64SUFFIX@
 
 Name: arpackSolver
 Description: Utility to test arpack with matrix market files
 Version: @PACKAGE_VERSION@
 URL: @PACKAGE_URL@
 Requires: arpack, eigen3 >= 3.3
-Cflags: -I${includedir}/arpack
+Cflags: -I${includedir}
diff --git a/PARPACK/SRC/MPI/parpack.pc.in b/pkg-config/parpack.pc.in
similarity index 60%
rename from PARPACK/SRC/MPI/parpack.pc.in
rename to pkg-config/parpack.pc.in
index bbc75c7..452be75 100644
--- a/PARPACK/SRC/MPI/parpack.pc.in
+++ b/pkg-config/parpack.pc.in
@@ -1,11 +1,13 @@
 prefix=@prefix@
 exec_prefix=@exec_prefix@
 libdir=@libdir@
+includedir=@includedir@/arpack-ng@ITF64SUFFIX@
 
 Name: @PACKAGE_NAME@
 Description: Collection of Fortran77 subroutines designed to solve large scale eigenvalue problems
 Version: @PACKAGE_VERSION@
 URL: @PACKAGE_URL@
-Requires.private: arpack@LIBSUFFIX@
-Libs: -L${libdir} -lparpack@LIBSUFFIX@
+Requires.private: arpack@LIBSUFFIX@@ITF64SUFFIX@
+Libs: -L${libdir} -lparpack@LIBSUFFIX@@ITF64SUFFIX@
 Libs.private: @PARPACK_PC_LIBS_PRIVATE@
+Cflags: -I${includedir}
diff --git a/pkg-config/tstAutotoolsInstall.sh.in b/pkg-config/tstAutotoolsInstall.sh.in
new file mode 100755
index 0000000..544b663
--- /dev/null
+++ b/pkg-config/tstAutotoolsInstall.sh.in
@@ -0,0 +1,103 @@
+#!/bin/bash -eu
+# Testing that PKG_CHECK_MODULES works.
+# Note: this script must not be added to the test suite as it will change cmake options.
+
+echo "***************************************************************************************"
+
+# 1. Define temporary directory.
+
+export TMP_DIR="/tmp/tstAutotoolsInstall"
+rm -fr "${TMP_DIR}" # Make sure we restart from scratch.
+mkdir -p "${TMP_DIR}"
+
+# 2. Rerun cmake with prefix, install arpack-ng.
+#    Note: this script must not be added to the test suite as it will change cmake options.
+
+make clean
+make distclean
+
+export PROJECT_SOURCE_DIR="$(pwd)"
+export TMP_PREFIX="${TMP_DIR}/local"
+export LIBSUFFIX="${1%-*}"
+echo "LIBSUFFIX: $LIBSUFFIX"
+export ITF64SUFFIX="${1#*-}"
+echo "ITF64SUFFIX: $ITF64SUFFIX"
+LIBSUFFIX="${LIBSUFFIX}" ITF64SUFFIX="${ITF64SUFFIX}" ./configure --prefix="${TMP_PREFIX}" --enable-mpi
+make all install
+tree "${TMP_PREFIX}"
+
+# 3. Setup environment for PKG_CHECK_MODULES to work (what you typically in module-environment files).
+
+cd "${TMP_DIR}"
+export PKG_CONFIG_PATH="$(find ${TMP_PREFIX} -name arpack${LIBSUFFIX}${ITF64SUFFIX}.pc)"
+export PKG_CONFIG_PATH="${PKG_CONFIG_PATH%/*}" # Same as dirname.
+echo "PKG_CONFIG_PATH: $PKG_CONFIG_PATH"
+
+# 4. Create new cmake project, in temporary directory, with files from arpack-ng.
+
+mkdir -p tstAutotoolsInstall
+cd tstAutotoolsInstall
+
+cp "${PROJECT_SOURCE_DIR}/EXAMPLES/BAND/dnband.f" .
+cp "${PROJECT_SOURCE_DIR}/EXAMPLES/BAND/dnbdr1.f" .
+cp "${PROJECT_SOURCE_DIR}/PARPACK/EXAMPLES/MPI/pdndrv1.f" .
+cp -fr "${PROJECT_SOURCE_DIR}/m4" .
+
+echo "AC_PREREQ([2.68])                                                       "  > configure.ac
+echo "AC_INIT([tstAutotoolsInstall], 1.0)                                     " >> configure.ac
+echo "AM_INIT_AUTOMAKE([foreign])                                             " >> configure.ac
+echo "AC_CONFIG_MACRO_DIR([m4])                                               " >> configure.ac
+echo "                                                                        " >> configure.ac
+echo "AC_PROG_FC                                                              " >> configure.ac
+echo "AC_PROG_MKDIR_P                                                         " >> configure.ac
+echo "AC_PROG_MAKE_SET                                                        " >> configure.ac
+echo "PKG_PROG_PKG_CONFIG                                                     " >> configure.ac
+echo "                                                                        " >> configure.ac
+echo "AX_BLAS([], [AC_MSG_ERROR([cannot find BLAS libraries])])               " >> configure.ac
+echo "AC_SUBST([BLAS_LIBS])                                                   " >> configure.ac
+echo "                                                                        " >> configure.ac
+echo "AX_LAPACK([], [AC_MSG_ERROR([cannot find LAPACK libraries])])           " >> configure.ac
+echo "AC_SUBST([LAPACK_LIBS])                                                 " >> configure.ac
+echo "                                                                        " >> configure.ac
+echo "AC_LANG_PUSH([Fortran 77])                                              " >> configure.ac
+echo "AX_MPI([], AC_MSG_ERROR([could not compile a Fortran MPI test program]))" >> configure.ac
+echo "F77=\$MPIF77                                                            " >> configure.ac
+echo "AC_SUBST([MPI_Fortran_LIBS])                                            " >> configure.ac
+echo "                                                                        " >> configure.ac
+echo "PKG_CHECK_MODULES([ARPACK], [arpack${LIBSUFFIX}${ITF64SUFFIX}])         " >> configure.ac
+echo "AC_SUBST([ARPACK_CFLAGS])                                               " >> configure.ac
+echo "AC_SUBST([ARPACK_LIBS])                                                 " >> configure.ac
+echo "                                                                        " >> configure.ac
+echo "PKG_CHECK_MODULES([PARPACK], [parpack${LIBSUFFIX}${ITF64SUFFIX}])       " >> configure.ac
+echo "AC_SUBST([PARPACK_CFLAGS])                                              " >> configure.ac
+echo "AC_SUBST([PARPACK_LIBS])                                                " >> configure.ac
+echo "                                                                        " >> configure.ac
+echo "LT_INIT                                                                 " >> configure.ac
+echo "                                                                        " >> configure.ac
+echo "AC_CONFIG_FILES([Makefile])                                             " >> configure.ac
+echo "AC_OUTPUT                                                               " >> configure.ac
+
+echo "AUTOMAKE_OPTIONS = foreign                                                                           "  > Makefile.am
+echo "ACLOCAL_AMFLAGS  = -I m4                                                                             " >> Makefile.am
+echo "                                                                                                     " >> Makefile.am
+echo "EXTRA_DIST = debug.h stat.h                                                                          " >> Makefile.am
+echo "                                                                                                     " >> Makefile.am
+echo "bin_PROGRAMS    = dnbdr1 pdndrv1                                                                     " >> Makefile.am
+echo "                                                                                                     " >> Makefile.am
+echo "dnbdr1_SOURCES = dnbdr1.f dnband.f                                                                   " >> Makefile.am
+echo "dnbdr1_FFLAGS  = \$(ARPACK_CFLAGS)                                                                   " >> Makefile.am
+echo "dnbdr1_LDADD   = \$(ARPACK_LIBS) \$(LAPACK_LIBS) \$(BLAS_LIBS)                                       " >> Makefile.am
+echo "                                                                                                     " >> Makefile.am
+echo "pdndrv1_SOURCES = pdndrv1.f dnband.f                                                                 " >> Makefile.am
+echo "pdndrv1_FFLAGS  = \$(PARPACK_CFLAGS) \$(ARPACK_CFLAGS)                                               " >> Makefile.am
+echo "pdndrv1_LDADD   = \$(PARPACK_LIBS) \$(ARPACK_LIBS) \$(LAPACK_LIBS) \$(BLAS_LIBS) \$(MPI_Fortran_LIBS)" >> Makefile.am
+
+# 5. Build and test this new project with cmake: for this to be possible, PKG_CHECK_MODULES must work.
+
+autoreconf --force --verbose --install
+
+./configure
+make all
+
+./dnbdr1
+mpirun -n 2 ./pdndrv1
diff --git a/scripts/travis_fedora.sh b/scripts/travis_fedora.sh
index ccc7561..99a85dc 100755
--- a/scripts/travis_fedora.sh
+++ b/scripts/travis_fedora.sh
@@ -8,16 +8,13 @@ then
   # fedora
   #   note: when you PR, docker-cp provides, in the container, the branch associated with the PR (not master where there's nothing new)
   #         1. docker create --name mobydick IMAGE CMD        <=> create a container (= instance of image) but container is NOT yet started
-  #         2. docker cp -a ${TRAVIS_BUILD_DIR} mobydick:/tmp <=> copy git repository (CI worker, checkout-ed on PR branch) into the container
+  #         2. docker cp -a ${GITHUB_WORKSPACE} mobydick:/tmp <=> copy git repository (CI worker, checkout-ed on PR branch) into the container
   #                                                               note: docker-cp works only if copy from/to containers (not images)
   #         3. docker start -a mobydick                       <=> start to run the container (initialized with docker-cp)
     test . != ".$2" && mpi="$2" || mpi=openmpi
-    test . != ".$3" && version="$3" || version=latest
-    time sudo docker pull registry.fedoraproject.org/fedora:$version ||
-	sudo docker pull fedora:$version
-    time sudo docker create --name mobydick fedora:$version \
-	/tmp/arpack-ng/scripts/travis_fedora.sh $mpi
-    time sudo docker cp -a ${TRAVIS_BUILD_DIR} mobydick:/tmp
+    time sudo docker pull fedora
+    time sudo docker create --name mobydick fedora /tmp/arpack-ng/scripts/travis_fedora.sh $mpi
+    time sudo docker cp -a ${GITHUB_WORKSPACE} mobydick:/tmp
     time sudo docker start -a mobydick ; e=$?
     exit $e
 fi
@@ -31,8 +28,7 @@ then
     # Ignore weak depencies
     echo "install_weak_deps=False" >> /etc/dnf/dnf.conf
     time dnf -y upgrade
-    time dnf -y install environment-modules git \
-        gfortran openblas-devel cmake ${mpi}-devel make gcc-c++
+    time dnf -y install environment-modules git gfortran openblas-devel cmake ${mpi}-devel make gcc-c++
     useradd test
     chown -R test /tmp
     sudo -u test $0 $mpi
diff --git a/scripts/travis_redhat.sh b/scripts/travis_redhat.sh
new file mode 100755
index 0000000..60ba085
--- /dev/null
+++ b/scripts/travis_redhat.sh
@@ -0,0 +1,32 @@
+#!/bin/sh
+# usage: ./travis_centos.sh [:7|:8|:latest|:stream]
+#
+## -e : Make sure all errors cause the script to fail
+## -x be verbose; write what we are doing, as we do it
+set -ex
+
+podman pull registry.access.redhat.com/ubi8/ubi                          \
+&&                                                                       \
+podman create --name ubi ${prefix}centos$1 /bin/bash -c                  \
+"cat /etc/os-release                                                  && \
+ dnf install -y dnf-plugins-core epel-release                         && \
+ dnf upgrade -y                                                       && \
+ dnf config-manager --set-enabled powertools                          && \
+ dnf install -y git make gcc gcc-gfortran gcc-c++ environment-modules && \
+ dnf install -y cmake                                                 && \
+ dnf install -y mpich-devel                                           && \
+ dnf --enablerepo=\"epel\" install -y openblas-devel lapack-devel     && \
+ . /etc/profile.d/modules.sh                                          && \
+ module avail && module load mpi && module list                       && \
+ cd /tmp                                                              && \
+ cd arpack-ng                                                         && \
+ git status                                                           && \
+ git log -2                                                           && \
+ mkdir -p build && cd build                                           && \
+ cmake -DEXAMPLES=ON -DMPI=ON -DICB=ON ..                             && \
+ make all && make test"                                                  \
+&&                                                                       \
+podman cp -a ${GITHUB_WORKSPACE} ubi:/tmp                                \
+&&                                                                       \
+podman start -a ubi
+
diff --git a/scripts/travis_ubuntu.sh b/scripts/travis_ubuntu.sh
index 66425b8..4952e98 100755
--- a/scripts/travis_ubuntu.sh
+++ b/scripts/travis_ubuntu.sh
@@ -3,10 +3,17 @@
 ## -x be verbose; write what we are doing, as we do it
 set -ex
 
+# for non-LTS && EOL'ed ubuntu, the mirror url must be modified to run `apt update`
+cmd=ls
+if [ $2 = ":eoan" ]; then
+    cmd="sed -i 's/\(security\|archive\).ubuntu/old-releases.ubuntu/g' /etc/apt/sources.list"
+fi 
+
 sudo docker pull "$1$2"                                                                                           \
 &&                                                                                                                \
 sudo docker create --name mobydick "$1$2" /bin/bash -c                                                            \
-"apt-get    update                                                                                             && \
+"${cmd} && \
+ apt-get    update                                                                                             && \
  ln -snf /usr/share/zoneinfo/Europe/Paris /etc/localtime && echo 'Europe/Paris' > /etc/timezone                && \
  apt-get -y install build-essential                                                                            && \
  apt-get -y install dialog apt-utils                                                                           && \
@@ -30,6 +37,6 @@ sudo docker create --name mobydick "$1$2" /bin/bash -c
  make all                                                                                                      && \
  make test; tail -n 50 ./Testing/Temporary/LastTest.log"                                                          \
 &&                                                                                                                \
-sudo docker cp -a ${TRAVIS_BUILD_DIR} mobydick:/tmp                                                               \
+sudo docker cp -a ${GITHUB_WORKSPACE} mobydick:/tmp                                                               \
 &&                                                                                                                \
 sudo docker start -a mobydick
diff --git a/stat.h b/statF90.h
similarity index 100%
rename from stat.h
rename to statF90.h

More details

Full run details

Historical runs