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: /*@
 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 viewer_specification - Calls `PetscRegressorView()` at the end of `PetscRegressorFit()`, see `PetscOptionsCreateViewer()` for the format of `viewer_specification`

 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()`, `PetscRegressorViewFromOptions()`, `PetscRegressorFit()`, `PetscOptionsCreateViewer()`
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, pass `NULL` to use the options prefix of `A`
145: - name - command line option

147:   Options Database Key:
148: . -name viewer_specification - See `PetscOptionsCreateViewer()` for the values of `viewer_specification`

150:   Level: intermediate

152:   Note:
153:   This checks the options database, creates the viewer on-the-fly, uses it and then destroys it. Hence it should not be called in heavily used routines,
154:   rather `PetscOptionsCreateViewer()` should be used to construct the viewer once which can then be utilized in the heavily used routine.

156: .seealso: [](ch_regressor), `PetscRegressor`, `PetscRegressorView()`, `PetscObjectViewFromOptions()`, `PetscRegressorCreate()`, `PetscOptionsCreateViewer()`
157: @*/
158: PetscErrorCode PetscRegressorViewFromOptions(PetscRegressor A, PetscObject obj, const char name[])
159: {
160:   PetscFunctionBegin;
162:   PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name));
163:   PetscFunctionReturn(PETSC_SUCCESS);
164: }

166: /*@
167:   PetscRegressorSetFromOptions - Sets `PetscRegressor` options from the options database.

169:   Collective

171:   Input Parameter:
172: . regressor - the `PetscRegressor` context

174:   Options Database Keys:
175: . -regressor_type (linear) - the particular type of regressor to be used

177:   Level: beginner

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

183: .seealso: `PetscRegressor`, `PetscRegressorCreate()`
184: @*/
185: PetscErrorCode PetscRegressorSetFromOptions(PetscRegressor regressor)
186: {
187:   PetscBool          flg;
188:   PetscRegressorType default_type = PETSCREGRESSORLINEAR;
189:   char               type[256];

191:   PetscFunctionBegin;
193:   if (((PetscObject)regressor)->type_name) default_type = ((PetscObject)regressor)->type_name;
194:   PetscObjectOptionsBegin((PetscObject)regressor);
195:   /* Check for type from options */
196:   PetscCall(PetscOptionsFList("-regressor_type", "PetscRegressor type", "PetscRegressorSetType", PetscRegressorList, default_type, type, sizeof(type), &flg));
197:   if (flg) {
198:     PetscCall(PetscRegressorSetType(regressor, type));
199:   } else if (!((PetscObject)regressor)->type_name) {
200:     PetscCall(PetscRegressorSetType(regressor, default_type));
201:   }
202:   PetscCall(PetscOptionsReal("-regressor_regularizer_weight", "Weight for the regularizer", "PetscRegressorSetRegularizerWeight", regressor->regularizer_weight, &regressor->regularizer_weight, &flg));
203:   if (flg) PetscCall(PetscRegressorSetRegularizerWeight(regressor, regressor->regularizer_weight));
204:   // 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!
205:   PetscTryTypeMethod(regressor, setfromoptions, PetscOptionsObject);
206:   PetscOptionsEnd();
207:   PetscFunctionReturn(PETSC_SUCCESS);
208: }

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

213:   Collective

215:   Input Parameter:
216: . regressor - the `PetscRegressor` context

218:   Notes:
219:   For basic use of the `PetscRegressor` solvers the user need not to explicitly call
220:   `PetscRegressorSetUp()`, since these actions will automatically occur during
221:   the call to `PetscRegressorFit()`.  However, if one wishes to control this
222:   phase separately, `PetscRegressorSetUp()` should be called after `PetscRegressorCreate()`,
223:   `PetscRegressorSetUp()`, and optional routines of the form `PetscRegressorSetXXX()`,
224:   but before `PetscRegressorFit()`.

226:   Level: advanced

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

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

248:   Collective

250:   Input Parameters:
251: + regressor - the `PetscRegressor` context
252: . X         - matrix of training data (of dimension [number of samples] x [number of features])
253: - y         - vector of target values from the training dataset

255:   Level: beginner

257: .seealso: `PetscRegressorCreate()`, `PetscRegressorSetUp()`, `PetscRegressorDestroy()`, `PetscRegressorPredict()`
258: @*/
259: PetscErrorCode PetscRegressorFit(PetscRegressor regressor, Mat X, Vec y)
260: {
261:   PetscFunctionBegin;

266:   if (X) {
267:     PetscCall(PetscObjectReference((PetscObject)X));
268:     PetscCall(MatDestroy(&regressor->training));
269:     regressor->training = X;
270:   }
271:   if (y) {
272:     PetscCall(PetscObjectReference((PetscObject)y));
273:     PetscCall(VecDestroy(&regressor->target));
274:     regressor->target = y;
275:   }
276:   PetscCall(PetscRegressorSetUp(regressor));

278:   PetscCall(PetscLogEventBegin(PetscRegressor_Fit, regressor, X, y, 0));
279:   PetscUseTypeMethod(regressor, fit);
280:   PetscCall(PetscLogEventEnd(PetscRegressor_Fit, regressor, X, y, 0));
281:   //TODO print convergence data
282:   PetscCall(PetscRegressorViewFromOptions(regressor, NULL, "-regressor_view"));
283:   regressor->fitcalled = PETSC_TRUE;
284:   PetscFunctionReturn(PETSC_SUCCESS);
285: }

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

290:   Collective

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

296:   Output Parameter:
297: . y - vector of predicted labels

299:   Level: beginner

301: .seealso: `PetscRegressorFit()`, `PetscRegressorDestroy()`
302: @*/
303: PetscErrorCode PetscRegressorPredict(PetscRegressor regressor, Mat X, Vec y)
304: {
305:   PetscFunctionBegin;
309:   PetscCheck(regressor->fitcalled == PETSC_TRUE, ((PetscObject)regressor)->comm, PETSC_ERR_ARG_WRONGSTATE, "PetscRegressorFit() must be called before PetscRegressorPredict()");
310:   PetscCall(PetscLogEventBegin(PetscRegressor_Predict, regressor, X, y, 0));
311:   PetscTryTypeMethod(regressor, predict, X, y);
312:   PetscCall(PetscLogEventEnd(PetscRegressor_Predict, regressor, X, y, 0));
313:   PetscFunctionReturn(PETSC_SUCCESS);
314: }

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

319:   Collective

321:   Input Parameter:
322: . regressor - context obtained from `PetscRegressorCreate()`

324:   Level: intermediate

326: .seealso: `PetscRegressorCreate()`, `PetscRegressorSetUp()`, `PetscRegressorFit()`, `PetscRegressorPredict()`, `PetscRegressorDestroy()`
327: @*/
328: PetscErrorCode PetscRegressorReset(PetscRegressor regressor)
329: {
330:   PetscFunctionBegin;
332:   if (regressor->ops->reset) PetscTryTypeMethod(regressor, reset);
333:   PetscCall(MatDestroy(&regressor->training));
334:   PetscCall(VecDestroy(&regressor->target));
335:   PetscCall(TaoDestroy(&regressor->tao));
336:   regressor->setupcalled = PETSC_FALSE;
337:   regressor->fitcalled   = PETSC_FALSE;
338:   PetscFunctionReturn(PETSC_SUCCESS);
339: }

341: /*@
342:   PetscRegressorDestroy - Destroys the regressor context that was created with `PetscRegressorCreate()`.

344:   Collective

346:   Input Parameter:
347: . regressor - the `PetscRegressor` context

349:   Level: beginner

351: .seealso: `PetscRegressorCreate()`, `PetscRegressorSetUp()`, `PetscRegressorReset()`, `PetscRegressor`
352: @*/
353: PetscErrorCode PetscRegressorDestroy(PetscRegressor *regressor)
354: {
355:   PetscFunctionBegin;
356:   if (!*regressor) PetscFunctionReturn(PETSC_SUCCESS);
358:   if (--((PetscObject)*regressor)->refct > 0) {
359:     *regressor = NULL;
360:     PetscFunctionReturn(PETSC_SUCCESS);
361:   }

363:   PetscCall(PetscRegressorReset(*regressor));
364:   PetscTryTypeMethod(*regressor, destroy);

366:   PetscCall(PetscHeaderDestroy(regressor));
367:   PetscFunctionReturn(PETSC_SUCCESS);
368: }

370: /*@
371:   PetscRegressorSetType - Sets the type for the regressor.

373:   Collective

375:   Input Parameters:
376: + regressor - the `PetscRegressor` context
377: - type      - a known regression method

379:   Options Database Key:
380: . -regressor_type type - Sets the type of regressor; use -help for a list of available types

382:   Level: intermediate

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

388:   Normally, it is best to use the `PetscRegressorSetFromOptions()` command and then
389:   set the `PetscRegressor` type from the options database rather than by using
390:   this routine, as this provides maximum flexibility.
391:   The `PetscRegressorSetType()` routine is provided for those situations where it
392:   is necessary to set the nonlinear solver independently of the command
393:   line or options database.

395: .seealso: `PetscRegressorType`
396: @*/
397: PetscErrorCode PetscRegressorSetType(PetscRegressor regressor, PetscRegressorType type)
398: {
399:   PetscErrorCode (*r)(PetscRegressor);
400:   PetscBool match;

402:   PetscFunctionBegin;
404:   PetscAssertPointer(type, 2);

406:   PetscCall(PetscObjectTypeCompare((PetscObject)regressor, type, &match));
407:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

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

412:   /* Destroy the existing solver information */
413:   PetscTryTypeMethod(regressor, destroy);
414:   PetscCall(TaoDestroy(&regressor->tao));
415:   regressor->ops->setup          = NULL;
416:   regressor->ops->setfromoptions = NULL;
417:   regressor->ops->settraining    = NULL;
418:   regressor->ops->fit            = NULL;
419:   regressor->ops->predict        = NULL;
420:   regressor->ops->destroy        = NULL;
421:   regressor->ops->reset          = NULL;
422:   regressor->ops->view           = NULL;

424:   /* Call the PetscRegressorCreate_XXX routine for this particular regressor */
425:   regressor->setupcalled = PETSC_FALSE;
426:   PetscCall((*r)(regressor));
427:   PetscCall(PetscObjectChangeTypeName((PetscObject)regressor, type));
428:   PetscFunctionReturn(PETSC_SUCCESS);
429: }

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

434:   Not Collective

436:   Input Parameter:
437: . regressor - the `PetscRegressor` solver context

439:   Output Parameter:
440: . type - the `PetscRegressorType`

442:   Level: intermediate

444: .seealso: [](ch_regressor), `PetscRegressor`, `PetscRegressorType`, `PetscRegressorSetType()`
445: @*/
446: PetscErrorCode PetscRegressorGetType(PetscRegressor regressor, PetscRegressorType *type)
447: {
448:   PetscFunctionBegin;
450:   PetscAssertPointer(type, 2);
451:   *type = ((PetscObject)regressor)->type_name;
452:   PetscFunctionReturn(PETSC_SUCCESS);
453: }

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

458:   Logically Collective

460:   Input Parameters:
461: + regressor - the `PetscRegressor` context
462: - weight    - the regularizer weight

464:   Options Database Key:
465: . regressor_regularizer_weight weight - sets the regularizer's weight

467:   Level: beginner

469: .seealso: `PetscRegressorSetType`
470: @*/
471: PetscErrorCode PetscRegressorSetRegularizerWeight(PetscRegressor regressor, PetscReal weight)
472: {
473:   PetscFunctionBegin;
476:   regressor->regularizer_weight = weight;
477:   PetscFunctionReturn(PETSC_SUCCESS);
478: }

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

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

485:   Input Parameter:
486: . regressor - the regressor context

488:   Output Parameter:
489: . tao - the `Tao` context

491:   Level: beginner

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

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

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

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

519: /*@
520:   PetscRegressorSetOptionsPrefix - Sets the prefix used for searching for all
521:   PetscRegressor options in the database.

523:   Logically Collective

525:   Input Parameters:
526: + regressor - the `PetscRegressor` context
527: - p         - the prefix string to prepend to all PetscRegressor option requests

529:   Level: advanced

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

535:   For example, to distinguish between the runtime options for two
536:   different PetscRegressor solvers, one could call
537: .vb
538:       PetscRegressorSetOptionsPrefix(regressor1,"sys1_")
539:       PetscRegressorSetOptionsPrefix(regressor2,"sys2_")
540: .ve

542:   This would enable use of different options for each system, such as
543: .vb
544:       -sys1_regressor_method linear -sys1_regressor_regularizer_weight 1.2
545:       -sys2_regressor_method linear -sys2_regressor_regularizer_weight 1.1
546: .ve

548: .seealso: [](ch_regressor), `PetscRegressor`, `PetscRegressorSetFromOptions()`, `PetscRegressorAppendOptionsPrefix()`, `PetscRegressorGetOptionsPrefix()`
549: @*/
550: PetscErrorCode PetscRegressorSetOptionsPrefix(PetscRegressor regressor, const char p[])
551: {
552:   PetscFunctionBegin;
554:   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)regressor, p));
555:   PetscFunctionReturn(PETSC_SUCCESS);
556: }

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

561:   Logically Collective

563:   Input Parameters:
564: + regressor - the `PetscRegressor` solver context
565: - p         - the prefix string to prepend to all `PetscRegressor` option requests

567:   Level: advanced

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

573: .seealso: [](ch_regressor), `PetscRegressor`, `PetscRegressorSetFromOptions()`, `PetscRegressorSetOptionsPrefix()`, `PetscRegressorGetOptionsPrefix()`
574: @*/
575: PetscErrorCode PetscRegressorAppendOptionsPrefix(PetscRegressor regressor, const char p[])
576: {
577:   PetscFunctionBegin;
579:   PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)regressor, p));
580:   PetscFunctionReturn(PETSC_SUCCESS);
581: }

583: /*@
584:   PetscRegressorGetOptionsPrefix - Gets the prefix used for searching for all
585:   PetscRegressor options in the database

587:   Not Collective

589:   Input Parameter:
590: . regressor - the `PetscRegressor` context

592:   Output Parameter:
593: . p - pointer to the prefix string used is returned

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

598:   Level: advanced

600: .seealso: [](ch_regressor), `PetscRegressor`, `PetscRegressorSetFromOptions()`, `PetscRegressorSetOptionsPrefix()`, `PetscRegressorAppendOptionsPrefix()`
601: @*/
602: PetscErrorCode PetscRegressorGetOptionsPrefix(PetscRegressor regressor, const char *p[])
603: {
604:   PetscFunctionBegin;
606:   PetscCall(PetscObjectGetOptionsPrefix((PetscObject)regressor, p));
607:   PetscFunctionReturn(PETSC_SUCCESS);
608: }