LCOV - code coverage report
Current view: top level - sys/classes/ds/interface - dsops.c (source / functions) Hit Total Coverage
Test: SLEPc Lines: 366 370 98.9 %
Date: 2024-12-18 00:51:33 Functions: 27 27 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       3             :    SLEPc - Scalable Library for Eigenvalue Problem Computations
       4             :    Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain
       5             : 
       6             :    This file is part of SLEPc.
       7             :    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
       8             :    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
       9             : */
      10             : /*
      11             :    DS operations: DSSolve(), DSVectors(), etc
      12             : */
      13             : 
      14             : #include <slepc/private/dsimpl.h>      /*I "slepcds.h" I*/
      15             : 
      16             : /*@
      17             :    DSGetLeadingDimension - Returns the leading dimension of the allocated
      18             :    matrices.
      19             : 
      20             :    Not Collective
      21             : 
      22             :    Input Parameter:
      23             : .  ds - the direct solver context
      24             : 
      25             :    Output Parameter:
      26             : .  ld - leading dimension (maximum allowed dimension for the matrices)
      27             : 
      28             :    Level: advanced
      29             : 
      30             : .seealso: DSAllocate(), DSSetDimensions()
      31             : @*/
      32       34299 : PetscErrorCode DSGetLeadingDimension(DS ds,PetscInt *ld)
      33             : {
      34       34299 :   PetscFunctionBegin;
      35       34299 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
      36       34299 :   PetscAssertPointer(ld,2);
      37       34299 :   *ld = ds->ld;
      38       34299 :   PetscFunctionReturn(PETSC_SUCCESS);
      39             : }
      40             : 
      41             : /*@
      42             :    DSSetState - Change the state of the DS object.
      43             : 
      44             :    Logically Collective
      45             : 
      46             :    Input Parameters:
      47             : +  ds    - the direct solver context
      48             : -  state - the new state
      49             : 
      50             :    Notes:
      51             :    The state indicates that the dense system is in an initial state (raw),
      52             :    in an intermediate state (such as tridiagonal, Hessenberg or
      53             :    Hessenberg-triangular), in a condensed state (such as diagonal, Schur or
      54             :    generalized Schur), or in a truncated state.
      55             : 
      56             :    This function is normally used to return to the raw state when the
      57             :    condensed structure is destroyed.
      58             : 
      59             :    Level: advanced
      60             : 
      61             : .seealso: DSGetState()
      62             : @*/
      63       20107 : PetscErrorCode DSSetState(DS ds,DSStateType state)
      64             : {
      65       20107 :   PetscFunctionBegin;
      66       20107 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
      67       60321 :   PetscValidLogicalCollectiveEnum(ds,state,2);
      68       20107 :   switch (state) {
      69       20107 :     case DS_STATE_RAW:
      70             :     case DS_STATE_INTERMEDIATE:
      71             :     case DS_STATE_CONDENSED:
      72             :     case DS_STATE_TRUNCATED:
      73       20107 :       if (ds->state!=state) PetscCall(PetscInfo(ds,"State has changed from %s to %s\n",DSStateTypes[ds->state],DSStateTypes[state]));
      74       20107 :       ds->state = state;
      75       20107 :       break;
      76           0 :     default:
      77           0 :       SETERRQ(PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_WRONG,"Wrong state");
      78             :   }
      79       20107 :   PetscFunctionReturn(PETSC_SUCCESS);
      80             : }
      81             : 
      82             : /*@
      83             :    DSGetState - Returns the current state.
      84             : 
      85             :    Not Collective
      86             : 
      87             :    Input Parameter:
      88             : .  ds - the direct solver context
      89             : 
      90             :    Output Parameter:
      91             : .  state - current state
      92             : 
      93             :    Level: advanced
      94             : 
      95             : .seealso: DSSetState()
      96             : @*/
      97           2 : PetscErrorCode DSGetState(DS ds,DSStateType *state)
      98             : {
      99           2 :   PetscFunctionBegin;
     100           2 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     101           2 :   PetscAssertPointer(state,2);
     102           2 :   *state = ds->state;
     103           2 :   PetscFunctionReturn(PETSC_SUCCESS);
     104             : }
     105             : 
     106             : /*@
     107             :    DSSetDimensions - Resize the matrices in the DS object.
     108             : 
     109             :    Logically Collective
     110             : 
     111             :    Input Parameters:
     112             : +  ds - the direct solver context
     113             : .  n  - the new size
     114             : .  l  - number of locked (inactive) leading columns
     115             : -  k  - intermediate dimension (e.g., position of arrow)
     116             : 
     117             :    Notes:
     118             :    The internal arrays are not reallocated.
     119             : 
     120             :    Some DS types have additional dimensions, e.g. the number of columns
     121             :    in DSSVD. For these, you should call a specific interface function.
     122             : 
     123             :    Use PETSC_CURRENT to leave any of the values unchanged. Use PETSC_DETERMINE
     124             :    to set n to the leading dimension, l to the minimum value (0), and k to n/2.
     125             : 
     126             :    Level: intermediate
     127             : 
     128             : .seealso: DSGetDimensions(), DSAllocate(), DSSVDSetDimensions()
     129             : @*/
     130       26100 : PetscErrorCode DSSetDimensions(DS ds,PetscInt n,PetscInt l,PetscInt k)
     131             : {
     132       26100 :   PetscInt       on,ol,ok;
     133       26100 :   PetscBool      issvd;
     134             : 
     135       26100 :   PetscFunctionBegin;
     136       26100 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     137       26100 :   DSCheckAlloc(ds,1);
     138       78300 :   PetscValidLogicalCollectiveInt(ds,n,2);
     139       78300 :   PetscValidLogicalCollectiveInt(ds,l,3);
     140       78300 :   PetscValidLogicalCollectiveInt(ds,k,4);
     141       26100 :   on = ds->n; ol = ds->l; ok = ds->k;
     142       26100 :   if (n == PETSC_DETERMINE) {
     143         132 :     ds->n = ds->extrarow? ds->ld-1: ds->ld;
     144       25968 :   } else if (n != PETSC_CURRENT) {
     145       25968 :     PetscCheck(n>=0 && n<=ds->ld,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of n. Must be between 0 and ld");
     146       25968 :     PetscCall(PetscObjectTypeCompareAny((PetscObject)ds,&issvd,DSSVD,DSGSVD,""));  /* SVD and GSVD have extra column instead of extra row */
     147       25968 :     PetscCheck(!ds->extrarow || n<ds->ld || issvd,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"A value of n equal to ld leaves no room for extra row");
     148       25968 :     ds->n = n;
     149             :   }
     150       26100 :   ds->t = ds->n;   /* truncated length equal to the new dimension */
     151       26100 :   if (l == PETSC_DETERMINE) {
     152         483 :     ds->l = 0;
     153       25617 :   } else if (l != PETSC_CURRENT) {
     154       25617 :     PetscCheck(l>=0 && l<=ds->n,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of l. Must be between 0 and n");
     155       25617 :     ds->l = l;
     156             :   }
     157       26100 :   if (k == PETSC_DETERMINE) {
     158        1426 :     ds->k = ds->n/2;
     159       24674 :   } else if (k != PETSC_CURRENT) {
     160       24674 :     PetscCheck(k>=0 || k<=ds->n,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of k. Must be between 0 and n");
     161       24674 :     ds->k = k;
     162             :   }
     163       26100 :   if (on!=ds->n || ol!=ds->l || ok!=ds->k) PetscCall(PetscInfo(ds,"New dimensions are: n=%" PetscInt_FMT ", l=%" PetscInt_FMT ", k=%" PetscInt_FMT "\n",ds->n,ds->l,ds->k));
     164       26100 :   PetscFunctionReturn(PETSC_SUCCESS);
     165             : }
     166             : 
     167             : /*@
     168             :    DSGetDimensions - Returns the current dimensions.
     169             : 
     170             :    Not Collective
     171             : 
     172             :    Input Parameter:
     173             : .  ds - the direct solver context
     174             : 
     175             :    Output Parameters:
     176             : +  n  - the current size
     177             : .  l  - number of locked (inactive) leading columns
     178             : .  k  - intermediate dimension (e.g., position of arrow)
     179             : -  t  - truncated length
     180             : 
     181             :    Note:
     182             :    The t parameter makes sense only if DSTruncate() has been called.
     183             :    Otherwise its value equals n.
     184             : 
     185             :    Some DS types have additional dimensions, e.g. the number of columns
     186             :    in DSSVD. For these, you should call a specific interface function.
     187             : 
     188             :    Level: intermediate
     189             : 
     190             : .seealso: DSSetDimensions(), DSTruncate(), DSSVDGetDimensions()
     191             : @*/
     192       18533 : PetscErrorCode DSGetDimensions(DS ds,PetscInt *n,PetscInt *l,PetscInt *k,PetscInt *t)
     193             : {
     194       18533 :   PetscFunctionBegin;
     195       18533 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     196       18533 :   DSCheckAlloc(ds,1);
     197       18533 :   if (n) *n = ds->n;
     198       18533 :   if (l) *l = ds->l;
     199       18533 :   if (k) *k = ds->k;
     200       18533 :   if (t) *t = ds->t;
     201       18533 :   PetscFunctionReturn(PETSC_SUCCESS);
     202             : }
     203             : 
     204             : /*@
     205             :    DSTruncate - Truncates the system represented in the DS object.
     206             : 
     207             :    Logically Collective
     208             : 
     209             :    Input Parameters:
     210             : +  ds   - the direct solver context
     211             : .  n    - the new size
     212             : -  trim - a flag to indicate if the factorization must be trimmed
     213             : 
     214             :    Note:
     215             :    The new size is set to n. Note that in some cases the new size could
     216             :    be n+1 or n-1 to avoid breaking a 2x2 diagonal block (e.g. in real
     217             :    Schur form). In cases where the extra row is meaningful, the first
     218             :    n elements are kept as the extra row for the new system.
     219             : 
     220             :    If the flag trim is turned on, it resets the locked and intermediate
     221             :    dimensions to zero, see DSSetDimensions(), and sets the state to RAW.
     222             :    It also cleans the extra row if being used.
     223             : 
     224             :    The typical usage of trim=true is to truncate the Schur decomposition
     225             :    at the end of a Krylov iteration. In this case, the state must be
     226             :    changed to RAW so that DSVectors() computes eigenvectors from scratch.
     227             : 
     228             :    Level: advanced
     229             : 
     230             : .seealso: DSSetDimensions(), DSSetExtraRow(), DSStateType
     231             : @*/
     232        5850 : PetscErrorCode DSTruncate(DS ds,PetscInt n,PetscBool trim)
     233             : {
     234        5850 :   DSStateType    old;
     235             : 
     236        5850 :   PetscFunctionBegin;
     237        5850 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     238        5850 :   PetscValidType(ds,1);
     239        5850 :   DSCheckAlloc(ds,1);
     240       17550 :   PetscValidLogicalCollectiveInt(ds,n,2);
     241       17550 :   PetscValidLogicalCollectiveBool(ds,trim,3);
     242        5850 :   PetscCheck(n>=ds->l && n<=ds->n,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of n (%" PetscInt_FMT "). Must be between l (%" PetscInt_FMT ") and n (%" PetscInt_FMT ")",n,ds->l,ds->n);
     243        5850 :   PetscCall(PetscLogEventBegin(DS_Other,ds,0,0,0));
     244        5850 :   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
     245        5850 :   PetscUseTypeMethod(ds,truncate,n,trim);
     246        5850 :   PetscCall(PetscFPTrapPop());
     247        5850 :   PetscCall(PetscLogEventEnd(DS_Other,ds,0,0,0));
     248       11009 :   PetscCall(PetscInfo(ds,"Decomposition %s to size n=%" PetscInt_FMT "\n",trim?"trimmed":"truncated",ds->n));
     249        5850 :   old = ds->state;
     250        5850 :   ds->state = trim? DS_STATE_RAW: DS_STATE_TRUNCATED;
     251        5850 :   if (old!=ds->state) PetscCall(PetscInfo(ds,"State has changed from %s to %s\n",DSStateTypes[old],DSStateTypes[ds->state]));
     252        5850 :   PetscCall(PetscObjectStateIncrease((PetscObject)ds));
     253        5850 :   PetscFunctionReturn(PETSC_SUCCESS);
     254             : }
     255             : 
     256             : /*@
     257             :    DSMatGetSize - Returns the numbers of rows and columns of one of the DS matrices.
     258             : 
     259             :    Not Collective
     260             : 
     261             :    Input Parameters:
     262             : +  ds - the direct solver context
     263             : -  t  - the requested matrix
     264             : 
     265             :    Output Parameters:
     266             : +  n  - the number of rows
     267             : -  m  - the number of columns
     268             : 
     269             :    Note:
     270             :    This is equivalent to MatGetSize() on a matrix obtained with DSGetMat().
     271             : 
     272             :    Level: developer
     273             : 
     274             : .seealso: DSSetDimensions(), DSGetMat()
     275             : @*/
     276       54437 : PetscErrorCode DSMatGetSize(DS ds,DSMatType t,PetscInt *m,PetscInt *n)
     277             : {
     278       54437 :   PetscInt       rows,cols;
     279             : 
     280       54437 :   PetscFunctionBegin;
     281       54437 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     282       54437 :   PetscValidType(ds,1);
     283       54437 :   DSCheckValidMat(ds,t,2);
     284       54437 :   if (ds->ops->matgetsize) PetscUseTypeMethod(ds,matgetsize,t,&rows,&cols);
     285             :   else {
     286       42526 :     if (ds->state==DS_STATE_TRUNCATED && t>=DS_MAT_Q) rows = ds->t;
     287       38824 :     else rows = (t==DS_MAT_A && ds->extrarow)? ds->n+1: ds->n;
     288       42526 :     if (t==DS_MAT_T) cols = PetscDefined(USE_COMPLEX)? 2: 3;
     289       40854 :     else if (t==DS_MAT_D) cols = 1;
     290       40455 :     else cols = ds->n;
     291             :   }
     292       54437 :   if (m) *m = rows;
     293       54437 :   if (n) *n = cols;
     294       54437 :   PetscFunctionReturn(PETSC_SUCCESS);
     295             : }
     296             : 
     297             : /*@
     298             :    DSMatIsHermitian - Checks if one of the DS matrices is known to be Hermitian.
     299             : 
     300             :    Not Collective
     301             : 
     302             :    Input Parameters:
     303             : +  ds - the direct solver context
     304             : -  t  - the requested matrix
     305             : 
     306             :    Output Parameter:
     307             : .  flg - the Hermitian flag
     308             : 
     309             :    Note:
     310             :    Does not check the matrix values directly. The flag is set according to the
     311             :    problem structure. For instance, in DSHEP matrix A is Hermitian.
     312             : 
     313             :    Level: developer
     314             : 
     315             : .seealso: DSGetMat()
     316             : @*/
     317       54407 : PetscErrorCode DSMatIsHermitian(DS ds,DSMatType t,PetscBool *flg)
     318             : {
     319       54407 :   PetscFunctionBegin;
     320       54407 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     321       54407 :   PetscValidType(ds,1);
     322       54407 :   DSCheckValidMat(ds,t,2);
     323       54407 :   PetscAssertPointer(flg,3);
     324       54407 :   *flg = PETSC_FALSE;
     325       54407 :   PetscTryTypeMethod(ds,hermitian,t,flg);
     326       54407 :   PetscFunctionReturn(PETSC_SUCCESS);
     327             : }
     328             : 
     329        1753 : PetscErrorCode DSGetTruncateSize_Default(DS ds,PetscInt l,PetscInt n,PetscInt *k)
     330             : {
     331             : #if !defined(PETSC_USE_COMPLEX)
     332             :   PetscScalar val;
     333             : #endif
     334             : 
     335        1753 :   PetscFunctionBegin;
     336             : #if !defined(PETSC_USE_COMPLEX)
     337             :   PetscCall(MatGetValue(ds->omat[DS_MAT_A],l+(*k),l+(*k)-1,&val));
     338             :   if (val != 0.0) {
     339             :     if (l+(*k)<n-1) (*k)++;
     340             :     else (*k)--;
     341             :   }
     342             : #endif
     343        1753 :   PetscFunctionReturn(PETSC_SUCCESS);
     344             : }
     345             : 
     346             : /*@
     347             :    DSGetTruncateSize - Gets the correct size to be used in DSTruncate()
     348             :    to avoid breaking a 2x2 block.
     349             : 
     350             :    Not Collective
     351             : 
     352             :    Input Parameters:
     353             : +  ds - the direct solver context
     354             : .  l  - the size of the locked part (set to 0 to use ds->l)
     355             : -  n  - the total matrix size (set to 0 to use ds->n)
     356             : 
     357             :    Output Parameter:
     358             : .  k  - the wanted truncation size (possibly modified)
     359             : 
     360             :    Notes:
     361             :    This should be called before DSTruncate() to make sure that the truncation
     362             :    does not break a 2x2 block corresponding to a complex conjugate eigenvalue.
     363             : 
     364             :    The total size is n (either user-provided or ds->n if 0 is passed). The
     365             :    size where the truncation is intended is equal to l+k (where l can be
     366             :    equal to the locked size ds->l if set to 0). Then if there is a 2x2 block
     367             :    at the l+k limit, the value of k is increased (or decreased) by 1.
     368             : 
     369             :    Level: advanced
     370             : 
     371             : .seealso: DSTruncate(), DSSetDimensions()
     372             : @*/
     373        2140 : PetscErrorCode DSGetTruncateSize(DS ds,PetscInt l,PetscInt n,PetscInt *k)
     374             : {
     375        2140 :   PetscFunctionBegin;
     376        2140 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     377        2140 :   DSCheckAlloc(ds,1);
     378        6420 :   PetscValidLogicalCollectiveInt(ds,l,2);
     379        6420 :   PetscValidLogicalCollectiveInt(ds,n,3);
     380        2140 :   PetscAssertPointer(k,4);
     381        2140 :   PetscUseTypeMethod(ds,gettruncatesize,l?l:ds->l,n?n:ds->n,k);
     382        2140 :   PetscFunctionReturn(PETSC_SUCCESS);
     383             : }
     384             : 
     385             : /*@
     386             :    DSGetMat - Returns a sequential dense Mat object containing the requested
     387             :    matrix.
     388             : 
     389             :    Not Collective
     390             : 
     391             :    Input Parameters:
     392             : +  ds - the direct solver context
     393             : -  m  - the requested matrix
     394             : 
     395             :    Output Parameter:
     396             : .  A  - Mat object
     397             : 
     398             :    Notes:
     399             :    The returned Mat has sizes equal to the current DS dimensions (nxm),
     400             :    and contains the values that would be obtained with DSGetArray()
     401             :    (not DSGetArrayReal()). If the DS was truncated, then the number of rows
     402             :    is equal to the dimension prior to truncation, see DSTruncate().
     403             :    The communicator is always PETSC_COMM_SELF.
     404             : 
     405             :    It is implemented with MatDenseGetSubMatrix(), and when no longer needed
     406             :    the user must call DSRestoreMat() which will invoke MatDenseRestoreSubMatrix().
     407             : 
     408             :    For matrices DS_MAT_T and DS_MAT_D, this function will return a Mat object
     409             :    that cannot be used directly for computations, since it uses compact storage
     410             :    (three and one diagonals for T and D, respectively). In complex scalars, the
     411             :    internal array stores real values, so it is sufficient with 2 columns for T.
     412             : 
     413             :    Level: advanced
     414             : 
     415             : .seealso: DSRestoreMat(), DSSetDimensions(), DSGetArray(), DSGetArrayReal(), DSTruncate()
     416             : @*/
     417       54407 : PetscErrorCode DSGetMat(DS ds,DSMatType m,Mat *A)
     418             : {
     419       54407 :   PetscInt  rows=0,cols=0;
     420       54407 :   PetscBool flg;
     421             : 
     422       54407 :   PetscFunctionBegin;
     423       54407 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     424       54407 :   DSCheckAlloc(ds,1);
     425       54407 :   DSCheckValidMat(ds,m,2);
     426       54407 :   PetscAssertPointer(A,3);
     427             : 
     428       54407 :   PetscCall(DSMatGetSize(ds,m,&rows,&cols));
     429       54407 :   PetscCheck(rows && cols,PetscObjectComm((PetscObject)ds),PETSC_ERR_ORDER,"Must call DSSetDimensions() first");
     430       54407 :   PetscCall(MatDenseGetSubMatrix(ds->omat[m],0,rows,0,cols,A));
     431             : 
     432             :   /* set Hermitian flag */
     433       54407 :   PetscCall(DSMatIsHermitian(ds,m,&flg));
     434       54407 :   PetscCall(MatSetOption(*A,MAT_SYMMETRIC,flg));
     435       54407 :   PetscCall(MatSetOption(*A,MAT_HERMITIAN,flg));
     436       54407 :   PetscFunctionReturn(PETSC_SUCCESS);
     437             : }
     438             : 
     439             : /*@
     440             :    DSRestoreMat - Restores the matrix after DSGetMat() was called.
     441             : 
     442             :    Not Collective
     443             : 
     444             :    Input Parameters:
     445             : +  ds - the direct solver context
     446             : .  m  - the requested matrix
     447             : -  A  - the fetched Mat object
     448             : 
     449             :    Note:
     450             :    A call to this function must match a previous call of DSGetMat().
     451             : 
     452             :    Level: advanced
     453             : 
     454             : .seealso: DSGetMat(), DSRestoreArray(), DSRestoreArrayReal()
     455             : @*/
     456       54407 : PetscErrorCode DSRestoreMat(DS ds,DSMatType m,Mat *A)
     457             : {
     458       54407 :   PetscFunctionBegin;
     459       54407 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     460       54407 :   DSCheckAlloc(ds,1);
     461       54407 :   DSCheckValidMat(ds,m,2);
     462       54407 :   PetscAssertPointer(A,3);
     463             : 
     464       54407 :   PetscCall(MatDenseRestoreSubMatrix(ds->omat[m],A));
     465       54407 :   PetscCall(PetscObjectStateIncrease((PetscObject)ds));
     466       54407 :   PetscFunctionReturn(PETSC_SUCCESS);
     467             : }
     468             : 
     469             : /*@
     470             :    DSGetMatAndColumn - Returns a sequential dense Mat object containing the requested
     471             :    matrix and one of its columns as a Vec.
     472             : 
     473             :    Not Collective
     474             : 
     475             :    Input Parameters:
     476             : +  ds  - the direct solver context
     477             : .  m   - the requested matrix
     478             : -  col - the requested column
     479             : 
     480             :    Output Parameters:
     481             : +  A   - Mat object
     482             : -  v   - Vec object (the column)
     483             : 
     484             :    Notes:
     485             :    This calls DSGetMat() and then it extracts the selected column.
     486             :    The user must call DSRestoreMatAndColumn() to recover the original state.
     487             :    For matrices DS_MAT_T and DS_MAT_D, in complex scalars this function implies
     488             :    copying from real values stored internally to scalar values in the Vec.
     489             : 
     490             :    Level: advanced
     491             : 
     492             : .seealso: DSRestoreMatAndColumn(), DSGetMat()
     493             : @*/
     494         479 : PetscErrorCode DSGetMatAndColumn(DS ds,DSMatType m,PetscInt col,Mat *A,Vec *v)
     495             : {
     496         479 :   PetscFunctionBegin;
     497         479 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     498         479 :   DSCheckAlloc(ds,1);
     499         479 :   DSCheckValidMat(ds,m,2);
     500         479 :   PetscAssertPointer(A,4);
     501         479 :   PetscAssertPointer(v,5);
     502             : 
     503         479 :   PetscCall(DSGetMat(ds,m,A));
     504         479 :   if (PetscDefined(USE_COMPLEX) && (m==DS_MAT_T || m==DS_MAT_D)) {
     505         479 :     const PetscScalar *as;
     506         479 :     PetscScalar       *vs;
     507         479 :     PetscReal         *ar;
     508         479 :     PetscInt          i,n,lda;
     509         479 :     PetscCall(MatCreateVecs(*A,NULL,v));
     510         479 :     PetscCall(VecGetSize(*v,&n));
     511         479 :     PetscCall(MatDenseGetLDA(*A,&lda));
     512         479 :     PetscCall(MatDenseGetArrayRead(*A,&as));
     513         479 :     PetscCall(VecGetArrayWrite(*v,&vs));
     514         479 :     ar = (PetscReal*)as;
     515        8448 :     for (i=0;i<n;i++) vs[i] = ar[i+col*lda];
     516         479 :     PetscCall(VecRestoreArrayWrite(*v,&vs));
     517         479 :     PetscCall(MatDenseRestoreArrayRead(*A,&as));
     518           0 :   } else PetscCall(MatDenseGetColumnVec(*A,col,v));
     519         479 :   PetscFunctionReturn(PETSC_SUCCESS);
     520             : }
     521             : 
     522             : /*@
     523             :    DSRestoreMatAndColumn - Restores the matrix and vector after DSGetMatAndColumn()
     524             :    was called.
     525             : 
     526             :    Not Collective
     527             : 
     528             :    Input Parameters:
     529             : +  ds  - the direct solver context
     530             : .  m   - the requested matrix
     531             : .  col - the requested column
     532             : .  A   - the fetched Mat object
     533             : -  v   - the fetched Vec object
     534             : 
     535             :    Note:
     536             :    A call to this function must match a previous call of DSGetMatAndColumn().
     537             : 
     538             :    Level: advanced
     539             : 
     540             : .seealso: DSGetMatAndColumn(), DSRestoreMat()
     541             : @*/
     542         479 : PetscErrorCode DSRestoreMatAndColumn(DS ds,DSMatType m,PetscInt col,Mat *A,Vec *v)
     543             : {
     544         479 :   PetscFunctionBegin;
     545         479 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     546         479 :   DSCheckAlloc(ds,1);
     547         479 :   DSCheckValidMat(ds,m,2);
     548         479 :   PetscAssertPointer(A,4);
     549         479 :   PetscAssertPointer(v,5);
     550             : 
     551         479 :   if (PetscDefined(USE_COMPLEX) && (m==DS_MAT_T || m==DS_MAT_D)) {
     552         479 :     const PetscScalar *vs;
     553         479 :     PetscScalar       *as;
     554         479 :     PetscReal         *ar;
     555         479 :     PetscInt          i,n,lda;
     556         479 :     PetscCall(VecGetSize(*v,&n));
     557         479 :     PetscCall(MatDenseGetLDA(*A,&lda));
     558         479 :     PetscCall(MatDenseGetArray(*A,&as));
     559         479 :     PetscCall(VecGetArrayRead(*v,&vs));
     560         479 :     ar = (PetscReal*)as;
     561        8448 :     for (i=0;i<n;i++) ar[i+col*lda] = PetscRealPart(vs[i]);
     562         479 :     PetscCall(VecRestoreArrayRead(*v,&vs));
     563         479 :     PetscCall(MatDenseRestoreArray(*A,&as));
     564         479 :     PetscCall(VecDestroy(v));
     565           0 :   } else PetscCall(MatDenseRestoreColumnVec(*A,col,v));
     566         479 :   PetscCall(DSRestoreMat(ds,m,A));
     567         479 :   PetscFunctionReturn(PETSC_SUCCESS);
     568             : }
     569             : 
     570             : /*@C
     571             :    DSGetArray - Returns a pointer to the internal array of one of the
     572             :    matrices. You MUST call DSRestoreArray() when you no longer
     573             :    need to access the array.
     574             : 
     575             :    Not Collective
     576             : 
     577             :    Input Parameters:
     578             : +  ds - the direct solver context
     579             : -  m  - the requested matrix
     580             : 
     581             :    Output Parameter:
     582             : .  a  - pointer to the values
     583             : 
     584             :    Note:
     585             :    To get read-only access, use DSGetMat() followed by MatDenseGetArrayRead().
     586             : 
     587             :    Level: advanced
     588             : 
     589             : .seealso: DSRestoreArray(), DSGetArrayReal()
     590             : @*/
     591       67240 : PetscErrorCode DSGetArray(DS ds,DSMatType m,PetscScalar *a[])
     592             : {
     593       67240 :   PetscFunctionBegin;
     594       67240 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     595       67240 :   DSCheckAlloc(ds,1);
     596       67240 :   DSCheckValidMat(ds,m,2);
     597       67240 :   PetscAssertPointer(a,3);
     598       67240 :   PetscCall(MatDenseGetArray(ds->omat[m],a));
     599       67240 :   PetscFunctionReturn(PETSC_SUCCESS);
     600             : }
     601             : 
     602             : /*@C
     603             :    DSRestoreArray - Restores the matrix after DSGetArray() was called.
     604             : 
     605             :    Not Collective
     606             : 
     607             :    Input Parameters:
     608             : +  ds - the direct solver context
     609             : .  m  - the requested matrix
     610             : -  a  - pointer to the values
     611             : 
     612             :    Level: advanced
     613             : 
     614             : .seealso: DSGetArray(), DSGetArrayReal()
     615             : @*/
     616       67140 : PetscErrorCode DSRestoreArray(DS ds,DSMatType m,PetscScalar *a[])
     617             : {
     618       67140 :   PetscFunctionBegin;
     619       67140 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     620       67140 :   DSCheckAlloc(ds,1);
     621       67140 :   DSCheckValidMat(ds,m,2);
     622       67140 :   PetscAssertPointer(a,3);
     623       67140 :   PetscCall(MatDenseRestoreArray(ds->omat[m],a));
     624       67140 :   PetscCall(PetscObjectStateIncrease((PetscObject)ds));
     625       67140 :   PetscFunctionReturn(PETSC_SUCCESS);
     626             : }
     627             : 
     628             : /*@C
     629             :    DSGetArrayReal - Returns a real pointer to the internal array of T or D.
     630             :    You MUST call DSRestoreArrayReal() when you no longer need to access the array.
     631             : 
     632             :    Not Collective
     633             : 
     634             :    Input Parameters:
     635             : +  ds - the direct solver context
     636             : -  m  - the requested matrix
     637             : 
     638             :    Output Parameter:
     639             : .  a  - pointer to the values
     640             : 
     641             :    Note:
     642             :    This function can be used only for DS_MAT_T and DS_MAT_D. These matrices always
     643             :    store real values, even in complex scalars, that is why the returned pointer is
     644             :    PetscReal.
     645             : 
     646             :    Level: advanced
     647             : 
     648             : .seealso: DSRestoreArrayReal(), DSGetArray()
     649             : @*/
     650       71132 : PetscErrorCode DSGetArrayReal(DS ds,DSMatType m,PetscReal *a[])
     651             : {
     652             : #if defined(PETSC_USE_COMPLEX)
     653       71132 :   PetscScalar *as;
     654             : #endif
     655             : 
     656       71132 :   PetscFunctionBegin;
     657       71132 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     658       71132 :   DSCheckAlloc(ds,1);
     659       71132 :   DSCheckValidMatReal(ds,m,2);
     660       71132 :   PetscAssertPointer(a,3);
     661             : #if defined(PETSC_USE_COMPLEX)
     662       71132 :   PetscCall(MatDenseGetArray(ds->omat[m],&as));
     663       71132 :   *a = (PetscReal*)as;
     664             : #else
     665             :   PetscCall(MatDenseGetArray(ds->omat[m],a));
     666             : #endif
     667       71132 :   PetscFunctionReturn(PETSC_SUCCESS);
     668             : }
     669             : 
     670             : /*@C
     671             :    DSRestoreArrayReal - Restores the matrix after DSGetArrayReal() was called.
     672             : 
     673             :    Not Collective
     674             : 
     675             :    Input Parameters:
     676             : +  ds - the direct solver context
     677             : .  m  - the requested matrix
     678             : -  a  - pointer to the values
     679             : 
     680             :    Level: advanced
     681             : 
     682             : .seealso: DSGetArrayReal(), DSGetArray()
     683             : @*/
     684       71130 : PetscErrorCode DSRestoreArrayReal(DS ds,DSMatType m,PetscReal *a[])
     685             : {
     686             : #if defined(PETSC_USE_COMPLEX)
     687       71130 :   PetscScalar *as;
     688             : #endif
     689             : 
     690       71130 :   PetscFunctionBegin;
     691       71130 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     692       71130 :   DSCheckAlloc(ds,1);
     693       71130 :   DSCheckValidMatReal(ds,m,2);
     694       71130 :   PetscAssertPointer(a,3);
     695             : #if defined(PETSC_USE_COMPLEX)
     696       71130 :   PetscCall(MatDenseRestoreArray(ds->omat[m],&as));
     697       71130 :   *a = NULL;
     698             : #else
     699             :   PetscCall(MatDenseRestoreArray(ds->omat[m],a));
     700             : #endif
     701       71130 :   PetscCall(PetscObjectStateIncrease((PetscObject)ds));
     702       71130 :   PetscFunctionReturn(PETSC_SUCCESS);
     703             : }
     704             : 
     705             : /*@
     706             :    DSSolve - Solves the problem.
     707             : 
     708             :    Logically Collective
     709             : 
     710             :    Input Parameters:
     711             : +  ds   - the direct solver context
     712             : .  eigr - array to store the computed eigenvalues (real part)
     713             : -  eigi - array to store the computed eigenvalues (imaginary part)
     714             : 
     715             :    Note:
     716             :    This call brings the dense system to condensed form. No ordering
     717             :    of the eigenvalues is enforced (for this, call DSSort() afterwards).
     718             : 
     719             :    Level: intermediate
     720             : 
     721             : .seealso: DSSort(), DSStateType
     722             : @*/
     723       20100 : PetscErrorCode DSSolve(DS ds,PetscScalar eigr[],PetscScalar eigi[])
     724             : {
     725       20100 :   PetscFunctionBegin;
     726       20100 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     727       20100 :   PetscValidType(ds,1);
     728       20100 :   DSCheckAlloc(ds,1);
     729       20100 :   PetscAssertPointer(eigr,2);
     730       20100 :   if (ds->state>=DS_STATE_CONDENSED) PetscFunctionReturn(PETSC_SUCCESS);
     731       20075 :   PetscCheck(ds->ops->solve[ds->method],PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_OUTOFRANGE,"The specified method number does not exist for this DS");
     732       20075 :   PetscCall(PetscInfo(ds,"Starting solve with problem sizes: n=%" PetscInt_FMT ", l=%" PetscInt_FMT ", k=%" PetscInt_FMT "\n",ds->n,ds->l,ds->k));
     733       20075 :   PetscCall(PetscLogEventBegin(DS_Solve,ds,0,0,0));
     734       20075 :   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
     735       20075 :   PetscUseTypeMethod(ds,solve[ds->method],eigr,eigi);
     736       20075 :   PetscCall(PetscFPTrapPop());
     737       20075 :   PetscCall(PetscLogEventEnd(DS_Solve,ds,0,0,0));
     738       20075 :   PetscCall(PetscInfo(ds,"State has changed from %s to CONDENSED\n",DSStateTypes[ds->state]));
     739       20075 :   ds->state = DS_STATE_CONDENSED;
     740       20075 :   PetscCall(PetscObjectStateIncrease((PetscObject)ds));
     741       20075 :   PetscFunctionReturn(PETSC_SUCCESS);
     742             : }
     743             : 
     744             : /*@
     745             :    DSSort - Sorts the result of DSSolve() according to a given sorting
     746             :    criterion.
     747             : 
     748             :    Logically Collective
     749             : 
     750             :    Input Parameters:
     751             : +  ds   - the direct solver context
     752             : .  rr   - (optional) array containing auxiliary values (real part)
     753             : -  ri   - (optional) array containing auxiliary values (imaginary part)
     754             : 
     755             :    Input/Output Parameters:
     756             : +  eigr - array containing the computed eigenvalues (real part)
     757             : .  eigi - array containing the computed eigenvalues (imaginary part)
     758             : -  k    - (optional) number of elements in the leading group
     759             : 
     760             :    Notes:
     761             :    This routine sorts the arrays provided in eigr and eigi, and also
     762             :    sorts the dense system stored inside ds (assumed to be in condensed form).
     763             :    The sorting criterion is specified with DSSetSlepcSC().
     764             : 
     765             :    If arrays rr and ri are provided, then a (partial) reordering based on these
     766             :    values rather than on the eigenvalues is performed. In symmetric problems
     767             :    a total order is obtained (parameter k is ignored), but otherwise the result
     768             :    is sorted only partially. In this latter case, it is only guaranteed that
     769             :    all the first k elements satisfy the comparison with any of the last n-k
     770             :    elements. The output value of parameter k is the final number of elements in
     771             :    the first set.
     772             : 
     773             :    Level: intermediate
     774             : 
     775             : .seealso: DSSolve(), DSSetSlepcSC(), DSSortWithPermutation()
     776             : @*/
     777       28620 : PetscErrorCode DSSort(DS ds,PetscScalar eigr[],PetscScalar eigi[],PetscScalar rr[],PetscScalar ri[],PetscInt *k)
     778             : {
     779       28620 :   PetscInt       i;
     780             : 
     781       28620 :   PetscFunctionBegin;
     782       28620 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     783       28620 :   PetscValidType(ds,1);
     784       28620 :   DSCheckSolved(ds,1);
     785       28620 :   PetscAssertPointer(eigr,2);
     786       28620 :   if (rr) PetscAssertPointer(rr,4);
     787       28620 :   PetscCheck(ds->state<DS_STATE_TRUNCATED,PetscObjectComm((PetscObject)ds),PETSC_ERR_ORDER,"Cannot sort a truncated DS");
     788       28620 :   PetscCheck(ds->sc,PetscObjectComm((PetscObject)ds),PETSC_ERR_ORDER,"Must provide a sorting criterion first");
     789       28620 :   PetscCheck(!k || rr,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_WRONG,"Argument k can only be used together with rr");
     790             : 
     791      405411 :   for (i=0;i<ds->n;i++) ds->perm[i] = i;   /* initialize to trivial permutation */
     792       28620 :   PetscCall(PetscLogEventBegin(DS_Other,ds,0,0,0));
     793       28620 :   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
     794       28620 :   PetscUseTypeMethod(ds,sort,eigr,eigi,rr,ri,k);
     795       28620 :   PetscCall(PetscFPTrapPop());
     796       28620 :   PetscCall(PetscLogEventEnd(DS_Other,ds,0,0,0));
     797       28620 :   PetscCall(PetscObjectStateIncrease((PetscObject)ds));
     798       28620 :   PetscCall(PetscInfo(ds,"Finished sorting\n"));
     799       28620 :   PetscFunctionReturn(PETSC_SUCCESS);
     800             : }
     801             : 
     802             : /*@
     803             :    DSSortWithPermutation - Reorders the result of DSSolve() according to a given
     804             :    permutation.
     805             : 
     806             :    Logically Collective
     807             : 
     808             :    Input Parameters:
     809             : +  ds   - the direct solver context
     810             : -  perm - permutation that indicates the new ordering
     811             : 
     812             :    Input/Output Parameters:
     813             : +  eigr - array with the reordered eigenvalues (real part)
     814             : -  eigi - array with the reordered eigenvalues (imaginary part)
     815             : 
     816             :    Notes:
     817             :    This routine reorders the arrays provided in eigr and eigi, and also the dense
     818             :    system stored inside ds (assumed to be in condensed form). There is no sorting
     819             :    criterion, as opposed to DSSort(). Instead, the new ordering is given in argument perm.
     820             : 
     821             :    Level: advanced
     822             : 
     823             : .seealso: DSSolve(), DSSort()
     824             : @*/
     825           1 : PetscErrorCode DSSortWithPermutation(DS ds,PetscInt perm[],PetscScalar eigr[],PetscScalar eigi[])
     826             : {
     827           1 :   PetscFunctionBegin;
     828           1 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     829           1 :   PetscValidType(ds,1);
     830           1 :   DSCheckSolved(ds,1);
     831           1 :   PetscAssertPointer(perm,2);
     832           1 :   PetscAssertPointer(eigr,3);
     833           1 :   PetscCheck(ds->state<DS_STATE_TRUNCATED,PetscObjectComm((PetscObject)ds),PETSC_ERR_ORDER,"Cannot sort a truncated DS");
     834             : 
     835           1 :   PetscCall(PetscLogEventBegin(DS_Other,ds,0,0,0));
     836           1 :   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
     837           1 :   PetscUseTypeMethod(ds,sortperm,perm,eigr,eigi);
     838           1 :   PetscCall(PetscFPTrapPop());
     839           1 :   PetscCall(PetscLogEventEnd(DS_Other,ds,0,0,0));
     840           1 :   PetscCall(PetscObjectStateIncrease((PetscObject)ds));
     841           1 :   PetscCall(PetscInfo(ds,"Finished sorting\n"));
     842           1 :   PetscFunctionReturn(PETSC_SUCCESS);
     843             : }
     844             : 
     845             : /*@
     846             :    DSSynchronize - Make sure that all processes have the same data, performing
     847             :    communication if necessary.
     848             : 
     849             :    Collective
     850             : 
     851             :    Input Parameter:
     852             : .  ds   - the direct solver context
     853             : 
     854             :    Input/Output Parameters:
     855             : +  eigr - (optional) array with the computed eigenvalues (real part)
     856             : -  eigi - (optional) array with the computed eigenvalues (imaginary part)
     857             : 
     858             :    Notes:
     859             :    When the DS has been created with a communicator with more than one process,
     860             :    the internal data, especially the computed matrices, may diverge in the
     861             :    different processes. This happens when using multithreaded BLAS and may
     862             :    cause numerical issues in some ill-conditioned problems. This function
     863             :    performs the necessary communication among the processes so that the
     864             :    internal data is exactly equal in all of them.
     865             : 
     866             :    Depending on the parallel mode as set with DSSetParallel(), this function
     867             :    will either do nothing or synchronize the matrices computed by DSSolve()
     868             :    and DSSort(). The arguments eigr and eigi are typically those used in the
     869             :    calls to DSSolve() and DSSort().
     870             : 
     871             :    Level: developer
     872             : 
     873             : .seealso: DSSetParallel(), DSSolve(), DSSort()
     874             : @*/
     875       19899 : PetscErrorCode DSSynchronize(DS ds,PetscScalar eigr[],PetscScalar eigi[])
     876             : {
     877       19899 :   PetscMPIInt    size;
     878             : 
     879       19899 :   PetscFunctionBegin;
     880       19899 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     881       19899 :   PetscValidType(ds,1);
     882       19899 :   DSCheckAlloc(ds,1);
     883       19899 :   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)ds),&size));
     884       19899 :   if (size>1 && ds->pmode==DS_PARALLEL_SYNCHRONIZED) {
     885         350 :     PetscCall(PetscLogEventBegin(DS_Synchronize,ds,0,0,0));
     886         350 :     PetscUseTypeMethod(ds,synchronize,eigr,eigi);
     887         350 :     PetscCall(PetscLogEventEnd(DS_Synchronize,ds,0,0,0));
     888         350 :     PetscCall(PetscObjectStateIncrease((PetscObject)ds));
     889         350 :     PetscCall(PetscInfo(ds,"Synchronization completed (%s)\n",DSParallelTypes[ds->pmode]));
     890             :   }
     891       19899 :   PetscFunctionReturn(PETSC_SUCCESS);
     892             : }
     893             : 
     894             : /*@
     895             :    DSVectors - Compute vectors associated to the dense system such
     896             :    as eigenvectors.
     897             : 
     898             :    Logically Collective
     899             : 
     900             :    Input Parameters:
     901             : +  ds  - the direct solver context
     902             : -  mat - the matrix, used to indicate which vectors are required
     903             : 
     904             :    Input/Output Parameter:
     905             : .  j   - (optional) index of vector to be computed
     906             : 
     907             :    Output Parameter:
     908             : .  rnorm - (optional) computed residual norm
     909             : 
     910             :    Notes:
     911             :    Allowed values for mat are DS_MAT_X, DS_MAT_Y, DS_MAT_U and DS_MAT_V, to
     912             :    compute right or left eigenvectors, or left or right singular vectors,
     913             :    respectively.
     914             : 
     915             :    If NULL is passed in argument j then all vectors are computed,
     916             :    otherwise j indicates which vector must be computed. In real non-symmetric
     917             :    problems, on exit the index j will be incremented when a complex conjugate
     918             :    pair is found.
     919             : 
     920             :    This function can be invoked after the dense problem has been solved,
     921             :    to get the residual norm estimate of the associated Ritz pair. In that
     922             :    case, the relevant information is returned in rnorm.
     923             : 
     924             :    For computing eigenvectors, LAPACK's _trevc is used so the matrix must
     925             :    be in (quasi-)triangular form, or call DSSolve() first.
     926             : 
     927             :    Level: intermediate
     928             : 
     929             : .seealso: DSSolve()
     930             : @*/
     931       47372 : PetscErrorCode DSVectors(DS ds,DSMatType mat,PetscInt *j,PetscReal *rnorm)
     932             : {
     933       47372 :   PetscFunctionBegin;
     934       47372 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     935       47372 :   PetscValidType(ds,1);
     936       47372 :   DSCheckAlloc(ds,1);
     937      142116 :   PetscValidLogicalCollectiveEnum(ds,mat,2);
     938       47372 :   PetscCheck(mat<DS_NUM_MAT,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_WRONG,"Invalid matrix");
     939       47372 :   PetscCheck(!rnorm || j,PetscObjectComm((PetscObject)ds),PETSC_ERR_ORDER,"Must give a value of j");
     940       47372 :   if (!ds->omat[mat]) PetscCall(DSAllocateMat_Private(ds,mat));
     941       47372 :   if (!j) PetscCall(PetscInfo(ds,"Computing all vectors on %s\n",DSMatName[mat]));
     942       47372 :   PetscCall(PetscLogEventBegin(DS_Vectors,ds,0,0,0));
     943       47372 :   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
     944       47372 :   PetscUseTypeMethod(ds,vectors,mat,j,rnorm);
     945       47372 :   PetscCall(PetscFPTrapPop());
     946       47372 :   PetscCall(PetscLogEventEnd(DS_Vectors,ds,0,0,0));
     947       47372 :   PetscCall(PetscObjectStateIncrease((PetscObject)ds));
     948       47372 :   PetscFunctionReturn(PETSC_SUCCESS);
     949             : }
     950             : 
     951             : /*@
     952             :    DSUpdateExtraRow - Performs all necessary operations so that the extra
     953             :    row gets up-to-date after a call to DSSolve().
     954             : 
     955             :    Logically Collective
     956             : 
     957             :    Input Parameters:
     958             : .  ds - the direct solver context
     959             : 
     960             :    Level: advanced
     961             : 
     962             : .seealso: DSSolve(), DSSetExtraRow()
     963             : @*/
     964        7339 : PetscErrorCode DSUpdateExtraRow(DS ds)
     965             : {
     966        7339 :   PetscFunctionBegin;
     967        7339 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
     968        7339 :   PetscValidType(ds,1);
     969        7339 :   DSCheckAlloc(ds,1);
     970        7339 :   PetscCheck(ds->extrarow,PetscObjectComm((PetscObject)ds),PETSC_ERR_ARG_WRONGSTATE,"Should have called DSSetExtraRow");
     971        7339 :   PetscCall(PetscInfo(ds,"Updating extra row\n"));
     972        7339 :   PetscCall(PetscLogEventBegin(DS_Other,ds,0,0,0));
     973        7339 :   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
     974        7339 :   PetscUseTypeMethod(ds,update);
     975        7339 :   PetscCall(PetscFPTrapPop());
     976        7339 :   PetscCall(PetscLogEventEnd(DS_Other,ds,0,0,0));
     977        7339 :   PetscFunctionReturn(PETSC_SUCCESS);
     978             : }
     979             : 
     980             : /*@
     981             :    DSCond - Compute the condition number.
     982             : 
     983             :    Logically Collective
     984             : 
     985             :    Input Parameters:
     986             : +  ds - the direct solver context
     987             : -  cond - the computed condition number
     988             : 
     989             :    Notes:
     990             :    In standard eigenvalue problems, returns the inf-norm condition number of the first
     991             :    matrix, computed as cond(A) = norm(A)*norm(inv(A)).
     992             : 
     993             :    In GSVD problems, returns the maximum of cond(A) and cond(B), where cond(.) is
     994             :    computed as the ratio of the largest and smallest singular values.
     995             : 
     996             :    Does not take into account the extra row.
     997             : 
     998             :    Level: advanced
     999             : 
    1000             : .seealso: DSSolve(), DSSetExtraRow()
    1001             : @*/
    1002         177 : PetscErrorCode DSCond(DS ds,PetscReal *cond)
    1003             : {
    1004         177 :   PetscFunctionBegin;
    1005         177 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
    1006         177 :   PetscValidType(ds,1);
    1007         177 :   DSCheckAlloc(ds,1);
    1008         177 :   PetscAssertPointer(cond,2);
    1009         177 :   PetscCall(PetscLogEventBegin(DS_Other,ds,0,0,0));
    1010         177 :   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
    1011         177 :   PetscUseTypeMethod(ds,cond,cond);
    1012         177 :   PetscCall(PetscFPTrapPop());
    1013         177 :   PetscCall(PetscLogEventEnd(DS_Other,ds,0,0,0));
    1014         177 :   PetscCall(PetscInfo(ds,"Computed condition number = %g\n",(double)*cond));
    1015         177 :   PetscFunctionReturn(PETSC_SUCCESS);
    1016             : }
    1017             : 
    1018             : /*@
    1019             :    DSTranslateHarmonic - Computes a translation of the dense system.
    1020             : 
    1021             :    Logically Collective
    1022             : 
    1023             :    Input Parameters:
    1024             : +  ds      - the direct solver context
    1025             : .  tau     - the translation amount
    1026             : .  beta    - last component of vector b
    1027             : -  recover - boolean flag to indicate whether to recover or not
    1028             : 
    1029             :    Output Parameters:
    1030             : +  g       - the computed vector (optional)
    1031             : -  gamma   - scale factor (optional)
    1032             : 
    1033             :    Notes:
    1034             :    This function is intended for use in the context of Krylov methods only.
    1035             :    It computes a translation of a Krylov decomposition in order to extract
    1036             :    eigenpair approximations by harmonic Rayleigh-Ritz.
    1037             :    The matrix is updated as A + g*b' where g = (A-tau*eye(n))'\b and
    1038             :    vector b is assumed to be beta*e_n^T.
    1039             : 
    1040             :    The gamma factor is defined as sqrt(1+g'*g) and can be interpreted as
    1041             :    the factor by which the residual of the Krylov decomposition is scaled.
    1042             : 
    1043             :    If the recover flag is activated, the computed translation undoes the
    1044             :    translation done previously. In that case, parameter tau is ignored.
    1045             : 
    1046             :    Level: developer
    1047             : 
    1048             : .seealso: DSTranslateRKS()
    1049             : @*/
    1050          80 : PetscErrorCode DSTranslateHarmonic(DS ds,PetscScalar tau,PetscReal beta,PetscBool recover,PetscScalar *g,PetscReal *gamma)
    1051             : {
    1052          80 :   PetscFunctionBegin;
    1053          80 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
    1054          80 :   PetscValidType(ds,1);
    1055          80 :   DSCheckAlloc(ds,1);
    1056          80 :   if (recover) PetscCall(PetscInfo(ds,"Undoing the translation\n"));
    1057          56 :   else PetscCall(PetscInfo(ds,"Computing the translation\n"));
    1058          80 :   PetscCall(PetscLogEventBegin(DS_Other,ds,0,0,0));
    1059          80 :   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
    1060          80 :   PetscUseTypeMethod(ds,transharm,tau,beta,recover,g,gamma);
    1061          80 :   PetscCall(PetscFPTrapPop());
    1062          80 :   PetscCall(PetscLogEventEnd(DS_Other,ds,0,0,0));
    1063          80 :   ds->state = DS_STATE_RAW;
    1064          80 :   PetscCall(PetscObjectStateIncrease((PetscObject)ds));
    1065          80 :   PetscFunctionReturn(PETSC_SUCCESS);
    1066             : }
    1067             : 
    1068             : /*@
    1069             :    DSTranslateRKS - Computes a modification of the dense system corresponding
    1070             :    to an update of the shift in a rational Krylov method.
    1071             : 
    1072             :    Logically Collective
    1073             : 
    1074             :    Input Parameters:
    1075             : +  ds    - the direct solver context
    1076             : -  alpha - the translation amount
    1077             : 
    1078             :    Notes:
    1079             :    This function is intended for use in the context of Krylov methods only.
    1080             :    It takes the leading (k+1,k) submatrix of A, containing the truncated
    1081             :    Rayleigh quotient of a Krylov-Schur relation computed from a shift
    1082             :    sigma1 and transforms it to obtain a Krylov relation as if computed
    1083             :    from a different shift sigma2. The new matrix is computed as
    1084             :    1.0/alpha*(eye(k)-Q*inv(R)), where [Q,R]=qr(eye(k)-alpha*A) and
    1085             :    alpha = sigma1-sigma2.
    1086             : 
    1087             :    Matrix Q is placed in DS_MAT_Q so that it can be used to update the
    1088             :    Krylov basis.
    1089             : 
    1090             :    Level: developer
    1091             : 
    1092             : .seealso: DSTranslateHarmonic()
    1093             : @*/
    1094          11 : PetscErrorCode DSTranslateRKS(DS ds,PetscScalar alpha)
    1095             : {
    1096          11 :   PetscFunctionBegin;
    1097          11 :   PetscValidHeaderSpecific(ds,DS_CLASSID,1);
    1098          11 :   PetscValidType(ds,1);
    1099          11 :   DSCheckAlloc(ds,1);
    1100          11 :   PetscCall(PetscInfo(ds,"Translating with alpha=%g\n",(double)PetscRealPart(alpha)));
    1101          11 :   PetscCall(DSSetCompact(ds,PETSC_FALSE));
    1102          11 :   PetscCall(PetscLogEventBegin(DS_Other,ds,0,0,0));
    1103          11 :   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
    1104          11 :   PetscUseTypeMethod(ds,transrks,alpha);
    1105          11 :   PetscCall(PetscFPTrapPop());
    1106          11 :   PetscCall(PetscLogEventEnd(DS_Other,ds,0,0,0));
    1107          11 :   ds->state = DS_STATE_RAW;
    1108          11 :   PetscCall(PetscObjectStateIncrease((PetscObject)ds));
    1109          11 :   PetscFunctionReturn(PETSC_SUCCESS);
    1110             : }

Generated by: LCOV version 1.14