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
1324 slepc 1
/*                      
2
 
3
   SLEPc singular value solver: "cyclic"
4
 
1325 slepc 5
   Method: Uses a Hermitian eigensolver for H(A) = [ 0  A ; A^T 0 ]
1324 slepc 6
 
1397 slepc 7
   Last update: Jun 2007
1324 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
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1324 slepc 27
*/
1376 slepc 28
 
1521 slepc 29
#include "private/svdimpl.h"                /*I "slepcsvd.h" I*/
2054 eromero 30
#include "private/epsimpl.h"                /*I "slepceps.h" I*/
1324 slepc 31
#include "slepceps.h"
32
 
33
typedef struct {
1370 slepc 34
  PetscTruth explicitmatrix;
1324 slepc 35
  EPS        eps;
2024 eromero 36
  PetscTruth setfromoptionscalled;
1324 slepc 37
  Mat        mat;
38
  Vec        x1,x2,y1,y2;
39
} SVD_CYCLIC;
40
 
41
#undef __FUNCT__  
42
#define __FUNCT__ "ShellMatMult_CYCLIC"
43
PetscErrorCode ShellMatMult_CYCLIC(Mat B,Vec x, Vec y)
44
{
45
  PetscErrorCode ierr;
46
  SVD            svd;
47
  SVD_CYCLIC     *cyclic;
48
  PetscScalar    *px,*py;
49
  PetscInt       m;
50
 
51
  PetscFunctionBegin;
52
  ierr = MatShellGetContext(B,(void**)&svd);CHKERRQ(ierr);
53
  cyclic = (SVD_CYCLIC *)svd->data;
54
  ierr = SVDMatGetLocalSize(svd,&m,PETSC_NULL);CHKERRQ(ierr);
55
  ierr = VecGetArray(x,&px);CHKERRQ(ierr);
56
  ierr = VecGetArray(y,&py);CHKERRQ(ierr);
57
  ierr = VecPlaceArray(cyclic->x1,px);CHKERRQ(ierr);
58
  ierr = VecPlaceArray(cyclic->x2,px+m);CHKERRQ(ierr);
59
  ierr = VecPlaceArray(cyclic->y1,py);CHKERRQ(ierr);
60
  ierr = VecPlaceArray(cyclic->y2,py+m);CHKERRQ(ierr);
61
  ierr = SVDMatMult(svd,PETSC_FALSE,cyclic->x2,cyclic->y1);CHKERRQ(ierr);
62
  ierr = SVDMatMult(svd,PETSC_TRUE,cyclic->x1,cyclic->y2);CHKERRQ(ierr);        
63
  ierr = VecResetArray(cyclic->x1);CHKERRQ(ierr);
64
  ierr = VecResetArray(cyclic->x2);CHKERRQ(ierr);
65
  ierr = VecResetArray(cyclic->y1);CHKERRQ(ierr);
66
  ierr = VecResetArray(cyclic->y2);CHKERRQ(ierr);
67
  ierr = VecRestoreArray(x,&px);CHKERRQ(ierr);
68
  ierr = VecRestoreArray(y,&py);CHKERRQ(ierr);
69
  PetscFunctionReturn(0);
70
}
71
 
72
#undef __FUNCT__  
73
#define __FUNCT__ "ShellMatGetDiagonal_CYCLIC"
74
PetscErrorCode ShellMatGetDiagonal_CYCLIC(Mat B,Vec diag)
75
{
76
  PetscErrorCode ierr;
77
 
78
  PetscFunctionBegin;
79
  ierr = VecSet(diag,0.0);CHKERRQ(ierr);
80
  PetscFunctionReturn(0);
81
}
82
 
83
 
84
#undef __FUNCT__  
85
#define __FUNCT__ "SVDSetUp_CYCLIC"
86
PetscErrorCode SVDSetUp_CYCLIC(SVD svd)
87
{
88
  PetscErrorCode    ierr;
89
  SVD_CYCLIC        *cyclic = (SVD_CYCLIC *)svd->data;
2079 eromero 90
  PetscInt          M,N,m,n,i,j,start,end,ncols,*pos,nloc,isl;
1324 slepc 91
  const PetscInt    *cols;
92
  const PetscScalar *vals;
1605 slepc 93
  PetscScalar       *pU;
2055 eromero 94
  PetscTruth        trackall;
2079 eromero 95
  Vec               v;
96
  PetscScalar       *isa,*va;
1324 slepc 97
 
98
  PetscFunctionBegin;
99
 
100
  if (cyclic->mat) {
101
    ierr = MatDestroy(cyclic->mat);CHKERRQ(ierr);
102
  }
103
  if (cyclic->x1) {
104
    ierr = VecDestroy(cyclic->x1);CHKERRQ(ierr);
105
    ierr = VecDestroy(cyclic->x2);CHKERRQ(ierr);
106
    ierr = VecDestroy(cyclic->y1);CHKERRQ(ierr);
107
    ierr = VecDestroy(cyclic->y2);CHKERRQ(ierr);
108
  }
109
 
110
  ierr = SVDMatGetSize(svd,&M,&N);CHKERRQ(ierr);
111
  ierr = SVDMatGetLocalSize(svd,&m,&n);CHKERRQ(ierr);
1370 slepc 112
  if (cyclic->explicitmatrix) {
1324 slepc 113
    cyclic->x1 = cyclic->x2 = cyclic->y1 = cyclic->y2 = PETSC_NULL;
1422 slepc 114
    ierr = MatCreate(((PetscObject)svd)->comm,&cyclic->mat);CHKERRQ(ierr);
1324 slepc 115
    ierr = MatSetSizes(cyclic->mat,m+n,m+n,M+N,M+N);CHKERRQ(ierr);
116
    ierr = MatSetFromOptions(cyclic->mat);CHKERRQ(ierr);
117
    if (svd->AT) {
118
      ierr = MatGetOwnershipRange(svd->AT,&start,&end);CHKERRQ(ierr);
119
      for (i=start;i<end;i++) {
120
        ierr = MatGetRow(svd->AT,i,&ncols,&cols,&vals);CHKERRQ(ierr);
121
        j = i + M;
122
        ierr = MatSetValues(cyclic->mat,1,&j,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr);
123
        ierr = MatSetValues(cyclic->mat,ncols,cols,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr);
124
        ierr = MatRestoreRow(svd->AT,i,&ncols,&cols,&vals);CHKERRQ(ierr);
125
      }
126
    } else {
127
      ierr = PetscMalloc(sizeof(PetscInt)*n,&pos);CHKERRQ(ierr);
128
      ierr = MatGetOwnershipRange(svd->A,&start,&end);CHKERRQ(ierr);
129
      for (i=start;i<end;i++) {
130
        ierr = MatGetRow(svd->A,i,&ncols,&cols,&vals);CHKERRQ(ierr);
131
        for (j=0;j<ncols;j++)
132
          pos[j] = cols[j] + M;
133
        ierr = MatSetValues(cyclic->mat,1,&i,ncols,pos,vals,INSERT_VALUES);CHKERRQ(ierr);
134
        ierr = MatSetValues(cyclic->mat,ncols,pos,1,&i,vals,INSERT_VALUES);CHKERRQ(ierr);
135
        ierr = MatRestoreRow(svd->A,i,&ncols,&cols,&vals);CHKERRQ(ierr);
136
      }
137
      ierr = PetscFree(pos);CHKERRQ(ierr);
138
    }
139
    ierr = MatAssemblyBegin(cyclic->mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
140
    ierr = MatAssemblyEnd(cyclic->mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);
141
  } else {
1422 slepc 142
    ierr = VecCreateMPIWithArray(((PetscObject)svd)->comm,m,M,PETSC_NULL,&cyclic->x1);CHKERRQ(ierr);
143
    ierr = VecCreateMPIWithArray(((PetscObject)svd)->comm,n,N,PETSC_NULL,&cyclic->x2);CHKERRQ(ierr);
144
    ierr = VecCreateMPIWithArray(((PetscObject)svd)->comm,m,M,PETSC_NULL,&cyclic->y1);CHKERRQ(ierr);
145
    ierr = VecCreateMPIWithArray(((PetscObject)svd)->comm,n,N,PETSC_NULL,&cyclic->y2);CHKERRQ(ierr);
146
    ierr = MatCreateShell(((PetscObject)svd)->comm,m+n,m+n,M+N,M+N,svd,&cyclic->mat);CHKERRQ(ierr);
1324 slepc 147
    ierr = MatShellSetOperation(cyclic->mat,MATOP_MULT,(void(*)(void))ShellMatMult_CYCLIC);CHKERRQ(ierr);  
148
    ierr = MatShellSetOperation(cyclic->mat,MATOP_GET_DIAGONAL,(void(*)(void))ShellMatGetDiagonal_CYCLIC);CHKERRQ(ierr);  
149
  }
150
 
151
  ierr = EPSSetOperators(cyclic->eps,cyclic->mat,PETSC_NULL);CHKERRQ(ierr);
152
  ierr = EPSSetProblemType(cyclic->eps,EPS_HEP);CHKERRQ(ierr);
1406 slepc 153
  ierr = EPSSetWhichEigenpairs(cyclic->eps,svd->which == SVD_LARGEST ? EPS_LARGEST_REAL : EPS_SMALLEST_MAGNITUDE);CHKERRQ(ierr);
1575 slepc 154
  ierr = EPSSetDimensions(cyclic->eps,svd->nsv,svd->ncv,svd->mpd);CHKERRQ(ierr);
1324 slepc 155
  ierr = EPSSetTolerances(cyclic->eps,svd->tol,svd->max_it);CHKERRQ(ierr);
2055 eromero 156
  /* Transfer the trackall option from svd to eps */
157
  ierr = SVDGetTrackAll(svd,&trackall);CHKERRQ(ierr);
158
  ierr = EPSSetTrackAll(cyclic->eps,trackall);CHKERRQ(ierr);
2079 eromero 159
  /* Transfer the initial subspace from svd to eps */
160
  if (svd->nini < 0) {
161
    for (i=0; i<-svd->nini; i++) {
162
      ierr = MatGetVecs(cyclic->mat,&v,PETSC_NULL);CHKERRQ(ierr);
163
      ierr = VecGetArray(v,&va);CHKERRQ(ierr);
164
      ierr = VecGetArray(svd->IS[i],&isa);CHKERRQ(ierr);
165
      ierr = VecGetSize(svd->IS[i],&isl);CHKERRQ(ierr);
166
      if (isl == m) {
167
        ierr = PetscMemcpy(va,isa,sizeof(PetscScalar)*m);CHKERRQ(ierr);
168
        ierr = PetscMemzero(&va[m],sizeof(PetscScalar)*n);CHKERRQ(ierr);
169
      } else if (isl == n) {
170
        ierr = PetscMemzero(va,sizeof(PetscScalar)*m);CHKERRQ(ierr);
171
        ierr = PetscMemcpy(&va[m],isa,sizeof(PetscScalar)*n);CHKERRQ(ierr);
172
      } else {
2214 jroman 173
        SETERRQ(((PetscObject)svd)->comm,PETSC_ERR_SUP,"Size of the initial subspace vectors should match to some dimension of A");
2079 eromero 174
      }
175
      ierr = VecRestoreArray(v,&va);CHKERRQ(ierr);
176
      ierr = VecRestoreArray(svd->IS[i],&isa);CHKERRQ(ierr);
177
      ierr = VecDestroy(svd->IS[i]);CHKERRQ(ierr);
178
      svd->IS[i] = v;
179
    }
180
    ierr = EPSSetInitialSpace(cyclic->eps,-svd->nini,svd->IS);CHKERRQ(ierr);
181
    for (i=0; i<-svd->nini; i++) {
182
      ierr = VecDestroy(svd->IS[i]);CHKERRQ(ierr);
183
    }
184
    ierr = PetscFree(svd->IS);CHKERRQ(ierr);
185
    svd->IS = PETSC_NULL;
186
    svd->nini = 0;
187
  }
2177 jroman 188
  if (cyclic->setfromoptionscalled) {
2024 eromero 189
    ierr = EPSSetFromOptions(cyclic->eps);CHKERRQ(ierr);
190
    cyclic->setfromoptionscalled = PETSC_FALSE;
191
  }
1324 slepc 192
  ierr = EPSSetUp(cyclic->eps);CHKERRQ(ierr);
1575 slepc 193
  ierr = EPSGetDimensions(cyclic->eps,PETSC_NULL,&svd->ncv,&svd->mpd);CHKERRQ(ierr);
1324 slepc 194
  ierr = EPSGetTolerances(cyclic->eps,&svd->tol,&svd->max_it);CHKERRQ(ierr);
195
 
1605 slepc 196
  if (svd->ncv != svd->n) {
197
    if (svd->U) {  
198
      ierr = VecGetArray(svd->U[0],&pU);CHKERRQ(ierr);
199
      for (i=0;i<svd->n;i++) { ierr = VecDestroy(svd->U[i]); CHKERRQ(ierr); }
200
      ierr = PetscFree(pU);CHKERRQ(ierr);
201
      ierr = PetscFree(svd->U);CHKERRQ(ierr);
202
    }
203
    ierr = PetscMalloc(sizeof(Vec)*svd->ncv,&svd->U);CHKERRQ(ierr);
204
    ierr = SVDMatGetLocalSize(svd,&nloc,PETSC_NULL);CHKERRQ(ierr);
205
    ierr = PetscMalloc(svd->ncv*nloc*sizeof(PetscScalar),&pU);CHKERRQ(ierr);
206
    for (i=0;i<svd->ncv;i++) {
207
      ierr = VecCreateMPIWithArray(((PetscObject)svd)->comm,nloc,PETSC_DECIDE,pU+i*nloc,&svd->U[i]);CHKERRQ(ierr);
208
    }
1324 slepc 209
  }
210
 
211
  PetscFunctionReturn(0);
212
}
213
 
214
#undef __FUNCT__  
215
#define __FUNCT__ "SVDSolve_CYCLIC"
216
PetscErrorCode SVDSolve_CYCLIC(SVD svd)
217
{
218
  PetscErrorCode ierr;
219
  SVD_CYCLIC     *cyclic = (SVD_CYCLIC *)svd->data;
1504 slepc 220
  PetscInt       i,j,M,m,idx,start,end;
1324 slepc 221
  PetscScalar    sigma,*px;
222
  Vec            x;
223
  IS             isU,isV;
224
  VecScatter     vsU,vsV;
225
 
226
  PetscFunctionBegin;
227
  ierr = EPSSolve(cyclic->eps);CHKERRQ(ierr);
228
  ierr = EPSGetConverged(cyclic->eps,&svd->nconv);CHKERRQ(ierr);
229
  ierr = EPSGetIterationNumber(cyclic->eps,&svd->its);CHKERRQ(ierr);
230
  ierr = EPSGetConvergedReason(cyclic->eps,(EPSConvergedReason*)&svd->reason);CHKERRQ(ierr);
231
 
232
  ierr = MatGetVecs(cyclic->mat,&x,PETSC_NULL);CHKERRQ(ierr);
1370 slepc 233
  if (cyclic->explicitmatrix) {
1352 slepc 234
    ierr = EPSGetOperationCounters(cyclic->eps,&svd->matvecs,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
1324 slepc 235
    ierr = SVDMatGetSize(svd,&M,PETSC_NULL);CHKERRQ(ierr);
236
    ierr = VecGetOwnershipRange(svd->U[0],&start,&end);CHKERRQ(ierr);
1422 slepc 237
    ierr = ISCreateBlock(((PetscObject)svd)->comm,end-start,1,&start,&isU);CHKERRQ(ierr);      
1324 slepc 238
    ierr = VecScatterCreate(x,isU,svd->U[0],PETSC_NULL,&vsU);CHKERRQ(ierr);
239
 
240
    ierr = VecGetOwnershipRange(svd->V[0],&start,&end);CHKERRQ(ierr);
241
    idx = start + M;
1422 slepc 242
    ierr = ISCreateBlock(((PetscObject)svd)->comm,end-start,1,&idx,&isV);CHKERRQ(ierr);      
1324 slepc 243
    ierr = VecScatterCreate(x,isV,svd->V[0],PETSC_NULL,&vsV);CHKERRQ(ierr);
244
 
245
    for (i=0,j=0;i<svd->nconv;i++) {
246
      ierr = EPSGetEigenpair(cyclic->eps,i,&sigma,PETSC_NULL,x,PETSC_NULL);CHKERRQ(ierr);
247
      if (PetscRealPart(sigma) > 0.0) {
248
        svd->sigma[j] = PetscRealPart(sigma);
1356 slepc 249
        ierr = VecScatterBegin(vsU,x,svd->U[j],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
250
        ierr = VecScatterBegin(vsV,x,svd->V[j],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
251
        ierr = VecScatterEnd(vsU,x,svd->U[j],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
252
        ierr = VecScatterEnd(vsV,x,svd->V[j],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1324 slepc 253
        ierr = VecScale(svd->U[j],1.0/sqrt(2.0));CHKERRQ(ierr);
254
        ierr = VecScale(svd->V[j],1.0/sqrt(2.0));CHKERRQ(ierr);          
255
        j++;
256
      }
257
    }
258
 
259
    ierr = ISDestroy(isU);CHKERRQ(ierr);
260
    ierr = VecScatterDestroy(vsU);CHKERRQ(ierr);
261
    ierr = ISDestroy(isV);CHKERRQ(ierr);
262
    ierr = VecScatterDestroy(vsV);CHKERRQ(ierr);
263
  } else {
264
    ierr = SVDMatGetLocalSize(svd,&m,PETSC_NULL);CHKERRQ(ierr);
265
    for (i=0,j=0;i<svd->nconv;i++) {
266
      ierr = EPSGetEigenpair(cyclic->eps,i,&sigma,PETSC_NULL,x,PETSC_NULL);CHKERRQ(ierr);
267
      if (PetscRealPart(sigma) > 0.0) {
268
        svd->sigma[j] = PetscRealPart(sigma);
269
        ierr = VecGetArray(x,&px);CHKERRQ(ierr);
270
        ierr = VecPlaceArray(cyclic->x1,px);CHKERRQ(ierr);
271
        ierr = VecPlaceArray(cyclic->x2,px+m);CHKERRQ(ierr);
272
 
273
        ierr = VecCopy(cyclic->x1,svd->U[j]);CHKERRQ(ierr);
274
        ierr = VecScale(svd->U[j],1.0/sqrt(2.0));CHKERRQ(ierr);
275
 
276
        ierr = VecCopy(cyclic->x2,svd->V[j]);CHKERRQ(ierr);
277
        ierr = VecScale(svd->V[j],1.0/sqrt(2.0));CHKERRQ(ierr);  
278
 
279
        ierr = VecResetArray(cyclic->x1);CHKERRQ(ierr);
280
        ierr = VecResetArray(cyclic->x2);CHKERRQ(ierr);
281
        ierr = VecRestoreArray(x,&px);CHKERRQ(ierr);
282
        j++;
283
      }
284
    }
285
  }
286
  svd->nconv = j;
287
 
288
  ierr = VecDestroy(x);CHKERRQ(ierr);
289
  PetscFunctionReturn(0);
290
}
291
 
292
#undef __FUNCT__  
293
#define __FUNCT__ "SVDMonitor_CYCLIC"
1504 slepc 294
PetscErrorCode SVDMonitor_CYCLIC(EPS eps,PetscInt its,PetscInt nconv,PetscScalar *eigr,PetscScalar *eigi,PetscReal *errest,PetscInt nest,void *ctx)
1324 slepc 295
{
2054 eromero 296
  PetscInt       i,j;
297
  SVD            svd = (SVD)ctx;
298
  PetscScalar    er,ei;
299
  PetscErrorCode ierr;
1324 slepc 300
 
301
  PetscFunctionBegin;
302
  nconv = 0;
303
  for (i=0,j=0;i<nest;i++) {
2054 eromero 304
    er = eigr[i]; ei = eigi[i];
305
    ierr = STBackTransform(eps->OP, 1, &er, &ei); CHKERRQ(ierr);
306
    if (PetscRealPart(er) > 0.0) {
307
      svd->sigma[j] = PetscRealPart(er);
1324 slepc 308
      svd->errest[j] = errest[i];
309
      if (errest[i] < svd->tol) nconv++;
310
      j++;
311
    }
312
  }
313
  nest = j;
314
  SVDMonitor(svd,its,nconv,svd->sigma,svd->errest,nest);
315
  PetscFunctionReturn(0);
316
}
317
 
318
#undef __FUNCT__  
319
#define __FUNCT__ "SVDSetFromOptions_CYCLIC"
320
PetscErrorCode SVDSetFromOptions_CYCLIC(SVD svd)
321
{
322
  PetscErrorCode ierr;
1923 jroman 323
  PetscTruth     set,val;
1324 slepc 324
  SVD_CYCLIC     *cyclic = (SVD_CYCLIC *)svd->data;
325
  ST             st;
326
 
327
  PetscFunctionBegin;
1422 slepc 328
  ierr = PetscOptionsBegin(((PetscObject)svd)->comm,((PetscObject)svd)->prefix,"CYCLIC Singular Value Solver Options","SVD");CHKERRQ(ierr);
1923 jroman 329
  ierr = PetscOptionsTruth("-svd_cyclic_explicitmatrix","Use cyclic explicit matrix","SVDCyclicSetExplicitMatrix",cyclic->explicitmatrix,&val,&set);CHKERRQ(ierr);
330
  if (set) {
331
    ierr = SVDCyclicSetExplicitMatrix(svd,val);CHKERRQ(ierr);
332
  }
1370 slepc 333
  if (cyclic->explicitmatrix) {
1324 slepc 334
    /* don't build the transpose */
335
    if (svd->transmode == PETSC_DECIDE)
336
      svd->transmode = SVD_TRANSPOSE_IMPLICIT;
337
  } else {
338
    /* use as default an ST with shell matrix and Jacobi */
339
    ierr = EPSGetST(cyclic->eps,&st);CHKERRQ(ierr);
1940 jroman 340
    ierr = STSetMatMode(st,ST_MATMODE_SHELL);CHKERRQ(ierr);
1324 slepc 341
  }
342
  ierr = PetscOptionsEnd();CHKERRQ(ierr);
2024 eromero 343
  cyclic->setfromoptionscalled = PETSC_TRUE;
1324 slepc 344
  PetscFunctionReturn(0);
345
}
346
 
347
EXTERN_C_BEGIN
348
#undef __FUNCT__  
349
#define __FUNCT__ "SVDCyclicSetExplicitMatrix_CYCLIC"
1370 slepc 350
PetscErrorCode SVDCyclicSetExplicitMatrix_CYCLIC(SVD svd,PetscTruth explicitmatrix)
1324 slepc 351
{
352
  SVD_CYCLIC *cyclic = (SVD_CYCLIC *)svd->data;
353
 
354
  PetscFunctionBegin;
1370 slepc 355
  cyclic->explicitmatrix = explicitmatrix;
1324 slepc 356
  PetscFunctionReturn(0);
357
}
1370 slepc 358
EXTERN_C_END
1324 slepc 359
 
360
#undef __FUNCT__
361
#define __FUNCT__ "SVDCyclicSetExplicitMatrix"
362
/*@
1325 slepc 363
   SVDCyclicSetExplicitMatrix - Indicate if the eigensolver operator
1324 slepc 364
   H(A) = [ 0  A ; A^T 0 ] must be computed explicitly.
365
 
366
   Collective on SVD
367
 
368
   Input Parameters:
369
+  svd      - singular value solver
1325 slepc 370
-  explicit - boolean flag indicating if H(A) is built explicitly
1324 slepc 371
 
372
   Options Database Key:
373
.  -svd_cyclic_explicitmatrix <boolean> - Indicates the boolean flag
374
 
1325 slepc 375
   Level: advanced
1324 slepc 376
 
377
.seealso: SVDCyclicGetExplicitMatrix()
378
@*/
1370 slepc 379
PetscErrorCode SVDCyclicSetExplicitMatrix(SVD svd,PetscTruth explicitmatrix)
1324 slepc 380
{
381
  PetscErrorCode ierr, (*f)(SVD,PetscTruth);
382
 
383
  PetscFunctionBegin;
2213 jroman 384
  PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
1324 slepc 385
  ierr = PetscObjectQueryFunction((PetscObject)svd,"SVDCyclicSetExplicitMatrix_C",(void (**)())&f);CHKERRQ(ierr);
386
  if (f) {
1370 slepc 387
    ierr = (*f)(svd,explicitmatrix);CHKERRQ(ierr);
1324 slepc 388
  }
389
  PetscFunctionReturn(0);
390
}
391
 
392
EXTERN_C_BEGIN
393
#undef __FUNCT__  
394
#define __FUNCT__ "SVDCyclicGetExplicitMatrix_CYCLIC"
1370 slepc 395
PetscErrorCode SVDCyclicGetExplicitMatrix_CYCLIC(SVD svd,PetscTruth *explicitmatrix)
1324 slepc 396
{
397
  SVD_CYCLIC *cyclic = (SVD_CYCLIC *)svd->data;
398
 
399
  PetscFunctionBegin;
1370 slepc 400
  PetscValidPointer(explicitmatrix,2);
401
  *explicitmatrix = cyclic->explicitmatrix;
1324 slepc 402
  PetscFunctionReturn(0);
403
}
1370 slepc 404
EXTERN_C_END
1324 slepc 405
 
406
#undef __FUNCT__
407
#define __FUNCT__ "SVDCyclicGetExplicitMatrix"
2061 eromero 408
/*@
1325 slepc 409
   SVDCyclicGetExplicitMatrix - Returns the flag indicating if H(A) is built explicitly
410
 
1324 slepc 411
   Not collective
412
 
413
   Input Parameter:
414
.  svd  - singular value solver
415
 
416
   Output Parameter:
417
.  explicit - the mode flag
418
 
1325 slepc 419
   Level: advanced
1324 slepc 420
 
421
.seealso: SVDCyclicSetExplicitMatrix()
422
@*/
1370 slepc 423
PetscErrorCode SVDCyclicGetExplicitMatrix(SVD svd,PetscTruth *explicitmatrix)
1324 slepc 424
{
425
  PetscErrorCode ierr, (*f)(SVD,PetscTruth*);
426
 
427
  PetscFunctionBegin;
2213 jroman 428
  PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
1324 slepc 429
  ierr = PetscObjectQueryFunction((PetscObject)svd,"SVDCyclicGetExplicitMatrix_C",(void (**)())&f);CHKERRQ(ierr);
430
  if (f) {
1370 slepc 431
    ierr = (*f)(svd,explicitmatrix);CHKERRQ(ierr);
1324 slepc 432
  }
433
  PetscFunctionReturn(0);
434
}
435
 
436
EXTERN_C_BEGIN
437
#undef __FUNCT__  
438
#define __FUNCT__ "SVDCyclicSetEPS_CYCLIC"
439
PetscErrorCode SVDCyclicSetEPS_CYCLIC(SVD svd,EPS eps)
440
{
441
  PetscErrorCode  ierr;
442
  SVD_CYCLIC *cyclic = (SVD_CYCLIC *)svd->data;
443
 
444
  PetscFunctionBegin;
2213 jroman 445
  PetscValidHeaderSpecific(eps,EPS_CLASSID,2);
1324 slepc 446
  PetscCheckSameComm(svd,1,eps,2);
447
  ierr = PetscObjectReference((PetscObject)eps);CHKERRQ(ierr);
448
  ierr = EPSDestroy(cyclic->eps);CHKERRQ(ierr);  
449
  cyclic->eps = eps;
450
  svd->setupcalled = 0;
451
  PetscFunctionReturn(0);
452
}
453
EXTERN_C_END
454
 
455
#undef __FUNCT__  
456
#define __FUNCT__ "SVDCyclicSetEPS"
457
/*@
1325 slepc 458
   SVDCyclicSetEPS - Associate an eigensolver object (EPS) to the
1324 slepc 459
   singular value solver.
460
 
461
   Collective on SVD
462
 
463
   Input Parameters:
464
+  svd - singular value solver
465
-  eps - the eigensolver object
466
 
467
   Level: advanced
468
 
469
.seealso: SVDCyclicGetEPS()
470
@*/
471
PetscErrorCode SVDCyclicSetEPS(SVD svd,EPS eps)
472
{
473
  PetscErrorCode ierr, (*f)(SVD,EPS eps);
474
 
475
  PetscFunctionBegin;
2213 jroman 476
  PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
1324 slepc 477
  ierr = PetscObjectQueryFunction((PetscObject)svd,"SVDCyclicSetEPS_C",(void (**)())&f);CHKERRQ(ierr);
478
  if (f) {
479
    ierr = (*f)(svd,eps);CHKERRQ(ierr);
480
  }
481
  PetscFunctionReturn(0);
482
}
483
 
484
EXTERN_C_BEGIN
485
#undef __FUNCT__  
486
#define __FUNCT__ "SVDCyclicGetEPS_CYCLIC"
487
PetscErrorCode SVDCyclicGetEPS_CYCLIC(SVD svd,EPS *eps)
488
{
489
  SVD_CYCLIC *cyclic = (SVD_CYCLIC *)svd->data;
490
 
491
  PetscFunctionBegin;
492
  PetscValidPointer(eps,2);
493
  *eps = cyclic->eps;
494
  PetscFunctionReturn(0);
495
}
496
EXTERN_C_END
497
 
498
#undef __FUNCT__  
499
#define __FUNCT__ "SVDCyclicGetEPS"
2061 eromero 500
/*@
1324 slepc 501
   SVDCyclicGetEPS - Retrieve the eigensolver object (EPS) associated
502
   to the singular value solver.
503
 
504
   Not Collective
505
 
1325 slepc 506
   Input Parameter:
1324 slepc 507
.  svd - singular value solver
508
 
509
   Output Parameter:
510
.  eps - the eigensolver object
511
 
512
   Level: advanced
513
 
514
.seealso: SVDCyclicSetEPS()
515
@*/
516
PetscErrorCode SVDCyclicGetEPS(SVD svd,EPS *eps)
517
{
518
  PetscErrorCode ierr, (*f)(SVD,EPS *eps);
519
 
520
  PetscFunctionBegin;
2213 jroman 521
  PetscValidHeaderSpecific(svd,SVD_CLASSID,1);
1324 slepc 522
  ierr = PetscObjectQueryFunction((PetscObject)svd,"SVDCyclicGetEPS_C",(void (**)())&f);CHKERRQ(ierr);
523
  if (f) {
524
    ierr = (*f)(svd,eps);CHKERRQ(ierr);
525
  }
526
  PetscFunctionReturn(0);
527
}
528
 
529
#undef __FUNCT__  
530
#define __FUNCT__ "SVDView_CYCLIC"
531
PetscErrorCode SVDView_CYCLIC(SVD svd,PetscViewer viewer)
532
{
533
  PetscErrorCode  ierr;
534
  SVD_CYCLIC *cyclic = (SVD_CYCLIC *)svd->data;
535
 
536
  PetscFunctionBegin;
1370 slepc 537
  if (cyclic->explicitmatrix) {
1324 slepc 538
    ierr = PetscViewerASCIIPrintf(viewer,"cyclic matrix: explicit\n");CHKERRQ(ierr);
539
  } else {
540
    ierr = PetscViewerASCIIPrintf(viewer,"cyclic matrix: implicit\n");CHKERRQ(ierr);
541
  }
542
  ierr = EPSView(cyclic->eps,viewer);CHKERRQ(ierr);
543
  PetscFunctionReturn(0);
544
}
545
 
546
#undef __FUNCT__  
547
#define __FUNCT__ "SVDDestroy_CYCLIC"
548
PetscErrorCode SVDDestroy_CYCLIC(SVD svd)
549
{
550
  PetscErrorCode  ierr;
551
  SVD_CYCLIC *cyclic = (SVD_CYCLIC *)svd->data;
552
 
553
  PetscFunctionBegin;
554
  ierr = EPSDestroy(cyclic->eps);CHKERRQ(ierr);
555
  if (cyclic->mat) { ierr = MatDestroy(cyclic->mat);CHKERRQ(ierr); }
556
  if (cyclic->x1) {
557
    ierr = VecDestroy(cyclic->x1);CHKERRQ(ierr);
558
    ierr = VecDestroy(cyclic->x2);CHKERRQ(ierr);
559
    ierr = VecDestroy(cyclic->y1);CHKERRQ(ierr);
560
    ierr = VecDestroy(cyclic->y2);CHKERRQ(ierr);
561
  }
1396 slepc 562
  ierr = PetscFree(svd->data);CHKERRQ(ierr);
1925 jroman 563
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicSetEPS_C","",PETSC_NULL);CHKERRQ(ierr);
564
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicGetEPS_C","",PETSC_NULL);CHKERRQ(ierr);
565
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicSetExplicitMatrix_C","",PETSC_NULL);CHKERRQ(ierr);
566
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicGetExplicitMatrix_C","",PETSC_NULL);CHKERRQ(ierr);
1324 slepc 567
  PetscFunctionReturn(0);
568
}
569
 
570
EXTERN_C_BEGIN
571
#undef __FUNCT__  
572
#define __FUNCT__ "SVDCreate_CYCLIC"
573
PetscErrorCode SVDCreate_CYCLIC(SVD svd)
574
{
575
  PetscErrorCode  ierr;
576
  SVD_CYCLIC *cyclic;
577
 
578
  PetscFunctionBegin;
579
  ierr = PetscNew(SVD_CYCLIC,&cyclic);CHKERRQ(ierr);
580
  PetscLogObjectMemory(svd,sizeof(SVD_CYCLIC));
581
  svd->data                      = (void *)cyclic;
582
  svd->ops->solve                = SVDSolve_CYCLIC;
583
  svd->ops->setup                = SVDSetUp_CYCLIC;
584
  svd->ops->setfromoptions       = SVDSetFromOptions_CYCLIC;
585
  svd->ops->destroy              = SVDDestroy_CYCLIC;
586
  svd->ops->view                 = SVDView_CYCLIC;
587
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicSetEPS_C","SVDCyclicSetEPS_CYCLIC",SVDCyclicSetEPS_CYCLIC);CHKERRQ(ierr);
588
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicGetEPS_C","SVDCyclicGetEPS_CYCLIC",SVDCyclicGetEPS_CYCLIC);CHKERRQ(ierr);
589
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicSetExplicitMatrix_C","SVDCyclicSetExplicitMatrix_CYCLIC",SVDCyclicSetExplicitMatrix_CYCLIC);CHKERRQ(ierr);
590
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)svd,"SVDCyclicGetExplicitMatrix_C","SVDCyclicGetExplicitMatrix_CYCLIC",SVDCyclicGetExplicitMatrix_CYCLIC);CHKERRQ(ierr);
591
 
1422 slepc 592
  ierr = EPSCreate(((PetscObject)svd)->comm,&cyclic->eps);CHKERRQ(ierr);
593
  ierr = EPSSetOptionsPrefix(cyclic->eps,((PetscObject)svd)->prefix);CHKERRQ(ierr);
1324 slepc 594
  ierr = EPSAppendOptionsPrefix(cyclic->eps,"svd_");CHKERRQ(ierr);
1532 slepc 595
  ierr = PetscObjectIncrementTabLevel((PetscObject)cyclic->eps,(PetscObject)svd,1);CHKERRQ(ierr);  
1324 slepc 596
  PetscLogObjectParent(svd,cyclic->eps);
1345 slepc 597
  ierr = EPSSetIP(cyclic->eps,svd->ip);CHKERRQ(ierr);
1324 slepc 598
  ierr = EPSSetWhichEigenpairs(cyclic->eps,EPS_LARGEST_REAL);CHKERRQ(ierr);
1331 slepc 599
  ierr = EPSMonitorSet(cyclic->eps,SVDMonitor_CYCLIC,svd,PETSC_NULL);CHKERRQ(ierr);
1370 slepc 600
  cyclic->explicitmatrix = PETSC_FALSE;
1324 slepc 601
  cyclic->mat = PETSC_NULL;
602
  cyclic->x1 = PETSC_NULL;
603
  cyclic->x2 = PETSC_NULL;
604
  cyclic->y1 = PETSC_NULL;
605
  cyclic->y2 = PETSC_NULL;
2024 eromero 606
  cyclic->setfromoptionscalled = PETSC_FALSE;
1324 slepc 607
  PetscFunctionReturn(0);
608
}
609
EXTERN_C_END