Subversion Repositories slepc-dev

Rev

Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1249 slepc 1
/*
2
      SVD routines related to the solution process.
1376 slepc 3
 
4
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5
      SLEPc - Scalable Library for Eigenvalue Problem Computations
6
      Copyright (c) 2002-2007, Universidad Politecnica de Valencia, Spain
7
 
8
      This file is part of SLEPc. See the README file for conditions of use
9
      and additional information.
10
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1249 slepc 11
*/
1376 slepc 12
 
1249 slepc 13
#include "src/svd/svdimpl.h"   /*I "slepcsvd.h" I*/
14
 
15
#undef __FUNCT__  
16
#define __FUNCT__ "SVDSolve"
17
/*@
18
   SVDSolve - Solves the singular value problem.
19
 
20
   Collective on SVD
21
 
22
   Input Parameter:
23
.  svd - singular value solver context obtained from SVDCreate()
24
 
25
   Options Database:
26
.   -svd_view - print information about the solver used
27
 
28
   Level: beginner
29
 
30
.seealso: SVDCreate(), SVDSetUp(), SVDDestroy()
31
@*/
32
PetscErrorCode SVDSolve(SVD svd)
33
{
34
  PetscErrorCode ierr;
35
  PetscTruth     flg;
1288 slepc 36
  int            i;
1249 slepc 37
 
38
  PetscFunctionBegin;
39
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
40
 
41
  if (!svd->setupcalled) { ierr = SVDSetUp(svd);CHKERRQ(ierr); }
1288 slepc 42
  svd->its = 0;
1305 slepc 43
  svd->matvecs = 0;
1288 slepc 44
  svd->nconv = 0;
1283 slepc 45
  svd->reason = SVD_CONVERGED_ITERATING;
1329 slepc 46
  ierr = IPResetOperationCounters(svd->ip);CHKERRQ(ierr);
1288 slepc 47
  for (i=0;i<svd->ncv;i++) svd->sigma[i]=svd->errest[i]=0.0;
48
  SVDMonitor(svd,svd->its,svd->nconv,svd->sigma,svd->errest,svd->ncv);
1249 slepc 49
 
50
  ierr = PetscLogEventBegin(SVD_Solve,svd,0,0,0);CHKERRQ(ierr);
51
  ierr = (*svd->ops->solve)(svd);CHKERRQ(ierr);
52
  ierr = PetscLogEventEnd(SVD_Solve,svd,0,0,0);CHKERRQ(ierr);
53
 
1422 slepc 54
  ierr = PetscOptionsHasName(((PetscObject)svd)->prefix,"-svd_view",&flg);CHKERRQ(ierr);
1249 slepc 55
  if (flg && !PetscPreLoadingOn) { ierr = SVDView(svd,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); }
56
 
57
  PetscFunctionReturn(0);
58
}
59
 
60
#undef __FUNCT__  
1283 slepc 61
#define __FUNCT__ "SVDGetIterationNumber"
62
/*@
63
   SVDGetIterationNumber - Gets the current iteration number. If the
64
   call to SVDSolve() is complete, then it returns the number of iterations
65
   carried out by the solution method.
66
 
67
   Not Collective
68
 
69
   Input Parameter:
70
.  svd - the singular value solver context
71
 
72
   Output Parameter:
73
.  its - number of iterations
74
 
75
   Level: intermediate
76
 
77
   Notes:
78
      During the i-th iteration this call returns i-1. If SVDSolve() is
79
      complete, then parameter "its" contains either the iteration number at
80
      which convergence was successfully reached, or failure was detected.  
81
      Call SVDGetConvergedReason() to determine if the solver converged or
82
      failed and why.
83
 
84
@*/
85
PetscErrorCode SVDGetIterationNumber(SVD svd,int *its)
86
{
87
  PetscFunctionBegin;
88
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
89
  PetscValidIntPointer(its,2);
90
  *its = svd->its;
91
  PetscFunctionReturn(0);
92
}
93
 
94
#undef __FUNCT__  
95
#define __FUNCT__ "SVDGetConvergedReason"
96
/*@C
97
   SVDGetConvergedReason - Gets the reason why the SVDSolve() iteration was
98
   stopped.
99
 
100
   Not Collective
101
 
102
   Input Parameter:
103
.  svd - the singular value solver context
104
 
105
   Output Parameter:
106
.  reason - negative value indicates diverged, positive value converged
107
   (see SVDConvergedReason)
108
 
109
   Possible values for reason:
110
+  SVD_CONVERGED_TOL - converged up to tolerance
111
.  SVD_DIVERGED_ITS - required more than its to reach convergence
112
-  SVD_DIVERGED_BREAKDOWN - generic breakdown in method
113
 
114
   Level: intermediate
115
 
116
   Notes: Can only be called after the call to SVDSolve() is complete.
117
 
118
.seealso: SVDSetTolerances(), SVDSolve(), SVDConvergedReason
119
@*/
120
PetscErrorCode SVDGetConvergedReason(SVD svd,SVDConvergedReason *reason)
121
{
122
  PetscFunctionBegin;
123
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
124
  PetscValidIntPointer(reason,2);
125
  *reason = svd->reason;
126
  PetscFunctionReturn(0);
127
}
128
 
129
#undef __FUNCT__  
1249 slepc 130
#define __FUNCT__ "SVDGetConverged"
131
/*@
132
   SVDGetConverged - Gets the number of converged singular values.
133
 
134
   Not Collective
135
 
136
   Input Parameter:
137
.  svd - the singular value solver context
138
 
139
   Output Parameter:
140
.  nconv - number of converged singular values
141
 
142
   Note:
143
   This function should be called after SVDSolve() has finished.
144
 
145
   Level: beginner
146
 
147
@*/
148
PetscErrorCode SVDGetConverged(SVD svd,int *nconv)
149
{
150
  PetscFunctionBegin;
151
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
152
  PetscValidIntPointer(nconv,2);
1283 slepc 153
  if (svd->reason == SVD_CONVERGED_ITERATING) {
1249 slepc 154
    SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "SVDSolve must be called first");
155
  }
156
  *nconv = svd->nconv;
157
  PetscFunctionReturn(0);
158
}
159
 
160
#undef __FUNCT__  
161
#define __FUNCT__ "SVDGetSingularTriplet"
162
/*@
163
   SVDGetSingularTriplet - Gets the i-th triplet of the singular value decomposition
164
   as computed by SVDSolve(). The solution consists in the singular value and its left
165
   and right singular vectors.
166
 
167
   Not Collective
168
 
169
   Input Parameters:
170
+  svd - singular value solver context
171
-  i   - index of the solution
172
 
173
   Output Parameters:
174
+  sigma - singular value
1251 slepc 175
.  u     - left singular vector
176
-  v     - right singular vector
1249 slepc 177
 
1267 slepc 178
   Note:
179
   The index i should be a value between 0 and nconv-1 (see SVDGetConverged()).
1249 slepc 180
   Both U or V can be PETSC_NULL if singular vectors are not required.
181
 
182
   Level: beginner
183
 
184
.seealso: SVDSolve(),  SVDGetConverged()
185
@*/
1251 slepc 186
PetscErrorCode SVDGetSingularTriplet(SVD svd, int i, PetscReal *sigma, Vec u, Vec v)
1249 slepc 187
{
188
  PetscErrorCode ierr;
189
 
190
  PetscFunctionBegin;
191
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
192
  PetscValidPointer(sigma,3);
1283 slepc 193
  if (svd->reason == SVD_CONVERGED_ITERATING) {
1249 slepc 194
    SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "SVDSolve must be called first");
195
  }
196
  if (i<0 || i>=svd->nconv) {
197
    SETERRQ(PETSC_ERR_ARG_OUTOFRANGE, "Argument 2 out of range");
198
  }
199
  *sigma = svd->sigma[i];
1251 slepc 200
  if (u) {
201
    PetscValidHeaderSpecific(u,VEC_COOKIE,4);
1314 slepc 202
    if (svd->U) {
203
      ierr = VecCopy(svd->U[i],u);CHKERRQ(ierr);
204
    } else {
205
      ierr = SVDMatMult(svd,PETSC_FALSE,svd->V[i],u);CHKERRQ(ierr);
206
      ierr = VecScale(u,1.0/svd->sigma[i]);CHKERRQ(ierr);
207
    }
1249 slepc 208
  }
1251 slepc 209
  if (v) {
210
    PetscValidHeaderSpecific(v,VEC_COOKIE,5);  
211
    ierr = VecCopy(svd->V[i],v);CHKERRQ(ierr);
1249 slepc 212
  }
213
  PetscFunctionReturn(0);
214
}
1251 slepc 215
 
216
#undef __FUNCT__  
1257 slepc 217
#define __FUNCT__ "SVDComputeResidualNorms"
1251 slepc 218
/*@
1320 slepc 219
   SVDComputeResidualNorms - Computes the norms of the residual vectors associated with
1251 slepc 220
   the i-th computed singular triplet.
221
 
1320 slepc 222
   Collective on SVD
1251 slepc 223
 
1267 slepc 224
   Input Parameters:
1320 slepc 225
+  svd  - the singular value solver context
1257 slepc 226
-  i    - the solution index
1251 slepc 227
 
1267 slepc 228
   Output Parameters:
1257 slepc 229
+  norm1 - the norm ||A*v-sigma*u||_2 where sigma is the
230
           singular value, u and v are the left and right singular vectors.
1283 slepc 231
-  norm2 - the norm ||A^T*u-sigma*v||_2 with the same sigma, u and v
1251 slepc 232
 
1267 slepc 233
   Note:
234
   The index i should be a value between 0 and nconv-1 (see SVDGetConverged()).
1257 slepc 235
   Both output parameters can be PETSC_NULL on input if not needed.
1251 slepc 236
 
237
   Level: beginner
238
 
1320 slepc 239
.seealso: SVDSolve(), SVDGetConverged(), SVDComputeRelativeError()
1251 slepc 240
@*/
1257 slepc 241
PetscErrorCode SVDComputeResidualNorms(SVD svd, int i, PetscReal *norm1, PetscReal *norm2)
1251 slepc 242
{
243
  PetscErrorCode ierr;
1257 slepc 244
  Vec            u,v,x = PETSC_NULL,y = PETSC_NULL;
1251 slepc 245
  PetscReal      sigma;
246
 
247
  PetscFunctionBegin;
248
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
1283 slepc 249
  if (svd->reason == SVD_CONVERGED_ITERATING) {
1251 slepc 250
    SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "SVDSolve must be called first");
251
  }
252
  if (i<0 || i>=svd->nconv) {
253
    SETERRQ(PETSC_ERR_ARG_OUTOFRANGE, "Argument 2 out of range");
254
  }
255
 
1314 slepc 256
  ierr = SVDMatGetVecs(svd,&v,&u);CHKERRQ(ierr);
1283 slepc 257
  ierr = SVDGetSingularTriplet(svd,i,&sigma,u,v);CHKERRQ(ierr);
1257 slepc 258
  if (norm1) {
259
    ierr = VecDuplicate(u,&x);CHKERRQ(ierr);
1314 slepc 260
    ierr = SVDMatMult(svd,PETSC_FALSE,v,x);CHKERRQ(ierr);
1257 slepc 261
    ierr = VecAXPY(x,-sigma,u);CHKERRQ(ierr);
262
    ierr = VecNorm(x,NORM_2,norm1);CHKERRQ(ierr);
263
  }
264
  if (norm2) {
265
    ierr = VecDuplicate(v,&y);CHKERRQ(ierr);
1314 slepc 266
    ierr = SVDMatMult(svd,PETSC_TRUE,u,y);CHKERRQ(ierr);
1257 slepc 267
    ierr = VecAXPY(y,-sigma,v);CHKERRQ(ierr);
268
    ierr = VecNorm(y,NORM_2,norm2);CHKERRQ(ierr);
269
  }
1251 slepc 270
 
271
  ierr = VecDestroy(v);CHKERRQ(ierr);
272
  ierr = VecDestroy(u);CHKERRQ(ierr);
1257 slepc 273
  if (x) { ierr = VecDestroy(x);CHKERRQ(ierr); }
274
  if (y) { ierr = VecDestroy(y);CHKERRQ(ierr); }
1251 slepc 275
  PetscFunctionReturn(0);
276
}
1305 slepc 277
 
278
#undef __FUNCT__  
1317 slepc 279
#define __FUNCT__ "SVDComputeRelativeError"
1320 slepc 280
/*@
281
   SVDComputeRelativeError - Computes the relative error bound associated
282
   with the i-th singular triplet.
283
 
284
   Collective on SVD
285
 
286
   Input Parameter:
1321 slepc 287
+  svd - the singular value solver context
288
-  i   - the solution index
1320 slepc 289
 
290
   Output Parameter:
1330 slepc 291
.  error - the relative error bound, computed as sqrt(n1^2+n2^2)/(sigma*sqrt(||u||_2^2+||v||_2^2))
292
   where n1 = ||A*v-sigma*u||_2 , n2 = ||A^T*u-sigma*v||_2 , sigma is the singular value,
293
   u and v are the left and right singular vectors.
294
   If sigma is too small the relative error is computed as sqrt(n1^2+n2^2)/sqrt(||u||_2^2+||v||_2^2).
1320 slepc 295
 
296
   Level: beginner
297
 
298
.seealso: SVDSolve(), SVDComputeResidualNorms()
299
@*/
1317 slepc 300
PetscErrorCode SVDComputeRelativeError(SVD svd, int i, PetscReal *error)
301
{
302
  PetscErrorCode ierr;
1330 slepc 303
  PetscReal      sigma,norm1,norm2,norm3,norm4;
304
  Vec            u,v;
1317 slepc 305
 
306
  PetscFunctionBegin;
307
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
308
  PetscValidPointer(error,2);
1330 slepc 309
  ierr = SVDMatGetVecs(svd,&v,&u);CHKERRQ(ierr);
310
  ierr = SVDGetSingularTriplet(svd,i,&sigma,u,v);CHKERRQ(ierr);
1317 slepc 311
  ierr = SVDComputeResidualNorms(svd,i,&norm1,&norm2);CHKERRQ(ierr);
1330 slepc 312
  ierr = VecNorm(u,NORM_2,&norm3);CHKERRQ(ierr);
313
  ierr = VecNorm(v,NORM_2,&norm4);CHKERRQ(ierr);
314
  *error = sqrt(norm1*norm1+norm2*norm2) / sqrt(norm3*norm3+norm4*norm4);
315
  if (sigma>*error) *error /= sigma;
316
  ierr = VecDestroy(v);CHKERRQ(ierr);
317
  ierr = VecDestroy(u);CHKERRQ(ierr);
1317 slepc 318
  PetscFunctionReturn(0);
319
}
320
 
321
#undef __FUNCT__  
1305 slepc 322
#define __FUNCT__ "SVDGetOperationCounters"
323
/*@
324
   SVDGetOperationCounters - Gets the total number of matrix vector and dot
325
   products used by the SVD object during the last SVDSolve() call.
326
 
327
   Not Collective
328
 
329
   Input Parameter:
330
.  svd - SVD context
331
 
332
   Output Parameter:
333
+  matvecs - number of matrix vector product operations
334
-  dots    - number of dot product operations
335
 
336
   Notes:
337
   These counters are reset to zero at each successive call to SVDSolve().
338
 
339
   Level: intermediate
340
 
341
@*/
342
PetscErrorCode SVDGetOperationCounters(SVD svd,int* matvecs,int* dots)
343
{
1329 slepc 344
  PetscErrorCode ierr;
345
 
1305 slepc 346
  PetscFunctionBegin;
347
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
348
  if (matvecs) *matvecs = svd->matvecs;
1329 slepc 349
  if (dots) {
350
    ierr = IPGetOperationCounters(svd->ip,dots);CHKERRQ(ierr);
351
  }
1305 slepc 352
  PetscFunctionReturn(0);
353
}