Actual source code: regressor.c

      1: #include <petsc/private/regressorimpl.h>

      3: PetscBool         PetscRegressorRegisterAllCalled = PETSC_FALSE;
      4: PetscFunctionList PetscRegressorList              = NULL;

      6: PetscClassId PETSCREGRESSOR_CLASSID;

      8: /* Logging support */
      9: PetscLogEvent PetscRegressor_SetUp, PetscRegressor_Fit, PetscRegressor_Predict;

     11: /*@C
     12:   PetscRegressorRegister - Adds a method to the `PetscRegressor` package.

     14:   Not collective

     16:   Input Parameters:
     17: + sname    - name of a new user-defined regressor
     18: - function - routine to create method context

     20:   Notes:
     21:   `PetscRegressorRegister()` may be called multiple times to add several user-defined regressors.

     23:   Example Usage:
     24: .vb
     25:    PetscRegressorRegister("my_regressor",MyRegressorCreate);
     26: .ve

     28:   Then, your regressor can be chosen with the procedural interface via
     29: .vb
     30:      PetscRegressorSetType(regressor,"my_regressor")
     31: .ve
     32:   or at runtime via the option
     33: .vb
     34:     -regressor_type my_regressor
     35: .ve

     37:   Level: advanced

     39: .seealso: `PetscRegressorRegisterAll()`
     40: @*/
     41: PetscErrorCode PetscRegressorRegister(const char sname[], PetscErrorCode (*function)(PetscRegressor))
     42: {
     43:   PetscFunctionBegin;
     44:   PetscCall(PetscRegressorInitializePackage());
     45:   PetscCall(PetscFunctionListAdd(&PetscRegressorList, sname, function));
     46:   PetscFunctionReturn(PETSC_SUCCESS);
     47: }

     49: /*@
     50:   PetscRegressorCreate - Creates a `PetscRegressor` object.

     52:   Collective

     54:   Input Parameter:
     55: . comm - the MPI communicator that will share the `PetscRegressor` object

     57:   Output Parameter:
     58: . newregressor - the new `PetscRegressor` object

     60:   Level: beginner

     62: .seealso: `PetscRegressorFit()`, `PetscRegressorPredict()`, `PetscRegressor`
     63: @*/
     64: PetscErrorCode PetscRegressorCreate(MPI_Comm comm, PetscRegressor *newregressor)
     65: {
     66:   PetscRegressor regressor;

     68:   PetscFunctionBegin;
     69:   PetscAssertPointer(newregressor, 2);
     70:   *newregressor = NULL;
     71:   PetscCall(PetscRegressorInitializePackage());

     73:   PetscCall(PetscHeaderCreate(regressor, PETSCREGRESSOR_CLASSID, "PetscRegressor", "Regressor", "PetscRegressor", comm, PetscRegressorDestroy, PetscRegressorView));

     75:   regressor->setupcalled = PETSC_FALSE;
     76:   regressor->fitcalled   = PETSC_FALSE;
     77:   regressor->data        = NULL;
     78:   regressor->training    = NULL;
     79:   regressor->target      = NULL;
     80:   PetscObjectParameterSetDefault(regressor, regularizer_weight, 1.0); // Default to regularizer weight of 1.0, usually the default in SciKit-learn

     82:   *newregressor = regressor;
     83:   PetscFunctionReturn(PETSC_SUCCESS);
     84: }

     86: /*@
     87:   PetscRegressorView - Prints information about the `PetscRegressor` object

     89:   Collective

     91:   Input Parameters:
     92: + regressor - the `PetscRegressor` context
     93: - viewer    - a `PetscViewer` context

     95:   Options Database Key:
     96: . -regressor_view - Calls `PetscRegressorView()` at the end of `PetscRegressorFit()`

     98:   Level: beginner

    100:   Notes:
    101:   The available visualization contexts include
    102: +     `PETSC_VIEWER_STDOUT_SELF` - standard output (default)
    103: -     `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard
    104:   output where only the first processor opens
    105:   the file.  All other processors send their
    106:   data to the first processor to print.

    108: .seealso: [](ch_regressor), `PetscRegressor`, `PetscViewerASCIIOpen()`
    109: @*/
    110: PetscErrorCode PetscRegressorView(PetscRegressor regressor, PetscViewer viewer)
    111: {
    112:   PetscBool          isascii, isstring;
    113:   PetscRegressorType type;

    115:   PetscFunctionBegin;
    117:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(((PetscObject)regressor)->comm, &viewer));
    119:   PetscCheckSameComm(regressor, 1, viewer, 2);

    121:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
    122:   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring));
    123:   if (isascii) {
    124:     PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)regressor, viewer));

    126:     PetscCall(PetscViewerASCIIPushTab(viewer));
    127:     PetscTryTypeMethod(regressor, view, viewer);
    128:     if (regressor->tao) PetscCall(TaoView(regressor->tao, viewer));
    129:     PetscCall(PetscViewerASCIIPopTab(viewer));
    130:   } else if (isstring) {
    131:     PetscCall(PetscRegressorGetType(regressor, &type));
    132:     PetscCall(PetscViewerStringSPrintf(viewer, " PetscRegressorType: %-7.7s", type));
    133:   }
    134:   PetscFunctionReturn(PETSC_SUCCESS);
    135: }

    137: /*@
    138:   PetscRegressorViewFromOptions - View a `PetscRegressor` object based on values in the options database

    140:   Collective

    142:   Input Parameters:
    143: + A    - the  `PetscRegressor` context
    144: . obj  - Optional object that provides the prefix for the options database
    145: - name - command line option

    147:   Level: intermediate

    149: .seealso: [](ch_regressor), `PetscRegressor`, `PetscRegressorView`, `PetscObjectViewFromOptions()`, `PetscRegressorCreate()`
    150: @*/
    151: PetscErrorCode PetscRegressorViewFromOptions(PetscRegressor A, PetscObject obj, const char name[])
    152: {
    153:   PetscFunctionBegin;
    155:   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
    156:   PetscFunctionReturn(PETSC_SUCCESS);
    157: }

    159: /*@
    160:   PetscRegressorSetFromOptions - Sets `PetscRegressor` options from the options database.

    162:   Collective

    164:   Input Parameter:
    165: . regressor - the `PetscRegressor` context

    167:   Options Database Keys:
    168: . -regressor_type <type> - the particular type of regressor to be used; see `PetscRegressorType` for complete list

    170:   Level: beginner

    172:   Note:
    173:   This routine must be called before `PetscRegressorSetUp()` (or `PetscRegressorFit()`, which calls
    174:   the former) if the user is to be allowed to set the regressor type.

    176: .seealso: `PetscRegressor`, `PetscRegressorCreate()`
    177: @*/
    178: PetscErrorCode PetscRegressorSetFromOptions(PetscRegressor regressor)
    179: {
    180:   PetscBool          flg;
    181:   PetscRegressorType default_type = PETSCREGRESSORLINEAR;
    182:   char               type[256];

    184:   PetscFunctionBegin;
    186:   if (((PetscObject)regressor)->type_name) default_type = ((PetscObject)regressor)->type_name;
    187:   PetscObjectOptionsBegin((PetscObject)regressor);
    188:   /* Check for type from options */
    189:   PetscCall(PetscOptionsFList("-regressor_type", "PetscRegressor type", "PetscRegressorSetType", PetscRegressorList, default_type, type, 256, &flg));
    190:   if (flg) {
    191:     PetscCall(PetscRegressorSetType(regressor, type));
    192:   } else if (!((PetscObject)regressor)->type_name) {
    193:     PetscCall(PetscRegressorSetType(regressor, default_type));
    194:   }
    195:   PetscCall(PetscOptionsReal("-regressor_regularizer_weight", "Weight for the regularizer", "PetscRegressorSetRegularizerWeight", regressor->regularizer_weight, &regressor->regularizer_weight, &flg));
    196:   if (flg) PetscCall(PetscRegressorSetRegularizerWeight(regressor, regressor->regularizer_weight));
    197:   // The above is a little superfluous, because we have already set regressor->regularizer_weight above, but we also need to set the flag indicating that the user has set the weight!
    198:   PetscTryTypeMethod(regressor, setfromoptions, PetscOptionsObject);
    199:   PetscOptionsEnd();
    200:   PetscFunctionReturn(PETSC_SUCCESS);
    201: }

    203: /*@
    204:   PetscRegressorSetUp - Sets up the internal data structures for the later use of a regressor.

    206:   Collective

    208:   Input Parameter:
    209: . regressor - the `PetscRegressor` context

    211:   Notes:
    212:   For basic use of the `PetscRegressor` solvers the user need not to explicitly call
    213:   `PetscRegressorSetUp()`, since these actions will automatically occur during
    214:   the call to `PetscRegressorFit()`.  However, if one wishes to control this
    215:   phase separately, `PetscRegressorSetUp()` should be called after `PetscRegressorCreate()`,
    216:   `PetscRegressorSetUp()`, and optional routines of the form `PetscRegressorSetXXX()`,
    217:   but before `PetscRegressorFit()`.

    219:   Level: advanced

    221: .seealso: `PetscRegressorCreate()`, `PetscRegressorFit()`, `PetscRegressorDestroy()`
    222: @*/
    223: PetscErrorCode PetscRegressorSetUp(PetscRegressor regressor)
    224: {
    225:   PetscFunctionBegin;
    227:   if (regressor->setupcalled) PetscFunctionReturn(PETSC_SUCCESS);
    228:   PetscCall(PetscLogEventBegin(PetscRegressor_SetUp, regressor, 0, 0, 0));
    229:   //TODO is there some mat vec etc that must be set, like TaoSolution?
    230:   PetscTryTypeMethod(regressor, setup);
    231:   regressor->setupcalled = PETSC_TRUE;
    232:   PetscCall(PetscLogEventEnd(PetscRegressor_SetUp, regressor, 0, 0, 0));
    233:   PetscFunctionReturn(PETSC_SUCCESS);
    234: }

    236: /* NOTE: I've decided to make this take X and y, like the Scikit-learn Fit routines do.
    237:  * Am I overlooking some reason that X should be set in a separate function call, a la KSPSetOperators()?. */
    238: /*@
    239:   PetscRegressorFit - Fit, or train, a regressor from a training dataset

    241:   Collective

    243:   Input Parameters:
    244: + regressor - the `PetscRegressor` context
    245: . X         - matrix of training data (of dimension [number of samples] x [number of features])
    246: - y         - vector of target values from the training dataset

    248:   Level: beginner

    250: .seealso: `PetscRegressorCreate()`, `PetscRegressorSetUp()`, `PetscRegressorDestroy()`, `PetscRegressorPredict()`
    251: @*/
    252: PetscErrorCode PetscRegressorFit(PetscRegressor regressor, Mat X, Vec y)
    253: {
    254:   PetscFunctionBegin;

    259:   if (X) {
    260:     PetscCall(PetscObjectReference((PetscObject)X));
    261:     PetscCall(MatDestroy(&regressor->training));
    262:     regressor->training = X;
    263:   }
    264:   if (y) {
    265:     PetscCall(PetscObjectReference((PetscObject)y));
    266:     PetscCall(VecDestroy(&regressor->target));
    267:     regressor->target = y;
    268:   }
    269:   PetscCall(PetscRegressorSetUp(regressor));

    271:   PetscCall(PetscLogEventBegin(PetscRegressor_Fit, regressor, X, y, 0));
    272:   PetscUseTypeMethod(regressor, fit);
    273:   PetscCall(PetscLogEventEnd(PetscRegressor_Fit, regressor, X, y, 0));
    274:   //TODO print convergence data
    275:   PetscCall(PetscRegressorViewFromOptions(regressor, NULL, "-regressor_view"));
    276:   regressor->fitcalled = PETSC_TRUE;
    277:   PetscFunctionReturn(PETSC_SUCCESS);
    278: }

    280: /*@
    281:   PetscRegressorPredict - Compute predictions (that is, perform inference) using a fitted regression model.

    283:   Collective

    285:   Input Parameters:
    286: + regressor - the `PetscRegressor` context (for which `PetscRegressorFit()` must have been called)
    287: - X         - data matrix of unlabeled observations

    289:   Output Parameter:
    290: . y - vector of predicted labels

    292:   Level: beginner

    294: .seealso: `PetscRegressorFit()`, `PetscRegressorDestroy()`
    295: @*/
    296: PetscErrorCode PetscRegressorPredict(PetscRegressor regressor, Mat X, Vec y)
    297: {
    298:   PetscFunctionBegin;
    302:   PetscCheck(regressor->fitcalled == PETSC_TRUE, ((PetscObject)regressor)->comm, PETSC_ERR_ARG_WRONGSTATE, "PetscRegressorFit() must be called before PetscRegressorPredict()");
    303:   PetscCall(PetscLogEventBegin(PetscRegressor_Predict, regressor, X, y, 0));
    304:   PetscTryTypeMethod(regressor, predict, X, y);
    305:   PetscCall(PetscLogEventEnd(PetscRegressor_Predict, regressor, X, y, 0));
    306:   PetscFunctionReturn(PETSC_SUCCESS);
    307: }

    309: /*@
    310:   PetscRegressorReset - Resets a `PetscRegressor` context by removing any allocated `Vec` and `Mat`. Any options set in the object remain.

    312:   Collective

    314:   Input Parameter:
    315: . regressor - context obtained from `PetscRegressorCreate()`

    317:   Level: intermediate

    319: .seealso: `PetscRegressorCreate()`, `PetscRegressorSetUp()`, `PetscRegressorFit()`, `PetscRegressorPredict()`, `PetscRegressorDestroy()`
    320: @*/
    321: PetscErrorCode PetscRegressorReset(PetscRegressor regressor)
    322: {
    323:   PetscFunctionBegin;
    325:   if (regressor->ops->reset) PetscTryTypeMethod(regressor, reset);
    326:   PetscCall(MatDestroy(&regressor->training));
    327:   PetscCall(VecDestroy(&regressor->target));
    328:   PetscCall(TaoDestroy(&regressor->tao));
    329:   regressor->setupcalled = PETSC_FALSE;
    330:   regressor->fitcalled   = PETSC_FALSE;
    331:   PetscFunctionReturn(PETSC_SUCCESS);
    332: }

    334: /*@C
    335:   PetscRegressorDestroy - Destroys the regressor context that was created with `PetscRegressorCreate()`.

    337:   Collective

    339:   Input Parameter:
    340: . regressor - the `PetscRegressor` context

    342:   Level: beginner

    344: .seealso: `PetscRegressorCreate()`, `PetscRegressorSetUp()`, `PetscRegressorReset()`, `PetscRegressor`
    345: @*/
    346: PetscErrorCode PetscRegressorDestroy(PetscRegressor *regressor)
    347: {
    348:   PetscFunctionBegin;
    349:   if (!*regressor) PetscFunctionReturn(PETSC_SUCCESS);
    351:   if (--((PetscObject)*regressor)->refct > 0) {
    352:     *regressor = NULL;
    353:     PetscFunctionReturn(PETSC_SUCCESS);
    354:   }

    356:   PetscCall(PetscRegressorReset(*regressor));
    357:   PetscTryTypeMethod(*regressor, destroy);

    359:   PetscCall(PetscHeaderDestroy(regressor));
    360:   PetscFunctionReturn(PETSC_SUCCESS);
    361: }

    363: /*@C
    364:   PetscRegressorSetType - Sets the type for the regressor.

    366:   Collective

    368:   Input Parameters:
    369: + regressor - the `PetscRegressor` context
    370: - type      - a known regression method

    372:   Options Database Key:
    373: . -regressor_type <type> - Sets the type of regressor; use -help for a list of available types

    375:   Level: intermediate

    377:   Notes:
    378:   See "include/petscregressor.h" for available methods (for instance)
    379: .    `PETSCREGRESSORLINEAR` - Regression model that is linear in its coefficients; supports ordinary least squares as well as regularized variants

    381:   Normally, it is best to use the `PetscRegressorSetFromOptions()` command and then
    382:   set the `PetscRegressor` type from the options database rather than by using
    383:   this routine, as this provides maximum flexibility.
    384:   The `PetscRegressorSetType()` routine is provided for those situations where it
    385:   is necessary to set the nonlinear solver independently of the command
    386:   line or options database.

    388: .seealso: `PetscRegressorType`
    389: @*/
    390: PetscErrorCode PetscRegressorSetType(PetscRegressor regressor, PetscRegressorType type)
    391: {
    392:   PetscErrorCode (*r)(PetscRegressor);
    393:   PetscBool match;

    395:   PetscFunctionBegin;
    397:   PetscAssertPointer(type, 2);

    399:   PetscCall(PetscObjectTypeCompare((PetscObject)regressor, type, &match));
    400:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

    402:   PetscCall(PetscFunctionListFind(PetscRegressorList, type, &r));
    403:   PetscCheck(r, PetscObjectComm((PetscObject)regressor), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested PetscRegressor type %s", type);

    405:   /* Destroy the existing solver information */
    406:   PetscTryTypeMethod(regressor, destroy);
    407:   PetscCall(TaoDestroy(&regressor->tao));
    408:   regressor->ops->setup          = NULL;
    409:   regressor->ops->setfromoptions = NULL;
    410:   regressor->ops->settraining    = NULL;
    411:   regressor->ops->fit            = NULL;
    412:   regressor->ops->predict        = NULL;
    413:   regressor->ops->destroy        = NULL;
    414:   regressor->ops->reset          = NULL;
    415:   regressor->ops->view           = NULL;

    417:   /* Call the PetscRegressorCreate_XXX routine for this particular regressor */
    418:   regressor->setupcalled = PETSC_FALSE;
    419:   PetscCall((*r)(regressor));
    420:   PetscCall(PetscObjectChangeTypeName((PetscObject)regressor, type));
    421:   PetscFunctionReturn(PETSC_SUCCESS);
    422: }

    424: /*@
    425:   PetscRegressorGetType - Gets the current `PetscRegressorType` being used in the `PetscRegressor` object

    427:   Not Collective

    429:   Input Parameter:
    430: . regressor - the `PetscRegressor` solver context

    432:   Output Parameter:
    433: . type - the `PetscRegressorType`

    435:   Level: intermediate

    437: .seealso: [](ch_regressor), `PetscRegressor`, `PetscRegressorType`, `PetscRegressorSetType()`
    438: @*/
    439: PetscErrorCode PetscRegressorGetType(PetscRegressor regressor, PetscRegressorType *type)
    440: {
    441:   PetscFunctionBegin;
    443:   PetscAssertPointer(type, 2);
    444:   *type = ((PetscObject)regressor)->type_name;
    445:   PetscFunctionReturn(PETSC_SUCCESS);
    446: }

    448: /*@
    449:   PetscRegressorSetRegularizerWeight - Sets the weight to be used for the regularizer for a `PetscRegressor` context

    451:   Logically Collective

    453:   Input Parameters:
    454: + regressor - the `PetscRegressor` context
    455: - weight    - the regularizer weight

    457:   Options Database Key:
    458: . regressor_regularizer_weight <weight> - sets the regularizer's weight

    460:   Level: beginner

    462: .seealso: `PetscRegressorSetType`
    463: @*/
    464: PetscErrorCode PetscRegressorSetRegularizerWeight(PetscRegressor regressor, PetscReal weight)
    465: {
    466:   PetscFunctionBegin;
    469:   regressor->regularizer_weight = weight;
    470:   PetscFunctionReturn(PETSC_SUCCESS);
    471: }

    473: /*@
    474:   PetscRegressorGetTao - Returns the `Tao` context for a `PetscRegressor` object.

    476:   Not Collective, but if the `PetscRegressor` is parallel, then the `Tao` object is parallel

    478:   Input Parameter:
    479: . regressor - the regressor context

    481:   Output Parameter:
    482: . tao - the `Tao` context

    484:   Level: beginner

    486:   Notes:
    487:   The `Tao` object will be created if it does not yet exist.

    489:   The user can directly manipulate the `Tao` context to set various
    490:   options, etc.  Likewise, the user can then extract and manipulate the
    491:   child contexts such as `KSP` or `TaoLineSearch`as well.

    493:   Depending on the type of the regressor and the options that are set, the regressor may use not use a `Tao` object.

    495: .seealso: `PetscRegressorLinearGetKSP()`
    496: @*/
    497: PetscErrorCode PetscRegressorGetTao(PetscRegressor regressor, Tao *tao)
    498: {
    499:   PetscFunctionBegin;
    501:   PetscAssertPointer(tao, 2);
    502:   // Analogous to how SNESGetKSP() operates, this routine should create the Tao if it doesn't exist.
    503:   if (!regressor->tao) {
    504:     PetscCall(TaoCreate(PetscObjectComm((PetscObject)regressor), &regressor->tao));
    505:     PetscCall(PetscObjectIncrementTabLevel((PetscObject)regressor->tao, (PetscObject)regressor, 1));
    506:     PetscCall(PetscObjectSetOptions((PetscObject)regressor->tao, ((PetscObject)regressor)->options));
    507:   }
    508:   *tao = regressor->tao;
    509:   PetscFunctionReturn(PETSC_SUCCESS);
    510: }

    512: /*@
    513:   PetscRegressorSetOptionsPrefix - Sets the prefix used for searching for all
    514:   PetscRegressor options in the database.

    516:   Logically Collective

    518:   Input Parameters:
    519: + regressor - the `PetscRegressor` context
    520: - p         - the prefix string to prepend to all PetscRegressor option requests

    522:   Level: advanced

    524:   Notes:
    525:   A hyphen (-) must NOT be given at the beginning of the prefix name.
    526:   The first character of all runtime options is AUTOMATICALLY the hyphen.

    528:   For example, to distinguish between the runtime options for two
    529:   different PetscRegressor solvers, one could call
    530: .vb
    531:       PetscRegressorSetOptionsPrefix(regressor1,"sys1_")
    532:       PetscRegressorSetOptionsPrefix(regressor2,"sys2_")
    533: .ve

    535:   This would enable use of different options for each system, such as
    536: .vb
    537:       -sys1_regressor_method linear -sys1_regressor_regularizer_weight 1.2
    538:       -sys2_regressor_method linear -sys2_regressor_regularizer_weight 1.1
    539: .ve

    541: .seealso: [](ch_regressor), `PetscRegressor`, `PetscRegressorSetFromOptions()`, `PetscRegressorAppendOptionsPrefix()`, `PetscRegressorGetOptionsPrefix()`
    542: @*/
    543: PetscErrorCode PetscRegressorSetOptionsPrefix(PetscRegressor regressor, const char p[])
    544: {
    545:   PetscFunctionBegin;
    547:   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)regressor, p));
    548:   PetscFunctionReturn(PETSC_SUCCESS);
    549: }

    551: /*@
    552:   PetscRegressorAppendOptionsPrefix - Appends to the prefix used for searching for all PetscRegressor options in the database.

    554:   Logically Collective

    556:   Input Parameters:
    557: + regressor - the `PetscRegressor` solver context
    558: - p         - the prefix string to prepend to all `PetscRegressor` option requests

    560:   Level: advanced

    562:   Note:
    563:   A hyphen (-) must NOT be given at the beginning of the prefix name.
    564:   The first character of all runtime options is automatically the hyphen.

    566: .seealso: [](ch_regressor), `PetscRegressor`, `PetscRegressorSetFromOptions()`, `PetscRegressorSetOptionsPrefix()`, `PetscRegressorGetOptionsPrefix()`
    567: @*/
    568: PetscErrorCode PetscRegressorAppendOptionsPrefix(PetscRegressor regressor, const char p[])
    569: {
    570:   PetscFunctionBegin;
    572:   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)regressor, p));
    573:   PetscFunctionReturn(PETSC_SUCCESS);
    574: }

    576: /*@
    577:   PetscRegressorGetOptionsPrefix - Gets the prefix used for searching for all
    578:   PetscRegressor options in the database

    580:   Not Collective

    582:   Input Parameter:
    583: . regressor - the `PetscRegressor` context

    585:   Output Parameter:
    586: . p - pointer to the prefix string used is returned

    588:   Fortran Notes:
    589:   Pass in a string 'prefix' of sufficient length to hold the prefix.

    591:   Level: advanced

    593: .seealso: [](ch_regressor), `PetscRegressor`, `PetscRegressorSetFromOptions()`, `PetscRegressorSetOptionsPrefix()`, `PetscRegressorAppendOptionsPrefix()`
    594: @*/
    595: PetscErrorCode PetscRegressorGetOptionsPrefix(PetscRegressor regressor, const char *p[])
    596: {
    597:   PetscFunctionBegin;
    599:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)regressor, p));
    600:   PetscFunctionReturn(PETSC_SUCCESS);
    601: }