Subversion Repositories slepc-dev

Rev

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