Using RandomParameters

To generate random samples of parameters, one can use the RandomParameters class as demonstrated in this example.

[1]:
import pymecht as pmt
from matplotlib import pyplot as plt
import numpy as np

mat = pmt.MatModel('nh')
sample = pmt.UniaxialExtension(mat)
sample_params = sample.parameters
print(sample_params)
------------------------------------------------------------------
Keys              Value       Fixed?      Lower bound Upper bound
------------------------------------------------------------------
L0                1.00        No          1.00e-04    1.00e+03
A0                1.00        No          1.00e-04    1.00e+03
mu_0              1.00        No          1.00e-04    1.00e+02
------------------------------------------------------------------

Once we have the parameters, we can use it to create a RandomParameter instance as follows

[2]:
Theta = pmt.RandomParameters(sample_params)
print(Theta)
Keys              Type              Lower/mean        Upper/std
------------------------------------------------------------------------
L0                uniform           1.00e-04          1.00e+03
A0                uniform           1.00e-04          1.00e+03
mu_0              uniform           1.00e-04          1.00e+02
------------------------------------------------------------------------

By default, each parameter will have a uniform probability density function (PDF) between the lower and upper bounds. From the random parameter Theta, we can create a required number of samples.

[3]:
Theta.sample?
Signature: Theta.sample(N=1, sample_type=None)
Docstring:
Returns a list of N samples of the parameters

Parameters
----------
N: int
    Number of samples to be generated

sample_type: str
    Type of sampling to be performed.
    Options are

        * None (default)
        * 'lhcube' for Latin-Hypercube sampling
        * 'sobol' for Sobol sequence sampling

    If None, random sampling is performed.

Returns
-------
list
    A list of N dictionaries with random values of the parameters
File:      /usr/local/lib/python3.9/site-packages/pymecht/RandomParameters.py
Type:      method

There are a few options available for sampling the random parameters: default, Latin hypercube, and Sobol. The latter two only work for uniformly distributed parameters. The sample method returns a list of (normal) dictionaries, that we can use to run simulations.

[4]:
theta_samples1 = Theta.sample(10)
theta_samples2 = Theta.sample(10,'lhcube')
theta_samples3 = Theta.sample(10,'sobol')
print(type(theta_samples1))
print(theta_samples2)
<class 'list'>
[{'L0': 891.507336479485, 'A0': 335.299648762739, 'mu_0': 95.4678573610962}, {'L0': 341.0010091911493, 'A0': 439.0918199716474, 'mu_0': 79.67639341557204}, {'L0': 137.405730071511, 'A0': 83.37527510409612, 'mu_0': 60.82007599086426}, {'L0': 929.2802499555028, 'A0': 238.28812347567, 'mu_0': 7.499850667149027}, {'L0': 718.0661804372189, 'A0': 608.0690988826448, 'mu_0': 20.728033597900517}, {'L0': 72.9417514464427, 'A0': 573.7396959544901, 'mu_0': 19.835028404995008}, {'L0': 568.2921881249891, 'A0': 167.03698843301927, 'mu_0': 31.550781679043173}, {'L0': 405.91357475801743, 'A0': 735.1233178703956, 'mu_0': 42.07752038879198}, {'L0': 243.7715469093828, 'A0': 815.2039715505399, 'mu_0': 53.67664849319548}, {'L0': 699.8607748041638, 'A0': 921.7720680553437, 'mu_0': 85.55720663091368}]
[5]:
for theta_i in theta_samples3:
    result = sample.disp_controlled([1.1],theta_i)
    print(theta_i, result)
{'L0': 337.6500076794028, 'A0': 348.5217149853289, 'mu_0': 47.428845286279916} [4521.838187728782]
{'L0': 879.7981263199628, 'A0': 879.9794436312377, 'mu_0': 91.39257934145331} [22000.17244712658]
{'L0': 632.7859530498386, 'A0': 168.79554954348802, 'mu_0': 19.473174274998904} [899.167012956701]
{'L0': 88.68471705517099, 'A0': 575.3297038363576, 'mu_0': 62.99445157353282} [9914.292317621073]
{'L0': 200.1005018954754, 'A0': 112.81597545432747, 'mu_0': 85.67158820576071} [2643.930558019085]
{'L0': 517.3883324675619, 'A0': 643.0570840150655, 'mu_0': 29.608790932279824} [5208.501861932982]
{'L0': 768.4285872287988, 'A0': 433.3359569731116, 'mu_0': 57.76784470908046} [6847.838589365981]
{'L0': 453.0938814613998, 'A0': 838.1649417587638, 'mu_0': 1.3662562773393467} [313.25952516027945]
{'L0': 398.56916719875335, 'A0': 202.77536437041314, 'mu_0': 51.08966354013086} [2833.9413399263003]
{'L0': 817.4261633341372, 'A0': 545.287594966942, 'mu_0': 7.165533751574158} [1068.8500631922789]

Normal and log-normal distributed parameters

The PDF of individual parameters can be changed to normal or log-normal, as follows:

[6]:
Theta.make_normal('L0')
print(Theta)
Keys              Type              Lower/mean        Upper/std
------------------------------------------------------------------------
L0                normal            5.00e+02          2.50e+02
A0                uniform           1.00e-04          1.00e+03
mu_0              uniform           1.00e-04          1.00e+02
------------------------------------------------------------------------

[7]:
Theta.make_lognormal('A0')
print(Theta)
Keys              Type              Lower/mean        Upper/std
------------------------------------------------------------------------
L0                normal            5.00e+02          2.50e+02
A0                lognormal         0.32              56.23
mu_0              uniform           1.00e-04          1.00e+02
------------------------------------------------------------------------

Note that when making a variable normal, by default, its mean is choosen to be as the mean of lower/upper bounds, and the standard deviation to be the 1/4th of the range (range being the upper-lower bound). Similarly, for log-normal, the same is done on the logarithm of the bounds.

Note that when the RandomParameter instance contains any normal or log-normal variable, only the default sampling is available.

[8]:
theta_samples1 = Theta.sample(10)
try:
    theta_samples2 = Theta.sample(10,'lhcube')
except ValueError as e:
    print("Error raised", e)

try:
    theta_samples3 = Theta.sample(10,'sobol')
except ValueError as e:
    print("Error raised", e)
Error raised For Latin Hypercube sampling, only uniform distributions are currently implemented
Error raised For Sobol sequence sampling, only uniform distributions are currently implemented

Fixing parameters

We can also fix certain parameters either before or after creating the RandomParameter instance.

[9]:
#fixing before
sample_params.fix('A0')
print(pmt.RandomParameters(sample_params))

#fixing after
Theta.fix('A0')
print(Theta)
Keys              Type              Lower/mean        Upper/std
------------------------------------------------------------------------
L0                uniform           1.00e-04          1.00e+03
A0                fixed             1.00              1.00
mu_0              uniform           1.00e-04          1.00e+02
------------------------------------------------------------------------

Keys              Type              Lower/mean        Upper/std
------------------------------------------------------------------------
L0                normal            5.00e+02          2.50e+02
A0                fixed             1.00              1.00
mu_0              uniform           1.00e-04          1.00e+02
------------------------------------------------------------------------

Evaluating PDF

Given a sample, one can also evaulate the PDF at that.

[10]:
theta_samples = Theta.sample()
Theta.prob(theta_samples[0])
[10]:
4.158572574771021e-06

Add parameter

If we want to add another parameter, we can do it either before or after creating the RandomParameter instance.

[11]:
#Adding before creating the RandomParameter instance
sample_params['phi'] = pmt.Param(10,0,90)
print(pmt.RandomParameters(sample_params))

#First create a RandomParameter instance
Theta = pmt.RandomParameters(sample.parameters)
print('Before adding:\n', Theta)
#then add a variable to it, with a current value of 10, lower limit of 0, upper limit of 90, and a uniform distribution
Theta.add('phi',10,0,90,'uniform')
print('After adding:\n', Theta)
Keys              Type              Lower/mean        Upper/std
------------------------------------------------------------------------
L0                uniform           1.00e-04          1.00e+03
A0                fixed             1.00              1.00
mu_0              uniform           1.00e-04          1.00e+02
phi               uniform           0.00              90.00
------------------------------------------------------------------------

Before adding:
 Keys              Type              Lower/mean        Upper/std
------------------------------------------------------------------------
L0                uniform           1.00e-04          1.00e+03
A0                fixed             1.00              1.00
mu_0              uniform           1.00e-04          1.00e+02
------------------------------------------------------------------------

After adding:
 Keys              Type              Lower/mean        Upper/std
------------------------------------------------------------------------
L0                uniform           1.00e-04          1.00e+03
A0                fixed             1.00              1.00
mu_0              uniform           1.00e-04          1.00e+02
phi               uniform           0.00              90.00
------------------------------------------------------------------------

Note that the current capability is limited to non-correlated parameters only.