Sets of random variables#

Introduction#

In Fesslix, sets of random variables can be defined. In this context, a set is a collection of random variables. Sets and random variables are addressed by their unique ID. Each set of random variables has a unique ID of type rvSetID. All random variables within a specific set have a unique ID of type rvID. The full ID (rvFullID) of a random variable is a combination of the set-ID and its internal ID: rvSetID::rvID.

import fesslix as flx
flx.load_engine()
import fesslix.plot as flx_plot
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
Random Number Generator: MT19937 - initialized with rand()=1398748231;
Random Number Generator: MT19937 - initialized with 1000 initial calls.

Sets of general random variables#

Definition#

flx.rv_set()#
Syntax:

flx.rv_set( config_set, rv_lst )

Description:

Returns a set of general random variables of type flx.rvset.

Parameters:
  • config_set (dict) –

    The following keys are allowed in config_set:

    • name (type rvSetID): The name of the set of random variables to create.

    • is_Nataf (bool, default: False): True: the set is based on the Nataf transformation; False: the set is based on the Rosenblatt transformation.

    In case of the Rosenblatt transformation (i.e., for config_set['is_Nataf']=False), additionally, the following keys can be specified:

    • parents (list, default: []): A list (of already defined sets or random variables) on which the set to be defined is to be conditioned on. The list entries must be of type rvSetID. Used this key if the parameters of random variables in the current set depend on the values of random variables in another set.

    • allow_x2y (bool, default: False): By default, only the transformation from standard normal space to original space is supported by this set. However, sometimes the reverse transformation is required – which is more involved from a mathematical and numerical point of view. By setting this parameter to True, the reverse transformation is activated if possible.

    In case of the Nataf transformation (i.e., for config_set['is_Nataf']=True), additionally, the following keys can be specified:

    • corr (list, default: []): A list of correlations. The entries in the list must be of type dict; the following keys are allowed:

      • rv_1 (rvID): identifier (name) of random variable in current set

      • rv_2 (rvID): identifier (name) of random variable in current set (must be different from rv_1)

      • value (float): value of the correlation coefficient of the pair of random variables rv_1 and rv_2.

      • corr_approx (bool, default: True): True: an approximate empirical relationship is used to determine the correlation coefficient of the underlying pair of standard Normal random variables. False: this value is evaluated numerically by means of the algorithm described in TODO. This parameter is only relevant if rhogauss is set to False.

      • rhogauss (bool, default: False): If True, the specified correlation coefficient is associated with the underlying standard Normal random variables (i.e., the correlation coefficient is applied to the random variables transformed to standard Normal space). Activating this option can reduce the computational costs of assembling the correlation matrix.

    • is_Nataf_only_once (bool, default: True): If True, the parameters of the marginal distributions of the Nataf transformation are evaluated only once. Only experienced users should consider setting the value of this parameter to False.

  • rv_lst (list) –

    A list with configurations for the random variables to create in the set. The list entries must be of type flx_gen_rv_config.

    In case of the Rosenblatt transformation (i.e., for config_set['is_Nataf']=False), additionally, the following keys can be specified for the individual entries:

    • corr (dict, optional): Defines a correlation coefficient between this random variable and another random variable in the set. The following keys are allowed:

      • rv_name (rvID): identifier (name) of random variable in current set

      • value (float): value of the correlation coefficient of the current random variable with the random variable specified in rv_name.

      • fix (bool, default: False): True: The correlation coefficient is evaluated a single time and the parameters of the involved random variables are constant. In this case the correlation of the underlying standard normal random variables is a constant and, thus, needs to be evaluated only once. False: The correlation of the underlying standard normal random variables is not treated as a constant and needs to be evaluated anew every time a new realization is generated. This mode can be computationally demanding – and should be used only if really needed.

Return type:

flx.rvset

type rvSetID#
Syntax:

Word

Description:

This data-type assigns a unique identifier (of type Word) to a set (i.e., a collection) of random variables.

Working with sets of random variables#

class flx.rvset#

A set (i.e., collection) of random variables.

get_name()#

Retrieves the name of the set of random variables.

Returns:

name of set

Return type:

rvSetID

get_NRV()#

Returns the total number of random variables (in standard Normal space) in the set.

Return type:

int

get_NOX()#

Returns the total number of random variables (in original space) in the set.

Return type:

int

get_values(mode)#

Returns an array of quantities of all entries contained in the set of random variables.

Parameters:

mode (Word) –

Specifies the mode of the operation.

The following keywords are allowed:

  • x: Return an array with the current realizations of the random variables in the set.

  • u: Return an array with the standard Normal transformed values of the current realizations of the random variables in the set.

  • mean: Return an array with the mean values of the random variables in the set.

  • sd: Return an array with the standard deviations of the random variables in the set.

Return type:

numpy.ndarray

get_rvs()#

Retrieves a list of all random variables in the set.

Return type:

Python list of flx.rv

set_y_vec(y_vec)#

Assign y_vec as standard Normal values of the random variables in the set.

Parameters:

y_vec (numpy.ndarray) – Vector with the standard Normal values to assign to the random variables in the set.

set_x_vec(x_vec)#

Assign x_vec as values of the random variables in the set.

Parameters:

x_vec (numpy.ndarray) – Vector with the values to assign to the random variables in the set.

pdf_log(x_vec)#

Evaluate the log-transformed PDF of the random variables at x_vec in the set.

Parameters:

x_vec (numpy.ndarray) – Vector at which to evaluate the PDF (in original space).

Return type:

float

flx.get_rv_from_set()#
Syntax:

flx.get_rv_from_set( rv_name )

Description:

Retrieve random variable rv_name from a set of random variables.

Parameters:

rv_name (rvFullID) – A unique global identifier of the targeted random variable.

Return type:

flx.rv

type rvFullID#
Syntax:

rvSetID::rvID

where rvSetID is of type rvSetID and rvID is of type rvID.

Description:

This data-type represents a unique global identifier for a random variable.

FlxFunction.rbrv()#
Syntax:

rbrv( rv_name )

Description:

This FlxFunction returns the current realization of random variable rv_name.

Parameters:

rv_name (rvFullID) – A unique global identifier of the targeted random variable.

Generating random samples#

class flx.sampler#

Used to generate random realizations from a set (or multiple sets) of random variables.

__init__(set_lst)#

Initialize a flx.sampler instance using a list of sets of random variables of type flx.rv_set().

Parameters:

set_lst (list) – A Python list containing sets of random variables of type flx.rv_set()

sample()#

Generate a random realization for a collection of sets of random variables. The generated realizations can be accessed using flx.rv.get_value(), flx.rvset.get_values() or FlxFunction.rbrv().

Return type:

None

get_NRV()#

Returns the total number of random variables (in standard Normal space) in the collection.

Return type:

int

get_values(mode)#

Returns an array of quantities of all entries contained in the sampler.

Parameters:

mode (Word) –

Specifies the mode of the operation.

The following keywords are allowed:

  • x: Return an array with the current realizations of the random variables in the sampler.

  • u: Return an array with the standard Normal transformed values of the current realizations of the random variables in the sampler.

  • mean: Return an array with the mean values of the random variables in the sampler.

  • sd: Return an array with the standard deviations of the random variables in the sampler.

Return type:

numpy.ndarray

get_NOX()#

Returns the total number of random variables (in original space) in the collection.

Return type:

int

assign_u(u_vec)#

Assign u_vec as standard Normal values of the random variables in the sampler and perform the transformation to original space.

Parameters:

u_vec (numpy.ndarray) – Vector with the standard Normal values to assign to the random variables in the sampler.

assign_x(x_vec, transform=True)#

Assign x_vec as values of the random variables in the sampler.

Parameters:
  • x_vec (numpy.ndarray) – Vector to assign.

  • transform (bool) – True: Assign x_vec and perform the transformation from original space to standard Normal space. False: just assign x_vec without performing the transformation.

Examples#

Set without dependencies (i.e., parents)#

## ================================================================
## Set without dependencies (i.e., parents)
## ================================================================

## ------------------------------------------
## Definition
## ------------------------------------------
config_rv_a1 = { 'name':'rv1', 'type':'stdn' }
config_rv_a2 = { 'name':'rv2', 'type':'logn', 'mu':1., 'sd':2. }
config_rv_a3 = { 'name':'rv3', 'type':'fun', 'fun':"rbrv(rv_set_a::rv2)" }
rv_set_a = flx.rv_set( {'name':'rv_set_a'}, [ config_rv_a1, config_rv_a2, config_rv_a3 ] )

## ------------------------------------------
## Retrieve random variables from the set
## ------------------------------------------
rv_a1 = flx.get_rv_from_set("rv_set_a::rv1")
rv_a2 = flx.get_rv_from_set("rv_set_a::rv2")
rv_a3 = flx.get_rv_from_set("rv_set_a::rv3")
print( rv_a1.info() )
print( rv_a3.info() )

## ------------------------------------------
## Generate random samples
## ------------------------------------------
sampler_a = flx.sampler(['rv_set_a'])
for i in range(10):
    sampler_a.sample()
    print(f"sample {i+1:2.0f}: {rv_a1.get_value():8.2f}, {rv_a2.get_value():8.2f}, {rv_a3.get_value():8.2f}" )

## ------------------------------------------
## List of variables in the set
## ------------------------------------------    
rv_lst = rv_set_a.get_rvs()
for rv_entry in rv_lst:
    rv_name = rv_entry.get_name()
    rv_val = rv_entry.get_value()
    print(f"{rv_name}: {rv_val:8.2f}")
    
{'type': 'stdn', 'name': 'rv_set_a::rv1', 'mean': 0.0, 'sd': 1.0, 'entropy': 1.4189385332046727}
{'type': 'fun', 'name': 'rv_set_a::rv3'}
sample  1:    -0.67,     1.32,     1.32
sample  2:    -1.92,     0.18,     0.18
sample  3:    -0.08,     2.12,     2.12
sample  4:     2.02,     0.60,     0.60
sample  5:     0.26,     0.36,     0.36
sample  6:    -0.24,     0.29,     0.29
sample  7:     0.96,     0.38,     0.38
sample  8:     0.32,     3.32,     3.32
sample  9:     2.02,     1.14,     1.14
sample 10:    -0.20,     0.16,     0.16
rv_set_a::rv1:    -0.20
rv_set_a::rv2:     0.16
rv_set_a::rv3:     0.16

Set that depends on another set#

## ================================================================
## Set that depends on 'rv_set_a'
## ================================================================

## ------------------------------------------
## Definition
## ------------------------------------------
config_rv_b1 = { 'name':'rv1', 'type':'normal', 'mu':"rbrv(rv_set_a::rv2)", 'sd':0.1 }
config_rv_b2 = { 'name':'rv2', 'type':'normal', 'mu':"rbrv(rv_set_b::rv1)", 'sd':0.05 }
rv_set_b = flx.rv_set( {'name':'rv_set_b', 'parents':['rv_set_a']}, [ config_rv_b1, config_rv_b2 ] )

## ------------------------------------------
## Retrieve random variables from the set
## ------------------------------------------
rv_b1 = flx.get_rv_from_set("rv_set_b::rv1")
rv_b2 = flx.get_rv_from_set("rv_set_b::rv2")

## ------------------------------------------
## Generate random samples
## ------------------------------------------
sampler_b = flx.sampler(['rv_set_b'])   ## 'rv_set_a' is added implicitly!
for i in range(10):
    sampler_b.sample()
    print(f"sample {i+1:2.0f}: {rv_a1.get_value():8.2f}, {rv_a2.get_value():8.2f}, {rv_b1.mean():8.2f}, {rv_b1.get_value():8.2f}, {rv_b2.mean():8.2f}, {rv_b2.get_value():8.2f}" )
sample  1:    -1.53,    11.65,    11.65,    11.51,    11.51,    11.62
sample  2:     0.55,     0.81,     0.81,     0.86,     0.86,     0.90
sample  3:    -0.66,     0.49,     0.49,     0.54,     0.54,     0.54
sample  4:    -0.64,     0.26,     0.26,     0.14,     0.14,     0.19
sample  5:     0.45,     0.77,     0.77,     0.76,     0.76,     0.75
sample  6:     1.43,     1.71,     1.71,     1.66,     1.66,     1.67
sample  7:     0.54,     0.07,     0.07,     0.05,     0.05,    -0.02
sample  8:     0.49,     0.20,     0.20,     0.24,     0.24,     0.19
sample  9:     1.48,     0.37,     0.37,     0.37,     0.37,     0.42
sample 10:     0.37,     4.51,     4.51,     4.36,     4.36,     4.39
## ------------------------------------------
## assign standard Normal vector to sampler
## ------------------------------------------
sampler_b.assign_u(np.zeros(sampler_b.get_NRV()))
print( rv_set_b.get_values('u'), rv_set_b.get_values('x') )
[0. 0.] [0.4472136 0.4472136]

Set with correlated random variables#

## ================================================================
## Set with correlated random variables
## ================================================================

## ------------------------------------------
## Definition
## ------------------------------------------
config_rv_c1 = { 'name':'rv1', 'type':'normal', 'mu':2., 'sd':1. }
config_rv_c2 = { 'name':'rv2', 'type':'stdn', 'corr':{ 'rv_name': 'rv1', 'value':0.95, 'fix':True } }
config_rv_c3 = { 'name':'rv3', 'type':'logn', 'mu':5., 'sd':5., 'corr':{ 'rv_name': 'rv1', 'value':0.7, 'fix':True } }
rv_set_c = flx.rv_set( {'name':'rv_set_c'}, [ config_rv_c1, config_rv_c2, config_rv_c3 ] )

## ------------------------------------------
## Retrieve random variables from the set
## ------------------------------------------
rv_c1 = flx.get_rv_from_set("rv_set_c::rv1")
rv_c2 = flx.get_rv_from_set("rv_set_c::rv2")
rv_c3 = flx.get_rv_from_set("rv_set_c::rv3")

## ------------------------------------------
## Output mean and std.dev. vector
## ------------------------------------------
print( "mean:", rv_set_c.get_values('mean') )
print( "sd:", rv_set_c.get_values('sd') )

## ------------------------------------------
## Generate random samples
## ------------------------------------------
N = 10000   ## number of samples to generate
sampler_c = flx.sampler(['rv_set_c'])  
smpl_mtx = np.empty((N, 3))
for i in range(N):
    sampler_c.sample()
    smpl_mtx[i] = rv_set_c.get_values('x')
    
## ------------------------------------------
## evaluate correlation of sample matrix
## ------------------------------------------
corr_mtx = np.corrcoef( smpl_mtx, rowvar=False )
print(corr_mtx)
## ------------------------------------------
## assign x-values without transformation (to standard Normal space)
## ------------------------------------------  
sampler_c.assign_x([3.,2.,8.],transform=False)
print( sampler_c.get_values('x') )
mean: [2. 0. 5.]
sd: [1. 1. 5.]
[[1.         0.95078839 0.70531333]
 [0.95078839 1.         0.67149119]
 [0.70531333 0.67149119 1.        ]]
[3. 2. 8.]

Set based on the Nataf transformation#

## ================================================================
## Set based on the Nataf transformation
## ================================================================

## ------------------------------------------
## Definition
## ------------------------------------------
config_rv_d1 = { 'name':'rv1', 'type':'normal', 'mu':2., 'sd':1. }
config_rv_d2 = { 'name':'rv2', 'type':'stdn' }
config_rv_d3 = { 'name':'rv3', 'type':'logn', 'mu':5., 'sd':5. }
rv_set_d = flx.rv_set( {'name':'rv_set_d', 
                        'is_Nataf':True, 
                        'allow_x2y':True,
                        'corr': [ {'rv_1':'rv1', 'rv_2':'rv2', 'value':0.95 }, 
                                  {'rv_1':'rv1', 'rv_2':'rv3', 'value':0.7 } , 
                                  {'rv_1':'rv2', 'rv_2':'rv3', 'value':0.8 } 
                                ]
                       }, [ config_rv_d1, config_rv_d2, config_rv_d3 ] )

## ------------------------------------------
## Generate random samples
## ------------------------------------------
N = 10000   ## number of samples to generate
sampler_d = flx.sampler(['rv_set_d'])  
smpl_mtx = np.empty((N, 3))
for i in range(N):
    sampler_d.sample()
    smpl_mtx[i] = rv_set_d.get_values('x')
    
## ------------------------------------------
## evaluate correlation of sample matrix
## ------------------------------------------
corr_mtx = np.corrcoef( smpl_mtx, rowvar=False )
print(corr_mtx)
[[1.         0.9505754  0.71505584]
 [0.9505754  1.         0.81656697]
 [0.71505584 0.81656697 1.        ]]
## ------------------------------------------
## evaluate log-PDF of set
## ------------------------------------------  
rv_set_d.set_y_vec(np.zeros(rv_set_d.get_NRV()))
x_smpl_vec = rv_set_d.get_values('x')
rv_set_d.set_x_vec(x_smpl_vec)
print(f"{rv_set_d.pdf_log(x_smpl_vec) = }")
print( rv_set_d.get_values('u') )
## ------------------------------------------
## assign x-values
## ------------------------------------------  
sampler_d.assign_x([3.,2.,8.],transform=True)
print( sampler_d.get_values('x') )
rv_set_d.pdf_log(x_smpl_vec) = -0.7950998394190119
[0. 0. 0.]
[3. 2. 8.]

Discrete random noise#

flx.rv_set_noise()#
Syntax:

flx.rv_set_noise( config_set, rv_config )

Description:

Creates a set of independent random variables that have all the same distribution.

Parameters:
  • config_set (dict) –

    The following keys are allowed in config_set:

    • name (rvSetID): The name of the set of random variables to create.

    • N (int): The number of random variables in the set. Value must be larger than zero.

    • parents (list, default: []): A list (of already defined sets or random variables) on which the set to be defined is to be conditioned on. The list entries must be of type rvSetID. Used this key if the parameters of random variables in the current set depend on the values of random variables in another set.

  • rv_config (flx_rv_config) – Defines the distribution underlying all random variables in the set.

Return type:

flx.rvset

Example:

## ================================================================
## Set to represent discrete random noise
## ================================================================

## ------------------------------------------
## Definition
## ------------------------------------------
rv_set_noise = flx.rv_set_noise( { 'name':'rv_set_noise',
                             'N': 5
                           }, { 'type':'logn', 'mu':1., 'sd':0.1} )

## ------------------------------------------
## Generate random samples
## ------------------------------------------
N = 10   ## number of samples to generate
sampler_noise = flx.sampler(['rv_set_noise'])  
for i in range(N):
    sampler_noise.sample()
    print( rv_set_noise.get_values('x') )
[0.84615637 1.15978955 0.93717533 1.00778074 1.17001303]
[1.07974646 0.8072773  0.80668592 0.93176884 0.8575905 ]
[1.02312948 1.11371386 0.81228694 0.96726066 1.11031083]
[1.010175   0.98925281 1.13516062 1.06141921 1.0254392 ]
[1.18151288 0.96257501 1.018801   0.96455563 1.21030636]
[0.89193171 0.89911687 1.22018997 0.94936926 1.02104049]
[0.75932835 1.24716922 1.16520133 1.13294892 0.98679499]
[0.93786991 1.0324204  0.95666333 0.8703847  0.84368171]
[0.94867622 1.0323857  1.22402387 0.9127574  0.93886572]
[1.08461874 1.00823835 1.00597821 1.11886755 0.88281809]

Discrete random process with given correlation structure#

flx.rv_set_proc()#
Syntax:

flx.rv_set_proc( config_set, rv_config )

Description:

Creates a set of independent random variables that have all the same distribution.

Parameters:
  • config_set (dict) –

    The following keys are allowed in config_set:

    • name (rvSetID): The name of the set of random variables to create.

    • N (int): The number of random variables in the set. Value must be larger than zero.

    • parents (list, default: []): A list (of already defined sets or random variables) on which the set to be defined is to be conditioned on. The list entries must be of type rvSetID. Used this key if the parameters of random variables in the current set depend on the values of random variables in another set.

    • rho (flxPara): The auto-correlation coefficient function. RHO should be a FlxFunction that depends on the special variables gx (cooridnate of first point), gx2 (coordinate of second point), and/or deltax (distance between first and second point).

    • dx (float, default: 1.0): The “distance” between two subsequent points; relevant for evaluating rho. Value must be positive.

    • M (int, default: 0): If this parameter equals 0, the Cholesky-decomposition is applied and the set will contain N random variables. If M > 0, then the EOLE method is used and M specifies the number of independent random variables in the set.

    • evtype (int, default: 2): This parameter is only relevant if the EOLE method is applied; i.e., for M > 0. For evtype=1, the matrix eigenvalue problem is solved by meansof Lanczos-methods. For evtype=2, the full matrix eigenvalue problem is solved.

    • only_once (bool, default: True): If True, the correlation matrix is assembled based on RHO only once. If False, the correlation matrix is assembled anew for each realization. The second option can be of relevance, if the auto-correlation coefficient function depends on random variables contained in one of the parent sets. However, note that assembling the correlation matrix can be computationally demanding.

    • rhogauss (bool, default: False): If True, the auto-correlation coefficient function RHO is associated with the underlying Gaussian process - and not with the actual stochastic process. Activating this option can reduce the computational costs of assembling the correlation matrix.

  • rv_config (flx_rv_config) – Defines the distribution underlying all random variables in the set.

Return type:

flx.rvset

Example:

## ================================================================
## rv_set_proc with Cholesky-decomposition
## ================================================================

## ------------------------------------------
## Definition
## ------------------------------------------
rv_set_proc_1 = flx.rv_set_proc( { 'name':'proc_1',
                                   'N': 100,
                                   'rho': "exp(-0.5*(deltax/3)^2)",
                                   'dx': 1.
                                 }, { 'type':'normal', 'mu':0.3, 'sd':0.2} )

## ------------------------------------------
## Generate and plot the random samples
## ------------------------------------------
N = 5   ## number of samples to generate
fig, ax = plt.subplots(figsize=(10, 4))
x_vec_1 = np.arange(100)
sampler_proc_1 = flx.sampler(['proc_1'])  
for i in range(N):
    sampler_proc_1.sample()
    ax.plot( x_vec_1, rv_set_proc_1.get_values('x') )
ax.set_xlim([0., 100.])
plt.xlabel(r"$x$")
plt.ylabel(r"realization")
plt.show()
_images/6a89b17d241d6c9a0dd5a9bb8afbb2ffa4adeab9b164c309eff7ca1cd170aa38.png
## ================================================================
## rv_set_proc employing EOLE
## ================================================================

## ------------------------------------------
## Definition
## ------------------------------------------
rv_set_proc_2 = flx.rv_set_proc( { 'name':'proc_2',
                                   'N': 1000,
                                   'rho': "exp(-0.5*(deltax/3)^2)",
                                   'dx': 0.1,
                                   'M': 100,
                                   'evtype': 2
                                 }, { 'type':'normal', 'mu':0.3, 'sd':0.2} )

## ------------------------------------------
## Generate and plot the random samples
## ------------------------------------------
N = 5   ## number of samples to generate
fig, ax = plt.subplots(figsize=(10, 4))
x_vec_2 = np.arange(1000)/10.
sampler_proc_2 = flx.sampler(['proc_2'])  
for i in range(N):
    sampler_proc_2.sample()
    ax.plot( x_vec_2, rv_set_proc_2.get_values('x') )
ax.set_xlim([0., 100.])
plt.xlabel(r"$x$")
plt.ylabel(r"realization")
plt.show()
_images/66e3072b49eefa35b0edb9e27d02ff0c26fc6598e8a1eb8ad2432a0298a28e88.png

Gaussian process with given power spectral density function#

flx.rv_set_psd()#
Syntax:

flx.rv_set_psd( config_set )

Description:

Creates a Gaussian process with given power spectral density function.

Parameters:

config_set (dict) –

The following keys are allowed in config_set:

  • name (rvSetID): The name of the set of random variables to create.

  • N (int): The number of intervals used when approximating the power spectral density. Note: 3*N independent standard Normal random variables are created. Must be a positive integer.

  • parents (list, default: []): A list (of already defined sets or random variables) on which the set to be defined is to be conditioned on. The list entries must be of type rvSetID. Used this key if the parameters of random variables in the current set depend on the values of random variables in another set.

  • psd (flxPara): The power spectral density function. psd can be a FlxFunction that depends on the special variables gx (frequency value).

  • lb (float): Lower bound for discretization of the power spectral density function in the frequency domain.

  • ub (float): Upper bound for discretization of the power spectral density function in the frequency domain.

Return type:

flx.rvset

classmethod flx.rv_set.eval_rp_psd()#
Syntax:

flx.rv_set.eval_rp_psd( t_vec )

Description:

Evaluates the realization of a random process with given power spectral density function.

This function is a method of class flx.rv_set that requires the underlying process to be defined using flx.rv_set_psd(); .i.e, the process needs to be associated with a power spectral density function.

Parameters:

t_vec (numpy.ndarray) – Vector with time-points at which to evaluate the realization of the random process.

Returns:

The realizations associated with t_vec.

Return type:

numpy.ndarray

Example:

## ================================================================
## Gaussian process with given power spectral density function
## ================================================================

## ------------------------------------------
## Definition
## ------------------------------------------
flx.set_const( 'sd', 2. )
flx.set_var( 'psd_1', "(sd/sqrt(18))^2" )
rv_set_psd_1 = flx.rv_set_psd( { 'name':'psd_1',
                                   'N': 100,
                                   'psd': "psd_1",
                                   'lb': 1.0,
                                   'ub': 10.0
                                 } )
flx.set_const( 'corr_l', 1. )
ub = flx.eval_fun("5./(2*pi*corr_l)")
flx.set_var( 'psd_2', "sd^2*sqrt(2*pi)*corr_l*exp(-2*(pi*corr_l*gx)^2)" )
rv_set_psd_2 = flx.rv_set_psd( { 'name':'psd_2',
                                   'N': 100,
                                   'psd': "psd_2",
                                   'lb': 0.0,
                                   'ub': ub
                                 } )
## ------------------------------------------
## estimate standard deviation
## ------------------------------------------
sampler_psd_1 = flx.sampler(['psd_1'])  
sampler_psd_2 = flx.sampler(['psd_2'])  
N = 2000   ## number of samples to generate
smpl_vec_1 = np.empty(N)
smpl_vec_2 = np.empty(N)
for i in range(N):
    sampler_psd_1.sample()
    sampler_psd_2.sample()
    smpl_vec_1[i] = rv_set_psd_1.eval_rp_psd([0.])[0]
    smpl_vec_2[i] = rv_set_psd_2.eval_rp_psd([0.])[0]
    
print( f"sample std.dev.: {np.std(smpl_vec_1):.2f}, {np.std(smpl_vec_2):.2f}" )
sample std.dev.: 2.02, 1.98
## ------------------------------------------
## Generate and plot the random samples
## ------------------------------------------
N = 5   ## number of samples to generate
t_max = 100.
fig, ax = plt.subplots(figsize=(10, 4))
t_vec_1 = np.arange(101)*(t_max/100)
for i in range(N):
    sampler_psd_1.sample()
    sampler_psd_2.sample()
    rp_smpl_1 = rv_set_psd_1.eval_rp_psd(t_vec_1)
    rp_smpl_2 = rv_set_psd_2.eval_rp_psd(t_vec_1)
    ax.plot( t_vec_1, rp_smpl_2 )
ax.set_xlim([0., t_max])
plt.xlabel(r"time $t$")
plt.ylabel(r"realization")
plt.show()
_images/9bcfdb5143f4639536d4585c480fe78a1d70a0d116bf041a2c087c4946305496.png

Random point uniformly distributed in hpyer-sphere#

flx.rv_set_sphere()#
Syntax:

flx.rv_set_sphere( config_set )

Description:

Creates a random point that is uniformly distribted in a hyper-sphere.

Parameters:

config_set (dict) –

The following keys are allowed in config_set:

  • name (rvSetID): The name of the set of random variables to create.

  • N (int): The dimension of the hyper-sphere (equals the number of random varibles in the set). Must be a positive integer.

  • radius (flxPara): The radius of the hyper-sphere.

  • parents (list, default: []): A list (of already defined sets or random variables) on which the set to be defined is to be conditioned on. The list entries must be of type rvSetID. Used this key if the parameters of random variables in the current set depend on the values of random variables in another set.

Return type:

flx.rvset

Example:

## ================================================================
## Random point uniformly distributed in hpyer-sphere
## ================================================================

## ------------------------------------------
## Definition
## ------------------------------------------
rv_set_sphere = flx.rv_set_sphere( { 'name':'sphere',
                                   'N': 2,
                                   'radius': 5.,
                                 } )

## ------------------------------------------
## Generate and plot the random samples
## ------------------------------------------
N = 1000   ## number of samples to generate
fig, ax = plt.subplots(figsize=(4, 4))
sampler_sphere = flx.sampler(['sphere'])  
for i in range(N):
    sampler_sphere.sample()
    smpl_vec = rv_set_sphere.get_values()
    ax.scatter( smpl_vec[0], smpl_vec[1], color=flx_plot.color_tumblue, s=100, alpha=0.5, edgecolors='none' )
plt.xlabel(r"$x_1$")
plt.ylabel(r"$x_2$")
plt.show()
_images/49b7ca74e6c6b38ac43448c85ba003f488928027989e421e8dc7be8883c44cc6.png

Vector function of random variables#

flx.rv_set_vfun()#
Syntax:

flx.rv_set_vfun( config_set )

Description:

Creates a vector that is an explicit function of random variables.

Parameters:

config_set (dict) –

The following keys are allowed in config_set:

  • name (rvSetID): The name of the set of random variables to create.

  • N (int): The dimension of the vector returned by the vector function. Must be a positive integer.

  • vecfun (flxVecPara): The vector function to evaluate. Must evaluate to an array of size N.

  • parents (list, default: []): A list (of already defined sets or random variables) on which the set to be defined is to be conditioned on. The list entries must be of type rvSetID. Used this key if the parameters of random variables in the current set depend on the values of random variables in another set.

Return type:

flx.rvset

Example:

## ================================================================
## Vector function of random variables
## ================================================================

## ------------------------------------------
## Parent set
## ------------------------------------------
rv_set_noise4vfun = flx.rv_set_noise( { 'name':'rv_set_noise4vfun',
                             'N': 5
                           }, { 'type':'logn', 'lambda':0., 'zeta':1.} )

## ------------------------------------------
## Definition V1
## ------------------------------------------
def vfun_1_map():
    y_vec = rv_set_noise4vfun.get_values('u')
    return np.exp( y_vec )
rv_set_vfun_1 = flx.rv_set_vfun( { 'name':'vfun_1',
                                   'N': 5,
                                   'vecfun': vfun_1_map,
                                   'parents': [ 'rv_set_noise4vfun' ]
                                 } )

## ------------------------------------------
## Generate random samples
## ------------------------------------------
N = 10   ## number of samples to generate
sampler_vfun_1 = flx.sampler(['vfun_1'])
print( sampler_vfun_1.get_NRV(), sampler_vfun_1.get_NOX() )
for i in range(N):
    sampler_vfun_1.sample()
    print( rv_set_vfun_1.get_values('x'), rv_set_noise4vfun.get_values('x') )
5 10
[0.80680695 1.90811171 2.88437008 0.66092016 0.60823602] [0.80680695 1.90811171 2.88437008 0.66092016 0.60823602]
[2.76143099 0.80737807 2.07867537 0.60883661 0.17017015] [2.76143099 0.80737807 2.07867537 0.60883661 0.17017015]
[1.26459702 1.37848193 0.52242359 1.39906091 0.64652622] [1.26459702 1.37848193 0.52242359 1.39906091 0.64652622]
[0.94187488 1.09781118 0.37250298 1.6076883  2.10130907] [0.94187488 1.09781118 0.37250298 1.6076883  2.10130907]
[0.9753055  0.63748154 3.00582175 1.0233048  2.72289369] [0.9753055  0.63748154 3.00582175 1.0233048  2.72289369]
[7.60044325 1.48629773 0.19427328 1.04261838 0.58098772] [7.60044325 1.48629773 0.19427328 1.04261838 0.58098772]
[0.67710028 2.05300156 1.09701321 3.92782954 2.02628235] [0.67710028 2.05300156 1.09701321 3.92782954 2.02628235]
[2.73162635 0.33751456 3.6072194  1.35839125 2.57396472] [2.73162635 0.33751456 3.6072194  1.35839125 2.57396472]
[1.44953272 0.23247917 3.26981667 1.59504694 0.75735399] [1.44953272 0.23247917 3.26981667 1.59504694 0.75735399]
[0.57819889 2.9934786  1.00972585 0.27187919 0.52136912] [0.57819889 2.9934786  1.00972585 0.27187919 0.52136912]
## ------------------------------------------
## Definition V2
## ------------------------------------------
rv_set_vfun_2 = flx.rv_set_vfun( { 'name':'vfun_2',
                                   'N': 5,
                                   'vecfun': """
                                      my_vec={
                                         rbrv_vec_get y: my_vec = "rv_set_noise4vfun";
                                         mtxconst_op my_vec(x) = exp(x);
                                      }
                                      """,
                                   'parents': [ 'rv_set_noise4vfun' ]
                                 } )

## ------------------------------------------
## Generate random samples
## ------------------------------------------
sampler_vfun_2 = flx.sampler(['vfun_2'])
for i in range(N):
    sampler_vfun_2.sample()
    print( rv_set_vfun_2.get_values('x'), rv_set_noise4vfun.get_values('x') )
[0.77606065 0.79828022 0.35746791 1.21423489 1.63729848] [0.77606065 0.79828022 0.35746791 1.21423489 1.63729848]
[0.11521389 0.45209466 6.78184628 1.23625227 1.75883763] [0.11521389 0.45209466 6.78184628 1.23625227 1.75883763]
[1.12635737 0.46699769 1.45703285 1.71103467 1.17578159] [1.12635737 0.46699769 1.45703285 1.71103467 1.17578159]
[0.51513982 0.65349515 2.51399593 0.48538244 3.05785361] [0.51513982 0.65349515 2.51399593 0.48538244 3.05785361]
[0.91366949 0.24201405 0.54166397 1.93369476 1.63094102] [0.91366949 0.24201405 0.54166397 1.93369476 1.63094102]
[2.07579308 1.11393933 0.89404093 0.08304713 0.33339091] [2.07579308 1.11393933 0.89404093 0.08304713 0.33339091]
[0.44864623 4.86573653 0.43634247 0.48615725 3.34192758] [0.44864623 4.86573653 0.43634247 0.48615725 3.34192758]
[1.06828115 4.41201742 2.87864068 0.37089891 1.56319634] [1.06828115 4.41201742 2.87864068 0.37089891 1.56319634]
[0.46098682 0.63137686 0.18124163 0.83837075 0.12065136] [0.46098682 0.63137686 0.18124163 0.83837075 0.12065136]
[0.46331677 0.24171149 0.25541245 0.82755231 0.88165531] [0.46331677 0.24171149 0.25541245 0.82755231 0.88165531]
import time
## ------------------------------------------
## measure performance
## ------------------------------------------
N = int(1e6)

start_time_1 = time.perf_counter()
for i in range(N):
    sampler_vfun_1.sample()
end_time_1 = time.perf_counter()
print(f"Runtime [1]: {end_time_1 - start_time_1:.6f} seconds")

start_time_2 = time.perf_counter()
for i in range(N):
    sampler_vfun_2.sample()
end_time_2 = time.perf_counter()
print(f"Runtime [2]: {end_time_2 - start_time_2:.6f} seconds")
Runtime [1]: 2.262341 seconds
Runtime [2]: 0.703763 seconds

Dirichlet distribution#

flx.rv_set_dirichlet()#
Syntax:

flx.rv_set_dirichlet( config_set )

Description:

Creates a vector that is the outcome of a Dirichlet distributed random variable.

Parameters:

config_set (dict) –

The following keys are allowed in config_set:

  • name (rvSetID): The name of the set of random variables to create.

  • N (int): The dimension of the hyper-sphere (equals the number of random variables in the set). Must be a positive integer.

  • alpha (numpy.ndarray): The parameter vector of the Dirichlet distribution. Must be of size N.

  • parents (list, default: []): A list (of already defined sets or random variables) on which the set to be defined is to be conditioned on. The list entries must be of type rvSetID. Used this key if the parameters of random variables in the current set depend on the values of random variables in another set.

Return type:

flx.rvset

Example:

## ================================================================
## Dirichlet distribution
## ================================================================

## ------------------------------------------
## Definition
## ------------------------------------------
rv_set_dirichlet = flx.rv_set_dirichlet( { 'name':'dirichlet',
                                   'alpha': [ 2., 4., 5. ]
                                 } )
## ------------------------------------------
## Generate samples
## ------------------------------------------
N = 10   ## number of samples to generate
sampler_dirichlet = flx.sampler(['dirichlet'])  
for i in range(N):
    sampler_dirichlet.sample()
    smpl_vec = rv_set_dirichlet.get_values()
    print( smpl_vec, sum(smpl_vec) )
[0.07853818 0.3016221  0.61983972] 1.0
[0.28839795 0.34388114 0.36772091] 1.0
[0.20521146 0.31405264 0.4807359 ] 1.0
[0.22227911 0.48574932 0.29197157] 1.0
[0.10140458 0.57040493 0.32819049] 1.0
[0.38921048 0.13656138 0.47422813] 1.0
[0.0809515  0.38200904 0.53703946] 1.0
[0.13385796 0.33736229 0.52877975] 1.0
[0.34400542 0.30028152 0.35571306] 1.0
[0.24467794 0.5306214  0.22470066] 1.0

Multinomial distribution#

flx.rv_set_multinomial()#
Syntax:

flx.rv_set_multinomial( config_set )

Description:

Creates a vector that is the outcome of a multinomially distributed random variable.

Parameters:

config_set (dict) –

The following keys are allowed in config_set:

  • name (rvSetID): The name of the set of random variables to create.

  • N (int): The dimension of the vector returned by the vector function. Must be a positive integer.

  • pvec (flxVecPara): The vector function to evaluate. Must evaluate to an array of size N.

  • Ntrial (int): The number of trials. Must be a positive integer.

  • parents (list, default: []): A list (of already defined sets or random variables) on which the set to be defined is to be conditioned on. The list entries must be of type rvSetID. Used this key if the parameters of random variables in the current set depend on the values of random variables in another set.

Return type:

flx.rvset

Example:

## ================================================================
## Multinomial distribution
## ================================================================

## ------------------------------------------
## Definition (without parents)
## ------------------------------------------
rv_set_multinomial_1 = flx.rv_set_multinomial( { 'name':'multinomial_1',
                                   'pvec': [ 0.3, 0.2, 0.5 ],
                                   'N': 3,
                                   'Ntrial': 100
                                 } )
## ------------------------------------------
## Generate samples
## ------------------------------------------
N = 10   ## number of samples to generate
sampler_multinomial_1 = flx.sampler(['multinomial_1'])  
for i in range(N):
    sampler_multinomial_1.sample()
    smpl_vec = rv_set_multinomial_1.get_values()
    print( smpl_vec, sum(smpl_vec) )
[27. 19. 54.] 100.0
[27. 21. 52.] 100.0
[36. 17. 47.] 100.0
[25. 26. 49.] 100.0
[31. 17. 52.] 100.0
[31. 16. 53.] 100.0
[30. 17. 53.] 100.0
[24. 23. 53.] 100.0
[28. 18. 54.] 100.0
[36. 21. 43.] 100.0
## ------------------------------------------
## Definition (with a parent)
## ------------------------------------------
def multinomial_2_map():
    return rv_set_dirichlet.get_values('x')
rv_set_multinomial_2 = flx.rv_set_multinomial( { 'name':'multinomial_2',
                                   'pvec': multinomial_2_map,
                                   'N': 3,
                                   'Ntrial': 100,
                                   'parents': [ 'dirichlet' ]
                                 } )
## ------------------------------------------
## Generate samples
## ------------------------------------------
N = 10   ## number of samples to generate
sampler_multinomial_2 = flx.sampler(['multinomial_2'])  
for i in range(N):
    sampler_multinomial_2.sample()
    smpl_vec = rv_set_multinomial_2.get_values()
    pr_vec = rv_set_dirichlet.get_values()
    print( smpl_vec, sum(smpl_vec), pr_vec )
[ 0. 67. 33.] 100.0 [0.01267759 0.49423551 0.4930869 ]
[23. 39. 38.] 100.0 [0.26882147 0.37470878 0.35646975]
[22. 45. 33.] 100.0 [0.32039555 0.42701282 0.25259162]
[18. 18. 64.] 100.0 [0.21950619 0.1711493  0.60934451]
[15. 10. 75.] 100.0 [0.1399798  0.12033737 0.73968283]
[11. 29. 60.] 100.0 [0.1222032  0.24743508 0.63036172]
[20. 31. 49.] 100.0 [0.18987329 0.32565397 0.48447274]
[22. 54. 24.] 100.0 [0.2007815  0.56840519 0.23081332]
[16. 30. 54.] 100.0 [0.1735748  0.23266715 0.59375805]
[34. 43. 23.] 100.0 [0.31331057 0.433798   0.25289143]
## ------------------------------------------
## Definition (with a parent)
## ------------------------------------------
rv_set_multinomial_3 = flx.rv_set_multinomial( { 'name':'multinomial_3',
                                   'pvec': """
                                       my_vec={
                                         rbrv_vec_get x: my_vec = "dirichlet";
                                       }
                                       """,
                                   'N': 3,
                                   'Ntrial': 100,
                                   'parents': [ 'dirichlet' ]
                                 } )
## ------------------------------------------
## Generate samples
## ------------------------------------------
N = 10   ## number of samples to generate
sampler_multinomial_3 = flx.sampler(['multinomial_3'])  
for i in range(N):
    sampler_multinomial_3.sample()
    smpl_vec = rv_set_multinomial_3.get_values()
    pr_vec = rv_set_dirichlet.get_values()
    print( smpl_vec, sum(smpl_vec), pr_vec )
[35. 35. 30.] 100.0 [0.3607523  0.36091843 0.27832927]
[15. 48. 37.] 100.0 [0.1818313  0.46863318 0.34953552]
[22. 32. 46.] 100.0 [0.22447953 0.28416473 0.49135574]
[14. 19. 67.] 100.0 [0.27998543 0.18053711 0.53947746]
[ 5. 26. 69.] 100.0 [0.07775234 0.26636441 0.65588325]
[29. 30. 41.] 100.0 [0.2278381  0.28206536 0.49009654]
[26. 31. 43.] 100.0 [0.17340696 0.29238131 0.53421173]
[35. 47. 18.] 100.0 [0.40996938 0.39485445 0.19517617]
[32.  7. 61.] 100.0 [0.22782875 0.07538667 0.69678458]
[15. 48. 37.] 100.0 [0.19945893 0.49458794 0.30595313]
## ------------------------------------------
## measure performance
## ------------------------------------------
N = int(1e5)

start_time_1 = time.perf_counter()
for i in range(N):
    sampler_multinomial_1.sample()
end_time_1 = time.perf_counter()
print(f"Runtime [1]: {end_time_1 - start_time_1:.6f} seconds")

start_time_2 = time.perf_counter()
for i in range(N):
    sampler_multinomial_2.sample()
end_time_2 = time.perf_counter()
print(f"Runtime [2]: {end_time_2 - start_time_2:.6f} seconds")

start_time_3 = time.perf_counter()
for i in range(N):
    sampler_multinomial_3.sample()
end_time_3 = time.perf_counter()
print(f"Runtime [3]: {end_time_3 - start_time_3:.6f} seconds")
Runtime [1]: 1.035534 seconds
Runtime [2]: 1.628568 seconds
Runtime [3]: 1.514796 seconds