|
51 | 51 | "source": [
|
52 | 52 | "### Method `probsolve_qp`\n",
|
53 | 53 | "\n",
|
54 |
| - "We will now take a closer look at the interface of our 1D noisy quadratic optimization method. At a basic level `probsolve_qp` takes a function of the type `Callable[[FloatArgType], FloatArgType]`. This hints that the optimization objective is a 1D function. Our prior knowledge about the parameters $(a,b,c)$ is encoded in the random variable `fun_params0`. However, we want to also give a user the option to not specify any prior knowledge or just a guess about the parameter values, hence this argument is optional or can be an `np.ndarray`. \n", |
| 54 | + "We will now take a closer look at the interface of our 1D noisy quadratic optimization method. At a basic level `probsolve_qp` takes a function of the type `Callable[[FloatLike], FloatLike]`. This hints that the optimization objective is a 1D function. Our prior knowledge about the parameters $(a,b,c)$ is encoded in the random variable `fun_params0`. However, we want to also give a user the option to not specify any prior knowledge or just a guess about the parameter values, hence this argument is optional or can be an `np.ndarray`. \n", |
55 | 55 | "\n",
|
56 | 56 | "The interface also has an `assume_fun` argument, which allows specification of the variant of the probabilistic numerical method to use based on the assumptions about the problem. For convenience, this can be inferred from the problem itself. The actual implementation of the PN method variant which is initialized in a modular fashion is separate from the interface and will be explained later. Finally, the actual optimization routine is called and the result is returned."
|
57 | 57 | ]
|
|
67 | 67 | "\n",
|
68 | 68 | "import probnum as pn\n",
|
69 | 69 | "from probnum import randvars, linops\n",
|
70 |
| - "from probnum.typing import FloatArgType, IntArgType\n", |
| 70 | + "from probnum.typing import FloatLike, IntLike\n", |
71 | 71 | "\n",
|
72 | 72 | "rng = np.random.default_rng(seed=123)"
|
73 | 73 | ]
|
|
83 | 83 | "# %load -s probsolve_qp quadopt_example/_probsolve_qp\n",
|
84 | 84 | "def probsolve_qp(\n",
|
85 | 85 | " rng: np.random.Generator,\n",
|
86 |
| - " fun: Callable[[FloatArgType], FloatArgType],\n", |
| 86 | + " fun: Callable[[FloatLike], FloatLike],\n", |
87 | 87 | " fun_params0: Optional[Union[np.ndarray, randvars.RandomVariable]] = None,\n",
|
88 | 88 | " assume_fun: Optional[str] = None,\n",
|
89 |
| - " tol: FloatArgType = 10 ** -5,\n", |
90 |
| - " maxiter: IntArgType = 10 ** 4,\n", |
| 89 | + " tol: FloatLike = 10 ** -5,\n", |
| 90 | + " maxiter: IntLike = 10 ** 4,\n", |
91 | 91 | " noise_cov: Optional[Union[np.ndarray, linops.LinearOperator]] = None,\n",
|
92 | 92 | " callback: Optional[\n",
|
93 |
| - " Callable[[FloatArgType, FloatArgType, randvars.RandomVariable], None]\n", |
| 93 | + " Callable[[FloatLike, FloatLike, randvars.RandomVariable], None]\n", |
94 | 94 | " ] = None,\n",
|
95 | 95 | ") -> Tuple[float, randvars.RandomVariable, randvars.RandomVariable, Dict]:\n",
|
96 | 96 | " \"\"\"Probabilistic 1D Quadratic Optimization.\n",
|
|
316 | 316 | "# Type aliases for quadratic optimization\n",
|
317 | 317 | "QuadOptPolicyType = Callable[\n",
|
318 | 318 | " [\n",
|
319 |
| - " Callable[[FloatArgType], FloatArgType],\n", |
| 319 | + " Callable[[FloatLike], FloatLike],\n", |
320 | 320 | " randvars.RandomVariable,\n",
|
321 | 321 | " ],\n",
|
322 |
| - " FloatArgType,\n", |
| 322 | + " FloatLike,\n", |
323 | 323 | "]\n",
|
324 | 324 | "QuadOptObservationOperatorType = Callable[\n",
|
325 |
| - " [Callable[[FloatArgType], FloatArgType], FloatArgType], FloatArgType\n", |
| 325 | + " [Callable[[FloatLike], FloatLike], FloatLike], FloatLike\n", |
326 | 326 | "]\n",
|
327 | 327 | "QuadOptBeliefUpdateType = Callable[\n",
|
328 | 328 | " [\n",
|
329 | 329 | " randvars.RandomVariable,\n",
|
330 |
| - " FloatArgType,\n", |
331 |
| - " FloatArgType,\n", |
| 330 | + " FloatLike,\n", |
| 331 | + " FloatLike,\n", |
332 | 332 | " ],\n",
|
333 | 333 | " randvars.RandomVariable,\n",
|
334 | 334 | "]\n",
|
335 | 335 | "QuadOptStoppingCriterionType = Callable[\n",
|
336 |
| - " [Callable[[FloatArgType], FloatArgType], randvars.RandomVariable, IntArgType],\n", |
| 336 | + " [Callable[[FloatLike], FloatLike], randvars.RandomVariable, IntLike],\n", |
337 | 337 | " Tuple[bool, Union[str, None]],\n",
|
338 | 338 | "]\n",
|
339 | 339 | "\n",
|
|
430 | 430 | " self.stopping_criteria = stopping_criteria\n",
|
431 | 431 | "\n",
|
432 | 432 | " def has_converged(\n",
|
433 |
| - " self, fun: Callable[[FloatArgType], FloatArgType], iteration: IntArgType\n", |
| 433 | + " self, fun: Callable[[FloatLike], FloatLike], iteration: IntLike\n", |
434 | 434 | " ) -> Tuple[bool, Union[str, None]]:\n",
|
435 | 435 | " \"\"\"Check whether the optimizer has converged.\n",
|
436 | 436 | "\n",
|
|
451 | 451 | "\n",
|
452 | 452 | " def optim_iterator(\n",
|
453 | 453 | " self,\n",
|
454 |
| - " fun: Callable[[FloatArgType], FloatArgType],\n", |
| 454 | + " fun: Callable[[FloatLike], FloatLike],\n", |
455 | 455 | " ) -> Tuple[float, float, randvars.RandomVariable]:\n",
|
456 | 456 | " \"\"\"Generator implementing the optimization iteration.\n",
|
457 | 457 | "\n",
|
|
486 | 486 | "\n",
|
487 | 487 | " def optimize(\n",
|
488 | 488 | " self,\n",
|
489 |
| - " fun: Callable[[FloatArgType], FloatArgType],\n", |
| 489 | + " fun: Callable[[FloatLike], FloatLike],\n", |
490 | 490 | " callback: Optional[\n",
|
491 | 491 | " Callable[[float, float, randvars.RandomVariable], None]\n",
|
492 | 492 | " ] = None,\n",
|
|
584 | 584 | "internal representation of those same objects. Canonical examples are different kinds of integer or float types, which might be passed by a user. These are all unified internally.\n",
|
585 | 585 | "\n",
|
586 | 586 | "```python\n",
|
587 |
| - "IntArgType = Union[int, numbers.Integral, np.integer]\n", |
588 |
| - "FloatArgType = Union[float, numbers.Real, np.floating]\n", |
| 587 | + "IntLike = Union[int, numbers.Integral, np.integer]\n", |
| 588 | + "FloatLike = Union[float, numbers.Real, np.floating]\n", |
589 | 589 | "\n",
|
590 |
| - "ShapeArgType = Union[IntArgType, Iterable[IntArgType]]\n", |
| 590 | + "ShapeLike = Union[IntLike, Iterable[IntLike]]\n", |
591 | 591 | "\"\"\"Type of a public API argument for supplying a shape. Values of this type should\n",
|
592 | 592 | "always be converted into :class:`ShapeType` using the function\n",
|
593 | 593 | ":func:`probnum.utils.as_shape` before further internal processing.\"\"\"\n",
|
|
602 | 602 | "metadata": {},
|
603 | 603 | "outputs": [],
|
604 | 604 | "source": [
|
605 |
| - "from probnum.typing import ShapeType, IntArgType, ShapeArgType\n", |
| 605 | + "from probnum.typing import ShapeType, IntLike, ShapeLike\n", |
606 | 606 | "from probnum.utils import as_shape\n",
|
607 | 607 | "\n",
|
608 | 608 | "\n",
|
609 |
| - "def extend_shape(shape: ShapeArgType, extension: IntArgType) -> ShapeType:\n", |
| 609 | + "def extend_shape(shape: ShapeLike, extension: IntLike) -> ShapeType:\n", |
610 | 610 | " return as_shape(shape) + as_shape(extension)"
|
611 | 611 | ]
|
612 | 612 | },
|
|
674 | 674 | "source": [
|
675 | 675 | "# %load -s explore_exploit_policy quadopt_example/policies\n",
|
676 | 676 | "def explore_exploit_policy(\n",
|
677 |
| - " fun: Callable[[FloatArgType], FloatArgType],\n", |
| 677 | + " fun: Callable[[FloatLike], FloatLike],\n", |
678 | 678 | " fun_params0: randvars.RandomVariable,\n",
|
679 | 679 | " rng: np.random.Generator,\n",
|
680 | 680 | ") -> float:\n",
|
|
704 | 704 | "```python\n",
|
705 | 705 | "QuadOptPolicyType = Callable[\n",
|
706 | 706 | " [\n",
|
707 |
| - " Callable[[FloatArgType], FloatArgType],\n", |
| 707 | + " Callable[[FloatLike], FloatLike],\n", |
708 | 708 | " randvars.RandomVariable\n",
|
709 | 709 | " ],\n",
|
710 |
| - " FloatArgType,\n", |
| 710 | + " FloatLike,\n", |
711 | 711 | "]\n",
|
712 | 712 | "```\n",
|
713 | 713 | "The observation process for this problem is very simple. It just evaluates the objective function. \n",
|
714 | 714 | "```python\n",
|
715 | 715 | "QuadOptObservationOperatorType = Callable[\n",
|
716 |
| - " [Callable[[FloatArgType], FloatArgType], FloatArgType], FloatArgType\n", |
| 716 | + " [Callable[[FloatLike], FloatLike], FloatLike], FloatLike\n", |
717 | 717 | "]\n",
|
718 | 718 | "```\n",
|
719 | 719 | "One can imagine a different probabilistic optimization method which evaluates the gradient as well. In this case the different observation processes would all get the function, its gradient and an evaluation point / action as arguments."
|
|
727 | 727 | "source": [
|
728 | 728 | "# %load -s function_evaluation quadopt_example/observation_operators\n",
|
729 | 729 | "def function_evaluation(\n",
|
730 |
| - " fun: Callable[[FloatArgType], FloatArgType], action: FloatArgType\n", |
| 730 | + " fun: Callable[[FloatLike], FloatLike], action: FloatLike\n", |
731 | 731 | ") -> np.float_:\n",
|
732 | 732 | " \"\"\"Observe a (noisy) function evaluation of the quadratic objective.\n",
|
733 | 733 | "\n",
|
|
758 | 758 | "QuadOptBeliefUpdateType = Callable[\n",
|
759 | 759 | " [\n",
|
760 | 760 | " randvars.RandomVariable,\n",
|
761 |
| - " FloatArgType,\n", |
762 |
| - " FloatArgType,\n", |
| 761 | + " FloatLike,\n", |
| 762 | + " FloatLike,\n", |
763 | 763 | " ],\n",
|
764 | 764 | " randvars.RandomVariable,\n",
|
765 | 765 | "]\n",
|
|
776 | 776 | "# %load -s gaussian_belief_update quadopt_example/belief_updates\n",
|
777 | 777 | "def gaussian_belief_update(\n",
|
778 | 778 | " fun_params0: randvars.RandomVariable,\n",
|
779 |
| - " action: FloatArgType,\n", |
780 |
| - " observation: FloatArgType,\n", |
| 779 | + " action: FloatLike,\n", |
| 780 | + " observation: FloatLike,\n", |
781 | 781 | " noise_cov: Union[np.ndarray, linops.LinearOperator],\n",
|
782 | 782 | ") -> randvars.RandomVariable:\n",
|
783 | 783 | " \"\"\"Update the belief over the parameters with an observation.\n",
|
|
823 | 823 | "The stopping criteria are also implemented as simple methods, which return a `bool` determining convergence and a string giving the name of the criterion.\n",
|
824 | 824 | "```python\n",
|
825 | 825 | "QuadOptStoppingCriterionType = Callable[\n",
|
826 |
| - " [Callable[[FloatArgType], FloatArgType], randvars.RandomVariable, IntArgType],\n", |
| 826 | + " [Callable[[FloatLike], FloatLike], randvars.RandomVariable, IntLike],\n", |
827 | 827 | " Tuple[bool, Union[str, None]],\n",
|
828 | 828 | "]\n",
|
829 | 829 | "```\n",
|
|
838 | 838 | "source": [
|
839 | 839 | "# %load -s parameter_uncertainty quadopt_example/stopping_criteria\n",
|
840 | 840 | "def parameter_uncertainty(\n",
|
841 |
| - " fun: Callable[[FloatArgType], FloatArgType],\n", |
| 841 | + " fun: Callable[[FloatLike], FloatLike],\n", |
842 | 842 | " fun_params0: randvars.RandomVariable,\n",
|
843 |
| - " current_iter: IntArgType,\n", |
844 |
| - " abstol: FloatArgType,\n", |
845 |
| - " reltol: FloatArgType,\n", |
| 843 | + " current_iter: IntLike,\n", |
| 844 | + " abstol: FloatLike,\n", |
| 845 | + " reltol: FloatLike,\n", |
846 | 846 | ") -> Tuple[bool, Union[str, None]]:\n",
|
847 | 847 | " \"\"\"Termination based on numerical uncertainty about the parameters.\n",
|
848 | 848 | "\n",
|
|
0 commit comments