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
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
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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 */
1952 jroman 195
  if (svd->nini==0) {
2027 jroman 196
    ierr = SlepcVecSetRandom(svd->V[0],svd->rand);CHKERRQ(ierr);
1952 jroman 197
  }
1315 slepc 198
  ierr = VecNormalize(svd->V[0],&norm);CHKERRQ(ierr);
1278 slepc 199
 
1283 slepc 200
  while (svd->reason == SVD_CONVERGED_ITERATING) {
201
    svd->its++;
202
 
1293 slepc 203
    /* inner loop */
1593 slepc 204
    nv = PetscMin(svd->nconv+svd->mpd,svd->n);
1315 slepc 205
    if (lanczos->oneside) {
1755 antodo 206
      ierr = SVDOneSideLanczos(svd,alpha,beta,svd->V,v,u,u_1,svd->nconv,nv,swork);CHKERRQ(ierr);
1315 slepc 207
    } else {
1755 antodo 208
      ierr = SVDTwoSideLanczos(svd,alpha,beta,svd->V,v,svd->U,svd->nconv,nv,swork);CHKERRQ(ierr);
1278 slepc 209
    }
210
 
1293 slepc 211
    /* compute SVD of bidiagonal matrix */
1593 slepc 212
    n = nv - svd->nconv;
1341 slepc 213
    ierr = PetscMemzero(PT,sizeof(PetscReal)*n*n);CHKERRQ(ierr);
214
    ierr = PetscMemzero(Q,sizeof(PetscReal)*n*n);CHKERRQ(ierr);
1278 slepc 215
    for (i=0;i<n;i++)
216
      PT[i*n+i] = Q[i*n+i] = 1.0;
1339 slepc 217
    ierr = PetscLogEventBegin(SVD_Dense,0,0,0,0);CHKERRQ(ierr);
1536 slepc 218
    LAPACKbdsdc_("U","I",&n,alpha,beta,Q,&n,PT,&n,PETSC_NULL,PETSC_NULL,work,iwork,&info);
1339 slepc 219
    ierr = PetscLogEventEnd(SVD_Dense,0,0,0,0);CHKERRQ(ierr);
1278 slepc 220
 
1328 slepc 221
    /* compute error estimates */
1315 slepc 222
    k = 0;
1293 slepc 223
    conv = PETSC_TRUE;
1593 slepc 224
    for (i=svd->nconv;i<nv;i++) {
1285 slepc 225
      if (svd->which == SVD_SMALLEST) j = n-i+svd->nconv-1;
226
      else j = i-svd->nconv;
227
      svd->sigma[i] = alpha[j];
1315 slepc 228
      svd->errest[i] = PetscAbsScalar(Q[j*n+n-1])*beta[n-1];
229
      if (alpha[j] > svd->tol) svd->errest[i] /= alpha[j];
1293 slepc 230
      if (conv) {
1315 slepc 231
        if (svd->errest[i] < svd->tol) k++;
232
        else conv = PETSC_FALSE;
1278 slepc 233
      }
234
    }
1293 slepc 235
 
1328 slepc 236
    /* check convergence */
237
    if (svd->its >= svd->max_it) svd->reason = SVD_DIVERGED_ITS;
238
    if (svd->nconv+k >= svd->nsv) svd->reason = SVD_CONVERGED_TOL;
239
 
1605 slepc 240
    /* compute restart vector */
241
    if (svd->reason == SVD_CONVERGED_ITERATING) {
242
      if (svd->which == SVD_SMALLEST) j = n-k-1;
243
      else j = k;
244
      for (m=0;m<n;m++) swork[m] = PT[m*n+j];
1755 antodo 245
      ierr = SlepcVecMAXPBY(v,0.0,1.0,n,swork,svd->V+svd->nconv);CHKERRQ(ierr);
1315 slepc 246
    }
247
 
248
    /* compute converged singular vectors */
1605 slepc 249
#if !defined(PETSC_USE_COMPLEX)
250
    if (svd->which == SVD_SMALLEST) {
251
#endif
1315 slepc 252
    for (i=0;i<k;i++) {
253
      if (svd->which == SVD_SMALLEST) j = n-i-1;
254
      else j = i;
1605 slepc 255
      for (m=0;m<n;m++) swork[i*n+m] = PT[m*n+j];
256
    }
257
    ierr = SlepcUpdateVectors(n,svd->V+svd->nconv,0,k,swork,n,PETSC_FALSE);CHKERRQ(ierr);
258
    if (!lanczos->oneside) {
259
      for (i=0;i<k;i++) {
260
        if (svd->which == SVD_SMALLEST) j = n-i-1;
261
        else j = i;
262
        for (m=0;m<n;m++) swork[i*n+m] = Q[j*n+m];
263
      }
264
      ierr = SlepcUpdateVectors(n,svd->U+svd->nconv,0,k,swork,n,PETSC_FALSE);CHKERRQ(ierr);
265
    }
266
#if !defined(PETSC_USE_COMPLEX)
267
    } else {
268
      ierr = SlepcUpdateVectors(n,svd->V+svd->nconv,0,k,PT,n,PETSC_TRUE);CHKERRQ(ierr);
1315 slepc 269
      if (!lanczos->oneside) {
1605 slepc 270
        ierr = SlepcUpdateVectors(n,svd->U+svd->nconv,0,k,Q,n,PETSC_FALSE);CHKERRQ(ierr);
1315 slepc 271
      }
272
    }
1605 slepc 273
#endif
274
 
275
    /* copy restart vector from temporary space */
1293 slepc 276
    if (svd->reason == SVD_CONVERGED_ITERATING) {
1328 slepc 277
      ierr = VecCopy(v,svd->V[svd->nconv+k]);CHKERRQ(ierr);
1293 slepc 278
    }
1605 slepc 279
 
1315 slepc 280
    svd->nconv += k;
1593 slepc 281
    SVDMonitor(svd,svd->its,svd->nconv,svd->sigma,svd->errest,nv);
1278 slepc 282
  }
283
 
1293 slepc 284
  /* free working space */
1315 slepc 285
  ierr = VecDestroy(v);CHKERRQ(ierr);
286
  if (lanczos->oneside) {
287
    ierr = VecDestroy(u);CHKERRQ(ierr);
288
    ierr = VecDestroy(u_1);CHKERRQ(ierr);
289
  }
1278 slepc 290
  ierr = PetscFree(alpha);CHKERRQ(ierr);
291
  ierr = PetscFree(beta);CHKERRQ(ierr);
292
  ierr = PetscFree(Q);CHKERRQ(ierr);
293
  ierr = PetscFree(PT);CHKERRQ(ierr);
294
  ierr = PetscFree(work);CHKERRQ(ierr);
1341 slepc 295
  ierr = PetscFree(iwork);CHKERRQ(ierr);
296
  ierr = PetscFree(swork);CHKERRQ(ierr);
1278 slepc 297
  PetscFunctionReturn(0);
1336 slepc 298
#endif
1278 slepc 299
}
300
 
1298 slepc 301
#undef __FUNCT__  
302
#define __FUNCT__ "SVDSetFromOptions_LANCZOS"
303
PetscErrorCode SVDSetFromOptions_LANCZOS(SVD svd)
304
{
305
  PetscErrorCode ierr;
1923 jroman 306
  PetscTruth     set,val;
1298 slepc 307
  SVD_LANCZOS    *lanczos = (SVD_LANCZOS *)svd->data;
308
 
309
  PetscFunctionBegin;
1422 slepc 310
  ierr = PetscOptionsBegin(((PetscObject)svd)->comm,((PetscObject)svd)->prefix,"LANCZOS Singular Value Solver Options","SVD");CHKERRQ(ierr);
1923 jroman 311
  ierr = PetscOptionsTruth("-svd_lanczos_oneside","Lanczos one-side reorthogonalization","SVDLanczosSetOneSide",lanczos->oneside,&val,&set);CHKERRQ(ierr);
312
  if (set) {
313
    ierr = SVDLanczosSetOneSide(svd,val);CHKERRQ(ierr);
314
  }
1298 slepc 315
  ierr = PetscOptionsEnd();CHKERRQ(ierr);
316
  PetscFunctionReturn(0);
317
}
1370 slepc 318
 
1278 slepc 319
EXTERN_C_BEGIN
320
#undef __FUNCT__  
1359 slepc 321
#define __FUNCT__ "SVDLanczosSetOneSide_LANCZOS"
322
PetscErrorCode SVDLanczosSetOneSide_LANCZOS(SVD svd,PetscTruth oneside)
1298 slepc 323
{
324
  SVD_LANCZOS    *lanczos = (SVD_LANCZOS *)svd->data;
325
 
326
  PetscFunctionBegin;
1315 slepc 327
  if (lanczos->oneside != oneside) {
328
    lanczos->oneside = oneside;
329
    svd->setupcalled = 0;
330
  }
1298 slepc 331
  PetscFunctionReturn(0);
332
}
1370 slepc 333
EXTERN_C_END
1298 slepc 334
 
335
#undef __FUNCT__
1359 slepc 336
#define __FUNCT__ "SVDLanczosSetOneSide"
1393 slepc 337
/*@
338
   SVDLanczosSetOneSide - Indicate if the variant of the Lanczos method
339
   to be used is one-sided or two-sided.
340
 
341
   Collective on SVD
342
 
343
   Input Parameters:
344
+  svd     - singular value solver
345
-  oneside - boolean flag indicating if the method is one-sided or not
346
 
347
   Options Database Key:
348
.  -svd_lanczos_oneside <boolean> - Indicates the boolean flag
349
 
350
   Note:
351
   By default, a two-sided variant is selected, which is sometimes slightly
352
   more robust. However, the one-sided variant is faster because it avoids
353
   the orthogonalization associated to left singular vectors. It also saves
354
   the memory required for storing such vectors.
355
 
356
   Level: advanced
357
 
358
.seealso: SVDTRLanczosSetOneSide()
359
@*/
1359 slepc 360
PetscErrorCode SVDLanczosSetOneSide(SVD svd,PetscTruth oneside)
1298 slepc 361
{
362
  PetscErrorCode ierr, (*f)(SVD,PetscTruth);
363
 
364
  PetscFunctionBegin;
365
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
1359 slepc 366
  ierr = PetscObjectQueryFunction((PetscObject)svd,"SVDLanczosSetOneSide_C",(void (**)())&f);CHKERRQ(ierr);
1298 slepc 367
  if (f) {
368
    ierr = (*f)(svd,oneside);CHKERRQ(ierr);
369
  }
370
  PetscFunctionReturn(0);
371
}
372
 
2079 eromero 373
#undef __FUNCT__
374
#define __FUNCT__ "SVDLanczosGetOneSide"
375
/*@
376
   SVDLanczosGetOneSide - Gets if the variant of the Lanczos method
377
   to be used is one-sided or two-sided.
378
 
379
   Collective on SVD
380
 
381
   Input Parameters:
382
.  svd     - singular value solver
383
 
384
   Output Parameters:
385
.  oneside - boolean flag indicating if the method is one-sided or not
386
 
387
   Level: advanced
388
 
389
.seealso: SVDLanczosSetOneSide()
390
@*/
391
PetscErrorCode SVDLanczosGetOneSide(SVD svd,PetscTruth *oneside)
392
{
393
  PetscErrorCode ierr, (*f)(SVD,PetscTruth*);
394
 
395
  PetscFunctionBegin;
396
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
397
  ierr = PetscObjectQueryFunction((PetscObject)svd,"SVDLanczosGetOneSide_C",(void (**)())&f);CHKERRQ(ierr);
398
  if (f) {
399
    ierr = (*f)(svd,oneside);CHKERRQ(ierr);
400
  }
401
  PetscFunctionReturn(0);
402
}
403
 
404
EXTERN_C_BEGIN
1298 slepc 405
#undef __FUNCT__  
2079 eromero 406
#define __FUNCT__ "SVDLanczosGetOneSide_LANCZOS"
407
PetscErrorCode SVDLanczosGetOneSide_LANCZOS(SVD svd,PetscTruth *oneside)
408
{
409
  SVD_LANCZOS    *lanczos = (SVD_LANCZOS *)svd->data;
410
 
411
  PetscFunctionBegin;
412
  PetscValidPointer(oneside,2);
413
  *oneside = lanczos->oneside;
414
  PetscFunctionReturn(0);
415
}
416
EXTERN_C_END
417
 
418
#undef __FUNCT__  
1925 jroman 419
#define __FUNCT__ "SVDDestroy_LANCZOS"
420
PetscErrorCode SVDDestroy_LANCZOS(SVD svd)
421
{
422
  PetscErrorCode ierr;
423
 
424
  PetscFunctionBegin;
425
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
426
  ierr = SVDDestroy_Default(svd);CHKERRQ(ierr);
427
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDLanczosSetOneSide_C","",PETSC_NULL);CHKERRQ(ierr);
2079 eromero 428
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDLanczosGetOneSide_C","",PETSC_NULL);CHKERRQ(ierr);
1925 jroman 429
  PetscFunctionReturn(0);
430
}
431
 
432
#undef __FUNCT__  
1298 slepc 433
#define __FUNCT__ "SVDView_LANCZOS"
434
PetscErrorCode SVDView_LANCZOS(SVD svd,PetscViewer viewer)
435
{
436
  PetscErrorCode ierr;
437
  SVD_LANCZOS    *lanczos = (SVD_LANCZOS *)svd->data;
438
 
439
  PetscFunctionBegin;
440
  ierr = PetscViewerASCIIPrintf(viewer,"Lanczos reorthogonalization: %s\n",lanczos->oneside ? "one-side" : "two-side");CHKERRQ(ierr);
441
  PetscFunctionReturn(0);
442
}
443
 
444
EXTERN_C_BEGIN
445
#undef __FUNCT__  
1278 slepc 446
#define __FUNCT__ "SVDCreate_LANCZOS"
447
PetscErrorCode SVDCreate_LANCZOS(SVD svd)
448
{
1298 slepc 449
  PetscErrorCode ierr;
450
  SVD_LANCZOS    *lanczos;
451
 
1278 slepc 452
  PetscFunctionBegin;
1298 slepc 453
  ierr = PetscNew(SVD_LANCZOS,&lanczos);CHKERRQ(ierr);
454
  PetscLogObjectMemory(svd,sizeof(SVD_LANCZOS));
455
  svd->data                = (void *)lanczos;
456
  svd->ops->setup          = SVDSetUp_LANCZOS;
457
  svd->ops->solve          = SVDSolve_LANCZOS;
1925 jroman 458
  svd->ops->destroy        = SVDDestroy_LANCZOS;
1298 slepc 459
  svd->ops->setfromoptions = SVDSetFromOptions_LANCZOS;
460
  svd->ops->view           = SVDView_LANCZOS;
461
  lanczos->oneside         = PETSC_FALSE;
1359 slepc 462
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDLanczosSetOneSide_C","SVDLanczosSetOneSide_LANCZOS",SVDLanczosSetOneSide_LANCZOS);CHKERRQ(ierr);
2079 eromero 463
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDLanczosGetOneSide_C","SVDLanczosGetOneSide_LANCZOS",SVDLanczosGetOneSide_LANCZOS);CHKERRQ(ierr);
1278 slepc 464
  PetscFunctionReturn(0);
465
}
466
EXTERN_C_END