Skip to content

Commit fe4a1f9

Browse files
Add exponential function from Dette & Pepelyshev (2010)
The three-dimensional exponential function from Dette and Pepelyshev for metamodeling exercises has been added to the codebase. The documentation has been updated accordingly. This commit should resolve Issue #331.
1 parent 015f860 commit fe4a1f9

File tree

9 files changed

+230
-43
lines changed

9 files changed

+230
-43
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12+
- The tree-dimensional exponential function from Dette and Pepelyshev (2010)
13+
for metamodeling exercises.
1214
- The one-dimensional sine function from Higdon (2002) featuring behaviors
1315
that are different in two scales; for metamodeling (multi-resolution)
1416
exercises.

docs/_toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ parts:
7070
title: Damped Oscillator
7171
- file: test-functions/damped-oscillator-reliability
7272
title: Damped Oscillator Reliability
73+
- file: test-functions/dette-exp
74+
title: Dette & Pepelyshev (2010) Exponential
7375
- file: test-functions/flood
7476
title: Flood
7577
- file: test-functions/forrester

docs/fundamentals/metamodeling.md

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -18,48 +18,49 @@ kernelspec:
1818
The table below listed the available test functions typically used
1919
in the comparison of metamodeling approaches.
2020

21-
| Name | Input Dimension | Constructor |
22-
|:----------------------------------------------------------------------:|:---------------:|:----------------------:|
23-
| {ref}`Ackley <test-functions:ackley>` | M | `Ackley()` |
24-
| {ref}`Alemazkoor & Meidani (2018) 2D <test-functions:alemazkoor-2d>` | 2 | `Alemazkoor2D()` |
25-
| {ref}`Alemazkoor & Meidani (2018) 20D <test-functions:alemazkoor-20d>` | 20 | `Alemazkoor20D()` |
26-
| {ref}`Borehole <test-functions:borehole>` | 8 | `Borehole()` |
27-
| {ref}`Cheng and Sandu (2010) 2D <test-functions:cheng2d>` | 2 | `Cheng2D` |
28-
| {ref}`Coffee Cup Model <test-functions:coffee-cup>` | 2 | `CoffeeCup()` |
29-
| {ref}`Currin et al. (1988) Sine <test-functions:currin-sine>` | 1 | `CurrinSine()` |
30-
| {ref}`Damped Cosine <test-functions:damped-cosine>` | 1 | `DampedCosine()` |
31-
| {ref}`Damped Oscillator <test-functions:damped-oscillator>` | 7 | `DampedOscillator()` |
32-
| {ref}`Flood <test-functions:flood>` | 8 | `Flood()` |
33-
| {ref}`Forrester et al. (2008) <test-functions:forrester>` | 1 | `Forrester2008()` |
34-
| {ref}`(1st) Franke <test-functions:franke-1>` | 2 | `Franke1()` |
35-
| {ref}`(2nd) Franke <test-functions:franke-2>` | 2 | `Franke2()` |
36-
| {ref}`(3rd) Franke <test-functions:franke-3>` | 2 | `Franke3()` |
37-
| {ref}`(4th) Franke <test-functions:franke-4>` | 2 | `Franke4()` |
38-
| {ref}`(5th) Franke <test-functions:franke-5>` | 2 | `Franke5()` |
39-
| {ref}`(6th) Franke <test-functions:franke-6>` | 2 | `Franke6()` |
40-
| {ref}`Friedman (6D) <test-functions:friedman-6d>` | 6 | `Friedman6D()` |
41-
| {ref}`Friedman (10D) <test-functions:friedman-10d>` | 10 | `Friedman10D()` |
42-
| {ref}`Genz (Corner Peak) <test-functions:genz-corner-peak>` | M | `GenzCornerPeak()` |
43-
| {ref}`Gramacy (2007) 1D Sine <test-functions:gramacy-1d-sine>` | 1 | `Gramacy1DSine()` |
44-
| {ref}`Higdon (2002) Sine <test-functions:higdon-sine>` | 1 | `HigdonSine()` |
45-
| {ref}`Holsclaw et al. (2013) Sine <test-functions:holsclaw-sine>` | 1 | `HolsclawSine()` |
46-
| {ref}`Lim et al. (2002) Non-Polynomial <test-functions:lim-non-poly>` | 2 | `LimNonPoly()` |
47-
| {ref}`Lim et al. (2002) Polynomial <test-functions:lim-poly>` | 2 | `LimPoly()` |
48-
| {ref}`McLain S1 <test-functions:mclain-s1>` | 2 | `McLainS1()` |
49-
| {ref}`McLain S2 <test-functions:mclain-s2>` | 2 | `McLainS2()` |
50-
| {ref}`McLain S3 <test-functions:mclain-s3>` | 2 | `McLainS3()` |
51-
| {ref}`McLain S4 <test-functions:mclain-s4>` | 2 | `McLainS4()` |
52-
| {ref}`McLain S5 <test-functions:mclain-s5>` | 2 | `McLainS5()` |
53-
| {ref}`Oakley & O'Hagan (2002) 1D <test-functions:oakley-1d>` | 1 | `Oakley1D()` |
54-
| {ref}`OTL Circuit <test-functions:otl-circuit>` | 6 / 20 | `OTLCircuit()` |
55-
| {ref}`Piston Simulation <test-functions:piston>` | 7 / 20 | `Piston()` |
56-
| {ref}`Robot Arm <test-functions:robot-arm>` | 8 | `RobotArm()` |
57-
| {ref}`Solar Cell Model <test-functions:solar-cell>` | 5 | `SolarCell()` |
58-
| {ref}`Sulfur <test-functions:sulfur>` | 9 | `Sulfur()` |
59-
| {ref}`Undamped Oscillator <test-functions:undamped-oscillator>` | 6 | `UndampedOscillator()` |
60-
| {ref}`Webster et al. (1996) 2D <test-functions:webster-2d>` | 2 | `Webster2D()` |
61-
| {ref}`Welch et al. (1992) <test-functions:welch1992>` | 20 | `Welch1992()` |
62-
| {ref}`Wing Weight <test-functions:wing-weight>` | 10 | `WingWeight()` |
21+
| Name | Input Dimension | Constructor |
22+
|:------------------------------------------------------------------------:|:---------------:|:----------------------:|
23+
| {ref}`Ackley <test-functions:ackley>` | M | `Ackley()` |
24+
| {ref}`Alemazkoor & Meidani (2018) 2D <test-functions:alemazkoor-2d>` | 2 | `Alemazkoor2D()` |
25+
| {ref}`Alemazkoor & Meidani (2018) 20D <test-functions:alemazkoor-20d>` | 20 | `Alemazkoor20D()` |
26+
| {ref}`Borehole <test-functions:borehole>` | 8 | `Borehole()` |
27+
| {ref}`Cheng and Sandu (2010) 2D <test-functions:cheng2d>` | 2 | `Cheng2D` |
28+
| {ref}`Coffee Cup Model <test-functions:coffee-cup>` | 2 | `CoffeeCup()` |
29+
| {ref}`Currin et al. (1988) Sine <test-functions:currin-sine>` | 1 | `CurrinSine()` |
30+
| {ref}`Damped Cosine <test-functions:damped-cosine>` | 1 | `DampedCosine()` |
31+
| {ref}`Damped Oscillator <test-functions:damped-oscillator>` | 7 | `DampedOscillator()` |
32+
| {ref}`Dette & Pepelyshev (2010) Exponential <test-functions:dette-exp>` | 3 | `DetteExp()` |
33+
| {ref}`Flood <test-functions:flood>` | 8 | `Flood()` |
34+
| {ref}`Forrester et al. (2008) <test-functions:forrester>` | 1 | `Forrester2008()` |
35+
| {ref}`(1st) Franke <test-functions:franke-1>` | 2 | `Franke1()` |
36+
| {ref}`(2nd) Franke <test-functions:franke-2>` | 2 | `Franke2()` |
37+
| {ref}`(3rd) Franke <test-functions:franke-3>` | 2 | `Franke3()` |
38+
| {ref}`(4th) Franke <test-functions:franke-4>` | 2 | `Franke4()` |
39+
| {ref}`(5th) Franke <test-functions:franke-5>` | 2 | `Franke5()` |
40+
| {ref}`(6th) Franke <test-functions:franke-6>` | 2 | `Franke6()` |
41+
| {ref}`Friedman (6D) <test-functions:friedman-6d>` | 6 | `Friedman6D()` |
42+
| {ref}`Friedman (10D) <test-functions:friedman-10d>` | 10 | `Friedman10D()` |
43+
| {ref}`Genz (Corner Peak) <test-functions:genz-corner-peak>` | M | `GenzCornerPeak()` |
44+
| {ref}`Gramacy (2007) 1D Sine <test-functions:gramacy-1d-sine>` | 1 | `Gramacy1DSine()` |
45+
| {ref}`Higdon (2002) Sine <test-functions:higdon-sine>` | 1 | `HigdonSine()` |
46+
| {ref}`Holsclaw et al. (2013) Sine <test-functions:holsclaw-sine>` | 1 | `HolsclawSine()` |
47+
| {ref}`Lim et al. (2002) Non-Polynomial <test-functions:lim-non-poly>` | 2 | `LimNonPoly()` |
48+
| {ref}`Lim et al. (2002) Polynomial <test-functions:lim-poly>` | 2 | `LimPoly()` |
49+
| {ref}`McLain S1 <test-functions:mclain-s1>` | 2 | `McLainS1()` |
50+
| {ref}`McLain S2 <test-functions:mclain-s2>` | 2 | `McLainS2()` |
51+
| {ref}`McLain S3 <test-functions:mclain-s3>` | 2 | `McLainS3()` |
52+
| {ref}`McLain S4 <test-functions:mclain-s4>` | 2 | `McLainS4()` |
53+
| {ref}`McLain S5 <test-functions:mclain-s5>` | 2 | `McLainS5()` |
54+
| {ref}`Oakley & O'Hagan (2002) 1D <test-functions:oakley-1d>` | 1 | `Oakley1D()` |
55+
| {ref}`OTL Circuit <test-functions:otl-circuit>` | 6 / 20 | `OTLCircuit()` |
56+
| {ref}`Piston Simulation <test-functions:piston>` | 7 / 20 | `Piston()` |
57+
| {ref}`Robot Arm <test-functions:robot-arm>` | 8 | `RobotArm()` |
58+
| {ref}`Solar Cell Model <test-functions:solar-cell>` | 5 | `SolarCell()` |
59+
| {ref}`Sulfur <test-functions:sulfur>` | 9 | `Sulfur()` |
60+
| {ref}`Undamped Oscillator <test-functions:undamped-oscillator>` | 6 | `UndampedOscillator()` |
61+
| {ref}`Webster et al. (1996) 2D <test-functions:webster-2d>` | 2 | `Webster2D()` |
62+
| {ref}`Welch et al. (1992) <test-functions:welch1992>` | 20 | `Welch1992()` |
63+
| {ref}`Wing Weight <test-functions:wing-weight>` | 10 | `WingWeight()` |
6364

6465
In a Python terminal, you can list all the available functions relevant
6566
for metamodeling applications using ``list_functions()``

docs/references.bib

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,4 +1032,15 @@ @InBook{Higdon2002
10321032
doi = {10.1007/978-1-4471-0657-9_2},
10331033
}
10341034

1035+
@Article{Dette2010,
1036+
author = {Dette, Holger and Pepelyshev, Andrey},
1037+
journal = {Technometrics},
1038+
title = {Generalized latin hypercube design for computer experiments},
1039+
year = {2010},
1040+
number = {4},
1041+
pages = {421--429},
1042+
volume = {52},
1043+
doi = {10.1198/tech.2010.09157},
1044+
}
1045+
10351046
@Comment{jabref-meta: databaseType:bibtex;}

docs/test-functions/available.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ regardless of their typical applications.
3838
| {ref}`Damped Cosine <test-functions:damped-cosine>` | 1 | `DampedCosine()` |
3939
| {ref}`Damped Oscillator <test-functions:damped-oscillator>` | 7 | `DampedOscillator()` |
4040
| {ref}`Damped Oscillator Reliability <test-functions:damped-oscillator-reliability>` | 8 | `DampedOscillatorReliability()` |
41+
| {ref}`Dette & Pepelyshev (2010) Exponential <test-functions:dette-exp>` | 3 | `DetteExp()` |
4142
| {ref}`Flood <test-functions:flood>` | 8 | `Flood()` |
4243
| {ref}`Forrester et al. (2008) <test-functions:forrester>` | 1 | `Forrester2008()` |
4344
| {ref}`Four-branch <test-functions:four-branch>` | 2 | `FourBranch()` |

docs/test-functions/dette-exp.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---
2+
jupytext:
3+
formats: ipynb,md:myst
4+
text_representation:
5+
extension: .md
6+
format_name: myst
7+
format_version: 0.13
8+
jupytext_version: 1.14.1
9+
kernelspec:
10+
display_name: Python 3 (ipykernel)
11+
language: python
12+
name: python3
13+
---
14+
15+
(test-functions:dette-exp)=
16+
# Exponential Function from Dette and Pepelyshev (2010)
17+
18+
```{code-cell} ipython3
19+
import numpy as np
20+
import matplotlib.pyplot as plt
21+
import uqtestfuns as uqtf
22+
```
23+
24+
The function is a three-dimensional, scalar-valued function that exhibits
25+
asymptotic behavior where the function value approaches zero near the origin
26+
and increases toward a value as the input moves farther away from the origin
27+
in any direction.
28+
29+
The function appeared in {cite}`Dette2010` as a test function for comparing
30+
different experimental designs in the construction of metamodels.
31+
32+
## Test function instance
33+
34+
To create a default instance of the test function:
35+
36+
```{code-cell} ipython3
37+
my_testfun = uqtf.DetteExp()
38+
```
39+
40+
Check if it has been correctly instantiated:
41+
42+
```{code-cell} ipython3
43+
print(my_testfun)
44+
```
45+
46+
## Description
47+
48+
The test function is defined as[^location]:
49+
50+
$$
51+
\mathcal{M}(\boldsymbol{x}) = 100 \left[ \exp{\left( -\frac{2}{x_1^{1.75}} \right)} + \exp{\left( -\frac{2}{x_2^{1.5}} \right)} + \exp{\left( -\frac{2}{x_3^{1.25}} \right)} \right],
52+
$$
53+
54+
where $\boldsymbol{x} = \left( x_1, x_2, x_3 \right)$ is the three-dimensional
55+
vector of input variables further defined below.
56+
57+
## Probabilistic input
58+
59+
The probabilistic input model for the test function is shown below.
60+
61+
```{code-cell} ipython3
62+
:tags: [hide-input]
63+
64+
print(my_testfun.prob_input)
65+
```
66+
67+
## Reference results
68+
69+
This section provides several reference results of typical UQ analyses involving
70+
the test function.
71+
72+
### Sample histogram
73+
74+
Shown below is the histogram of the output based on $100'000$ random points:
75+
76+
```{code-cell} ipython3
77+
:tags: [hide-input]
78+
79+
my_testfun.prob_input.reset_rng(42)
80+
xx_test = my_testfun.prob_input.get_sample(100000)
81+
yy_test = my_testfun(xx_test)
82+
83+
plt.hist(yy_test, bins="auto", color="#8da0cb");
84+
plt.grid();
85+
plt.ylabel("Counts [-]");
86+
plt.xlabel("$\mathcal{M}(X)$");
87+
plt.gcf().tight_layout(pad=3.0)
88+
plt.gcf().set_dpi(150);
89+
```
90+
91+
## References
92+
93+
```{bibliography}
94+
:style: unsrtalpha
95+
:filter: docname in docnames
96+
```
97+
98+
[^location]: see Eq. (4), Section 3.1, p. 424, in {cite}`Dette2010`.

src/uqtestfuns/test_functions/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from .currin_sine import CurrinSine
1515
from .damped_cosine import DampedCosine
1616
from .damped_oscillator import DampedOscillator, DampedOscillatorReliability
17+
from .dette import DetteExp
1718
from .flood import Flood
1819
from .forrester import Forrester2008
1920
from .four_branch import FourBranch
@@ -75,6 +76,7 @@
7576
"DampedCosine",
7677
"DampedOscillator",
7778
"DampedOscillatorReliability",
79+
"DetteExp",
7880
"Flood",
7981
"Forrester2008",
8082
"FourBranch",
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
"""
2+
Module with an implementation of the functions from Dette and Pepelyshev (2010)
3+
4+
The paper by Dette and Pepelyshev [1] contains several analytical test
5+
functions used to compare different experimental designs for metamodeling
6+
applications.
7+
8+
References
9+
----------
10+
11+
1. H. Dette and A. Pepelyshev, “Generalized Latin Hypercube Design for Computer
12+
Experiments,” Technometrics, vol. 52, no. 4, pp. 421–429, 2010.
13+
DOI: 10.1198/TECH.2010.09157.
14+
"""
15+
16+
import numpy as np
17+
18+
from uqtestfuns.core.custom_typing import ProbInputSpecs
19+
from uqtestfuns.core.uqtestfun_abc import UQTestFunFixDimABC
20+
21+
__all__ = ["DetteExp"]
22+
23+
24+
def evaluate_exp(xx: np.ndarray) -> np.ndarray:
25+
"""Evaluate the exponential function from Dette and Pepelyshev (2010).
26+
27+
Parameters
28+
----------
29+
xx : np.ndarray
30+
M-Dimensional input values given by an N-by-3 array where
31+
N is the number of input values.
32+
33+
Returns
34+
-------
35+
np.ndarray
36+
The output of the test function evaluated on the input values.
37+
The output is a 1-dimensional array of length N.
38+
"""
39+
yy = np.sum(np.exp(-2 / xx**([1.75, 1.5, 1.25])), axis=1)
40+
41+
return 100 * yy
42+
43+
44+
class DetteExp(UQTestFunFixDimABC):
45+
"""A concrete implementation of the exponential function."""
46+
47+
_tags = ["metamodeling"]
48+
_description = "Exponential function from Dette and Pepelyshev (2010)"
49+
_available_inputs: ProbInputSpecs = {
50+
"Dette2010": {
51+
"function_id": "DetteExp",
52+
"description": (
53+
"Input specification for the exponential test function "
54+
"from Dette and Pepelyshev et al. (2010)"
55+
),
56+
"marginals": [
57+
{
58+
"name": f"x_{i + 1}",
59+
"distribution": "uniform",
60+
"parameters": [0, 1],
61+
"description": None,
62+
}
63+
for i in range(3)
64+
],
65+
"copulas": None,
66+
},
67+
}
68+
_available_parameters = None
69+
70+
evaluate = staticmethod(evaluate_exp) # type: ignore

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def create_random_marginals(length: int) -> List[Marginal]:
6969
parameters = np.sort(1 + 2 * np.random.rand(3))
7070
parameters[[0, 1]] = parameters[[1, 0]]
7171
# Insert sigma/beta as the second parameter
72-
parameters = np.insert(parameters, 1, np.random.rand(1))
72+
parameters = np.insert(parameters, 1, 0.5 + np.random.rand(1))
7373
elif distribution == "lognormal":
7474
# Limit the size of the parameters
7575
parameters = 1 + np.random.rand(2)

0 commit comments

Comments
 (0)