Subversion Repositories slepc-dev

Rev

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
2575 eromero 4
   Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain
6 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
 
161 dsic.upv.es!antodo 22
static char help[] = "Eigenvalue problem associated with a Markov model of a random walk on a triangular grid. "
1156 slepc 23
  "It is a standard nonsymmetric eigenproblem with real eigenvalues and the rightmost eigenvalue is known to be 1.\n"
6 dsic.upv.es!jroman 24
  "This example illustrates how the user can set the initial vector.\n\n"
1156 slepc 25
  "The command line options are:\n"
6 dsic.upv.es!jroman 26
  "  -m <m>, where <m> = number of grid subdivisions in each dimension.\n\n";
2342 jroman 27
 
2283 jroman 28
#include <slepceps.h>
6 dsic.upv.es!jroman 29
 
30
/*
31
   User-defined routines
32
*/
2331 jroman 33
PetscErrorCode MatMarkovModel(PetscInt m,Mat A);
2551 eromero 34
PetscErrorCode MyEigenSort(EPS eps,PetscScalar ar,PetscScalar ai,PetscScalar br,PetscScalar bi,PetscInt *r,void *ctx);
6 dsic.upv.es!jroman 35
 
36
#undef __FUNCT__
37
#define __FUNCT__ "main"
2331 jroman 38
int main(int argc,char **argv)
6 dsic.upv.es!jroman 39
{
2316 jroman 40
  Vec            v0;              /* initial vector */
41
  Mat            A;               /* operator matrix */
42
  EPS            eps;             /* eigenproblem solver context */
43
  const EPSType  type;
2557 eromero 44
  PetscReal      tol=1000*PETSC_MACHINE_EPSILON;
45
  PetscInt       N,m=15,nev,maxit;
2551 eromero 46
  PetscScalar    origin=0.0;
2317 jroman 47
  PetscErrorCode ierr;
983 slepc 48
 
6 dsic.upv.es!jroman 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;
2503 jroman 53
  ierr = PetscPrintf(PETSC_COMM_WORLD,"\nMarkov Model, N=%D (m=%D)\n\n",N,m);CHKERRQ(ierr);
6 dsic.upv.es!jroman 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);
6 dsic.upv.es!jroman 61
  ierr = MatSetFromOptions(A);CHKERRQ(ierr);
2331 jroman 62
  ierr = MatMarkovModel(m,A);CHKERRQ(ierr);
6 dsic.upv.es!jroman 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
  /*
74
     Set operators. In this case, it is a standard eigenvalue problem
75
  */
76
  ierr = EPSSetOperators(eps,A,PETSC_NULL);CHKERRQ(ierr);
408 dsic.upv.es!antodo 77
  ierr = EPSSetProblemType(eps,EPS_NHEP);CHKERRQ(ierr);
2557 eromero 78
  ierr = EPSSetTolerances(eps,tol,PETSC_DECIDE);CHKERRQ(ierr);
6 dsic.upv.es!jroman 79
 
80
  /*
2551 eromero 81
     Set the custom comparing routine in order to obtain the eigenvalues
82
     closest to the target on the right only
83
  */
84
  ierr = EPSSetEigenvalueComparison(eps,MyEigenSort,&origin);CHKERRQ(ierr);
85
 
86
 
87
  /*
6 dsic.upv.es!jroman 88
     Set solver parameters at runtime
89
  */
90
  ierr = EPSSetFromOptions(eps);CHKERRQ(ierr);
91
 
92
  /*
93
     Set the initial vector. This is optional, if not done the initial
94
     vector is set to random values
95
  */
583 dsic.upv.es!jroman 96
  ierr = MatGetVecs(A,&v0,PETSC_NULL);CHKERRQ(ierr);
828 dsic.upv.es!antodo 97
  ierr = VecSet(v0,1.0);CHKERRQ(ierr);
1933 jroman 98
  ierr = EPSSetInitialSpace(eps,1,&v0);CHKERRQ(ierr);
6 dsic.upv.es!jroman 99
 
100
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
101
                      Solve the eigensystem
102
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
103
 
78 dsic.upv.es!antodo 104
  ierr = EPSSolve(eps);CHKERRQ(ierr);
6 dsic.upv.es!jroman 105
 
106
  /*
107
     Optional: Get some information from the solver and display it
108
  */
109
  ierr = EPSGetType(eps,&type);CHKERRQ(ierr);
110
  ierr = PetscPrintf(PETSC_COMM_WORLD," Solution method: %s\n\n",type);CHKERRQ(ierr);
1575 slepc 111
  ierr = EPSGetDimensions(eps,&nev,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
2503 jroman 112
  ierr = PetscPrintf(PETSC_COMM_WORLD," Number of requested eigenvalues: %D\n",nev);CHKERRQ(ierr);
6 dsic.upv.es!jroman 113
  ierr = EPSGetTolerances(eps,&tol,&maxit);CHKERRQ(ierr);
2503 jroman 114
  ierr = PetscPrintf(PETSC_COMM_WORLD," Stopping condition: tol=%.4G, maxit=%D\n",tol,maxit);CHKERRQ(ierr);
6 dsic.upv.es!jroman 115
 
116
  /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
117
                    Display solution and clean up
118
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
119
 
2503 jroman 120
  ierr = EPSPrintSolution(eps,PETSC_NULL);CHKERRQ(ierr);
2308 jroman 121
  ierr = EPSDestroy(&eps);CHKERRQ(ierr);
2305 jroman 122
  ierr = MatDestroy(&A);CHKERRQ(ierr);
123
  ierr = VecDestroy(&v0);CHKERRQ(ierr);
6 dsic.upv.es!jroman 124
  ierr = SlepcFinalize();CHKERRQ(ierr);
125
  return 0;
126
}
127
 
128
#undef __FUNCT__
129
#define __FUNCT__ "MatMarkovModel"
130
/*
131
    Matrix generator for a Markov model of a random walk on a triangular grid.
132
 
133
    This subroutine generates a test matrix that models a random walk on a
134
    triangular grid. This test example was used by G. W. Stewart ["{SRRIT} - a
135
    FORTRAN subroutine to calculate the dominant invariant subspaces of a real
136
    matrix", Tech. report. TR-514, University of Maryland (1978).] and in a few
137
    papers on eigenvalue problems by Y. Saad [see e.g. LAA, vol. 34, pp. 269-295
138
    (1980) ]. These matrices provide reasonably easy test problems for eigenvalue
139
    algorithms. The transpose of the matrix  is stochastic and so it is known
140
    that one is an exact eigenvalue. One seeks the eigenvector of the transpose
141
    associated with the eigenvalue unity. The problem is to calculate the steady
142
    state probability distribution of the system, which is the eigevector
143
    associated with the eigenvalue one and scaled in such a way that the sum all
144
    the components is equal to one.
145
 
146
    Note: the code will actually compute the transpose of the stochastic matrix
147
    that contains the transition probabilities.
148
*/
2331 jroman 149
PetscErrorCode MatMarkovModel(PetscInt m,Mat A)
6 dsic.upv.es!jroman 150
{
151
  const PetscReal cst = 0.5/(PetscReal)(m-1);
2331 jroman 152
  PetscReal       pd,pu;
153
  PetscInt        Istart,Iend,i,j,jmax,ix=0;
983 slepc 154
  PetscErrorCode  ierr;
6 dsic.upv.es!jroman 155
 
983 slepc 156
  PetscFunctionBegin;
6 dsic.upv.es!jroman 157
  ierr = MatGetOwnershipRange(A,&Istart,&Iend);CHKERRQ(ierr);
2331 jroman 158
  for (i=1;i<=m;i++) {
6 dsic.upv.es!jroman 159
    jmax = m-i+1;
2331 jroman 160
    for (j=1;j<=jmax;j++) {
6 dsic.upv.es!jroman 161
      ix = ix + 1;
2331 jroman 162
      if (ix-1<Istart || ix>Iend) continue;  /* compute only owned rows */
163
      if (j!=jmax) {
6 dsic.upv.es!jroman 164
        pd = cst*(PetscReal)(i+j-1);
165
        /* north */
2331 jroman 166
        if (i==1) {
167
          ierr = MatSetValue(A,ix-1,ix,2*pd,INSERT_VALUES);CHKERRQ(ierr);
2316 jroman 168
        } else {
2331 jroman 169
          ierr = MatSetValue(A,ix-1,ix,pd,INSERT_VALUES);CHKERRQ(ierr);
6 dsic.upv.es!jroman 170
        }
171
        /* east */
2331 jroman 172
        if (j==1) {
173
          ierr = MatSetValue(A,ix-1,ix+jmax-1,2*pd,INSERT_VALUES);CHKERRQ(ierr);
2316 jroman 174
        } else {
2331 jroman 175
          ierr = MatSetValue(A,ix-1,ix+jmax-1,pd,INSERT_VALUES);CHKERRQ(ierr);
6 dsic.upv.es!jroman 176
        }
177
      }
178
      /* south */
179
      pu = 0.5 - cst*(PetscReal)(i+j-3);
2331 jroman 180
      if (j>1) {
181
        ierr = MatSetValue(A,ix-1,ix-2,pu,INSERT_VALUES);CHKERRQ(ierr);
6 dsic.upv.es!jroman 182
      }
183
      /* west */
2331 jroman 184
      if (i>1) {
185
        ierr = MatSetValue(A,ix-1,ix-jmax-2,pu,INSERT_VALUES);CHKERRQ(ierr);
6 dsic.upv.es!jroman 186
      }
187
    }
188
  }
2331 jroman 189
  ierr = MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
190
  ierr = MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
983 slepc 191
  PetscFunctionReturn(0);
6 dsic.upv.es!jroman 192
}
193
 
2551 eromero 194
#undef __FUNCT__
195
#define __FUNCT__ "MyEigenSort"
196
/*
197
    Function for user-defined eigenvalue ordering criterion.
198
 
199
    Given two eigenvalues ar+i*ai and br+i*bi, the subroutine must choose
200
    one of them as the preferred one according to the criterion.
201
    In this example, the preferred value is the one furthest to the origin.
202
*/
203
PetscErrorCode MyEigenSort(EPS eps,PetscScalar ar,PetscScalar ai,PetscScalar br,PetscScalar bi,PetscInt *r,void *ctx)
204
{
205
  PetscScalar origin = *(PetscScalar*)ctx;
206
  PetscReal   d;
207
 
208
  PetscFunctionBegin;
209
  d = (SlepcAbsEigenvalue(br-origin,bi) - SlepcAbsEigenvalue(ar-origin,ai))/PetscMax(SlepcAbsEigenvalue(ar-origin,ai),SlepcAbsEigenvalue(br-origin,bi));
210
  *r = d > PETSC_SQRT_MACHINE_EPSILON ? 1 : (d < -PETSC_SQRT_MACHINE_EPSILON ? -1 : PetscSign(PetscRealPart(br)));
211
  PetscFunctionReturn(0);
212
}