arpack_general (complex)

more...

Computes some of the eigenvalues and eigenvectors of the generalized eigenvalue problem Ax = λBx using an implicitly restarted Arnoldi method (IRAM). The algorithm can also be used for the standard case B=I. The matrices A, B are complex.

Note: Function arpack_general(complex) is available in double precision only.

Synopsis

#include <imsl.h>

d_complex *imsl_z_arpack_general (void fcn(), int n, int nev, …, 0)

Required Arguments

void fcn (int n, d_complex x[], int task, d_complex y[]) (Input)

User-supplied function to return matrix-vector operations or solutions of linear systems.

int n (Input)

The dimension of the problem.

d_complex x[] (Input)

An array of size n containing the vector to which the operator will be applied.

int task (Input)

An enumeration type which specifies the operation to be performed. Variable task is an enumerated integer value associated with enum type Imsl_arpack_task. The following values are possible:

Value

Description

IMSL_ARPACK_PREPARE

Take initial steps to prepare for the operations to follow. These steps can include defining data for the matrices, factorizations for upcoming linear system solves or recording the vectors used in the operations.

IMSL_ARPACK_A_X

y = Ax

IMSL_ARPACK_B_X

y = Bx

IMSL_ARPACK_INV_SHIFT_X

y = (A  σB)-1x, σ complex

IMSL_ARPACK_INV_B_X

y = B-1x

d_complex y[] (Output)

An array of size n containing the result of a matrix-vector operation or the solution of a linear system.

int n (Input)

The dimension of the problem.

int nev (Input)

The number of eigenvalues to be computed. It is required that 0 < nev < n.

Return Value

A pointer to the nev eigenvalues of the eigenvalue problem in decreasing order of magnitude. To release this space, use imsl_free. If no value can be computed, then NULL is returned.

Synopsis with Optional Arguments

#include <imsl.h>

d_complex *imsl_z_arpack_general (void fcn(), int n, int nev,

IMSL_XGUESS, d_complex xguess[],

IMSL_ITMAX, int itmax,

IMSL_TOLERANCE, double tol,

IMSL_SHIFT, d_complex  shift,

IMSL_EIGVAL_LOCATION, Imsl_arpack_eigval_location eigval_loc,

IMSL_EIG_PROBLEM_TYPE, Imsl_arpack_problem_type problem_type,

IMSL_EIG_SOLVE_MODE, Imsl_arpack_solve_mode mode,

IMSL_NUM_ARNOLDI_VECTORS, int ncv,

IMSL_NUM_ACCURATE_EIGVALS, int *n_acc,

IMSL_VECTORS, d_complex **evec,

IMSL_VECTORS_USER, d_complex evecu[],

IMSL_EVECU_COL_DIM, int evecu_col_dim,

IMSL_RETURN_USER, d_complex evalu[],

IMSL_FCN_W_DATA, void fcn(), void *data,

0)

Optional Arguments

IMSL_XGUESS, d_complex xguess[] (Input)
A non-zero vector of size n containing the starting vector for the implicitly restarted Arnoldi method.

By default, a random starting vector is computed internally.

IMSL_ITMAX, int itmax (Input)
The maximum number of Arnoldi iterations.
Default: itmax = 1000.

IMSL_TOLERANCE, double tol (Input)
Tolerance value used in the criterion for the acceptability of the relative accuracy of the Ritz values. Values of tol 0 are internally set back to the default value.
Default: tol = imsl_d_machine(3).

IMSL_SHIFT, d_complex shift (Input)
The shift value used in the shift-invert spectral transformations.
Default: shift = {0, 0}.

IMSL_EIGVAL_LOCATION, Imsl_arpack_eigval_location eigval_loc (Input)
An enumeration type which specifies the location of the eigenvalues to compute.

eigval_loc

Description

IMSL_ARPACK_LARGEST_MAGNITUDE

Compute eigenvalues of largest magnitude.

IMSL_ARPACK_SMALLEST_MAGNITUDE

Compute eigenvalues of smallest magnitude.

IMSL_ARPACK_LARGEST_REAL_PART

Compute eigenvalues of algebraically largest real part.

IMSL_ARPACK_SMALLEST_REAL_PART

Compute eigenvalues of algebraically smallest real part.

IMSL_ARPACK_LARGEST_IMAG_PART

Compute eigenvalues of algebraically largest imaginary part.

IMSL_ARPACK_SMALLEST_IMAG_PART

Compute eigenvalues of algebraically smallest imaginary part.

For computational modes that use a spectral transformation the eigenvalue location refers to the transformed - not the original - problem. See the Description section for an example.
Default: eigval_loc = IMSL_ARPACK_LARGEST_MAGNITUDE.

IMSL_EIG_PROBLEM_TYPE, Imsl_arpack_problem_type problem_type (Input)
An enumeration type that indicates if a standard or generalized eigenvalue problem is to be solved.

problem_type

Description

IMSL_ARPACK_STANDARD

Solve standard problem, Ax = λx.

IMSL_ARPACK_GENERALIZED

Solve generalized problem, Ax = λBx.

Default: problem_type = IMSL_ARPACK_STANDARD.

IMSL_EIG_SOLVE_MODE, Imsl_arpack_solve_mode mode (Input)
An enumeration type indicating which computational mode is used for the eigenvalue computation. Variables problem_type and mode together define the tasks that have to be provided in the user-supplied function. The following table describes the values variable mode can take, the feasible combinations with variable problem_type and the related tasks:

mode

problem_type

Required tasks

IMSL_ARPACK_REGULAR

IMSL_ARPACK_STANDARD

y = Ax

IMSL_ARPACK_REGULAR_INVERSE

IMSL_ARPACK_GENERALIZED

y = Ax, y = Bx, y = B-1x

IMSL_ARPACK_SHIFT_INVERT

IMSL_ARPACK_STANDARD

y = (A  σI)-1x

IMSL_ARPACK_SHIFT_INVERT

IMSL_ARPACK_GENERALIZED

y = Bx, y = (A  σB)-1x

Default: mode = IMSL_ARPACK_REGULAR.

IMSL_NUM_ARNOLDI_VECTORS, int ncv (Input)
The number of Arnoldi vectors generated in each iteration of the Arnoldi method. It is required that nev + 1 <= ncv <= n. A value ncv >= min(2*nev, n) is recommended.

Default: ncv = min(2*nev, n).

IMSL_NUM_ACCURATE_EIGVALS, int *n_acc (Output)
The number of eigenvalues that the algorithm was able to compute accurately. This number can be smaller than nev.

IMSL_VECTORS, d_complex **evec (Output)
The address of a pointer to an array of size n × nev containing the eigenvectors corresponding to the n_acc converged eigenvalues. Typically, d_complex * evec is declared, and &evec is used as an argument.

IMSL_VECTORS_USER, d_complex evecu[] (Output)
A user-defined array of size n× nev containing the n_acc eigenvectors of the eigenvalue problem. The eigenvectors are stored column-wise in the same order as the eigenvalues.

IMSL_EVECU_COL_DIM, int evecu_col_dim (Input)
The column dimension of array evecu.
Default: evecu_col_dim = nev.

IMSL_RETURN_USER, d_complex evalu[] (Output)
An array of size nev containing the accurately computed eigenvalues in the first n_acc locations.

IMSL_FCN_W_DATA, void fcn (int n, d_complex x[], int task, d_complex y[], void *data), void *data (Input/Output)
User-supplied function to return matrix-vector operations or solutions of linear systems, which also accepts a pointer to data that is supplied by the user. data is a pointer to the data to be passed to the user-supplied function.

Note: The possibility to supply user-data via IMSL_FCN_W_DATA is an important feature of arpack_general (complex). It allows the user to transfer problem-specific data to the algorithm without the need to define global data. See Passing Data to User-Supplied Functions in the introduction to this manual for more details.

Description

Function imsl_z_arpack_general, which is based on ARPACK subroutines ZNAUPD and ZNEUPD (see the ARPACK Users’ Guide, Lehoucq et al. (1998)), computes selected eigenvalue-eigenvector pairs for generalized eigenvalue problems of the form

Ax = λBx.

Here, A is a complex general and B a positive (semi-)definite matrix. For B = I, the generalized problem reduces to the standard non-Hermitian eigenvalue problem.

The ARPACK routine ZNAUPD implements a variant of the Arnoldi method and uses reverse communication to obtain the required matrix-vector products or solutions of linear systems for the iterations. Responses to these requests are made by calling the user-defined function fcn. User data can be made available for the evaluations by optional argument IMSL_FCN_W_DATA.

For a given problem, the requested responses depend on the settings of optional arguments IMSL_EIG_PROBLEM_TYPE and IMSL_EIG_SOLVE_MODE. For each response, a corresponding task must be defined in the user-defined function fcn. The table under optional argument IMSL_EIG_SOLVE_MODE shows which tasks have to be defined for a certain problem. The following code snippet shows the complete list of tasks available for fcn and their meaning:

void fcn(int n, d_complex x[], int itask, d_complex y[])
{
    switch (itask) {
        /*
         * Define responses to different tasks for the generalized
         * eigenvalue problem
         *        A*x = lambda * B * x,
         * which includes the ordinary case B = I.
         */
    case IMSL_ARPACK_PREPARE:
        /* 
         * Take initial steps to prepare for the operations
         * that follow. Note that arpack_general internally
         * always calls fcn with this enum value, even if it is
         * not required by the user. 
         */
        break;
    case IMSL_ARPACK_A_X:
        /*
         * Compute matrix-vector product y = A * x
         */
        break;
    case IMSL_ARPACK_B_X:
        /*
         * Compute matrix-vector product y = B * x
         */
        break;
    case IMSL_ARPACK_INV_SHIFT_X:
        /*
         *  Compute the matrix-vector product
         *     z = inv(A - sigma * B) * x,
         *  and return
         *     y = z.
         *
         *  Usually, matrix A - sigma * B is not directly inverted.
         *  Instead, a factorization of A - sigma * B is determined,
         *  and the factors are used to compute z via backsolves.
         *
         *  Example:
         *  If an LU factorization of A - sigma * B exists, then
         *      A - sigma * B = P * L * U,
         *  P a permutation matrix. Vector z can then be determined
         *  as solution of the linear system
         *      L * U * z = trans(P) * x.
         *  The LU factorization only has to be computed once, for
         *  example outside of fcn or within IMSL_ARPACK_PREPARE.
         */
        break;
    case IMSL_ARPACK_INV_B_X:
        /*
         *  Compute matrix-vector product
         *     y = inv(B) * x.
         *  Usually, matrix B is not directly inverted.
         *  Instead, a factorization of B is determined, and the
         *  factors are used to compute y via backsolves.
         *  
         *  Example:
         *  If matrix B is positive definite, then a Cholesky
         *  factorization B = L * ctrans(L) exists. Vector y can then
         *  be determined by solving the linear system
         *     L * ctrans(L) * y = x
         *  via the two backsolves
         *     L * z = x  and  ctrans(L) * y = z.
         *  The Cholesky factorization only has to be computed once,
         *  for example outside of fcn or within IMSL_ARPACK_PREPARE.
         */
        break;
    default:
        /*
         *  Define error conditions, if necessary.
         */
        break;
    }
}

 

Internally, implemented via ARPACK routine ZNAUPD, imsl_z_arpack_general first determines the eigenvalues for the problem specified by optional arguments IMSL_SOLVE_MODE and IMSL_PROBLEM_TYPE.

The following table shows the matrices whose eigenvalues are determined for a given combination of these optional arguments:

mode

problem_type

Matrix

IMSL_ARPACK_REGULAR IMSL_ARPACK_STANDARD A

IMSL_ARPACK_REGULAR_INVERSE

IMSL_ARPACK_GENERALIZED

B-1A

IMSL_ARPACK_SHIFT_INVERT

IMSL_ARPACK_STANDARD

(A  σI)-1, σ complex

IMSL_ARPACK_SHIFT_INVERT

IMSL_ARPACK_GENERALIZED

(A  σB)-1B, σ complex

Note that the eigenvalue location defined by optional argument IMSL_EIGVAL_LOCATION always refers to the matrices of the above table.

For example, for mode=IMSL_ARPACK_SHIFT_INVERT, problem_type=IMSL_ARPACK_STANDARD, and eigval_loc=IMSL_ARPACK_LARGEST_MAGNITUDE, the eigenvalues of largest magnitude of the shift-inverted matrix (A  σI)-1 are computed. Because of the relationship

 

these eigenvalues correspond to the eigenvalues of the original problem Ax = λx that are closest to the shift σ in absolute value.

In a second step, implemented via ARPACK routine ZNEUPD, imsl_z_arpack_general internally transforms the eigenvalues back to the eigenvalues of the original problem Ax = λBx or Ax = λx and computes eigenvectors, if required.

Besides matrix A being complex and general, the modes for the generalized eigenproblem require some additional properties of matrix B that are summarized in the following table:

mode

Matrix properties

IMSL_ARPACK_REGULAR_INVERSE

B positive definite

IMSL_ARPACK_SHIFT_INVERT

B positive semi-definite

Copyright notice for ARPACK:

Copyright (c) 1996-2008 Rice University. Developed by D.C. Sorensen, R.B. Lehoucq, C. Yang, and K. Maschhoff. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer listed in this license in the documentation and/or other materials provided with the distribution.

- Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Examples

Example 1

This example computes the two eigenvalues of largest magnitude for a small complex matrix of order 4.

#include <imsl.h>
#include <stdio.h>
#include <stdlib.h>

static void fcn(int, d_complex[], int, d_complex[]);

int main()
{
    int n = 4, nev = 2, n_acc;
    d_complex *eval = NULL;

    /* Compute eigenvalues */
    eval = imsl_z_arpack_general(fcn, n, nev,
        IMSL_NUM_ACCURATE_EIGVALS, &n_acc,
        0);

    printf("Number of requested eigenvalues : %d\n", nev);
    printf("Number of computed (converged) eigenvalues : %d\n", n_acc);
    
    /* Print eigenvalues of largest magnitude */
    imsl_z_write_matrix("Largest eigenvalues", 1, n_acc, eval, 0);

    if (eval)
        imsl_free(eval);
}

static void fcn(int n, d_complex x[], int itask, d_complex y[])
{
    d_complex a[] = {
        {5.0, 9.0}, {5.0, 5.0}, {-6.0, -6.0}, {-7.0, -7.0},
        {3.0, 3.0}, {6.0, 10.0}, {-5.0, -5.0}, {-6.0, -6.0},
        {2.0, 2.0}, {3.0, 3.0}, {-1.0, 3.0}, {-5.0, -5.0},
        {1.0, 1.0}, {2.0, 2.0}, {-3.0, -3.0}, {0.0, 4.0}
    };

    switch (itask) {
    case IMSL_ARPACK_PREPARE:
        /* Do nothing here */
        break;
    case IMSL_ARPACK_A_X:
        imsl_z_mat_mul_rect("A*x",
            IMSL_A_MATRIX, n, n, a,
            IMSL_X_VECTOR, n, x,
            IMSL_RETURN_USER, y,
            0);
        break;
    default:
        imsl_set_user_fcn_return_flag(1);
        break;
    }
}

Output

Number of requested eigenvalues : 2
Number of accurate (converged) eigenvalues : 2
 
                 Largest eigenvalues
                        1                          2
(          4,          8)  (          3,          7)

Example 2

This example is a variation of the first example for arpack_symmetric. The convection-diffusion operator

with Laplacian

is approximated by a standard central difference discretization on the unit square [0,1] × [0,1] with zero Dirichlet boundary condition. The resulting discretization matrix A is used to approximate eigenvalue-eigenfunction pairs ( λ,u) of the operator,

,

by eigenpairs ( λ,x) of the matrix A,

Ax = λx

Since now the parameter ρ is complex, eigenvalues and eigenfunctions (both exact and discrete) are complex as well.

#include <imsl.h>
#include <stdio.h>
#include <stdlib.h>

static void fcn(int, d_complex[], int, d_complex[]);
static void fcn_w_data(int, d_complex[], int, d_complex[], void *);
static void ax(int, double, d_complex[], d_complex[], d_complex[]);
static void tx(int, d_complex[], d_complex[], d_complex[]);
static void compute_residuals_fcn(
    void(*fcn_w_data) (int n, d_complex x[], int itask, d_complex y[],
        void *data),
    int n, int n_acc, d_complex eval[], d_complex evecu[],
    int evecu_col_dim, d_complex cwork[], double res_norm[], void *data);
static d_complex l_mul(d_complex, d_complex);
static void l_zaxpy(int, d_complex, d_complex[], d_complex[]);

typedef struct {
    int nx;
    double hsq;
    d_complex rho;
    d_complex *dt;
} imsl_arpack_data;

int main() {
    int nx = 10, nev = 6, ncv = 25, n_acc, n, i;
    d_complex *eval = NULL, dt[3];
    d_complex *evecu = NULL, *cwork = NULL;
    d_complex rho = { 100.0, 1.0 };
    double *res_norm = NULL;
    imsl_arpack_data usr_data;

    usr_data.nx = nx;
    usr_data.rho = rho;
    usr_data.dt = dt;

    n = nx * nx;

    evecu = (d_complex *)malloc(n * nev * sizeof(d_complex));
    cwork = (d_complex *)malloc(2 * n * sizeof(d_complex));
    res_norm = (double *)malloc(nev * sizeof(double));

    /* Compute eigenvalues */
    eval = imsl_z_arpack_general(NULL, n, nev,
        IMSL_NUM_ACCURATE_EIGVALS, &n_acc,
        IMSL_NUM_ARNOLDI_VECTORS, ncv,
        IMSL_VECTORS_USER, evecu,
        IMSL_FCN_W_DATA, fcn_w_data, &usr_data,
        0);

    compute_residuals_fcn(fcn_w_data, n, n_acc, eval, evecu, nev, cwork,
        res_norm, &usr_data);

    printf("\nNumber of requested eigenvalues : %d\n", nev);
    printf("Number of computed (converged) eigenvalues : %d\n",
        n_acc);
    printf("\n%20sLargest Magnitude Operator eigenvalues\n", " ");
    printf("%15sRitz values (Real, Imag)%18srelative "
        "residuals\n", " ", " ");
    for (i = 0; i < n_acc; i++) {
        printf("%d  (%20.13lf, %20.13lf)    %25.17lf\n",
            i, eval[i].re, eval[i].im, res_norm[i]);
    }

    if (eval)
        imsl_free(eval);
    if (evecu)
        free(evecu);
    if (cwork)
        free(cwork);
    if (res_norm)
        free(res_norm);
}

static void fcn_w_data(int n, d_complex x[], int itask,
    d_complex y[], void *data)
{
    int nx;
    double h, hsq;
    d_complex dd, dl, du, rho;
    d_complex *dt;
    imsl_arpack_data *usr_data = (imsl_arpack_data *)data;
    dt = usr_data->dt;
    rho = usr_data->rho;
    nx = usr_data->nx;

    switch (itask) {
    case IMSL_ARPACK_PREPARE:
        /* Create tridiagonal matrix in band storage format */
        h = 1.0 / (nx + 1);
        hsq = h * h;
        dd.re = 4.0 / hsq;
        dd.im = 0.0;
        dl.re = -1.0 / hsq - 0.5 * rho.re / h;
        dl.im = -0.5 * rho.im / h;
        du.re = -1.0 / hsq + 0.5 * rho.re / h;
        du.im = 0.5 * rho.im / h;

        dt[0] = dl;
        dt[1] = dd;
        dt[2] = du;
        usr_data->hsq = hsq;
        break;
    case IMSL_ARPACK_A_X:
        hsq = usr_data->hsq;
        ax(nx, hsq, dt, x, y);
        break;
    default:
        imsl_set_user_fcn_return_flag(1);
        break;
    }
}

/*
 *     Matrix-vector function.
 *
 *     Computes y <- A*x, where A is the nx^2 by nx^2 block
 *     tridiagonal matrix
 *
 *                 | T -I          |
 *                 |-I  T -I       |
 *             A = |   -I  T       |
 *                 |        ...  -I|
 *                 |           -I T|
 *
 *    derived from the standard central difference discretization
 *    of the convection-diffusion operator (Laplacian u) + rho*(du/dx)
 *    with zero boundary condition.
 *
 *    Function tx() is called to compute y <- T*x.
 */
static void ax(int nx, double hsq, d_complex dt[], d_complex x[],
    d_complex y[]) {
    int i, j;

    tx(nx, x, dt, y);
    for (i = 1; i <= nx; i++) {
        y[i - 1].re -= x[nx + i - 1].re / hsq;
        y[i - 1].im -= x[nx + i - 1].im / hsq;
    }

    for (j = nx + 1; j <= nx * (nx - 1); j += nx) {
        tx(nx, &x[j - 1], dt, &y[j - 1]);
        for (i = j; i <= j + nx - 1; i++) {
            y[i - 1].re -= (x[i - nx - 1].re + x[i + nx - 1].re) / hsq;
            y[i - 1].im -= (x[i - nx - 1].im + x[i + nx - 1].im) / hsq;
        }

    }

    tx(nx, &x[nx * (nx - 1)], dt, &y[nx * (nx - 1)]);
    for (i = (nx - 1) * nx + 1; i <= nx * nx; i++) {
        y[i - 1].re -= x[i - nx - 1].re / hsq;
        y[i - 1].im -= x[i - nx - 1].im / hsq;
    }
}

/*
 *    Compute the matrix vector multiplication y <- T * x
 *    where T is an nx by nx tridiagonal matrix with dd on the
 *    diagonal, dl on the subdiagonal, and du on the superdiagonal.
 */
static void tx(int nx, d_complex x[], d_complex dt[],
    d_complex v[]) {
    int j;
    d_complex dl, dd, du, temp1, temp2, temp3;

    dl = dt[0];
    dd = dt[1];
    du = dt[2];

    temp1 = l_mul(dd, x[0]);
    temp2 = l_mul(du, x[1]);
    v[0].re = temp1.re + temp2.re;
    v[0].im = temp1.im + temp2.im;

    for (j = 2; j <= nx - 1; j++) {
        temp1 = l_mul(dl, x[j - 2]);
        temp2 = l_mul(dd, x[j - 1]);
        temp3 = l_mul(du, x[j]);

        v[j - 1].re = temp1.re + temp2.re + temp3.re;
        v[j - 1].im = temp1.im + temp2.im + temp3.im;
    }

    temp1 = l_mul(dl, x[nx - 2]);
    temp2 = l_mul(dd, x[nx - 1]);
    v[nx - 1].re = temp1.re + temp2.re;
    v[nx - 1].im = temp1.im + temp2.im;
}

/*
 *    Compute the residual norm
 *
 *     || A * x - lambda * x || / |lambda|
 *
 *    for the n_acc accurately computed eigenvalues and
 *    eigenvectors.
 */
static void compute_residuals_fcn(
    void(*fcn_w_data) (int n, d_complex x[], int itask, d_complex y[],
        void *data),
    int n, int n_acc, d_complex eval[], d_complex evecu[],
    int evecu_col_dim, d_complex cwork[], double res_norm[], void *data) {
    int i, j;
    double eval_abs;
    d_complex temp;

    for (j = 0; j < n_acc; j++) {
        /* Copy j-th eigenvector into cwork */
        for (i = 0; i < n; i++) {
            cwork[i] = evecu[i * evecu_col_dim + j];
        }
        /*  Compute ax <- A * x  */
        fcn_w_data(n, cwork, IMSL_ARPACK_A_X, &cwork[n], data);
        /*  Compute ax <- ax - lambda * x */
        temp.re = -eval[j].re;
        temp.im = -eval[j].im;
        l_zaxpy(n, temp, cwork, &cwork[n]);
        /* Save residual norms */
        res_norm[j] = imsl_z_vector_norm(n, &cwork[n], 0);
        eval_abs = imsl_z_abs(eval[j]);
        if (eval_abs > 0.0) {
            res_norm[j] /= eval_abs;
        }
    }
}

/*
 *  Compute complex scalar product x * y.
 *
 *  This is faster than imsl_z_mul since the IMSL error handler is not
 *  involved.
 */
static d_complex l_mul(d_complex x, d_complex y) {
    d_complex t;

    t.re = x.re * y.re - x.im * y.im;
    t.im = x.re * y.im + x.im * y.re;

    return t;
}

/*
 *  Compute y <- alpha * x + y.
 */
static void l_zaxpy(int n, d_complex alpha, d_complex x[],
    d_complex y[]) {
    int i;
    d_complex temp;

    for (i = 0; i < n; i++) {
        temp = l_mul(alpha, x[i]);
        y[i].re += temp.re;
        y[i].im += temp.im;
    }
}

Output

Number of requested eigenvalues : 6
Number of computed (converged) eigenvalues : 6

                    Largest Magnitude Operator eigenvalues
               Ritz values (Real, Imag)             relative residuals
0  (   727.0167725961721,  -1029.5865512774324)     0.00000000000000454
1  (   705.3778266332353,   1029.5865512774278)     0.00000000000000788
2  (   698.4028279266130,  -1029.5865512774401)     0.00000000000000541
3  (   676.7638819636808,   1029.5865512774371)     0.00000000000000512
4  (   653.2957705962293,  -1029.5865512774360)     0.00000000000000389
5  (   631.6568246332987,   1029.5865512774408)     0.00000000000000820

Warning Errors

IMSL_ARPACK_MAX_ITER_REACHED

The maximum number of iterations has been reached. All possible eigenvalues have been found. Variable "n_acc" returns the number of wanted converged Ritz values.

IMSL_ARPACK_NO_SHIFTS_APPLIED

No shifts could be applied during a cycle of the implicitly restarted Arnoldi iteration. One possibility is to increase the size of "ncv" = # relative to "nev" = #.

 

Fatal Errors

 

IMSL_START_VECTOR_ZERO

The starting vector "xguess" is zero. Use a non-zero vector instead.

IMSL_UNABLE_TO_BUILD_ARNOLDI

The algorithm was not able to build an Arnoldi factorization. The size of the current Arnoldi factorization is #. Use of a different starting vector "xguess" may help.

IMSL_QR_CONVERGENCE_ERROR

The iteration for an eigenvalue failed to converge during the processing of the implicitly restarted Arnoldi method.

IMSL_QR_CONVERGENCE_ERROR_1

The iteration for an eigenvalue failed to converge during the postprocessing phase of the implicitly restarted Arnoldi method.

IMSL_SCHUR_FORM_REORD_ERROR

Reordering of the Schur form failed because some eigenvalues are too close to separate (the problem is very ill-conditioned).

IMSL_EIGVEC_COMPUTATION_ERROR

The eigenvector computation during the postprocessing phase of the implicitly restarted Arnoldi method failed.

IMSL_ARPACK_NO_EIGVALS_FOUND

The implicitly restarted Arnoldi method did not find any eigenvalues to sufficient accuracy. Use of a different starting vector "xguess", a larger iteration number "itmax", a different number "ncv" of Arnoldi vectors or a different problem type and/or solve mode may help.

IMSL_DIFF_N_CONV_RITZ_VALUES

The number of converged Ritz values computed by the iteratively restarted Arnoldi method differs from the number of converged Ritz values determined during the post-processing phase.