Subversion Repositories slepc-dev

Rev

Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1376 slepc 1
/*
2
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 slepc 3
   SLEPc - Scalable Library for Eigenvalue Problem Computations
2116 eromero 4
   Copyright (c) 2002-2010, Universidad Politecnica de Valencia, Spain
782 dsic.upv.es!jroman 5
 
1672 slepc 6
   This file is part of SLEPc.
7
 
8
   SLEPc is free software: you can redistribute it and/or modify it under  the
9
   terms of version 3 of the GNU Lesser General Public License as published by
10
   the Free Software Foundation.
11
 
12
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
13
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
14
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
15
   more details.
16
 
17
   You  should have received a copy of the GNU Lesser General  Public  License
18
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
1376 slepc 19
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
20
*/
21
 
782 dsic.upv.es!jroman 22
static char help[] = "Solves the same eigenproblem as in example ex5, but computing also left eigenvectors. "
23
  "It is a Markov model of a random walk on a triangular grid. "
24
  "A standard nonsymmetric eigenproblem with real eigenvalues. The rightmost eigenvalue is known to be 1.\n\n"
1156 slepc 25
  "The command line options are:\n"
782 dsic.upv.es!jroman 26
  "  -m <m>, where <m> = number of grid subdivisions in each dimension.\n\n";
27
 
28
#include "slepceps.h"
29
 
30
/*
31
   User-defined routines
32
*/
983 slepc 33
PetscErrorCode MatMarkovModel( PetscInt m, Mat A );
782 dsic.upv.es!jroman 34
 
35
#undef __FUNCT__
36
#define __FUNCT__ "main"
37
int main( int argc, char **argv )
38
{
1090 slepc 39
  PetscErrorCode ierr;
1947 jroman 40
  Vec            v0,w0;           /* initial vector */
41
  Vec            *X,*Y;           /* right and left eigenvectors */
42
  Mat            A;               /* operator matrix */
43
  EPS            eps;             /* eigenproblem solver context */
1507 slepc 44
  const EPSType  type;
1090 slepc 45
  PetscReal      error1, error2, tol, re, im;
46
  PetscScalar    kr, ki;
1505 slepc 47
  PetscInt       nev, maxit, i, its, nconv, N, m=15;
782 dsic.upv.es!jroman 48
 
49
  SlepcInitialize(&argc,&argv,(char*)0,help);
50
 
51
  ierr = PetscOptionsGetInt(PETSC_NULL,"-m",&m,PETSC_NULL);CHKERRQ(ierr);
52
  N = m*(m+1)/2;
53
  ierr = PetscPrintf(PETSC_COMM_WORLD,"\nMarkov Model, N=%d (m=%d)\n\n",N,m);CHKERRQ(ierr);
54
 
55
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
56
     Compute the operator matrix that defines the eigensystem, Ax=kx
57
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
58
 
828 dsic.upv.es!antodo 59
  ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr);
60
  ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,N,N);CHKERRQ(ierr);
782 dsic.upv.es!jroman 61
  ierr = MatSetFromOptions(A);CHKERRQ(ierr);
62
  ierr = MatMarkovModel( m, A );CHKERRQ(ierr);
63
 
64
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
65
                Create the eigensolver and set various options
66
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
67
 
68
  /*
69
     Create eigensolver context
70
  */
71
  ierr = EPSCreate(PETSC_COMM_WORLD,&eps);CHKERRQ(ierr);
72
 
73
  /*
1947 jroman 74
     Set operators. In this case, it is a standard eigenvalue problem.
75
     Request also left eigenvectors
782 dsic.upv.es!jroman 76
  */
77
  ierr = EPSSetOperators(eps,A,PETSC_NULL);CHKERRQ(ierr);
78
  ierr = EPSSetProblemType(eps,EPS_NHEP);CHKERRQ(ierr);
1947 jroman 79
  ierr = EPSSetLeftVectorsWanted(eps,PETSC_TRUE);CHKERRQ(ierr);
782 dsic.upv.es!jroman 80
 
81
  /*
82
     Set solver parameters at runtime
83
  */
84
  ierr = EPSSetFromOptions(eps);CHKERRQ(ierr);
85
 
947 dsic.upv.es!jroman 86
  /*
87
     Set the initial vector. This is optional, if not done the initial
88
     vector is set to random values
89
  */
1947 jroman 90
  ierr = MatGetVecs(A,&v0,&w0);CHKERRQ(ierr);
947 dsic.upv.es!jroman 91
  ierr = VecSet(v0,1.0);CHKERRQ(ierr);
1947 jroman 92
  ierr = MatMult(A,v0,w0);CHKERRQ(ierr);
1933 jroman 93
  ierr = EPSSetInitialSpace(eps,1,&v0);CHKERRQ(ierr);
1947 jroman 94
  ierr = EPSSetInitialSpaceLeft(eps,1,&w0);CHKERRQ(ierr);
947 dsic.upv.es!jroman 95
 
782 dsic.upv.es!jroman 96
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
97
                      Solve the eigensystem
98
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
99
 
100
  ierr = EPSSolve(eps);CHKERRQ(ierr);
101
  ierr = EPSGetIterationNumber(eps, &its);CHKERRQ(ierr);
102
  ierr = PetscPrintf(PETSC_COMM_WORLD," Number of iterations of the method: %d\n",its);CHKERRQ(ierr);
103
 
104
  /*
105
     Optional: Get some information from the solver and display it
106
  */
107
  ierr = EPSGetType(eps,&type);CHKERRQ(ierr);
108
  ierr = PetscPrintf(PETSC_COMM_WORLD," Solution method: %s\n\n",type);CHKERRQ(ierr);
1575 slepc 109
  ierr = EPSGetDimensions(eps,&nev,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
782 dsic.upv.es!jroman 110
  ierr = PetscPrintf(PETSC_COMM_WORLD," Number of requested eigenvalues: %d\n",nev);CHKERRQ(ierr);
111
  ierr = EPSGetTolerances(eps,&tol,&maxit);CHKERRQ(ierr);
112
  ierr = PetscPrintf(PETSC_COMM_WORLD," Stopping condition: tol=%.4g, maxit=%d\n",tol,maxit);CHKERRQ(ierr);
113
 
114
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
115
                    Display solution and clean up
116
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
117
 
118
  /*
119
     Get number of converged approximate eigenpairs
120
  */
121
  ierr = EPSGetConverged(eps,&nconv);CHKERRQ(ierr);
122
  ierr = PetscPrintf(PETSC_COMM_WORLD," Number of converged approximate eigenpairs: %d\n\n",nconv);CHKERRQ(ierr);
123
 
124
  if (nconv>0) {
125
    /*
126
       Display eigenvalues and relative errors
127
    */
128
    ierr = PetscPrintf(PETSC_COMM_WORLD,
129
         "           k          ||Ax-kx||/||kx||   ||y'A-ky'||/||ky||\n"
130
         "   ----------------- ------------------ --------------------\n" );CHKERRQ(ierr);
131
 
132
    for( i=0; i<nconv; i++ ) {
133
      /*
134
        Get converged eigenpairs: i-th eigenvalue is stored in kr (real part) and
135
        ki (imaginary part)
136
      */
1936 jroman 137
      ierr = EPSGetEigenvalue(eps,i,&kr,&ki);CHKERRQ(ierr);
782 dsic.upv.es!jroman 138
      /*
139
         Compute the relative errors associated to both right and left eigenvectors
140
      */
141
      ierr = EPSComputeRelativeError(eps,i,&error1);CHKERRQ(ierr);
142
      ierr = EPSComputeRelativeErrorLeft(eps,i,&error2);CHKERRQ(ierr);
143
 
144
#ifdef PETSC_USE_COMPLEX
145
      re = PetscRealPart(kr);
146
      im = PetscImaginaryPart(kr);
147
#else
148
      re = kr;
149
      im = ki;
150
#endif
151
      if (im!=0.0) {
1162 slepc 152
        ierr = PetscPrintf(PETSC_COMM_WORLD," %9f%+9f j %12g%12g\n",re,im,error1,error2);CHKERRQ(ierr);
782 dsic.upv.es!jroman 153
      } else {
1162 slepc 154
        ierr = PetscPrintf(PETSC_COMM_WORLD,"   %12f       %12g       %12g\n",re,error1,error2);CHKERRQ(ierr);
782 dsic.upv.es!jroman 155
      }
156
    }
157
    ierr = PetscPrintf(PETSC_COMM_WORLD,"\n" );CHKERRQ(ierr);
947 dsic.upv.es!jroman 158
 
159
    ierr = VecDuplicateVecs(v0,nconv,&X);
1947 jroman 160
    ierr = VecDuplicateVecs(w0,nconv,&Y);
947 dsic.upv.es!jroman 161
    for (i=0;i<nconv;i++) {
1936 jroman 162
      ierr = EPSGetEigenvector(eps,i,X[i],PETSC_NULL);CHKERRQ(ierr);
163
      ierr = EPSGetEigenvectorLeft(eps,i,Y[i],PETSC_NULL);CHKERRQ(ierr);
947 dsic.upv.es!jroman 164
    }
165
    ierr = PetscPrintf(PETSC_COMM_WORLD,
166
         "                   Bi-orthogonality <x,y>                   \n"
167
         "   ---------------------------------------------------------\n" );CHKERRQ(ierr);
168
 
169
    ierr = SlepcCheckOrthogonality(X,nconv,Y,nconv,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
170
    ierr = PetscPrintf(PETSC_COMM_WORLD,"\n" );CHKERRQ(ierr);
171
    ierr = VecDestroyVecs(X,nconv);CHKERRQ(ierr);
172
    ierr = VecDestroyVecs(Y,nconv);CHKERRQ(ierr);
173
 
782 dsic.upv.es!jroman 174
  }
175
 
176
  /*
177
     Free work space
178
  */
947 dsic.upv.es!jroman 179
  ierr = VecDestroy(v0);CHKERRQ(ierr);
1947 jroman 180
  ierr = VecDestroy(w0);CHKERRQ(ierr);
782 dsic.upv.es!jroman 181
  ierr = EPSDestroy(eps);CHKERRQ(ierr);
182
  ierr = MatDestroy(A);CHKERRQ(ierr);
183
  ierr = SlepcFinalize();CHKERRQ(ierr);
184
  return 0;
185
}
186
 
187
#undef __FUNCT__
188
#define __FUNCT__ "MatMarkovModel"
189
/*
190
    Matrix generator for a Markov model of a random walk on a triangular grid.
191
 
192
    This subroutine generates a test matrix that models a random walk on a
193
    triangular grid. This test example was used by G. W. Stewart ["{SRRIT} - a
194
    FORTRAN subroutine to calculate the dominant invariant subspaces of a real
195
    matrix", Tech. report. TR-514, University of Maryland (1978).] and in a few
196
    papers on eigenvalue problems by Y. Saad [see e.g. LAA, vol. 34, pp. 269-295
197
    (1980) ]. These matrices provide reasonably easy test problems for eigenvalue
198
    algorithms. The transpose of the matrix  is stochastic and so it is known
199
    that one is an exact eigenvalue. One seeks the eigenvector of the transpose
200
    associated with the eigenvalue unity. The problem is to calculate the steady
201
    state probability distribution of the system, which is the eigevector
202
    associated with the eigenvalue one and scaled in such a way that the sum all
203
    the components is equal to one.
204
 
205
    Note: the code will actually compute the transpose of the stochastic matrix
206
    that contains the transition probabilities.
207
*/
983 slepc 208
PetscErrorCode MatMarkovModel( PetscInt m, Mat A )
782 dsic.upv.es!jroman 209
{
210
  const PetscReal cst = 0.5/(PetscReal)(m-1);
983 slepc 211
  PetscReal       pd, pu;
212
  PetscErrorCode  ierr;
213
  PetscInt        i, j, jmax, ix=0, Istart, Iend;
782 dsic.upv.es!jroman 214
 
983 slepc 215
  PetscFunctionBegin;
782 dsic.upv.es!jroman 216
  ierr = MatGetOwnershipRange(A,&Istart,&Iend);CHKERRQ(ierr);
217
  for( i=1; i<=m; i++ ) {
218
    jmax = m-i+1;
219
    for( j=1; j<=jmax; j++ ) {
220
      ix = ix + 1;
221
      if( ix-1<Istart || ix>Iend ) continue;  /* compute only owned rows */
222
      if( j!=jmax ) {
223
        pd = cst*(PetscReal)(i+j-1);
224
        /* north */
225
        if( i==1 ) {
226
          ierr = MatSetValue( A, ix-1, ix, 2*pd, INSERT_VALUES );CHKERRQ(ierr);
227
        }
228
        else {
229
          ierr = MatSetValue( A, ix-1, ix, pd, INSERT_VALUES );CHKERRQ(ierr);
230
        }
231
        /* east */
232
        if( j==1 ) {
233
          ierr = MatSetValue( A, ix-1, ix+jmax-1, 2*pd, INSERT_VALUES );CHKERRQ(ierr);
234
        }
235
        else {
236
          ierr = MatSetValue( A, ix-1, ix+jmax-1, pd, INSERT_VALUES );CHKERRQ(ierr);
237
        }
238
      }
239
      /* south */
240
      pu = 0.5 - cst*(PetscReal)(i+j-3);
241
      if( j>1 ) {
242
        ierr = MatSetValue( A, ix-1, ix-2, pu, INSERT_VALUES );CHKERRQ(ierr);
243
      }
244
      /* west */
245
      if( i>1 ) {
246
        ierr = MatSetValue( A, ix-1, ix-jmax-2, pu, INSERT_VALUES );CHKERRQ(ierr);
247
      }
248
    }
249
  }
250
  ierr = MatAssemblyBegin( A, MAT_FINAL_ASSEMBLY );CHKERRQ(ierr);
251
  ierr = MatAssemblyEnd( A, MAT_FINAL_ASSEMBLY );CHKERRQ(ierr);
983 slepc 252
  PetscFunctionReturn(0);
782 dsic.upv.es!jroman 253
}
254