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
1278 slepc 1
/*                      
2
 
3
   SLEPc singular value solver: "lanczos"
4
 
1281 slepc 5
   Method: Golub-Kahan-Lanczos bidiagonalization
1278 slepc 6
 
1397 slepc 7
   Last update: Jun 2007
1278 slepc 8
 
1376 slepc 9
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 slepc 10
   SLEPc - Scalable Library for Eigenvalue Problem Computations
11
   Copyright (c) 2002-2009, 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
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1278 slepc 27
*/
1376 slepc 28
 
1521 slepc 29
#include "private/svdimpl.h"                /*I "slepcsvd.h" I*/
1696 slepc 30
#include "private/ipimpl.h"
1283 slepc 31
#include "slepcblaslapack.h"
1278 slepc 32
 
1298 slepc 33
typedef struct {
34
  PetscTruth oneside;
35
} SVD_LANCZOS;
36
 
1278 slepc 37
#undef __FUNCT__  
38
#define __FUNCT__ "SVDSetUp_LANCZOS"
39
PetscErrorCode SVDSetUp_LANCZOS(SVD svd)
40
{
41
  PetscErrorCode  ierr;
1605 slepc 42
  SVD_LANCZOS     *lanczos = (SVD_LANCZOS *)svd->data;
43
  PetscInt        i,N,nloc;
44
  PetscScalar     *pU;
1278 slepc 45
 
46
  PetscFunctionBegin;
1315 slepc 47
  ierr = SVDMatGetSize(svd,PETSC_NULL,&N);CHKERRQ(ierr);
1594 slepc 48
  if (svd->ncv) { /* ncv set */
1593 slepc 49
    if (svd->ncv<svd->nsv) SETERRQ(1,"The value of ncv must be at least nsv");
50
  }
51
  else if (svd->mpd) { /* mpd set */
52
    svd->ncv = PetscMin(N,svd->nsv+svd->mpd);
53
  }
54
  else { /* neither set: defaults depend on nsv being small or large */
55
    if (svd->nsv<500) svd->ncv = PetscMin(N,PetscMax(2*svd->nsv,10));
56
    else { svd->mpd = 500; svd->ncv = PetscMin(N,svd->nsv+svd->mpd); }
57
  }
58
  if (!svd->mpd) svd->mpd = svd->ncv;
59
  if (svd->ncv>svd->nsv+svd->mpd) SETERRQ(1,"The value of ncv must not be larger than nev+mpd");
1594 slepc 60
  if (!svd->max_it)
1315 slepc 61
    svd->max_it = PetscMax(N/svd->ncv,100);
62
  if (svd->U) {
1605 slepc 63
    ierr = VecGetArray(svd->U[0],&pU);CHKERRQ(ierr);
1315 slepc 64
    for (i=0;i<svd->n;i++) { ierr = VecDestroy(svd->U[i]); CHKERRQ(ierr); }
1605 slepc 65
    ierr = PetscFree(pU);CHKERRQ(ierr);
1315 slepc 66
    ierr = PetscFree(svd->U);CHKERRQ(ierr);
67
  }
68
  if (!lanczos->oneside) {
69
    ierr = PetscMalloc(sizeof(Vec)*svd->ncv,&svd->U);CHKERRQ(ierr);
1605 slepc 70
    ierr = SVDMatGetLocalSize(svd,&nloc,PETSC_NULL);CHKERRQ(ierr);
71
    ierr = PetscMalloc(svd->ncv*nloc*sizeof(PetscScalar),&pU);CHKERRQ(ierr);
72
    for (i=0;i<svd->ncv;i++) {
73
      ierr = VecCreateMPIWithArray(((PetscObject)svd)->comm,nloc,PETSC_DECIDE,pU+i*nloc,&svd->U[i]);CHKERRQ(ierr);
74
    }
1315 slepc 75
  }
1278 slepc 76
  PetscFunctionReturn(0);
77
}
78
 
79
#undef __FUNCT__  
1315 slepc 80
#define __FUNCT__ "SVDTwoSideLanczos"
1755 antodo 81
PetscErrorCode SVDTwoSideLanczos(SVD svd,PetscReal *alpha,PetscReal *beta,Vec *V,Vec v,Vec *U,PetscInt k,PetscInt n,PetscScalar* work)
1315 slepc 82
{
83
  PetscErrorCode ierr;
1504 slepc 84
  PetscInt       i;
1315 slepc 85
 
86
  PetscFunctionBegin;
1328 slepc 87
  ierr = SVDMatMult(svd,PETSC_FALSE,V[k],U[k]);CHKERRQ(ierr);
1755 antodo 88
  ierr = IPOrthogonalize(svd->ip,0,PETSC_NULL,k,PETSC_NULL,U,U[k],work,alpha,PETSC_NULL);CHKERRQ(ierr);
1328 slepc 89
  ierr = VecScale(U[k],1.0/alpha[0]);CHKERRQ(ierr);
90
  for (i=k+1;i<n;i++) {
91
    ierr = SVDMatMult(svd,PETSC_TRUE,U[i-1],V[i]);CHKERRQ(ierr);
1755 antodo 92
    ierr = IPOrthogonalize(svd->ip,0,PETSC_NULL,i,PETSC_NULL,V,V[i],work,beta+i-k-1,PETSC_NULL);CHKERRQ(ierr);
1328 slepc 93
    ierr = VecScale(V[i],1.0/beta[i-k-1]);CHKERRQ(ierr);
94
 
1315 slepc 95
    ierr = SVDMatMult(svd,PETSC_FALSE,V[i],U[i]);CHKERRQ(ierr);
1755 antodo 96
    ierr = IPOrthogonalize(svd->ip,0,PETSC_NULL,i,PETSC_NULL,U,U[i],work,alpha+i-k,PETSC_NULL);CHKERRQ(ierr);
1315 slepc 97
    ierr = VecScale(U[i],1.0/alpha[i-k]);CHKERRQ(ierr);
98
  }
1328 slepc 99
  ierr = SVDMatMult(svd,PETSC_TRUE,U[n-1],v);CHKERRQ(ierr);
1755 antodo 100
  ierr = IPOrthogonalize(svd->ip,0,PETSC_NULL,n,PETSC_NULL,V,v,work,beta+n-k-1,PETSC_NULL);CHKERRQ(ierr);
1315 slepc 101
  PetscFunctionReturn(0);
102
}
103
 
104
#undef __FUNCT__  
105
#define __FUNCT__ "SVDOneSideLanczos"
1755 antodo 106
static PetscErrorCode SVDOneSideLanczos(SVD svd,PetscReal *alpha,PetscReal *beta,Vec *V,Vec v,Vec u,Vec u_1,PetscInt k,PetscInt n,PetscScalar* work)
1315 slepc 107
{
108
  PetscErrorCode ierr;
1755 antodo 109
  PetscInt       i;
1328 slepc 110
  PetscReal      a,b;
111
  Vec            temp;
1315 slepc 112
 
113
  PetscFunctionBegin;
1328 slepc 114
  ierr = SVDMatMult(svd,PETSC_FALSE,V[k],u);CHKERRQ(ierr);
115
  for (i=k+1;i<n;i++) {
116
    ierr = SVDMatMult(svd,PETSC_TRUE,u,V[i]);CHKERRQ(ierr);
1352 slepc 117
    ierr = IPNormBegin(svd->ip,u,&a);CHKERRQ(ierr);
1381 slepc 118
    ierr = IPMInnerProductBegin(svd->ip,V[i],i,V,work);CHKERRQ(ierr);
1352 slepc 119
    ierr = IPNormEnd(svd->ip,u,&a);CHKERRQ(ierr);
1381 slepc 120
    ierr = IPMInnerProductEnd(svd->ip,V[i],i,V,work);CHKERRQ(ierr);
1315 slepc 121
 
1328 slepc 122
    ierr = VecScale(u,1.0/a);CHKERRQ(ierr);
1755 antodo 123
    ierr = SlepcVecMAXPBY(V[i],1.0/a,-1.0/a,i,work,V);CHKERRQ(ierr);
1328 slepc 124
 
1755 antodo 125
    ierr = IPOrthogonalizeCGS1(svd->ip,0,PETSC_NULL,i,PETSC_NULL,V,V[i],work,PETSC_NULL,&b);CHKERRQ(ierr);
1328 slepc 126
    ierr = VecScale(V[i],1.0/b);CHKERRQ(ierr);
127
 
128
    ierr = SVDMatMult(svd,PETSC_FALSE,V[i],u_1);CHKERRQ(ierr);
129
    ierr = VecAXPY(u_1,-b,u);CHKERRQ(ierr);
130
 
131
    alpha[i-k-1] = a;
132
    beta[i-k-1] = b;
133
    temp = u;
134
    u = u_1;
135
    u_1 = temp;
136
  }
137
  ierr = SVDMatMult(svd,PETSC_TRUE,u,v);CHKERRQ(ierr);
1352 slepc 138
  ierr = IPNormBegin(svd->ip,u,&a);CHKERRQ(ierr);
1381 slepc 139
  ierr = IPMInnerProductBegin(svd->ip,v,n,V,work);CHKERRQ(ierr);
1352 slepc 140
  ierr = IPNormEnd(svd->ip,u,&a);CHKERRQ(ierr);
1381 slepc 141
  ierr = IPMInnerProductEnd(svd->ip,v,n,V,work);CHKERRQ(ierr);
1315 slepc 142
 
1328 slepc 143
  ierr = VecScale(u,1.0/a);CHKERRQ(ierr);
1755 antodo 144
  ierr = SlepcVecMAXPBY(v,1.0/a,-1.0/a,n,work,V);CHKERRQ(ierr);
1315 slepc 145
 
1755 antodo 146
  ierr = IPOrthogonalizeCGS1(svd->ip,0,PETSC_NULL,n,PETSC_NULL,V,v,work,PETSC_NULL,&b);CHKERRQ(ierr);
1328 slepc 147
 
148
  alpha[n-k-1] = a;
149
  beta[n-k-1] = b;
1315 slepc 150
  PetscFunctionReturn(0);
151
}
152
 
153
#undef __FUNCT__  
1278 slepc 154
#define __FUNCT__ "SVDSolve_LANCZOS"
155
PetscErrorCode SVDSolve_LANCZOS(SVD svd)
156
{
1341 slepc 157
#if defined(SLEPC_MISSING_LAPACK_BDSDC)
1336 slepc 158
  PetscFunctionBegin;
1341 slepc 159
  SETERRQ(PETSC_ERR_SUP,"BDSDC - Lapack routine is unavailable.");
1336 slepc 160
#else
1278 slepc 161
  PetscErrorCode ierr;
1298 slepc 162
  SVD_LANCZOS    *lanczos = (SVD_LANCZOS *)svd->data;
1341 slepc 163
  PetscReal      *alpha,*beta,norm,*work,*Q,*PT;
164
  PetscScalar    *swork;
1511 slepc 165
  PetscBLASInt   n,info,*iwork;
1605 slepc 166
  PetscInt       i,j,k,m,nv;
1755 antodo 167
  Vec            v,u,u_1;
1293 slepc 168
  PetscTruth     conv;
1278 slepc 169
 
170
  PetscFunctionBegin;
1293 slepc 171
  /* allocate working space */
1278 slepc 172
  ierr = PetscMalloc(sizeof(PetscReal)*svd->n,&alpha);CHKERRQ(ierr);
173
  ierr = PetscMalloc(sizeof(PetscReal)*svd->n,&beta);CHKERRQ(ierr);
1341 slepc 174
  ierr = PetscMalloc(sizeof(PetscReal)*svd->n*svd->n,&Q);CHKERRQ(ierr);
175
  ierr = PetscMalloc(sizeof(PetscReal)*svd->n*svd->n,&PT);CHKERRQ(ierr);
176
  ierr = PetscMalloc(sizeof(PetscReal)*(3*svd->n+4)*svd->n,&work);CHKERRQ(ierr);
1511 slepc 177
  ierr = PetscMalloc(sizeof(PetscBLASInt)*8*svd->n,&iwork);CHKERRQ(ierr);
1605 slepc 178
#if !defined(PETSC_USE_COMPLEX)
179
  if (svd->which == SVD_SMALLEST) {
180
#endif
181
    ierr = PetscMalloc(sizeof(PetscScalar)*svd->n*svd->n,&swork);CHKERRQ(ierr);
182
#if !defined(PETSC_USE_COMPLEX)
183
  } else {
184
    ierr = PetscMalloc(sizeof(PetscScalar)*svd->n,&swork);CHKERRQ(ierr);
185
  }
186
#endif
187
 
1315 slepc 188
  ierr = VecDuplicate(svd->V[0],&v);CHKERRQ(ierr);
189
  if (lanczos->oneside) {
190
    ierr = SVDMatGetVecs(svd,PETSC_NULL,&u);CHKERRQ(ierr);
191
    ierr = SVDMatGetVecs(svd,PETSC_NULL,&u_1);CHKERRQ(ierr);
192
  }
1278 slepc 193
 
1293 slepc 194
  /* normalize start vector */
1315 slepc 195
  ierr = VecCopy(svd->vec_initial,svd->V[0]);CHKERRQ(ierr);
196
  ierr = VecNormalize(svd->V[0],&norm);CHKERRQ(ierr);
1278 slepc 197
 
1283 slepc 198
  while (svd->reason == SVD_CONVERGED_ITERATING) {
199
    svd->its++;
200
 
1293 slepc 201
    /* inner loop */
1593 slepc 202
    nv = PetscMin(svd->nconv+svd->mpd,svd->n);
1315 slepc 203
    if (lanczos->oneside) {
1755 antodo 204
      ierr = SVDOneSideLanczos(svd,alpha,beta,svd->V,v,u,u_1,svd->nconv,nv,swork);CHKERRQ(ierr);
1315 slepc 205
    } else {
1755 antodo 206
      ierr = SVDTwoSideLanczos(svd,alpha,beta,svd->V,v,svd->U,svd->nconv,nv,swork);CHKERRQ(ierr);
1278 slepc 207
    }
208
 
1293 slepc 209
    /* compute SVD of bidiagonal matrix */
1593 slepc 210
    n = nv - svd->nconv;
1341 slepc 211
    ierr = PetscMemzero(PT,sizeof(PetscReal)*n*n);CHKERRQ(ierr);
212
    ierr = PetscMemzero(Q,sizeof(PetscReal)*n*n);CHKERRQ(ierr);
1278 slepc 213
    for (i=0;i<n;i++)
214
      PT[i*n+i] = Q[i*n+i] = 1.0;
1339 slepc 215
    ierr = PetscLogEventBegin(SVD_Dense,0,0,0,0);CHKERRQ(ierr);
1536 slepc 216
    LAPACKbdsdc_("U","I",&n,alpha,beta,Q,&n,PT,&n,PETSC_NULL,PETSC_NULL,work,iwork,&info);
1339 slepc 217
    ierr = PetscLogEventEnd(SVD_Dense,0,0,0,0);CHKERRQ(ierr);
1278 slepc 218
 
1328 slepc 219
    /* compute error estimates */
1315 slepc 220
    k = 0;
1293 slepc 221
    conv = PETSC_TRUE;
1593 slepc 222
    for (i=svd->nconv;i<nv;i++) {
1285 slepc 223
      if (svd->which == SVD_SMALLEST) j = n-i+svd->nconv-1;
224
      else j = i-svd->nconv;
225
      svd->sigma[i] = alpha[j];
1315 slepc 226
      svd->errest[i] = PetscAbsScalar(Q[j*n+n-1])*beta[n-1];
227
      if (alpha[j] > svd->tol) svd->errest[i] /= alpha[j];
1293 slepc 228
      if (conv) {
1315 slepc 229
        if (svd->errest[i] < svd->tol) k++;
230
        else conv = PETSC_FALSE;
1278 slepc 231
      }
232
    }
1293 slepc 233
 
1328 slepc 234
    /* check convergence */
235
    if (svd->its >= svd->max_it) svd->reason = SVD_DIVERGED_ITS;
236
    if (svd->nconv+k >= svd->nsv) svd->reason = SVD_CONVERGED_TOL;
237
 
1605 slepc 238
    /* compute restart vector */
239
    if (svd->reason == SVD_CONVERGED_ITERATING) {
240
      if (svd->which == SVD_SMALLEST) j = n-k-1;
241
      else j = k;
242
      for (m=0;m<n;m++) swork[m] = PT[m*n+j];
1755 antodo 243
      ierr = SlepcVecMAXPBY(v,0.0,1.0,n,swork,svd->V+svd->nconv);CHKERRQ(ierr);
1315 slepc 244
    }
245
 
246
    /* compute converged singular vectors */
1605 slepc 247
#if !defined(PETSC_USE_COMPLEX)
248
    if (svd->which == SVD_SMALLEST) {
249
#endif
1315 slepc 250
    for (i=0;i<k;i++) {
251
      if (svd->which == SVD_SMALLEST) j = n-i-1;
252
      else j = i;
1605 slepc 253
      for (m=0;m<n;m++) swork[i*n+m] = PT[m*n+j];
254
    }
255
    ierr = SlepcUpdateVectors(n,svd->V+svd->nconv,0,k,swork,n,PETSC_FALSE);CHKERRQ(ierr);
256
    if (!lanczos->oneside) {
257
      for (i=0;i<k;i++) {
258
        if (svd->which == SVD_SMALLEST) j = n-i-1;
259
        else j = i;
260
        for (m=0;m<n;m++) swork[i*n+m] = Q[j*n+m];
261
      }
262
      ierr = SlepcUpdateVectors(n,svd->U+svd->nconv,0,k,swork,n,PETSC_FALSE);CHKERRQ(ierr);
263
    }
264
#if !defined(PETSC_USE_COMPLEX)
265
    } else {
266
      ierr = SlepcUpdateVectors(n,svd->V+svd->nconv,0,k,PT,n,PETSC_TRUE);CHKERRQ(ierr);
1315 slepc 267
      if (!lanczos->oneside) {
1605 slepc 268
        ierr = SlepcUpdateVectors(n,svd->U+svd->nconv,0,k,Q,n,PETSC_FALSE);CHKERRQ(ierr);
1315 slepc 269
      }
270
    }
1605 slepc 271
#endif
272
 
273
    /* copy restart vector from temporary space */
1293 slepc 274
    if (svd->reason == SVD_CONVERGED_ITERATING) {
1328 slepc 275
      ierr = VecCopy(v,svd->V[svd->nconv+k]);CHKERRQ(ierr);
1293 slepc 276
    }
1605 slepc 277
 
1315 slepc 278
    svd->nconv += k;
1593 slepc 279
    SVDMonitor(svd,svd->its,svd->nconv,svd->sigma,svd->errest,nv);
1278 slepc 280
  }
281
 
1293 slepc 282
  /* free working space */
1315 slepc 283
  ierr = VecDestroy(v);CHKERRQ(ierr);
284
  if (lanczos->oneside) {
285
    ierr = VecDestroy(u);CHKERRQ(ierr);
286
    ierr = VecDestroy(u_1);CHKERRQ(ierr);
287
  }
1278 slepc 288
  ierr = PetscFree(alpha);CHKERRQ(ierr);
289
  ierr = PetscFree(beta);CHKERRQ(ierr);
290
  ierr = PetscFree(Q);CHKERRQ(ierr);
291
  ierr = PetscFree(PT);CHKERRQ(ierr);
292
  ierr = PetscFree(work);CHKERRQ(ierr);
1341 slepc 293
  ierr = PetscFree(iwork);CHKERRQ(ierr);
294
  ierr = PetscFree(swork);CHKERRQ(ierr);
1278 slepc 295
  PetscFunctionReturn(0);
1336 slepc 296
#endif
1278 slepc 297
}
298
 
1298 slepc 299
#undef __FUNCT__  
300
#define __FUNCT__ "SVDSetFromOptions_LANCZOS"
301
PetscErrorCode SVDSetFromOptions_LANCZOS(SVD svd)
302
{
303
  PetscErrorCode ierr;
1923 jroman 304
  PetscTruth     set,val;
1298 slepc 305
  SVD_LANCZOS    *lanczos = (SVD_LANCZOS *)svd->data;
306
 
307
  PetscFunctionBegin;
1422 slepc 308
  ierr = PetscOptionsBegin(((PetscObject)svd)->comm,((PetscObject)svd)->prefix,"LANCZOS Singular Value Solver Options","SVD");CHKERRQ(ierr);
1923 jroman 309
  ierr = PetscOptionsTruth("-svd_lanczos_oneside","Lanczos one-side reorthogonalization","SVDLanczosSetOneSide",lanczos->oneside,&val,&set);CHKERRQ(ierr);
310
  if (set) {
311
    ierr = SVDLanczosSetOneSide(svd,val);CHKERRQ(ierr);
312
  }
1298 slepc 313
  ierr = PetscOptionsEnd();CHKERRQ(ierr);
314
  PetscFunctionReturn(0);
315
}
1370 slepc 316
 
1278 slepc 317
EXTERN_C_BEGIN
318
#undef __FUNCT__  
1359 slepc 319
#define __FUNCT__ "SVDLanczosSetOneSide_LANCZOS"
320
PetscErrorCode SVDLanczosSetOneSide_LANCZOS(SVD svd,PetscTruth oneside)
1298 slepc 321
{
322
  SVD_LANCZOS    *lanczos = (SVD_LANCZOS *)svd->data;
323
 
324
  PetscFunctionBegin;
1315 slepc 325
  if (lanczos->oneside != oneside) {
326
    lanczos->oneside = oneside;
327
    svd->setupcalled = 0;
328
  }
1298 slepc 329
  PetscFunctionReturn(0);
330
}
1370 slepc 331
EXTERN_C_END
1298 slepc 332
 
333
#undef __FUNCT__
1359 slepc 334
#define __FUNCT__ "SVDLanczosSetOneSide"
1393 slepc 335
/*@
336
   SVDLanczosSetOneSide - Indicate if the variant of the Lanczos method
337
   to be used is one-sided or two-sided.
338
 
339
   Collective on SVD
340
 
341
   Input Parameters:
342
+  svd     - singular value solver
343
-  oneside - boolean flag indicating if the method is one-sided or not
344
 
345
   Options Database Key:
346
.  -svd_lanczos_oneside <boolean> - Indicates the boolean flag
347
 
348
   Note:
349
   By default, a two-sided variant is selected, which is sometimes slightly
350
   more robust. However, the one-sided variant is faster because it avoids
351
   the orthogonalization associated to left singular vectors. It also saves
352
   the memory required for storing such vectors.
353
 
354
   Level: advanced
355
 
356
.seealso: SVDTRLanczosSetOneSide()
357
@*/
1359 slepc 358
PetscErrorCode SVDLanczosSetOneSide(SVD svd,PetscTruth oneside)
1298 slepc 359
{
360
  PetscErrorCode ierr, (*f)(SVD,PetscTruth);
361
 
362
  PetscFunctionBegin;
363
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
1359 slepc 364
  ierr = PetscObjectQueryFunction((PetscObject)svd,"SVDLanczosSetOneSide_C",(void (**)())&f);CHKERRQ(ierr);
1298 slepc 365
  if (f) {
366
    ierr = (*f)(svd,oneside);CHKERRQ(ierr);
367
  }
368
  PetscFunctionReturn(0);
369
}
370
 
371
#undef __FUNCT__  
1925 jroman 372
#define __FUNCT__ "SVDDestroy_LANCZOS"
373
PetscErrorCode SVDDestroy_LANCZOS(SVD svd)
374
{
375
  PetscErrorCode ierr;
376
 
377
  PetscFunctionBegin;
378
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
379
  ierr = SVDDestroy_Default(svd);CHKERRQ(ierr);
380
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDLanczosSetOneSide_C","",PETSC_NULL);CHKERRQ(ierr);
381
  PetscFunctionReturn(0);
382
}
383
 
384
#undef __FUNCT__  
1298 slepc 385
#define __FUNCT__ "SVDView_LANCZOS"
386
PetscErrorCode SVDView_LANCZOS(SVD svd,PetscViewer viewer)
387
{
388
  PetscErrorCode ierr;
389
  SVD_LANCZOS    *lanczos = (SVD_LANCZOS *)svd->data;
390
 
391
  PetscFunctionBegin;
392
  ierr = PetscViewerASCIIPrintf(viewer,"Lanczos reorthogonalization: %s\n",lanczos->oneside ? "one-side" : "two-side");CHKERRQ(ierr);
393
  PetscFunctionReturn(0);
394
}
395
 
396
EXTERN_C_BEGIN
397
#undef __FUNCT__  
1278 slepc 398
#define __FUNCT__ "SVDCreate_LANCZOS"
399
PetscErrorCode SVDCreate_LANCZOS(SVD svd)
400
{
1298 slepc 401
  PetscErrorCode ierr;
402
  SVD_LANCZOS    *lanczos;
403
 
1278 slepc 404
  PetscFunctionBegin;
1298 slepc 405
  ierr = PetscNew(SVD_LANCZOS,&lanczos);CHKERRQ(ierr);
406
  PetscLogObjectMemory(svd,sizeof(SVD_LANCZOS));
407
  svd->data                = (void *)lanczos;
408
  svd->ops->setup          = SVDSetUp_LANCZOS;
409
  svd->ops->solve          = SVDSolve_LANCZOS;
1925 jroman 410
  svd->ops->destroy        = SVDDestroy_LANCZOS;
1298 slepc 411
  svd->ops->setfromoptions = SVDSetFromOptions_LANCZOS;
412
  svd->ops->view           = SVDView_LANCZOS;
413
  lanczos->oneside         = PETSC_FALSE;
1359 slepc 414
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDLanczosSetOneSide_C","SVDLanczosSetOneSide_LANCZOS",SVDLanczosSetOneSide_LANCZOS);CHKERRQ(ierr);
1278 slepc 415
  PetscFunctionReturn(0);
416
}
417
EXTERN_C_END