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
1249 slepc 1
/*
2
     SVD routines for setting up the solver.
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__ "SVDSetOperator"
1333 slepc 17
/*@
1249 slepc 18
   SVDSetOperator - Set the matrix associated with the singular value problem.
19
 
20
   Collective on SVD and Mat
21
 
22
   Input Parameters:
23
+  svd - the singular value solver context
24
-  A  - the matrix associated with the singular value problem
25
 
26
   Level: beginner
27
 
1268 slepc 28
.seealso: SVDSolve(), SVDGetOperator()
1249 slepc 29
@*/
30
PetscErrorCode SVDSetOperator(SVD svd,Mat mat)
31
{
32
  PetscErrorCode ierr;
33
 
34
  PetscFunctionBegin;
35
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
36
  PetscValidHeaderSpecific(mat,MAT_COOKIE,2);
37
  PetscCheckSameComm(svd,1,mat,2);
38
  ierr = PetscObjectReference((PetscObject)mat);CHKERRQ(ierr);
1314 slepc 39
  if (svd->OP) {
40
    ierr = MatDestroy(svd->OP);CHKERRQ(ierr);
1249 slepc 41
  }
1314 slepc 42
  svd->OP = mat;
1272 slepc 43
  if (svd->vec_initial) {
44
    ierr = VecDestroy(svd->vec_initial);CHKERRQ(ierr);
45
    svd->vec_initial = PETSC_NULL;
46
  }
1249 slepc 47
  svd->setupcalled = 0;
48
  PetscFunctionReturn(0);
49
}
50
 
51
#undef __FUNCT__  
1268 slepc 52
#define __FUNCT__ "SVDGetOperator"
1333 slepc 53
/*@
54
   SVDGetOperator - Get the matrix associated with the singular value problem.
1255 slepc 55
 
1249 slepc 56
   Not collective, though parallel Mats are returned if the SVD is parallel
57
 
58
   Input Parameter:
59
.  svd - the singular value solver context
60
 
61
   Output Parameters:
1268 slepc 62
.  A    - the matrix associated with the singular value problem
1249 slepc 63
 
1255 slepc 64
   Level: advanced
1249 slepc 65
 
1268 slepc 66
.seealso: SVDSolve(), SVDSetOperator()
1249 slepc 67
@*/
1268 slepc 68
PetscErrorCode SVDGetOperator(SVD svd,Mat *A)
1249 slepc 69
{
70
  PetscFunctionBegin;
71
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
1268 slepc 72
  PetscValidPointer(A,2);
1314 slepc 73
  *A = svd->OP;
1249 slepc 74
  PetscFunctionReturn(0);
75
}
76
 
77
#undef __FUNCT__  
1272 slepc 78
#define __FUNCT__ "SVDSetInitialVector"
1268 slepc 79
/*@
1272 slepc 80
   SVDSetInitialVector - Sets the initial vector from which the
81
   singular value solver starts to iterate.
1268 slepc 82
 
1272 slepc 83
   Collective on SVD and Vec
1268 slepc 84
 
1272 slepc 85
   Input Parameters:
86
+  svd - the singular value solver context
87
-  vec - the vector
1268 slepc 88
 
1272 slepc 89
   Level: intermediate
90
 
91
.seealso: SVDGetInitialVector()
92
 
1268 slepc 93
@*/
1272 slepc 94
PetscErrorCode SVDSetInitialVector(SVD svd,Vec vec)
1268 slepc 95
{
1272 slepc 96
  PetscErrorCode ierr;
97
 
1268 slepc 98
  PetscFunctionBegin;
99
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
1272 slepc 100
  PetscValidHeaderSpecific(vec,VEC_COOKIE,2);
101
  PetscCheckSameComm(svd,1,vec,2);
1278 slepc 102
  ierr = PetscObjectReference((PetscObject)vec);CHKERRQ(ierr);
1272 slepc 103
  if (svd->vec_initial) {
104
    ierr = VecDestroy(svd->vec_initial); CHKERRQ(ierr);
105
  }
106
  svd->vec_initial = vec;
1268 slepc 107
  PetscFunctionReturn(0);
108
}
109
 
110
#undef __FUNCT__  
1272 slepc 111
#define __FUNCT__ "SVDGetInitialVector"
1249 slepc 112
/*@
1272 slepc 113
   SVDGetInitialVector - Gets the initial vector associated with the
114
   singular value solver; if the vector was not set it will return a 0
115
   pointer or a vector randomly generated by SVDSetUp().
1249 slepc 116
 
1272 slepc 117
   Not collective, but vector is shared by all processors that share the SVD
1249 slepc 118
 
1272 slepc 119
   Input Parameter:
1249 slepc 120
.  svd - the singular value solver context
121
 
1272 slepc 122
   Output Parameter:
123
.  vec - the vector
1249 slepc 124
 
1272 slepc 125
   Level: intermediate
1249 slepc 126
 
1272 slepc 127
.seealso: SVDSetInitialVector()
128
 
1249 slepc 129
@*/
1272 slepc 130
PetscErrorCode SVDGetInitialVector(SVD svd,Vec *vec)
1249 slepc 131
{
132
  PetscFunctionBegin;
133
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
1272 slepc 134
  PetscValidPointer(vec,2);
135
  *vec = svd->vec_initial;
1249 slepc 136
  PetscFunctionReturn(0);
137
}
138
 
139
#undef __FUNCT__  
140
#define __FUNCT__ "SVDSetUp"
141
/*@
142
   SVDSetUp - Sets up all the internal data structures necessary for the
143
   execution of the singular value solver.
144
 
145
   Collective on SVD
146
 
147
   Input Parameter:
148
.  SVD   - singular value solver context
149
 
150
   Level: advanced
151
 
152
   Notes:
153
   This function need not be called explicitly in most cases, since SVDSolve()
154
   calls it. It can be useful when one wants to measure the set-up time
155
   separately from the solve time.
156
 
157
.seealso: SVDCreate(), SVDSolve(), SVDDestroy()
158
@*/
159
PetscErrorCode SVDSetUp(SVD svd)
160
{
161
  PetscErrorCode ierr;
1263 slepc 162
  int            i;
1264 slepc 163
  PetscTruth     flg;
1272 slepc 164
  PetscInt       M,N;
1249 slepc 165
 
166
  PetscFunctionBegin;
167
  PetscValidHeaderSpecific(svd,SVD_COOKIE,1);
168
  if (svd->setupcalled) PetscFunctionReturn(0);
169
  ierr = PetscLogEventBegin(SVD_SetUp,svd,0,0,0);CHKERRQ(ierr);
170
 
171
  /* Set default solver type */
172
  if (!svd->type_name) {
1342 slepc 173
    ierr = SVDSetType(svd,SVDCROSS);CHKERRQ(ierr);
1249 slepc 174
  }
175
 
176
  /* check matrix */
1314 slepc 177
  if (!svd->OP)
1272 slepc 178
    SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "SVDSetOperator must be called first");
1256 slepc 179
 
1264 slepc 180
  /* determine how to build the transpose */
1283 slepc 181
  if (svd->transmode == PETSC_DECIDE) {
1314 slepc 182
    ierr = MatHasOperation(svd->OP,MATOP_TRANSPOSE,&flg);CHKERRQ(ierr);    
1264 slepc 183
    if (flg) svd->transmode = SVD_TRANSPOSE_EXPLICIT;
1283 slepc 184
    else svd->transmode = SVD_TRANSPOSE_IMPLICIT;
1264 slepc 185
  }
186
 
1256 slepc 187
  /* build transpose matrix */
1314 slepc 188
  if (svd->A) { ierr = MatDestroy(svd->A);CHKERRQ(ierr); }
1283 slepc 189
  if (svd->AT) { ierr = MatDestroy(svd->AT);CHKERRQ(ierr); }
1314 slepc 190
  ierr = MatGetSize(svd->OP,&M,&N);CHKERRQ(ierr);
191
  ierr = PetscObjectReference((PetscObject)svd->OP);CHKERRQ(ierr);
1256 slepc 192
  switch (svd->transmode) {
193
    case SVD_TRANSPOSE_EXPLICIT:
1314 slepc 194
      ierr = MatHasOperation(svd->OP,MATOP_TRANSPOSE,&flg);CHKERRQ(ierr);
1319 slepc 195
      if (!flg) SETERRQ(1,"Matrix has not defined the MatTranpose operation");
1314 slepc 196
      if (M>=N) {
197
        svd->A = svd->OP;
198
        ierr = MatTranspose(svd->OP,&svd->AT);CHKERRQ(ierr);
199
      } else {
200
        ierr = MatTranspose(svd->OP,&svd->A);CHKERRQ(ierr);
201
        svd->AT = svd->OP;
202
      }
1256 slepc 203
      break;
1283 slepc 204
    case SVD_TRANSPOSE_IMPLICIT:
1314 slepc 205
      ierr = MatHasOperation(svd->OP,MATOP_MULT_TRANSPOSE,&flg);CHKERRQ(ierr);
1319 slepc 206
      if (!flg) SETERRQ(1,"Matrix has not defined the MatMultTranpose operation");
1314 slepc 207
      if (M>=N) {
208
        svd->A = svd->OP;
209
        svd->AT = PETSC_NULL;    
210
      } else {
211
        svd->A = PETSC_NULL;
212
        svd->AT = svd->OP;
213
      }
1256 slepc 214
      break;
215
    default:
216
      SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid transpose mode");
217
  }
1249 slepc 218
 
1272 slepc 219
  /* set initial vector */
220
  if (!svd->vec_initial) {
1314 slepc 221
    ierr = SVDMatGetVecs(svd,&svd->vec_initial,PETSC_NULL);CHKERRQ(ierr);
1272 slepc 222
    ierr = SlepcVecSetRandom(svd->vec_initial);CHKERRQ(ierr);
1263 slepc 223
  }
224
 
1249 slepc 225
  /* call specific solver setup */
226
  ierr = (*svd->ops->setup)(svd);CHKERRQ(ierr);
227
 
1272 slepc 228
  if (svd->ncv > M || svd->ncv > N)
229
    SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"ncv bigger than matrix dimensions");
230
  if (svd->nsv > svd->ncv)
231
    SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"nsv bigger than ncv");
232
 
233
  if (svd->ncv != svd->n) {
234
    /* free memory for previous solution  */
235
    if (svd->n) {
236
      ierr = PetscFree(svd->sigma);CHKERRQ(ierr);
1288 slepc 237
      ierr = PetscFree(svd->errest);CHKERRQ(ierr);
1272 slepc 238
      for (i=0;i<svd->n;i++) {
239
        ierr = VecDestroy(svd->V[i]);CHKERRQ(ierr);
240
      }
241
      ierr = PetscFree(svd->V);CHKERRQ(ierr);
242
    }
243
    /* allocate memory for next solution */
244
    ierr = PetscMalloc(svd->ncv*sizeof(PetscReal),&svd->sigma);CHKERRQ(ierr);
1288 slepc 245
    ierr = PetscMalloc(svd->ncv*sizeof(PetscReal),&svd->errest);CHKERRQ(ierr);
1272 slepc 246
    ierr = PetscMalloc(svd->ncv*sizeof(Vec),&svd->V);CHKERRQ(ierr);
247
    for (i=0;i<svd->ncv;i++) {
1314 slepc 248
      ierr = SVDMatGetVecs(svd,svd->V+i,PETSC_NULL);CHKERRQ(ierr);
1272 slepc 249
    }
250
    svd->n = svd->ncv;
1263 slepc 251
  }
252
 
1249 slepc 253
  ierr = PetscLogEventEnd(SVD_SetUp,svd,0,0,0);CHKERRQ(ierr);
254
  svd->setupcalled = 1;
255
  PetscFunctionReturn(0);
256
}