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.