Skip to content

Commit

Permalink
Merge pull request #373 from damar-wicaksono/dev-372
Browse files Browse the repository at this point in the history
Refactor UQTestFunABC class hierarchy
  • Loading branch information
damar-wicaksono authored Nov 8, 2024
2 parents 5c815fb + 8e749b9 commit 43a697b
Show file tree
Hide file tree
Showing 49 changed files with 600 additions and 398 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Two new abstract base classes are added, namely `UQTestFunFixDimABC` and
`UQTestFunVarDimABC` to deal with the construction of UQ test functions of
fixed and variable dimensions, respectively. Both abstract classes are derived
from `UQTestFunABC` such that the interfaces remain consistent.
- `function_id` and `input_id` are now property of `ProbInput`.
- `output_dimension` is now property of `UQTestFunBareABC` and inherited to
all concrete classes of UQ test functions.
Expand All @@ -26,6 +30,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- Application tags are now displayed when an instance of test function is
printed on the terminal.
- `list_functions()` is now printed in grid format and include information
regarding the output dimension and the parameterization. Furthermore,
filtering can be done based on the input dimension, output dimension,
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,11 @@ and sensitivity analysis purposes; to create an instance of this test function:
>>> my_testfun = uqtf.Borehole()
>>> print(my_testfun)
Function ID : Borehole
Input Dimension : 8
Input Dimension : 8 (fixed)
Output Dimension : 1
Parameterized : False
Description : Borehole function from Harper and Gupta (1983)
Applications : ['metamodeling', 'sensitivity']
```

The probabilistic input specification of this test function is built-in:
Expand Down
10 changes: 7 additions & 3 deletions docs/api/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ To make sense of how the objects in UQTestFuns are organized,
let's start from the top, the {ref}`built-in test functions <test-functions:available>`:

- Each of the built-in UQ test functions is a concrete implementation of the
abstract base class {ref}`UQTestFunABC <api_reference_uqtestfun_abc>`.
The base class, in turns, is derived
from {ref}`UQTestFunABC <api_reference_uqtestfun_bare_abc>`).
abstract base classes: {ref}`UQTestFunFixDimABC <api_reference_uqtestfun_fix_dim_abc>`
(for UQ test functions with fixed dimension) or
{ref}`UQTestFunVarDimABC <api_reference_uqtestfun_var_dim_abc>`
(for UQ test functions with variable dimension).
- Both of those abstract classes are derived from {ref}`UQTestFunABC <api_reference_uqtestfun_abc>`.
This base class, in turn, is derived
from {ref}`UQTestFunBareABC <api_reference_uqtestfun_bare_abc>`).
Therefore, all the instances share the same underlying interfaces.
In particular, all instances share, among other things, the ``evaluate()``
method, the ``prob_input`` property, and the ``parameters`` property [^essence].
Expand Down
18 changes: 18 additions & 0 deletions docs/api/uqtestfun-abc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,21 @@ Abstract Base Classes

.. autoclass:: uqtestfuns.core.uqtestfun_abc.UQTestFunABC
:members:


.. _api_reference_uqtestfun_fix_dim_abc:

``UQTestFunFixDimABC`` Abstract Base Class
------------------------------------

.. autoclass:: uqtestfuns.core.uqtestfun_abc.UQTestFunVarDimABC
:members:


.. _api_reference_uqtestfun_var_dim_abc:

``UQTestFunVarDimABC`` Abstract Base Class
------------------------------------

.. autoclass:: uqtestfuns.core.uqtestfun_abc.UQTestFunFixDimABC
:members:
21 changes: 13 additions & 8 deletions docs/development/adding-test-function-implementation.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,22 +110,28 @@ Here are the few things we usually use:
import numpy as np

from uqtestfuns.core.custom_typing import ProbInputSpecs, FunParamSpecs
from uqtestfuns.core.uqtestfun_abc import UQTestFunABC
from uqtestfuns.core.uqtestfun_abc import UQTestFunFixDimABC

__all__ = ["Branin"]
```

Here are some explanations:

- NumPy is usually a must, especially for implementing the evaluation function.
- All built-in test functions are concrete implementations of the abstract base
class `UQTestFunABC`.
- Because Branin test function is a test function with a fixed number of (input)
dimensions, the class will be derived from the abstract base class
{ref}`UQTestFunFixDimABC <api_reference_uqtestfun_fix_dim_abc>`.
- To assist specifying the data for probabilistic input model the custom type
`ProbInputSpecs` can be used; these are supposed to help you specifying
all the required data via the typechecker.
- Similarly, the custom type `FunParamSpecs` is used for specifying the
function parameters.

```{notes}
In case the function is of variable dimension, use the abstract base class
{ref}`UQTestFunVarDimABC <api_reference_uqtestfun_var_dim_abc>` instead.
```

### Implementing a concrete evaluation function

For an implementation of a test function, create a top module-level function
Expand Down Expand Up @@ -285,8 +291,8 @@ A concrete implementation of this base class requires the following:

- a static method named `evaluate()`
- several class-level properties, namely: `_tags`, `_description`,
`_available_inputs`, `_available_parameters`, `_default_input_dimension`,
`_default_input`, and `_default_parameters`.
`_available_inputs`, `_available_parameters`, `_default_input_id`,
and `_default_parameters_id`.

The full definition of the class for the Branin test function is shown below.

Expand All @@ -298,9 +304,8 @@ class Branin(UQTestFunABC):
_description = "Branin function from Dixon and Szegö (1978)" # Short description
_available_inputs = AVAILABLE_INPUTS # As defined above
_available_parameters = AVAILABLE_PARAMETERS # As defined above
_default_input_dimension = 2 # input dimension of the function
_default_input = "Dixon1978" # Optional, if only one input is available
_default_parameters = "Dixon1978" # Optional, if only one set of parameters is available
_default_input_id = "Dixon1978" # Optional, if only one input is available
_default_parameters_id = "Dixon1978" # Optional, if only one set of parameters is available

evaluate = staticmethod(evaluate) # assuming `evaluate()` has been defined
```
Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started/tutorial-custom-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ marginals = [
uqtf.Marginal(distribution="uniform", parameters=[0, 15], name="x2"),
]
# Create a probabilistic input
my_input = uqtf.ProbInput(marginals=marginals, name="Branin-Input")
my_input = uqtf.ProbInput(marginals=marginals, function_id="Branin", input_id="custom")
```

To verify if the instance has been created successfully,
Expand Down
4 changes: 2 additions & 2 deletions docs/getting-started/tutorial-reliability.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,13 +220,13 @@ The input variables $w$ and $h$ are probabilistically defined according
to the table below.

```{code-cell} ipython3
cantilever.prob_input
print(cantilever.prob_input)
```

The default values of the parameters $E$ and $l$ are:

```{code-cell} ipython3
cantilever.parameters
print(cantilever.parameters)
```

For reproducibility of this tutorial, set the seed number of the
Expand Down
4 changes: 2 additions & 2 deletions docs/getting-started/tutorial-sensitivity.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,13 +316,13 @@ The input variables of the function are probabilistically defined according
to the table below.

```{code-cell} ipython3
ishigami.prob_input
print(ishigami.prob_input)
```

Finally, the default values for the parameters $a$ and $b$ are:

```{code-cell} ipython3
ishigami.parameters
print(ishigami.parameters)
```

For reproducibility of this tutorial, set the seed number for the pseudo-random
Expand Down
10 changes: 8 additions & 2 deletions src/uqtestfuns/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@

from .core import Marginal
from .core import ProbInput
from .core import UQTestFunBareABC, UQTestFunABC
from .core import (
UQTestFunBareABC,
UQTestFunABC,
UQTestFunFixDimABC,
UQTestFunVarDimABC,
)
from .core import UQTestFun
from .core import FunParams

Expand All @@ -30,9 +35,10 @@
"Marginal",
"ProbInput",
"FunParams",
"UQTestFunABC",
"UQTestFunBareABC",
"UQTestFunABC",
"UQTestFunFixDimABC",
"UQTestFunVarDimABC",
"UQTestFun",
"test_functions",
"UQMetaFunSpec",
Expand Down
9 changes: 8 additions & 1 deletion src/uqtestfuns/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@
from .parameters import FunParams
from .prob_input.marginal import Marginal
from .prob_input.probabilistic_input import ProbInput
from .uqtestfun_abc import UQTestFunBareABC, UQTestFunABC
from .uqtestfun_abc import (
UQTestFunBareABC,
UQTestFunABC,
UQTestFunFixDimABC,
UQTestFunVarDimABC,
)
from .uqtestfun import UQTestFun

__all__ = [
Expand All @@ -14,5 +19,7 @@
"FunParams",
"UQTestFunBareABC",
"UQTestFunABC",
"UQTestFunFixDimABC",
"UQTestFunVarDimABC",
"UQTestFun",
]
Loading

0 comments on commit 43a697b

Please sign in to comment.