Date: 2016-03-29T14:57:35+00:00

Actual source code: rginterval.c
slepc-3.6.3 2016-03-29
Report Typos and Errors

      1: /*
      2:    Interval of the real axis or more generally a (possibly open) rectangle
      3:    of the complex plane.

      5:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      6:    SLEPc - Scalable Library for Eigenvalue Problem Computations
      7:    Copyright (c) 2002-2015, Universitat Politecnica de Valencia, Spain

      9:    This file is part of SLEPc.

     11:    SLEPc is free software: you can redistribute it and/or modify it under  the
     12:    terms of version 3 of the GNU Lesser General Public License as published by
     13:    the Free Software Foundation.

     15:    SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
     16:    WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
     17:    FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
     18:    more details.

     20:    You  should have received a copy of the GNU Lesser General  Public  License
     21:    along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
     22:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     23: */

     25: #include <slepc/private/rgimpl.h>      /*I "slepcrg.h" I*/

     27: typedef struct {
     28:   PetscReal   a,b;     /* interval in the real axis */
     29:   PetscReal   c,d;     /* interval in the imaginary axis */
     30: } RG_INTERVAL;

     34: static PetscErrorCode RGIntervalSetEndpoints_Interval(RG rg,PetscReal a,PetscReal b,PetscReal c,PetscReal d)
     35: {
     36:   RG_INTERVAL *ctx = (RG_INTERVAL*)rg->data;

     39:   if (!a && !b && !c && !d) SETERRQ(PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_WRONG,"At least one argument must be nonzero");
     40:   if (a==b && a) SETERRQ(PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_WRONG,"Badly defined interval, endpoints must be distinct (or both zero)");
     41:   if (a>b) SETERRQ(PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_WRONG,"Badly defined interval, must be a<b");
     42:   if (c==d && c) SETERRQ(PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_WRONG,"Badly defined interval, endpoints must be distinct (or both zero)");
     43:   if (c>d) SETERRQ(PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_WRONG,"Badly defined interval, must be c<d");
     44: #if !defined(PETSC_USE_COMPLEX)
     45:   if (c!=-d) SETERRQ(PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_WRONG,"In real scalars the region must be symmetric wrt real axis");
     46: #endif
     47:   ctx->a = a;
     48:   ctx->b = b;
     49:   ctx->c = c;
     50:   ctx->d = d;
     51:   return(0);
     52: }

     56: /*@
     57:    RGIntervalSetEndpoints - Sets the parameters defining the interval region.

     59:    Logically Collective on RG

     61:    Input Parameters:
     62: +  rg  - the region context
     63: .  a,b - endpoints of the interval in the real axis
     64: -  c,d - endpoints of the interval in the imaginary axis

     66:    Options Database Keys:
     67: .  -rg_interval_endpoints - the four endpoints

     69:    Note:
     70:    The region is defined as [a,b]x[c,d]. Particular cases are an interval on
     71:    the real axis (c=d=0), similar for the imaginary axis (a=b=0), the whole
     72:    complex plane (a=-inf,b=inf,c=-inf,d=inf), and so on.

     74:    Level: advanced

     76: .seealso: RGIntervalGetEndpoints()
     77: @*/
     78: PetscErrorCode RGIntervalSetEndpoints(RG rg,PetscReal a,PetscReal b,PetscReal c,PetscReal d)
     79: {

     88:   PetscTryMethod(rg,"RGIntervalSetEndpoints_C",(RG,PetscReal,PetscReal,PetscReal,PetscReal),(rg,a,b,c,d));
     89:   return(0);
     90: }

     94: static PetscErrorCode RGIntervalGetEndpoints_Interval(RG rg,PetscReal *a,PetscReal *b,PetscReal *c,PetscReal *d)
     95: {
     96:   RG_INTERVAL *ctx = (RG_INTERVAL*)rg->data;

     99:   if (a) *a = ctx->a;
    100:   if (b) *b = ctx->b;
    101:   if (c) *c = ctx->c;
    102:   if (d) *d = ctx->d;
    103:   return(0);
    104: }

    108: /*@
    109:    RGIntervalGetEndpoints - Gets the parameters that define the interval region.

    111:    Not Collective

    113:    Input Parameter:
    114: .  rg - the region context

    116:    Output Parameters:
    117: +  a,b - endpoints of the interval in the real axis
    118: -  c,d - endpoints of the interval in the imaginary axis

    120:    Level: advanced

    122: .seealso: RGIntervalSetEndpoints()
    123: @*/
    124: PetscErrorCode RGIntervalGetEndpoints(RG rg,PetscReal *a,PetscReal *b,PetscReal *c,PetscReal *d)
    125: {

    130:   PetscTryMethod(rg,"RGIntervalGetEndpoints_C",(RG,PetscReal*,PetscReal*,PetscReal*,PetscReal*),(rg,a,b,c,d));
    131:   return(0);
    132: }

    136: PetscErrorCode RGView_Interval(RG rg,PetscViewer viewer)
    137: {
    139:   RG_INTERVAL    *ctx = (RG_INTERVAL*)rg->data;
    140:   PetscBool      isascii;

    143:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    144:   if (isascii) {
    145:     PetscViewerASCIIPrintf(viewer,"region: [%g,%g]x[%g,%g]\n",RGShowReal(ctx->a),RGShowReal(ctx->b),RGShowReal(ctx->c),RGShowReal(ctx->d));
    146:   }
    147:   return(0);
    148: }

    152: PetscErrorCode RGIsTrivial_Interval(RG rg,PetscBool *trivial)
    153: {
    154:   RG_INTERVAL *ctx = (RG_INTERVAL*)rg->data;

    157:   if (rg->complement) *trivial = (ctx->a==ctx->b && ctx->c==ctx->d)? PETSC_TRUE: PETSC_FALSE;
    158:   else *trivial = (ctx->a<=-PETSC_MAX_REAL && ctx->b>=PETSC_MAX_REAL && ctx->c<=-PETSC_MAX_REAL && ctx->d>=PETSC_MAX_REAL)? PETSC_TRUE: PETSC_FALSE;
    159:   return(0);
    160: }

    164: PetscErrorCode RGComputeContour_Interval(RG rg,PetscInt n,PetscScalar *cr,PetscScalar *ci)
    165: {
    166:   RG_INTERVAL *ctx = (RG_INTERVAL*)rg->data;

    169:   if (!(ctx->a>-PETSC_MAX_REAL && ctx->b<PETSC_MAX_REAL && ctx->c>-PETSC_MAX_REAL && ctx->d<PETSC_MAX_REAL)) SETERRQ(PetscObjectComm((PetscObject)rg),PETSC_ERR_SUP,"Contour not defined in unbounded regions");
    170:   SETERRQ(PetscObjectComm((PetscObject)rg),1,"Not implemented yet");
    171:   return(0);
    172: }

    176: PetscErrorCode RGCheckInside_Interval(RG rg,PetscReal dx,PetscReal dy,PetscInt *inside)
    177: {
    178:   RG_INTERVAL *ctx = (RG_INTERVAL*)rg->data;

    181:   if (dx>ctx->a && dx<ctx->b) *inside = 1;
    182:   else if (dx==ctx->a || dx==ctx->b) *inside = 0;
    183:   else *inside = -1;
    184:   if (*inside>=0) {
    185:     if (dy>ctx->c && dy<ctx->d) ;
    186:     else if (dy==ctx->c || dy==ctx->d) *inside = 0;
    187:     else *inside = -1;
    188:   }
    189:   return(0);
    190: }

    194: PetscErrorCode RGSetFromOptions_Interval(PetscOptions *PetscOptionsObject,RG rg)
    195: {
    197:   PetscBool      flg;
    198:   PetscInt       k;
    199:   PetscReal      array[4]={0,0,0,0};

    202:   PetscOptionsHead(PetscOptionsObject,"RG Interval Options");

    204:   k = 4;
    205:   PetscOptionsRealArray("-rg_interval_endpoints","Interval endpoints (four real values separated with a comma without spaces)","RGIntervalSetEndpoints",array,&k,&flg);
    206:   if (flg) {
    207:     if (k<2) SETERRQ(PetscObjectComm((PetscObject)rg),PETSC_ERR_ARG_SIZ,"Must pass at leat two values in -rg_interval_endpoints (comma-separated without spaces)");
    208:     RGIntervalSetEndpoints(rg,array[0],array[1],array[2],array[3]);
    209:   }

    211:   PetscOptionsTail();
    212:   return(0);
    213: }

    217: PetscErrorCode RGDestroy_Interval(RG rg)
    218: {

    222:   PetscFree(rg->data);
    223:   PetscObjectComposeFunction((PetscObject)rg,"RGIntervalSetEndpoints_C",NULL);
    224:   PetscObjectComposeFunction((PetscObject)rg,"RGIntervalGetEndpoints_C",NULL);
    225:   return(0);
    226: }

    230: PETSC_EXTERN PetscErrorCode RGCreate_Interval(RG rg)
    231: {
    232:   RG_INTERVAL    *interval;

    236:   PetscNewLog(rg,&interval);
    237:   interval->a = -PETSC_MAX_REAL;
    238:   interval->b = PETSC_MAX_REAL;
    239:   interval->c = -PETSC_MAX_REAL;
    240:   interval->d = PETSC_MAX_REAL;
    241:   rg->data = (void*)interval;

    243:   rg->ops->istrivial      = RGIsTrivial_Interval;
    244:   rg->ops->computecontour = RGComputeContour_Interval;
    245:   rg->ops->checkinside    = RGCheckInside_Interval;
    246:   rg->ops->setfromoptions = RGSetFromOptions_Interval;
    247:   rg->ops->view           = RGView_Interval;
    248:   rg->ops->destroy        = RGDestroy_Interval;
    249:   PetscObjectComposeFunction((PetscObject)rg,"RGIntervalSetEndpoints_C",RGIntervalSetEndpoints_Interval);
    250:   PetscObjectComposeFunction((PetscObject)rg,"RGIntervalGetEndpoints_C",RGIntervalGetEndpoints_Interval);
    251:   return(0);
    252: }