Model Definition

This tutorial describes how to setup a function with random inputs.

We start by defining a function of two random variables. We will use the Rosenbrock benchmark. See pyapprox.benchmarks.benchmarks.setup_rosenbrock_function()

import numpy as np
from scipy import stats
from pyapprox.variables import IndependentMarginalsVariable


def fun(samples):
    return np.sum(samples*2, axis=0)[:, None]

Now lets define the inputs to the function of interest. For independent random variables we use SciPy random variablest to represent each one-dimensional variables. For documentation refer to the scipy.stats module.

We define multivariate random variables by specifying each 1D variable in a list. Here we will setup a 2D variable which is the tensor product of two independent and identically distributed uniform random variables

univariate_variables = [stats.uniform(-2, 4), stats.uniform(-2, 4)]
variable = IndependentMarginalsVariable(univariate_variables)

To print a summary of the random variable use

print(variable)
Independent Marginal Variable
Number of variables: 2
Unique variables and global id:
    uniform(loc=[-2],scale=[4]): z0, z1

We can draw random samples from variable and evaluate the function using

nsamples = 1000
samples = variable.rvs(nsamples)
values = fun(samples)

Summary statistics of the samples and values can be printed using

from pyapprox.variables import print_statistics
print_statistics(samples, values)
           z0         z1         y0
count  1000.000000 1000.000000 1000.000000
mean    -0.038207  -0.041565  -0.159543
std      1.165293   1.175000   3.340050
min     -1.992304  -1.996393  -7.725900
max      1.995606   1.988541   7.762915

User defined functions

PyApprox can be used with pretty much any function provided an appropriate interface is defined. Here will show how to setup a simple function.

PyApprox requires all functions to take 2D np.ndarray with shape (nvars,nsamples) and requires a function to return a 2D np.ndarray with shape (nsampels,nqoi). nqoi==1 for scalar valued functions and nqoi>1 for vectored value functions.

Lets define a function which does not match this criteria and use wrappers provided by PyApprox to convert it to the correct format. Specifically we will define a function that only takes a 1D np.ndarray and returns a scalar. We import these functions from a separate file

def fun_0(sample):
    assert sample.ndim == 1
    return np.sum(sample**2)


def pyapprox_fun_0(samples):
    values = evaluate_1darray_function_on_2d_array(fun_0, samples)
    return values


from __util import pyapprox_fun_0, fun_0
values = pyapprox_fun_0(samples)

The function pyapprox.interface.wrappers.evaluate_1darray_function_on_2d_array() avoids the need to write a for loop but we can do this also and does some checking to make sure values is the correct shape

values_loop = np.array([np.atleast_1d(fun_0(s)) for s in samples.T])
assert np.allclose(values, values_loop)

Total running time of the script: ( 0 minutes 0.021 seconds)

Gallery generated by Sphinx-Gallery