SLEPC4PY(1) | SLEPc for Python | SLEPC4PY(1) |
slepc4py - SLEPc for Python
This document describes slepc4py, a Python port to the SLEPc libraries.
SLEPc is a software package for the parallel solution of large-scale eigenvalue problems. It can be used for computing eigenvalues and eigenvectors of large, sparse matrices, or matrix pairs, and also for computing singular values and vectors of a rectangular matrix.
SLEPc relies on PETSc for basic functionality such as the representation of matrices and vectors, and the solution of linear systems of equations. Thus, slepc4py must be used together with its companion petsc4py.
SLEPc for Python (slepc4py) is a Python package that provides convenient access to the functionality of SLEPc.
SLEPc [1], [2] implements algorithms and tools for the numerical solution of large, sparse eigenvalue problems on parallel computers. It can be used for linear eigenvalue problems in either standard or generalized form, with real or complex arithmetic. It can also be used for computing a partial SVD of a large, sparse, rectangular matrix, and to solve nonlinear eigenvalue problems (polynomial or general). Additionally, SLEPc provides solvers for the computation of the action of a matrix function on a vector.
SLEPc is intended for computing a subset of the spectrum of a matrix (or matrix pair). One can for instance approximate the largest magnitude eigenvalues, or the smallest ones, or even those eigenvalues located near a given region of the complex plane. Interior eigenvalues are harder to compute, so SLEPc provides different methodologies. One such method is to use a spectral transformation. Cheaper alternatives are also available.
Currently, the following types of eigenproblems can be addressed:
For the linear eigenvalue problem, the following methods are available:
For singular value computations, the following alternatives can be used:
For polynomial eigenvalue problems, the following methods are available:
For general nonlinear eigenvalue problems, the following methods can be used:
Computation of interior eigenvalues is supported by means of the following methodologies:
Other remarkable features include:
SLEPc provides the following components, which are mirrored by slepc4py for its use from Python. The first five components are solvers for different classes of problems, while the rest can be considered auxiliary object.
This tutorial is intended for basic use of slepc4py. For more advanced use, the reader is referred to SLEPc tutorials as well as to slepc4py reference documentation.
In this section, we include the source code of example demo/ex1.py available in the slepc4py distribution, with comments inserted inline.
The first thing to do is initialize the libraries. This is normally not required, as it is done automatically at import time. However, if you want to gain access to the facilities for accessing command-line options, the following lines must be executed by the main script prior to any petsc4py or slepc4py calls:
import sys, slepc4py slepc4py.init(sys.argv)
Next, we have to import the relevant modules. Normally, both PETSc and SLEPc modules have to be imported in all slepc4py programs. It may be useful to import NumPy as well:
from petsc4py import PETSc from slepc4py import SLEPc import numpy
At this point, we can use any petsc4py and slepc4py operations. For instance, the following lines allow the user to specify an integer command-line argument n with a default value of 30 (see the next section for example usage of command-line options):
opts = PETSc.Options() n = opts.getInt('n', 30)
It is necessary to build a matrix to define an eigenproblem (or two in the case of generalized eigenproblems). The following fragment of code creates the matrix object and then fills the non-zero elements one by one. The matrix of this particular example is tridiagonal, with value 2 in the diagonal, and -1 in off-diagonal positions. See petsc4py documentation for details about matrix objects:
A = PETSc.Mat().create() A.setSizes([n, n]) A.setFromOptions() A.setUp() rstart, rend = A.getOwnershipRange() # first row if rstart == 0:
A[0, :2] = [2, -1]
rstart += 1 # last row if rend == n:
A[n-1, -2:] = [-1, 2]
rend -= 1 # other rows for i in range(rstart, rend):
A[i, i-1:i+2] = [-1, 2, -1] A.assemble()
The solver object is created in a similar way as other objects in petsc4py:
E = SLEPc.EPS(); E.create()
Once the object is created, the eigenvalue problem must be specified. At least one matrix must be provided. The problem type must be indicated as well, in this case it is HEP (Hermitian eigenvalue problem). Apart from these, other settings could be provided here (for instance, the tolerance for the computation). After all options have been set, the user should call the setFromOptions() operation, so that any options specified at run time in the command line are passed to the solver object:
E.setOperators(A) E.setProblemType(SLEPc.EPS.ProblemType.HEP) E.setFromOptions()
After that, the solve() method will run the selected eigensolver, keeping the solution stored internally:
E.solve()
Once the computation has finished, we are ready to print the results. First, some informative data can be retrieved from the solver object:
Print = PETSc.Sys.Print Print() Print("******************************") Print("*** SLEPc Solution Results ***") Print("******************************") Print() its = E.getIterationNumber() Print("Number of iterations of the method: %d" % its) eps_type = E.getType() Print("Solution method: %s" % eps_type) nev, ncv, mpd = E.getDimensions() Print("Number of requested eigenvalues: %d" % nev) tol, maxit = E.getTolerances() Print("Stopping condition: tol=%.4g, maxit=%d" % (tol, maxit))
For retrieving the solution, it is necessary to find out how many eigenpairs have converged to the requested precision:
nconv = E.getConverged() Print("Number of converged eigenpairs %d" % nconv)
For each of the nconv eigenpairs, we can retrieve the eigenvalue k, and the eigenvector, which is represented by means of two petsc4py vectors vr and vi (the real and imaginary part of the eigenvector, since for real matrices the eigenvalue and eigenvector may be complex). We also compute the corresponding relative errors in order to make sure that the computed solution is indeed correct:
if nconv > 0:
# Create the results vectors
vr, wr = A.getVecs()
vi, wi = A.getVecs()
#
Print()
Print(" k ||Ax-kx||/||kx|| ")
Print("----------------- ------------------")
for i in range(nconv):
k = E.getEigenpair(i, vr, vi)
error = E.computeError(i)
if k.imag != 0.0:
Print(" %9f%+9f j %12g" % (k.real, k.imag, error))
else:
Print(" %12f %12g" % (k.real, error))
Print()
Now we illustrate how to specify command-line options in order to extract the full potential of slepc4py.
A simple execution of the demo/ex1.py script will result in the following output:
$ python demo/ex1.py ****************************** *** SLEPc Solution Results *** ****************************** Number of iterations of the method: 4 Solution method: krylovschur Number of requested eigenvalues: 1 Stopping condition: tol=1e-07, maxit=100 Number of converged eigenpairs 4
k ||Ax-kx||/||kx|| ----------------- ------------------
3.989739 5.76012e-09
3.959060 1.41957e-08
3.908279 6.74118e-08
3.837916 8.34269e-08
For specifying different setting for the solver parameters, we can use SLEPc command-line options with the -eps prefix. For instance, to change the number of requested eigenvalues and the tolerance:
$ python demo/ex1.py -eps_nev 10 -eps_tol 1e-11
The method used by the solver object can also be set at run time:
$ python demo/ex1.py -eps_type subspace
All the above settings can also be changed within the source code by making use of the appropriate slepc4py method. Since options can be set from within the code and the command-line, it is often useful to view the particular settings that are currently being used:
$ python demo/ex1.py -eps_view EPS Object: 1 MPI process
type: krylovschur
50% of basis vectors kept after restart
using the locking variant
problem type: symmetric eigenvalue problem
selected portion of the spectrum: largest eigenvalues in magnitude
number of eigenvalues (nev): 1
number of column vectors (ncv): 16
maximum dimension of projected problem (mpd): 16
maximum number of iterations: 100
tolerance: 1e-08
convergence test: relative to the eigenvalue BV Object: 1 MPI process
type: svec
17 columns of global length 30
orthogonalization method: classical Gram-Schmidt
orthogonalization refinement: if needed (eta: 0.7071)
block orthogonalization method: GS
doing matmult as a single matrix-matrix product DS Object: 1 MPI process
type: hep
solving the problem with: Implicit QR method (_steqr) ST Object: 1 MPI process
type: shift
shift: 0
number of matrices: 1
Note that for computing eigenvalues of smallest magnitude we can use the option -eps_smallest_magnitude, but for interior eigenvalues things are not so straightforward. One possibility is to try with harmonic extraction, for instance to get the eigenvalues closest to 0.6:
$ python demo/ex1.py -eps_harmonic -eps_target 0.6
Depending on the problem, harmonic extraction may fail to converge. In those cases, it is necessary to specify a spectral transformation other than the default. In the command-line, this is indicated with the -st_ prefix. For example, shift-and-invert with a value of the shift equal to 0.6 would be:
$ python demo/ex1.py -st_type sinvert -eps_target 0.6
You can use pip to install slepc4py and its dependencies (mpi4py is optional but highly recommended):
$ pip install [--user] numpy mpi4py $ pip install [--user] petsc petsc4py $ pip install [--user] slepc slepc4py
Alternatively, you can use easy_install (deprecated):
$ easy_install [--user] slepc4py
If you already have working PETSc and SLEPc installs, set environment variables SLEPC_DIR and PETSC_DIR (and perhaps PETSC_ARCH for non-prefix installs) to appropriate values and next use pip:
$ export SLEPC_DIR=/path/to/slepc $ export PETSC_DIR=/path/to/petsc $ export PETSC_ARCH=arch-linux2-c-opt $ pip install [--user] petsc4py slepc4py
You need to have the following software properly installed in order to build SLEPc for Python:
The SLEPc for Python package is available for download at the Python Package Index. You can use curl or wget to get a release tarball.
$ curl -LO https://pypi.io/packages/source/s/slepc4py/slepc4py-X.Y.Z.tar.gz
$ wget https://pypi.io/packages/source/s/slepc4py/slepc4py-X.Y.Z.tar.gz
After unpacking the release tarball:
$ tar -zxf slepc4py-X.Y.tar.gz $ cd slepc4py-X.Y
the distribution is ready for building.
NOTE:
$ export MACOSX_DEPLOYMENT_TARGET=10.6 $ export SDKROOT=/ $ export ARCHFLAGS='-arch x86_64'
Some environment configuration is needed to inform the location of PETSc and SLEPc. You can set (using setenv, export or what applies to you shell or system) the environment variables SLEPC_DIR`, PETSC_DIR, and PETSC_ARCH indicating where you have built/installed SLEPc and PETSc:
$ export SLEPC_DIR=/usr/local/slepc $ export PETSC_DIR=/usr/local/petsc $ export PETSC_ARCH=arch-linux2-c-opt
Alternatively, you can edit the file setup.cfg and provide the required information below the [config] section:
[config] slepc_dir = /usr/local/slepc petsc_dir = /usr/local/petsc petsc_arch = arch-linux2-c-opt ...
Finally, you can build the distribution by typing:
$ python setup.py build
After building, the distribution is ready for installation.
If you have root privileges (either by log-in as the root user of by using sudo) and you want to install SLEPc for Python in your system for all users, just do:
$ python setup.py install
The previous steps will install the slepc4py package at standard location prefix/lib/pythonX.X/site-packages.
If you do not have root privileges or you want to install SLEPc for Python for your private use, just do:
$ python setup.py install --user
If SLEPc for Python been significant to a project that leads to an academic publication, please acknowledge that fact by citing the project.
Lisandro Dalcin
2022, Lisandro Dalcin and Jose Roman
January 26, 2023 | 3.1 |