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(typervSetID): 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 typervSetID. 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 toTrue, 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 setrv_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): IfTrue, 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 toFalse.
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 setvalue(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:
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:
- 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:
- set_y_vec(y_vec)#
Assign
y_vecas 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_vecas 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_vecin 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.
- type rvFullID#
- FlxFunction.rbrv()#
- Syntax:
rbrv( rv_name )- Description:
This
FlxFunctionreturns 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()orFlxFunction.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:
- get_NOX()#
Returns the total number of random variables (in original space) in the collection.
- Return type:
int
- assign_u(u_vec)#
Assign
u_vecas 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_vecas values of the random variables in the sampler.- Parameters:
x_vec (numpy.ndarray) – Vector to assign.
transform (bool) –
True: Assignx_vecand perform the transformation from original space to standard Normal space.False: just assignx_vecwithout 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 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 typervSetID. 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:
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 typervSetID. 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 aFlxFunctionthat depends on the special variablesgx(cooridnate of first point),gx2(coordinate of second point), and/ordeltax(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 equals0, the Cholesky-decomposition is applied and the set will contain N random variables. IfM > 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., forM > 0. Forevtype=1, the matrix eigenvalue problem is solved by meansof Lanczos-methods. Forevtype=2, the full matrix eigenvalue problem is solved.only_once(bool, default: True): If True, the correlation matrix is assembled based onRHOonly 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 functionRHOis 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:
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()
## ================================================================
## 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()
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 typervSetID. 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 aFlxFunctionthat depends on the special variablesgx(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:
- 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_setthat requires the underlying process to be defined usingflx.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:
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()
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 typervSetID. 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:
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()
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 typervSetID. 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:
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 typervSetID. 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:
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 typervSetID. 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:
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