Add graph references

This commit is contained in:
Abdelrahman Said
2026-06-28 13:49:01 +01:00
parent 0a9807e448
commit a11edf0c53
2578 changed files with 868045 additions and 0 deletions
@@ -0,0 +1,395 @@
/*
igraph library.
Copyright (C) 2007-2025 The igraph development team <igraph@igraph.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef IGRAPH_ARPACK_H
#define IGRAPH_ARPACK_H
#include "igraph_decls.h"
#include "igraph_error.h"
#include "igraph_matrix.h"
#include "igraph_types.h"
#include "igraph_vector.h"
IGRAPH_BEGIN_C_DECLS
/**
* \section about_arpack ARPACK interface in igraph
*
* <para>
* ARPACK is a library for solving large scale eigenvalue problems.
* The package is designed to compute a few eigenvalues and corresponding
* eigenvectors of a general \c n by \c n matrix \c A. It is
* most appropriate for large sparse or structured matrices \c A where
* structured means that a matrix-vector product <code>w &lt;- Av</code> requires
* order \c n rather than the usual order <code>n^2</code> floating point
* operations. Please see https://github.com/opencollab/arpack-ng for details.
* </para>
*
* <para>
* The eigenvalue calculation in ARPACK (in the simplest
* case) involves the calculation of the \c Av product where \c A
* is the matrix we work with and \c v is an arbitrary vector. A
* user-defined function of type \ref igraph_arpack_function_t
* is expected to perform this product. If the product can be done
* efficiently, e.g. if the matrix is sparse, then ARPACK is usually
* able to calculate the eigenvalues very quickly.
* </para>
*
* <para>In igraph, eigenvalue/eigenvector calculations usually
* involve the following steps:
* \olist
* \oli Initialization of an \ref igraph_arpack_options_t data
* structure using \ref igraph_arpack_options_init.
* \oli Setting some options in the initialized \ref
* igraph_arpack_options_t object.
* \oli Defining a function of type \ref igraph_arpack_function_t.
* The input of this function is a vector, and the output
* should be the output matrix multiplied by the input vector.
* \oli Calling \ref igraph_arpack_rssolve() (is the matrix is
* symmetric), or \ref igraph_arpack_rnsolve().
* \endolist
* The \ref igraph_arpack_options_t object can be used multiple
* times.
* </para>
*
* <para>
* If we have many eigenvalue problems to solve, then it might worth
* to create an \ref igraph_arpack_storage_t object, and initialize it
* via \ref igraph_arpack_storage_init(). This structure contains all
* memory needed for ARPACK (with the given upper limit regerding to
* the size of the eigenvalue problem). Then many problems can be
* solved using the same \ref igraph_arpack_storage_t object, without
* always reallocating the required memory.
* The \ref igraph_arpack_storage_t object needs to be destroyed by
* calling \ref igraph_arpack_storage_destroy() on it, when it is not
* needed any more.
* </para>
*
* <para>
* igraph does not contain all
* ARPACK routines, only the ones dealing with symmetric and
* non-symmetric eigenvalue problems using double precision real
* numbers.
* </para>
*
*/
/**
* \struct igraph_arpack_options_t
* \brief Options for ARPACK.
*
* This data structure contains the options of the ARPACK eigenvalue
* solver routines. It must be initialized by calling \ref
* igraph_arpack_options_init() on it. Then it can be used for
* multiple ARPACK calls, as the ARPACK solvers do not modify it.
*
* Input options:
*
* \member bmat Character. Whether to solve a standard ('I') ot a
* generalized problem ('B').
* \member n Dimension of the eigenproblem.
* \member which Specifies which eigenvalues/vectors to
* compute. Possible values for symmetric matrices:
* \clist \cli LA
* Compute \c nev largest (algebraic) eigenvalues.
* \cli SA
* Compute \c nev smallest (algebraic) eigenvalues.
* \cli LM
* Compute \c nev largest (in magnitude) eigenvalues.
* \cli SM
* Compute \c nev smallest (in magnitude) eigenvalues.
* \cli BE
* Compute \c nev eigenvalues, half from each end of
* the spectrum. When \c nev is odd, compute one
* more from the high en than from the low
* end. \endclist
* Possible values for non-symmetric matrices:
* \clist \cli LM
* Compute \c nev largest (in magnitude) eigenvalues.
* \cli SM
* Compute \c nev smallest (in magnitude) eigenvalues.
* \cli LR
* Compute \c nev eigenvalues of largest real part.
* \cli SR
* Compute \c nev eigenvalues of smallest real part.
* \cli LI
* Compute \c nev eigenvalues of largest imaginary part.
* \cli SI
* Compute \c nev eigenvalues of smallest imaginary
* part. \endclist
* \member nev The number of eigenvalues to be computed.
* \member tol Stopping criterion: the relative accuracy
* of the Ritz value is considered acceptable if its error is less
* than \c tol times its estimated value. If this is set to zero
* then machine precision is used.
* \member ncv Number of Lanczos vectors to be generated. Setting this
* to zero means that \ref igraph_arpack_rssolve and \ref igraph_arpack_rnsolve
* will determine a suitable value for \c ncv automatically.
* \member ldv Numberic scalar. It should be set to
* zero in the current igraph implementation.
* \member ishift Either zero or one. If zero then the shifts are
* provided by the user via reverse communication. If one then exact
* shifts with respect to the reduced tridiagonal matrix \c T.
* Please always set this to one.
* \member mxiter Maximum number of Arnoldi update iterations allowed.
* \member nb Blocksize to be used in the recurrence. Please always
* leave this on the default value, one.
* \member mode The type of the eigenproblem to be solved.
* Possible values if the input matrix is symmetric:
* \olist
* \oli A*x=lambda*x, A is symmetric.
* \oli A*x=lambda*M*x, A is
* symmetric, M is symmetric positive definite.
* \oli K*x=lambda*M*x, K is
* symmetric, M is symmetric positive semi-definite.
* \oli K*x=lambda*KG*x, K is
* symmetric positive semi-definite, KG is symmetric
* indefinite.
* \oli A*x=lambda*M*x, A is
* symmetric, M is symmetric positive
* semi-definite. (Cayley transformed mode.) \endolist
* Please note that only \c mode ==1 was tested and other values
* might not work properly.
* Possible values if the input matrix is not symmetric:
* \olist
* \oli A*x=lambda*x.
* \oli A*x=lambda*M*x, M is
* symmetric positive definite.
* \oli A*x=lambda*M*x, M is
* symmetric semi-definite.
* \oli A*x=lambda*M*x, M is
* symmetric semi-definite. \endolist
* Please note that only \c mode == 1 was tested and other values
* might not work properly.
* \member start Whether to use the supplied starting vector (1), or
* use a random starting vector (0). The starting vector must be
* supplied in the first column of the \c vectors argument of the
* \ref igraph_arpack_rssolve() of \ref igraph_arpack_rnsolve() call.
*
* Output options:
*
* \member info Error flag of ARPACK. Possible values:
* \clist \cli 0
* Normal exit.
* \cli 1
* Maximum number of iterations taken.
* \cli 3
* No shifts could be applied during a cycle of the
* Implicitly restarted Arnoldi iteration. One possibility
* is to increase the size of \c ncv relative to \c
* nev. \endclist
* ARPACK can return other error flags as well, but these are
* converted to igraph errors, see \ref igraph_error_type_t.
* \member ierr Error flag of the second ARPACK call (one eigenvalue
* computation usually involves two calls to ARPACK). This is
* always zero, as other error codes are converted to igraph errors.
* \member noiter Number of Arnoldi iterations taken.
* \member nconv Number of converged Ritz values. This
* represents the number of Ritz values that satisfy the
* convergence critetion.
* \member numop Total number of matrix-vector multiplications.
* \member numopb Not used currently.
* \member numreo Total number of steps of re-orthogonalization.
*
* Internal options:
* \member lworkl Do not modify this option.
* \member sigma The shift for the shift-invert mode.
* \member sigmai The imaginary part of the shift, for the
* non-symmetric or complex shift-invert mode.
* \member iparam Do not modify this option.
* \member ipntr Do not modify this option.
*
*/
typedef struct igraph_arpack_options_t {
/* INPUT */
char bmat[1]; /* I-standard problem, G-generalized */
int n; /* Dimension of the eigenproblem */
char which[2]; /* LA, SA, LM, SM, BE */
int nev; /* Number of eigenvalues to be computed */
igraph_real_t tol; /* Stopping criterion */
int ncv; /* Number of columns in V */
int ldv; /* Leading dimension of V */
int ishift; /* 0-reverse comm., 1-exact with tridiagonal */
int mxiter; /* Maximum number of update iterations to take */
int nb; /* Block size on the recurrence, only 1 works */
int mode; /* The kind of problem to be solved (1-5)
1: A*x=l*x, A symmetric
2: A*x=l*M*x, A symm. M pos. def.
3: K*x = l*M*x, K symm., M pos. semidef.
4: K*x = l*KG*x, K s. pos. semidef. KG s. indef.
5: A*x = l*M*x, A symm., M symm. pos. semidef. */
int start; /* 0: random, 1: use the supplied vector */
int lworkl; /* Size of temporary storage, default is fine */
igraph_real_t sigma; /* The shift for modes 3,4,5 */
igraph_real_t sigmai; /* The imaginary part of shift for rnsolve */
/* OUTPUT */
int info; /* What happened, see docs */
int ierr; /* What happened in the dseupd call */
int noiter; /* The number of iterations taken */
int nconv;
int numop; /* Number of OP*x operations */
int numopb; /* Number of B*x operations if BMAT='G' */
int numreo; /* Number of steps of re-orthogonalizations */
/* INTERNAL */
int iparam[11];
int ipntr[14];
} igraph_arpack_options_t;
/**
* \struct igraph_arpack_storage_t
* \brief Storage for ARPACK.
*
* Public members, do not modify them directly, these are considered
* to be read-only.
* \member maxn Maximum rank of matrix.
* \member maxncv Maximum NCV.
* \member maxldv Maximum LDV.
*
* These members are considered to be private:
* \member workl Working memory.
* \member workd Working memory.
* \member d Memory for eigenvalues.
* \member resid Memory for residuals.
* \member ax Working memory.
* \member select Working memory.
* \member di Memory for eigenvalues, non-symmetric case only.
* \member workev Working memory, non-symmetric case only.
*/
typedef struct igraph_arpack_storage_t {
int maxn, maxncv, maxldv;
igraph_real_t *v;
igraph_real_t *workl;
igraph_real_t *workd;
igraph_real_t *d;
igraph_real_t *resid;
igraph_real_t *ax;
int *select;
/* The following two are only used for non-symmetric problems: */
igraph_real_t *di;
igraph_real_t *workev;
} igraph_arpack_storage_t;
/**
* \typedef igraph_arpack_error_t
* \brief Error codes from ARPACK.
*
* These error codes represent error conditions returned from ARPACK.
* They are used internally to format error messages when igraph itself
* returns an \c IGRAPH_EARPACK error code from an ARPACK-related function.
*
* \enumval IGRAPH_ARPACK_NO_ERROR No error was encountered in ARPACK.
* \enumval IGRAPH_ARPACK_PROD Matrix-vector product failed (not used any more).
* \enumval IGRAPH_ARPACK_NPOS N must be positive.
* \enumval IGRAPH_ARPACK_NEVNPOS NEV must be positive.
* \enumval IGRAPH_ARPACK_NCVSMALL NCV must be bigger.
* \enumval IGRAPH_ARPACK_NONPOSI Maximum number of iterations should be positive.
* \enumval IGRAPH_ARPACK_WHICHINV Invalid WHICH parameter.
* \enumval IGRAPH_ARPACK_BMATINV Invalid BMAT parameter.
* \enumval IGRAPH_ARPACK_WORKLSMALL WORKL is too small.
* \enumval IGRAPH_ARPACK_TRIDERR LAPACK error in tridiagonal eigenvalue calculation.
* \enumval IGRAPH_ARPACK_ZEROSTART Starting vector is zero.
* \enumval IGRAPH_ARPACK_MODEINV MODE is invalid.
* \enumval IGRAPH_ARPACK_MODEBMAT MODE and BMAT are not compatible.
* \enumval IGRAPH_ARPACK_ISHIFT ISHIFT must be 0 or 1.
* \enumval IGRAPH_ARPACK_NEVBE NEV and WHICH='BE' are incompatible.
* \enumval IGRAPH_ARPACK_NOFACT Could not build an Arnoldi factorization.
* \enumval IGRAPH_ARPACK_FAILED No eigenvalues to sufficient accuracy.
* \enumval IGRAPH_ARPACK_HOWMNY HOWMNY is invalid.
* \enumval IGRAPH_ARPACK_HOWMNYS HOWMNY='S' is not implemented.
* \enumval IGRAPH_ARPACK_EVDIFF Different number of converged Ritz values.
* \enumval IGRAPH_ARPACK_SHUR Error from calculation of a real Schur form.
* \enumval IGRAPH_ARPACK_LAPACK LAPACK (dtrevc) error for calculating eigenvectors.
* \enumval IGRAPH_ARPACK_UNKNOWN Unknown ARPACK error.
*/
typedef enum {
IGRAPH_ARPACK_NO_ERROR = 0,
IGRAPH_ARPACK_PROD = 15,
IGRAPH_ARPACK_NPOS = 16,
IGRAPH_ARPACK_NEVNPOS = 17,
IGRAPH_ARPACK_NCVSMALL = 18,
IGRAPH_ARPACK_NONPOSI = 19,
IGRAPH_ARPACK_WHICHINV = 20,
IGRAPH_ARPACK_BMATINV = 21,
IGRAPH_ARPACK_WORKLSMALL = 22,
IGRAPH_ARPACK_TRIDERR = 23,
IGRAPH_ARPACK_ZEROSTART = 24,
IGRAPH_ARPACK_MODEINV = 25,
IGRAPH_ARPACK_MODEBMAT = 26,
IGRAPH_ARPACK_ISHIFT = 27,
IGRAPH_ARPACK_NEVBE = 28,
IGRAPH_ARPACK_NOFACT = 29,
IGRAPH_ARPACK_FAILED = 30,
IGRAPH_ARPACK_HOWMNY = 31,
IGRAPH_ARPACK_HOWMNYS = 32,
IGRAPH_ARPACK_EVDIFF = 33,
IGRAPH_ARPACK_SHUR = 34,
IGRAPH_ARPACK_LAPACK = 35,
IGRAPH_ARPACK_UNKNOWN = 36,
IGRAPH_ARPACK_MAXIT = 39,
IGRAPH_ARPACK_NOSHIFT = 40,
IGRAPH_ARPACK_REORDER = 41,
} igraph_arpack_error_t;
IGRAPH_EXPORT void igraph_arpack_options_init(igraph_arpack_options_t *o);
IGRAPH_EXPORT igraph_arpack_options_t* igraph_arpack_options_get_default(void);
IGRAPH_EXPORT igraph_error_t igraph_arpack_storage_init(igraph_arpack_storage_t *s, igraph_int_t maxn,
igraph_int_t maxncv, igraph_int_t maxldv, igraph_bool_t symm);
IGRAPH_EXPORT void igraph_arpack_storage_destroy(igraph_arpack_storage_t *s);
/**
* \typedef igraph_arpack_function_t
* \brief Type of the ARPACK callback function.
*
* \param to Pointer to an \c igraph_real_t, the result of the
* matrix-vector product is expected to be stored here.
* \param from Pointer to an \c igraph_real_t, the input matrix should
* be multiplied by the vector stored here.
* \param n The length of the vector (which is the same as the order
* of the input matrix).
* \param extra Extra argument to the matrix-vector calculation
* function. This is coming from the \ref igraph_arpack_rssolve()
* or \ref igraph_arpack_rnsolve() function.
* \return Error code. If not \c IGRAPH_SUCCESS, then the ARPACK solver considers
* this as an error, stops and calls the igraph error handler.
*/
typedef igraph_error_t igraph_arpack_function_t(igraph_real_t *to, const igraph_real_t *from,
int n, void *extra);
IGRAPH_EXPORT igraph_error_t igraph_arpack_rssolve(igraph_arpack_function_t *fun, void *extra,
igraph_arpack_options_t *options,
igraph_arpack_storage_t *storage,
igraph_vector_t *values, igraph_matrix_t *vectors);
IGRAPH_EXPORT igraph_error_t igraph_arpack_rnsolve(igraph_arpack_function_t *fun, void *extra,
igraph_arpack_options_t *options,
igraph_arpack_storage_t *storage,
igraph_matrix_t *values, igraph_matrix_t *vectors);
IGRAPH_EXPORT igraph_error_t igraph_arpack_unpack_complex(igraph_matrix_t *vectors, igraph_matrix_t *values,
igraph_int_t nev);
IGRAPH_EXPORT const char* igraph_arpack_error_to_string(igraph_arpack_error_t error);
IGRAPH_EXPORT igraph_arpack_error_t igraph_arpack_get_last_error(void);
IGRAPH_END_C_DECLS
#endif