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
1298 slepc 1
/*                      
2
 
3
   SLEPc singular value solver: "trlanczos"
4
 
5
   Method: Golub-Kahan-Lanczos bidiagonalization with thick-restart
6
 
1397 slepc 7
   Last update: Jun 2007
1298 slepc 8
 
1376 slepc 9
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 slepc 10
   SLEPc - Scalable Library for Eigenvalue Problem Computations
2116 eromero 11
   Copyright (c) 2002-2010, Universidad Politecnica de Valencia, Spain
1376 slepc 12
 
1672 slepc 13
   This file is part of SLEPc.
14
 
15
   SLEPc is free software: you can redistribute it and/or modify it under  the
16
   terms of version 3 of the GNU Lesser General Public License as published by
17
   the Free Software Foundation.
18
 
19
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
20
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
21
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
22
   more details.
23
 
24
   You  should have received a copy of the GNU Lesser General  Public  License
25
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
1376 slepc 26
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1298 slepc 27
*/
1376 slepc 28
 
2284 jroman 29
#include <private/svdimpl.h>                /*I "slepcsvd.h" I*/
30
#include <private/ipimpl.h>                 /*I "slepcip.h" I*/
31
#include <slepcblaslapack.h>
1298 slepc 32
 
33
typedef struct {
2216 jroman 34
  PetscBool oneside;
1298 slepc 35
} SVD_TRLANCZOS;
36
 
37
#undef __FUNCT__  
2324 jroman 38
#define __FUNCT__ "SVDSetUp_TRLanczos"
39
PetscErrorCode SVDSetUp_TRLanczos(SVD svd)
1298 slepc 40
{
2317 jroman 41
  PetscErrorCode ierr;
42
  PetscInt       i,N,nloc;
43
  PetscScalar    *pU;
1298 slepc 44
 
45
  PetscFunctionBegin;
1314 slepc 46
  ierr = SVDMatGetSize(svd,PETSC_NULL,&N);CHKERRQ(ierr);
1595 slepc 47
  if (svd->ncv) { /* ncv set */
2214 jroman 48
    if (svd->ncv<svd->nsv) SETERRQ(((PetscObject)svd)->comm,1,"The value of ncv must be at least nsv");
1595 slepc 49
  }
50
  else if (svd->mpd) { /* mpd set */
51
    svd->ncv = PetscMin(N,svd->nsv+svd->mpd);
52
  }
53
  else { /* neither set: defaults depend on nsv being small or large */
54
    if (svd->nsv<500) svd->ncv = PetscMin(N,PetscMax(2*svd->nsv,10));
55
    else { svd->mpd = 500; svd->ncv = PetscMin(N,svd->nsv+svd->mpd); }
56
  }
57
  if (!svd->mpd) svd->mpd = svd->ncv;
2214 jroman 58
  if (svd->ncv>svd->nsv+svd->mpd) SETERRQ(((PetscObject)svd)->comm,1,"The value of ncv must not be larger than nev+mpd");
1594 slepc 59
  if (!svd->max_it)
1314 slepc 60
    svd->max_it = PetscMax(N/svd->ncv,100);
61
  if (svd->ncv!=svd->n) {  
62
    if (svd->U) {
1605 slepc 63
      ierr = VecGetArray(svd->U[0],&pU);CHKERRQ(ierr);
2305 jroman 64
      for (i=0;i<svd->n;i++) { ierr = VecDestroy(&svd->U[i]); CHKERRQ(ierr); }
1605 slepc 65
      ierr = PetscFree(pU);CHKERRQ(ierr);
1314 slepc 66
      ierr = PetscFree(svd->U);CHKERRQ(ierr);
67
    }
68
    ierr = PetscMalloc(sizeof(Vec)*svd->ncv,&svd->U);CHKERRQ(ierr);
1605 slepc 69
    ierr = SVDMatGetLocalSize(svd,&nloc,PETSC_NULL);CHKERRQ(ierr);
70
    ierr = PetscMalloc(svd->ncv*nloc*sizeof(PetscScalar),&pU);CHKERRQ(ierr);
71
    for (i=0;i<svd->ncv;i++) {
72
      ierr = VecCreateMPIWithArray(((PetscObject)svd)->comm,nloc,PETSC_DECIDE,pU+i*nloc,&svd->U[i]);CHKERRQ(ierr);
73
    }
1314 slepc 74
  }
1298 slepc 75
  PetscFunctionReturn(0);
76
}
77
 
78
#undef __FUNCT__  
1431 slepc 79
#define __FUNCT__ "SVDOneSideTRLanczosMGS"
1755 antodo 80
static PetscErrorCode SVDOneSideTRLanczosMGS(SVD svd,PetscReal *alpha,PetscReal *beta,PetscScalar* bb,Vec *V,Vec v,Vec* U,PetscInt nconv,PetscInt l,PetscInt n,PetscScalar* work)
1431 slepc 81
{
82
  PetscErrorCode ierr;
83
  PetscReal      a,b;
1504 slepc 84
  PetscInt       i,k=nconv+l;
1431 slepc 85
 
86
  PetscFunctionBegin;
87
  ierr = SVDMatMult(svd,PETSC_FALSE,V[k],U[k]);CHKERRQ(ierr);
88
  if (l>0) {
1755 antodo 89
    ierr = SlepcVecMAXPBY(U[k],1.0,-1.0,l,bb,U+nconv);CHKERRQ(ierr);
1431 slepc 90
  }
91
  ierr = IPNorm(svd->ip,U[k],&a);CHKERRQ(ierr);
92
  ierr = VecScale(U[k],1.0/a);CHKERRQ(ierr);
93
  alpha[0] = a;
94
  for (i=k+1;i<n;i++) {
95
    ierr = SVDMatMult(svd,PETSC_TRUE,U[i-1],V[i]);CHKERRQ(ierr);
1755 antodo 96
    ierr = IPOrthogonalize(svd->ip,0,PETSC_NULL,i,PETSC_NULL,V,V[i],work,&b,PETSC_NULL);CHKERRQ(ierr);  
1431 slepc 97
    ierr = VecScale(V[i],1.0/b);CHKERRQ(ierr);
98
    beta[i-k-1] = b;
99
 
100
    ierr = SVDMatMult(svd,PETSC_FALSE,V[i],U[i]);CHKERRQ(ierr);
101
    ierr = VecAXPY(U[i],-b,U[i-1]);CHKERRQ(ierr);
102
    ierr = IPNorm(svd->ip,U[i],&a);CHKERRQ(ierr);
103
    ierr = VecScale(U[i],1.0/a);CHKERRQ(ierr);
104
    alpha[i-k] = a;
105
  }
106
  ierr = SVDMatMult(svd,PETSC_TRUE,U[n-1],v);CHKERRQ(ierr);
1755 antodo 107
  ierr = IPOrthogonalize(svd->ip,0,PETSC_NULL,n,PETSC_NULL,V,v,work,&b,PETSC_NULL);CHKERRQ(ierr);      
1431 slepc 108
  beta[n-k-1] = b;
109
  PetscFunctionReturn(0);
110
}
111
 
112
#undef __FUNCT__  
1489 slepc 113
#define __FUNCT__ "SVDOneSideTRLanczosCGS"
1755 antodo 114
static PetscErrorCode SVDOneSideTRLanczosCGS(SVD svd,PetscReal *alpha,PetscReal *beta,PetscScalar* bb,Vec *V,Vec v,Vec* U,PetscInt nconv,PetscInt l,PetscInt n,PetscScalar* work)
1328 slepc 115
{
116
  PetscErrorCode ierr;
1414 slepc 117
  PetscReal      a,b,sum,onorm;
118
  PetscScalar    dot;
1504 slepc 119
  PetscInt       i,j,k=nconv+l;
1328 slepc 120
 
121
  PetscFunctionBegin;
122
  ierr = SVDMatMult(svd,PETSC_FALSE,V[k],U[k]);CHKERRQ(ierr);
123
  if (l>0) {
1755 antodo 124
    ierr = SlepcVecMAXPBY(U[k],1.0,-1.0,l,bb,U+nconv);CHKERRQ(ierr);
1328 slepc 125
  }
126
  for (i=k+1;i<n;i++) {
127
    ierr = SVDMatMult(svd,PETSC_TRUE,U[i-1],V[i]);CHKERRQ(ierr);
1352 slepc 128
    ierr = IPNormBegin(svd->ip,U[i-1],&a);CHKERRQ(ierr);
1414 slepc 129
    if (svd->ip->orthog_ref == IP_ORTH_REFINE_IFNEEDED) {
130
      ierr = IPInnerProductBegin(svd->ip,V[i],V[i],&dot);CHKERRQ(ierr);
131
    }
1381 slepc 132
    ierr = IPMInnerProductBegin(svd->ip,V[i],i,V,work);CHKERRQ(ierr);
1352 slepc 133
    ierr = IPNormEnd(svd->ip,U[i-1],&a);CHKERRQ(ierr);
1414 slepc 134
    if (svd->ip->orthog_ref == IP_ORTH_REFINE_IFNEEDED) {
135
      ierr = IPInnerProductEnd(svd->ip,V[i],V[i],&dot);CHKERRQ(ierr);
136
    }
1381 slepc 137
    ierr = IPMInnerProductEnd(svd->ip,V[i],i,V,work);CHKERRQ(ierr);
1328 slepc 138
 
139
    ierr = VecScale(U[i-1],1.0/a);CHKERRQ(ierr);
1755 antodo 140
    for (j=0;j<i;j++) work[j] = work[j] / a;
141
    ierr = SlepcVecMAXPBY(V[i],1.0/a,-1.0,i,work,V);CHKERRQ(ierr);
1328 slepc 142
 
1414 slepc 143
    switch (svd->ip->orthog_ref) {
144
    case IP_ORTH_REFINE_NEVER:
145
      ierr = IPNorm(svd->ip,V[i],&b);CHKERRQ(ierr);
146
      break;      
147
    case IP_ORTH_REFINE_ALWAYS:
1755 antodo 148
      ierr = IPOrthogonalizeCGS1(svd->ip,0,PETSC_NULL,i,PETSC_NULL,V,V[i],work,PETSC_NULL,&b);CHKERRQ(ierr);
1414 slepc 149
      break;
150
    case IP_ORTH_REFINE_IFNEEDED:
151
      onorm = sqrt(PetscRealPart(dot)) / a;
152
      sum = 0.0;
153
      for (j=0;j<i;j++) {
154
        sum += PetscRealPart(work[j] * PetscConj(work[j]));
155
      }
156
      b = PetscRealPart(dot)/(a*a) - sum;
157
      if (b>0.0) b = sqrt(b);
158
      else {
159
        ierr = IPNorm(svd->ip,V[i],&b);CHKERRQ(ierr);
160
      }
161
      if (b < svd->ip->orthog_eta * onorm) {
1755 antodo 162
        ierr = IPOrthogonalizeCGS1(svd->ip,0,PETSC_NULL,i,PETSC_NULL,V,V[i],work,PETSC_NULL,&b);CHKERRQ(ierr);
1414 slepc 163
      }
164
      break;
165
    }
166
 
1328 slepc 167
    ierr = VecScale(V[i],1.0/b);CHKERRQ(ierr);
168
 
169
    ierr = SVDMatMult(svd,PETSC_FALSE,V[i],U[i]);CHKERRQ(ierr);
170
    ierr = VecAXPY(U[i],-b,U[i-1]);CHKERRQ(ierr);
171
 
172
    alpha[i-k-1] = a;
173
    beta[i-k-1] = b;
174
  }
175
  ierr = SVDMatMult(svd,PETSC_TRUE,U[n-1],v);CHKERRQ(ierr);
1352 slepc 176
  ierr = IPNormBegin(svd->ip,U[n-1],&a);CHKERRQ(ierr);
1415 slepc 177
  if (svd->ip->orthog_ref == IP_ORTH_REFINE_IFNEEDED) {
178
    ierr = IPInnerProductBegin(svd->ip,v,v,&dot);CHKERRQ(ierr);
179
  }
1381 slepc 180
  ierr = IPMInnerProductBegin(svd->ip,v,n,V,work);CHKERRQ(ierr);
1352 slepc 181
  ierr = IPNormEnd(svd->ip,U[n-1],&a);CHKERRQ(ierr);
1415 slepc 182
  if (svd->ip->orthog_ref == IP_ORTH_REFINE_IFNEEDED) {
183
    ierr = IPInnerProductEnd(svd->ip,v,v,&dot);CHKERRQ(ierr);
184
  }
1381 slepc 185
  ierr = IPMInnerProductEnd(svd->ip,v,n,V,work);CHKERRQ(ierr);
1328 slepc 186
 
187
  ierr = VecScale(U[n-1],1.0/a);CHKERRQ(ierr);
1755 antodo 188
  for (j=0;j<n;j++) work[j] = work[j] / a;
189
  ierr = SlepcVecMAXPBY(v,1.0/a,-1.0,n,work,V);CHKERRQ(ierr);
1328 slepc 190
 
1415 slepc 191
  switch (svd->ip->orthog_ref) {
192
  case IP_ORTH_REFINE_NEVER:
193
    ierr = IPNorm(svd->ip,v,&b);CHKERRQ(ierr);
194
    break;      
195
  case IP_ORTH_REFINE_ALWAYS:
1755 antodo 196
    ierr = IPOrthogonalizeCGS1(svd->ip,0,PETSC_NULL,n,PETSC_NULL,V,v,work,PETSC_NULL,&b);CHKERRQ(ierr);
1415 slepc 197
    break;
198
  case IP_ORTH_REFINE_IFNEEDED:
199
    onorm = sqrt(PetscRealPart(dot)) / a;
200
    sum = 0.0;
201
    for (j=0;j<i;j++) {
202
      sum += PetscRealPart(work[j] * PetscConj(work[j]));
203
    }
204
    b = PetscRealPart(dot)/(a*a) - sum;
205
    if (b>0.0) b = sqrt(b);
206
    else {
207
      ierr = IPNorm(svd->ip,v,&b);CHKERRQ(ierr);
208
    }
209
    if (b < svd->ip->orthog_eta * onorm) {
1755 antodo 210
      ierr = IPOrthogonalizeCGS1(svd->ip,0,PETSC_NULL,n,PETSC_NULL,V,v,work,PETSC_NULL,&b);CHKERRQ(ierr);
1415 slepc 211
    }
212
    break;
213
  }
214
 
1328 slepc 215
  alpha[n-k-1] = a;
216
  beta[n-k-1] = b;
217
  PetscFunctionReturn(0);
218
}
219
 
220
#undef __FUNCT__  
2324 jroman 221
#define __FUNCT__ "SVDSolve_TRLanczos"
222
PetscErrorCode SVDSolve_TRLanczos(SVD svd)
1298 slepc 223
{
224
  PetscErrorCode ierr;
225
  SVD_TRLANCZOS  *lanczos = (SVD_TRLANCZOS *)svd->data;
1328 slepc 226
  PetscReal      *alpha,*beta,norm;
1341 slepc 227
  PetscScalar    *b,*Q,*PT,*swork;
1605 slepc 228
  PetscInt       i,j,k,l,m,n,nv;
1755 antodo 229
  Vec            v;
2216 jroman 230
  PetscBool      conv;
1431 slepc 231
  IPOrthogonalizationType orthog;
1298 slepc 232
 
233
  PetscFunctionBegin;
234
  /* allocate working space */
1307 slepc 235
  ierr = PetscMalloc(sizeof(PetscReal)*svd->n,&alpha);CHKERRQ(ierr);
236
  ierr = PetscMalloc(sizeof(PetscReal)*svd->n,&beta);CHKERRQ(ierr);
237
  ierr = PetscMalloc(sizeof(PetscScalar)*svd->n,&b);CHKERRQ(ierr);
238
  ierr = PetscMalloc(sizeof(PetscScalar)*svd->n*svd->n,&Q);CHKERRQ(ierr);
239
  ierr = PetscMalloc(sizeof(PetscScalar)*svd->n*svd->n,&PT);CHKERRQ(ierr);
1605 slepc 240
#if !defined(PETSC_USE_COMPLEX)
241
  if (svd->which == SVD_SMALLEST) {
242
#endif
243
    ierr = PetscMalloc(sizeof(PetscScalar)*svd->n*svd->n,&swork);CHKERRQ(ierr);
244
#if !defined(PETSC_USE_COMPLEX)
245
  } else {
246
    ierr = PetscMalloc(sizeof(PetscScalar)*svd->n,&swork);CHKERRQ(ierr);
247
  }
248
#endif
1328 slepc 249
  ierr = VecDuplicate(svd->V[0],&v);CHKERRQ(ierr);
1431 slepc 250
  ierr = IPGetOrthogonalization(svd->ip,&orthog,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1298 slepc 251
 
252
  /* normalize start vector */
1952 jroman 253
  if (svd->nini==0) {
2027 jroman 254
    ierr = SlepcVecSetRandom(svd->V[0],svd->rand);CHKERRQ(ierr);
1952 jroman 255
  }
1328 slepc 256
  ierr = VecNormalize(svd->V[0],&norm);CHKERRQ(ierr);
1298 slepc 257
 
258
  l = 0;
259
  while (svd->reason == SVD_CONVERGED_ITERATING) {
260
    svd->its++;
261
 
262
    /* inner loop */
1595 slepc 263
    nv = PetscMin(svd->nconv+svd->mpd,svd->n);
1328 slepc 264
    if (lanczos->oneside) {
1940 jroman 265
      if (orthog == IP_ORTH_MGS) {
1755 antodo 266
        ierr = SVDOneSideTRLanczosMGS(svd,alpha,beta,b+svd->nconv,svd->V,v,svd->U,svd->nconv,l,nv,swork);CHKERRQ(ierr);
1431 slepc 267
      } else {
1755 antodo 268
        ierr = SVDOneSideTRLanczosCGS(svd,alpha,beta,b+svd->nconv,svd->V,v,svd->U,svd->nconv,l,nv,swork);CHKERRQ(ierr);
1431 slepc 269
      }
1328 slepc 270
    } else {
1755 antodo 271
      ierr = SVDTwoSideLanczos(svd,alpha,beta,svd->V,v,svd->U,svd->nconv+l,nv,swork);CHKERRQ(ierr);
1298 slepc 272
    }
1595 slepc 273
    ierr = VecScale(v,1.0/beta[nv-svd->nconv-l-1]);CHKERRQ(ierr);
1328 slepc 274
 
1298 slepc 275
    /* compute SVD of general matrix */
1595 slepc 276
    n = nv - svd->nconv;
1298 slepc 277
    /* first l columns */
278
    for (j=0;j<l;j++) {
279
      for (i=0;i<j;i++) Q[j*n+i] = 0.0;    
1328 slepc 280
      Q[j*n+j] = svd->sigma[svd->nconv+j];
1298 slepc 281
      for (i=j+1;i<n;i++) Q[j*n+i] = 0.0;
282
    }
283
    /* l+1 column */
1328 slepc 284
    for (i=0;i<l;i++) Q[l*n+i] = b[i+svd->nconv];
285
    Q[l*n+l] = alpha[0];
1298 slepc 286
    for (i=l+1;i<n;i++) Q[l*n+i] = 0.0;
287
    /* rest of matrix */
288
    for (j=l+1;j<n;j++) {
289
      for (i=0;i<j-1;i++) Q[j*n+i] = 0.0;
1328 slepc 290
      Q[j*n+j-1] = beta[j-l-1];
291
      Q[j*n+j] = alpha[j-l];
1298 slepc 292
      for (i=j+1;i<n;i++) Q[j*n+i] = 0.0;
293
    }
1328 slepc 294
    ierr = SVDDense(n,n,Q,alpha,PETSC_NULL,PT);CHKERRQ(ierr);
1298 slepc 295
 
296
    /* compute error estimates */
1328 slepc 297
    k = 0;
298
    conv = PETSC_TRUE;
1606 slepc 299
    for (i=svd->nconv;i<nv;i++) {
1328 slepc 300
      if (svd->which == SVD_SMALLEST) j = n-i+svd->nconv-1;
301
      else j = i-svd->nconv;
302
      svd->sigma[i] = alpha[j];
303
      b[i] = Q[j*n+n-1]*beta[n-l-1];
304
      svd->errest[i] = PetscAbsScalar(b[i]);
305
      if (alpha[j] > svd->tol) svd->errest[i] /= alpha[j];
306
      if (conv) {
307
        if (svd->errest[i] < svd->tol) k++;
308
        else conv = PETSC_FALSE;
1304 slepc 309
      }
1298 slepc 310
    }
311
 
1328 slepc 312
    /* check convergence and update l */
313
    if (svd->its >= svd->max_it) svd->reason = SVD_DIVERGED_ITS;
314
    if (svd->nconv+k >= svd->nsv) svd->reason = SVD_CONVERGED_TOL;
315
    if (svd->reason != SVD_CONVERGED_ITERATING) l = 0;
1606 slepc 316
    else l = PetscMax((nv - svd->nconv - k) / 2,0);
1300 slepc 317
 
1328 slepc 318
    /* compute converged singular vectors and restart vectors*/
1605 slepc 319
#if !defined(PETSC_USE_COMPLEX)
320
    if (svd->which == SVD_SMALLEST) {
321
#endif
1328 slepc 322
    for (i=0;i<k+l;i++) {
323
      if (svd->which == SVD_SMALLEST) j = n-i-1;
324
      else j = i;
1605 slepc 325
      for (m=0;m<n;m++) swork[j*n+m] = PT[m*n+j];
1328 slepc 326
    }
1605 slepc 327
    ierr = SlepcUpdateVectors(n,svd->V+svd->nconv,0,k+l,swork,n,PETSC_FALSE);CHKERRQ(ierr);
328
    for (i=0;i<k+l;i++) {
329
      if (svd->which == SVD_SMALLEST) j = n-i-1;
330
      else j = i;
331
      for (m=0;m<n;m++) swork[j*n+m] = Q[j*n+m];
332
    }
333
    ierr = SlepcUpdateVectors(n,svd->U+svd->nconv,0,k+l,swork,n,PETSC_FALSE);CHKERRQ(ierr);
334
#if !defined(PETSC_USE_COMPLEX)
335
    } else {
336
      ierr = SlepcUpdateVectors(n,svd->V+svd->nconv,0,k+l,PT,n,PETSC_TRUE);CHKERRQ(ierr);
337
      ierr = SlepcUpdateVectors(n,svd->U+svd->nconv,0,k+l,Q,n,PETSC_FALSE);CHKERRQ(ierr);
338
    }
339
#endif
1328 slepc 340
 
1298 slepc 341
    /* copy the last vector to be the next initial vector */
342
    if (svd->reason == SVD_CONVERGED_ITERATING) {
1328 slepc 343
      ierr = VecCopy(v,svd->V[svd->nconv+k+l]);CHKERRQ(ierr);
1298 slepc 344
    }
345
 
1328 slepc 346
    svd->nconv += k;
2313 jroman 347
    ierr = SVDMonitor(svd,svd->its,svd->nconv,svd->sigma,svd->errest,nv);CHKERRQ(ierr);
1298 slepc 348
  }
349
 
1603 slepc 350
  /* orthonormalize U columns in one side method */
351
  if (lanczos->oneside) {
352
    for (i=0;i<svd->nconv;i++) {
1755 antodo 353
      ierr = IPOrthogonalize(svd->ip,0,PETSC_NULL,i,PETSC_NULL,svd->U,svd->U[i],PETSC_NULL,&norm,PETSC_NULL);CHKERRQ(ierr);
1489 slepc 354
      ierr = VecScale(svd->U[i],1.0/norm);CHKERRQ(ierr);
355
    }
1298 slepc 356
  }
357
 
358
  /* free working space */
2305 jroman 359
  ierr = VecDestroy(&v);CHKERRQ(ierr);
1298 slepc 360
 
361
  ierr = PetscFree(alpha);CHKERRQ(ierr);
362
  ierr = PetscFree(beta);CHKERRQ(ierr);
363
  ierr = PetscFree(b);CHKERRQ(ierr);
364
  ierr = PetscFree(Q);CHKERRQ(ierr);
365
  ierr = PetscFree(PT);CHKERRQ(ierr);
1341 slepc 366
  ierr = PetscFree(swork);CHKERRQ(ierr);
1298 slepc 367
  PetscFunctionReturn(0);
368
}
369
 
370
#undef __FUNCT__  
2324 jroman 371
#define __FUNCT__ "SVDSetFromOptions_TRLanczos"
372
PetscErrorCode SVDSetFromOptions_TRLanczos(SVD svd)
1298 slepc 373
{
374
  PetscErrorCode ierr;
2216 jroman 375
  PetscBool      set,val;
1298 slepc 376
  SVD_TRLANCZOS  *lanczos = (SVD_TRLANCZOS *)svd->data;
377
 
378
  PetscFunctionBegin;
2324 jroman 379
  ierr = PetscOptionsBegin(((PetscObject)svd)->comm,((PetscObject)svd)->prefix,"TRLanczos Singular Value Solver Options","SVD");CHKERRQ(ierr);
2216 jroman 380
  ierr = PetscOptionsBool("-svd_trlanczos_oneside","Lanczos one-side reorthogonalization","SVDTRLanczosSetOneSide",lanczos->oneside,&val,&set);CHKERRQ(ierr);
1923 jroman 381
  if (set) {
382
    ierr = SVDTRLanczosSetOneSide(svd,val);CHKERRQ(ierr);
383
  }
1298 slepc 384
  ierr = PetscOptionsEnd();CHKERRQ(ierr);
385
  PetscFunctionReturn(0);
386
}
1370 slepc 387
 
1298 slepc 388
EXTERN_C_BEGIN
389
#undef __FUNCT__  
2324 jroman 390
#define __FUNCT__ "SVDTRLanczosSetOneSide_TRLanczos"
391
PetscErrorCode SVDTRLanczosSetOneSide_TRLanczos(SVD svd,PetscBool oneside)
1298 slepc 392
{
393
  SVD_TRLANCZOS *lanczos = (SVD_TRLANCZOS *)svd->data;
394
 
395
  PetscFunctionBegin;
396
  lanczos->oneside = oneside;
397
  PetscFunctionReturn(0);
398
}
1370 slepc 399
EXTERN_C_END
1298 slepc 400
 
401
#undef __FUNCT__
1359 slepc 402
#define __FUNCT__ "SVDTRLanczosSetOneSide"
1393 slepc 403
/*@
404
   SVDTRLanczosSetOneSide - Indicate if the variant of the Lanczos method
405
   to be used is one-sided or two-sided.
406
 
407
   Collective on SVD
408
 
409
   Input Parameters:
410
+  svd     - singular value solver
411
-  oneside - boolean flag indicating if the method is one-sided or not
412
 
413
   Options Database Key:
414
.  -svd_trlanczos_oneside <boolean> - Indicates the boolean flag
415
 
416
   Note:
417
   By default, a two-sided variant is selected, which is sometimes slightly
418
   more robust. However, the one-sided variant is faster because it avoids
419
   the orthogonalization associated to left singular vectors.
420
 
421
   Level: advanced
422
 
423
.seealso: SVDLanczosSetOneSide()
424
@*/
2216 jroman 425
PetscErrorCode SVDTRLanczosSetOneSide(SVD svd,PetscBool oneside)
1298 slepc 426
{
2221 jroman 427
  PetscErrorCode ierr;
1298 slepc 428
 
429
  PetscFunctionBegin;
2213 jroman 430
  PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
2326 jroman 431
  PetscValidLogicalCollectiveBool(svd,oneside,2);
2221 jroman 432
  ierr = PetscTryMethod(svd,"SVDTRLanczosSetOneSide_C",(SVD,PetscBool),(svd,oneside));CHKERRQ(ierr);
1298 slepc 433
  PetscFunctionReturn(0);
434
}
435
 
2079 eromero 436
#undef __FUNCT__
437
#define __FUNCT__ "SVDTRLanczosGetOneSide"
438
/*@
439
   SVDTRLanczosGetOneSide - Gets if the variant of the Lanczos method
440
   to be used is one-sided or two-sided.
441
 
442
   Collective on SVD
443
 
444
   Input Parameters:
445
.  svd     - singular value solver
446
 
447
   Output Parameters:
448
.  oneside - boolean flag indicating if the method is one-sided or not
449
 
450
   Level: advanced
451
 
452
.seealso: SVDTRLanczosSetOneSide()
453
@*/
2216 jroman 454
PetscErrorCode SVDTRLanczosGetOneSide(SVD svd,PetscBool *oneside)
2079 eromero 455
{
2221 jroman 456
  PetscErrorCode ierr;
2079 eromero 457
 
458
  PetscFunctionBegin;
2213 jroman 459
  PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
2326 jroman 460
  PetscValidPointer(oneside,2);
2221 jroman 461
  ierr = PetscTryMethod(svd,"SVDTRLanczosGetOneSide_C",(SVD,PetscBool*),(svd,oneside));CHKERRQ(ierr);
2079 eromero 462
  PetscFunctionReturn(0);
463
}
464
 
465
EXTERN_C_BEGIN
1298 slepc 466
#undef __FUNCT__  
2324 jroman 467
#define __FUNCT__ "SVDTRLanczosGetOneSide_TRLanczos"
468
PetscErrorCode SVDTRLanczosGetOneSide_TRLanczos(SVD svd,PetscBool *oneside)
2079 eromero 469
{
470
  SVD_TRLANCZOS    *lanczos = (SVD_TRLANCZOS *)svd->data;
471
 
472
  PetscFunctionBegin;
473
  *oneside = lanczos->oneside;
474
  PetscFunctionReturn(0);
475
}
476
EXTERN_C_END
477
 
478
#undef __FUNCT__  
2324 jroman 479
#define __FUNCT__ "SVDDestroy_TRLanczos"
480
PetscErrorCode SVDDestroy_TRLanczos(SVD svd)
1925 jroman 481
{
482
  PetscErrorCode ierr;
483
 
484
  PetscFunctionBegin;
2213 jroman 485
  PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
1925 jroman 486
  ierr = SVDDestroy_Default(svd);CHKERRQ(ierr);
487
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDTRLanczosSetOneSide_C","",PETSC_NULL);CHKERRQ(ierr);
2079 eromero 488
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDTRLanczosGetOneSide_C","",PETSC_NULL);CHKERRQ(ierr);
1925 jroman 489
  PetscFunctionReturn(0);
490
}
491
 
492
#undef __FUNCT__  
2324 jroman 493
#define __FUNCT__ "SVDView_TRLanczos"
494
PetscErrorCode SVDView_TRLanczos(SVD svd,PetscViewer viewer)
1298 slepc 495
{
496
  PetscErrorCode ierr;
497
  SVD_TRLANCZOS  *lanczos = (SVD_TRLANCZOS *)svd->data;
498
 
499
  PetscFunctionBegin;
500
  ierr = PetscViewerASCIIPrintf(viewer,"Lanczos reorthogonalization: %s\n",lanczos->oneside ? "one-side" : "two-side");CHKERRQ(ierr);
501
  PetscFunctionReturn(0);
502
}
503
 
504
EXTERN_C_BEGIN
505
#undef __FUNCT__  
2324 jroman 506
#define __FUNCT__ "SVDCreate_TRLanczos"
507
PetscErrorCode SVDCreate_TRLanczos(SVD svd)
1298 slepc 508
{
509
  PetscErrorCode ierr;
510
  SVD_TRLANCZOS  *lanczos;
511
 
512
  PetscFunctionBegin;
513
  ierr = PetscNew(SVD_TRLANCZOS,&lanczos);CHKERRQ(ierr);
514
  PetscLogObjectMemory(svd,sizeof(SVD_TRLANCZOS));
515
  svd->data                = (void *)lanczos;
2324 jroman 516
  svd->ops->setup          = SVDSetUp_TRLanczos;
517
  svd->ops->solve          = SVDSolve_TRLanczos;
518
  svd->ops->destroy        = SVDDestroy_TRLanczos;
519
  svd->ops->setfromoptions = SVDSetFromOptions_TRLanczos;
520
  svd->ops->view           = SVDView_TRLanczos;
1298 slepc 521
  lanczos->oneside         = PETSC_FALSE;
2324 jroman 522
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDTRLanczosSetOneSide_C","SVDTRLanczosSetOneSide_TRLanczos",SVDTRLanczosSetOneSide_TRLanczos);CHKERRQ(ierr);
523
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDTRLanczosGetOneSide_C","SVDTRLanczosGetOneSide_TRLanczos",SVDTRLanczosGetOneSide_TRLanczos);CHKERRQ(ierr);
1298 slepc 524
  PetscFunctionReturn(0);
525
}
526
EXTERN_C_END