Parameter Distributions
While instantiating a Model
object, we define the distribution functions used to sample blob parameters from.
So far we have only used the default distributions but in this section we cover how change these.
DefaultBlobFactory
We can use DefaultBlobFactory
class in order to change the distribution functions of the following blob parameters:
Amplitudes
widths in x
widths in y
velocities in x
velocities in y
The distributions for these parameters are set with the *_dist
arguments. The following distribution functions are implemented:
“exp” |
exponential distribution with mean 1 |
“gamma” |
gamma distribution with |
“normal” |
normal distribution with zero mean and |
“uniform” |
uniform distribution with mean 1 and |
“ray” |
Rayleight distribution with mean 1 |
“deg” |
degenerate distribution at |
“zeros” |
array of zeros |
As you can see, some of these distributions require an additional free_parameter
to specify the distribution.
This is done by the *_parameter
arguments.
Let’s take a look at an example. Let’s assume we want to sample the blob amplitudes from normal distribution with 5 as the scale parameter. We chose the defualt distributions for all other blob parameters. We would set up the Model as follows:
from blobmodel import Model, DefaultBlobFactory
my_blob_factory = DefaultBlobFactory(A_dist="normal", A_parameter=5)
bm = Model(
Nx=200,
Ny=100,
Lx=10,
Ly=10,
dt=0.1,
T=20,
blob_shape="gauss",
blob_factory=my_blob_factory,
t_drain=100,
num_blobs=100,
)
ds = bm.make_realization()
CustomBlobFactory
But what if you want to use a distribution function that is not implemented? Or maybe you even want to change the initial position and arrival time of each blob?
In this case you can use the CustomBlobFactory
class to define all blob parameters individually. An example could look like this:
from blobmodel import (
Model,
BlobFactory,
Blob,
AbstractBlobShape,
)
import numpy as np
# create custom class that inherits from BlobFactory
# here you can define your custom parameter distributions
class CustomBlobFactory(BlobFactory):
def __init__(self) -> None:
pass
def sample_blobs(
self,
Ly: float,
T: float,
num_blobs: int,
blob_shape: AbstractBlobShape,
t_drain: float,
) -> list[Blob]:
# set custom parameter distributions
amp = np.linspace(0.01, 1, num=num_blobs)
width = np.linspace(0.01, 1, num=num_blobs)
vx = np.linspace(0.01, 1, num=num_blobs)
vy = np.linspace(0.01, 1, num=num_blobs)
posx = np.zeros(num_blobs)
posy = np.random.uniform(low=0.0, high=Ly, size=num_blobs)
t_init = np.random.uniform(low=0, high=T, size=num_blobs)
# sort blobs by _t_init
t_init = np.sort(t_init)
return [
Blob(
blob_id=i,
blob_shape=blob_shape,
amplitude=amp[i],
width_prop=width[i],
width_perp=width[i],
v_x=vx[i],
v_y=vy[i],
pos_x=posx[i],
pos_y=posy[i],
t_init=t_init[i],
t_drain=t_drain,
)
for i in range(num_blobs)
]
def is_one_dimensional(self) -> bool:
return False
bf = CustomBlobFactory()
tmp = Model(
Nx=100,
Ny=100,
Lx=2,
Ly=2,
dt=0.1,
T=10,
blob_shape="gauss",
t_drain=2,
periodic_y=True,
num_blobs=1000,
blob_factory=bf,
)
ds = tmp.make_realization()
By assigning an array like to the variables amp
, width
, vx
, vy
, posx
, posy
and t_init
we can exactly define every single blob parameter of every single blob.
Note
When using CustomBlobFactory
it is your responsibility to make sure all blob variables have the correct dimensions. Also, if you wish to normalize the parameters you have to do this manually.