Skip to content

Commit 58cbb5a

Browse files
committed
Merge remote-tracking branch 'origin/devel'
2 parents 252fc58 + a024fbe commit 58cbb5a

File tree

143 files changed

+15657
-5823
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

143 files changed

+15657
-5823
lines changed

docs/papers/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Papers
2+
3+
This folder contains scripts associated with papers that use PyApprox
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FROM ubuntu:latest
2+
3+
RUN apt-get update && \
4+
apt-get install -y python3-pip
5+
6+
RUN update-ca-certificates && \
7+
pip3 config set global.trusted-host "pypi.org files.pythonhosted.org pypi.python.org"
8+
9+
RUN pip3 install umbridge
10+
11+
RUN pip3 install pyapprox
12+
13+
COPY minimal_server.py /
14+
15+
CMD python3 minimal_server.py
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Genz Integration Functions
2+
3+
## Overview
4+
This benchmark consists of fix families of analytical functions $F_k:\mathbb{R}^D\to\mathbb{R}$, $k=1,\ldots,6$, with means $\mathbb{E}[F(\theta)]$ that can be computed analytically. The number of inputs $D$ and the anisotropy (relative importance of each variable and interactions) of the functions can be adjusted.
5+
6+
## Authors
7+
John D. Jakeman
8+
9+
## Run
10+
docker run -it -p 4243:4243 linusseelinger/benchmark-genz
11+
12+
## Properties
13+
14+
Model | Description
15+
---|---
16+
forward | Forward model
17+
18+
### forward
19+
Mapping | Dimensions | Description
20+
---|---|---
21+
input | [D] | 2D coordinates $x \in \mathbb{R}^D$
22+
output | [1] | Function $F(x)$ evaluated at $x$
23+
24+
Feature | Supported
25+
---|---
26+
Evaluate | True
27+
Gradient | False
28+
ApplyJacobian | False
29+
ApplyHessian | False
30+
31+
Config | Type | Default | Description
32+
---|---|---|---
33+
nvars | int | D | Number of inputs
34+
c_factor | double | 1.0 | Normalization parameter
35+
w_factor | double | 0. | shift parameter
36+
coef_type | string | "sqexp" | Coefficient decay type
37+
name | string | "oscillatory" | Name of the test function
38+
39+
The supported values of the coef_type and name config variables are:
40+
41+
name=["oscillatory", "product_peak", "corner_peak", "gaussian", "c0continuous", "discontinuous"]
42+
coef_type=["none", "quadratic", "quartic", "exp", "sqexp"]
43+
44+
45+
## Mount directories
46+
Mount directory | Purpose
47+
---|---
48+
None |
49+
50+
## Source code
51+
52+
[Model sources here.](https://github.com/sandialabs/pyapprox/blob/master/pyapprox/benchmarks/genz.py)
53+
54+
55+
## Description
56+
The six Genz test function are:
57+
58+
Oscillatory ('oscillatory')
59+
60+
$$ f(z) = \cos\left(2\pi w_1 + \sum_{d=1}^D c_dz_d\right)$$
61+
62+
Product Peak ('product_peak')
63+
64+
$$ f(z) = \prod_{d=1}^D \left(c_d^{-2}+(z_d-w_d)^2\right)^{-1}$$
65+
66+
Corner Peak ('corner_peak')
67+
68+
$$ f(z)=\left( 1+\sum_{d=1}^D c_dz_d\right)^{-(D+1)}$$
69+
70+
Gaussian Peak ('gaussian')
71+
72+
$$ f(z) = \exp\left( -\sum_{d=1}^D c_d^2(z_d-w_d)^2\right)$$
73+
74+
C0 Continuous ('c0continuous')
75+
76+
$$ f(z) = \exp\left( -\sum_{d=1}^D c_d\lvert z_d-w_d\rvert\right)$$
77+
78+
Discontinuous ('discontinuous')
79+
80+
$$ f(z) = \begin{cases}
81+
0 & z_1>w_1 \;\mathrm{or}\; z_2>w_2\\
82+
\exp\left(\sum_{d=1}^D c_dz_d\right) & \mathrm{otherwise}
83+
\end{cases}$$
84+
85+
Increasing $\lVert c \rVert$ will in general make
86+
the integrands more difficult.
87+
88+
The $0\le w_d \le 1$ parameters do not affect the difficulty
89+
of the integration problem. We set $w_1=w_2=\ldots=W_D$.
90+
91+
The coefficient types implement different decay rates for $c_d$.
92+
This allows testing of methods that can identify and exploit anisotropy.
93+
They are as follows:
94+
95+
No decay (none)
96+
97+
$$ \hat{c}_d=\frac{d+0.5}{D}$$
98+
99+
Quadratic decay (qudratic)
100+
101+
$$ \hat{c}_d = \frac{1}{(D + 1)^2}$$
102+
103+
Quartic decay (quartic)
104+
105+
$$ \hat{c}_d = \frac{1}{(D + 1)^4}$$
106+
107+
Exponential decay (exp)
108+
109+
$$ \hat{c}_d=\exp\left(\log(c_\mathrm{min})\frac{d+1}{D}\right)$$
110+
111+
Squared-exponential decay (sqexp)
112+
113+
$$ \hat{c}_d=10^{\left(\log_{10}(c_\mathrm{min})\frac{(d+1)^2}{D}\right)}$$
114+
115+
Here $c_\mathrm{min}$ is argument that sets the minimum value of $c_D$.
116+
117+
Once the formula are used the coefficients are normalized such that
118+
119+
$$ c_d = c_\text{factor}\frac{\hat{c}_d}{\sum_{d=1}^D \hat{c}_d}.$$
120+
121+
## References
122+
This benchmark was first proposed [here.](https://doi.org/10.1007/978-94-009-3889-2_33)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env python3
2+
import argparse
3+
import itertools
4+
5+
import umbridge
6+
import numpy as np
7+
8+
9+
parser = argparse.ArgumentParser(description='Model output test.')
10+
parser.add_argument(
11+
'url', metavar='url', type=str,
12+
help='the ULR on which the model is running, for example {0}'.format(
13+
'http://localhost:4242'))
14+
args = parser.parse_args()
15+
print(f"Connecting to host URL {args.url}")
16+
17+
model = umbridge.HTTPModel(args.url, "genz")
18+
19+
assert model.get_input_sizes({"nvars": 4}) == [4]
20+
assert model.get_output_sizes() == [1]
21+
22+
# check all combinations of config runs
23+
names = ["oscillatory", "product_peak", "corner_peak", "gaussian",
24+
"c0continuous", "discontinuous"]
25+
nvars = np.arange(2, 7).astype(float)
26+
decays = ["none", "quadratic", "quartic", "exp", "sqexp"]
27+
test_scenarios = itertools.product(*[names, nvars, decays])
28+
for test_scenario in test_scenarios:
29+
np.random.seed(1)
30+
parameters = [np.random.uniform(0, 1, (int(test_scenario[1]))).tolist()]
31+
config = {"name": test_scenario[0], "nvars": test_scenario[1],
32+
"coef_type": test_scenario[2]}
33+
value = model(parameters, config)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import umbridge
2+
3+
4+
def fun():
5+
model = umbridge.HTTPModel("http://localhost:4242", "genz")
6+
print(model.get_input_sizes())
7+
print(model.get_output_sizes())
8+
sample = [[0, 0.5, 1.0, 0.7, 0.4]]
9+
print(model(sample))
10+
11+
12+
if __name__ == '__main__':
13+
fun()
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import umbridge
2+
import numpy as np
3+
4+
from pyapprox.benchmarks.genz import GenzFunction
5+
6+
7+
class GenzModel(umbridge.Model):
8+
def __init__(self):
9+
super().__init__("genz")
10+
self._model = GenzFunction()
11+
12+
def get_input_sizes(self, config):
13+
return [config.get("nvars", 5)]
14+
15+
def get_output_sizes(self, config):
16+
return [1]
17+
18+
def __call__(self, parameters, config):
19+
sample = np.asarray(parameters).T
20+
assert sample.shape[0] == config.get("nvars", 5)
21+
self._model.set_coefficients(
22+
sample.shape[0],
23+
config.get("c_factor", 1),
24+
config.get("coef_type", "sqexp"),
25+
config.get("w_factor", 0.5))
26+
name = config.get("name", "oscillatory")
27+
val = self._model(name, sample)[0, 0]
28+
return [[val]]
29+
30+
def supports_evaluate(self):
31+
return True
32+
33+
34+
models = [GenzModel()]
35+
umbridge.serve_models(models, 4242)

0 commit comments

Comments
 (0)