1- """An example implementation of a Gaussian noise model ."""
1+ """Example implementations of Gaussian noise models ."""
22
33from functools import partial
44
55import numpy as np
66import scipy .stats as ss
77
88import elfi
9+ from elfi .examples .gnk import euclidean_multidim
910
1011
11- def Gauss (mu , sigma , n_obs = 50 , batch_size = 1 , random_state = None ):
12- """Sample the Gaussian distribution.
12+ def gauss (mu , sigma , n_obs = 50 , batch_size = 1 , random_state = None ):
13+ """Sample the 1-D Gaussian distribution.
1314
1415 Parameters
1516 ----------
1617 mu : float, array_like
1718 sigma : float, array_like
1819 n_obs : int, optional
1920 batch_size : int, optional
20- random_state : RandomState, optional
21+ random_state : np.random.RandomState, optional
22+
23+ Returns
24+ -------
25+ y_obs : array_like
26+ 1-D observation.
2127
2228 """
23- # Standardising the parameter's format.
24- mu = np .asanyarray (mu ).reshape ((- 1 , 1 ))
25- sigma = np .asanyarray (sigma ).reshape ((- 1 , 1 ))
26- y = ss .norm .rvs (loc = mu , scale = sigma , size = (batch_size , n_obs ), random_state = random_state )
27- return y
29+ # Handling batching.
30+ batches_mu = np .asanyarray (mu ).reshape ((- 1 , 1 ))
31+ batches_sigma = np .asanyarray (sigma ).reshape ((- 1 , 1 ))
32+
33+ # Sampling observations.
34+ y_obs = ss .norm .rvs (loc = batches_mu , scale = batches_sigma ,
35+ size = (batch_size , n_obs ), random_state = random_state )
36+ return y_obs
37+
38+
39+ def gauss_nd_mean (* mu , cov_matrix , n_obs = 15 , batch_size = 1 , random_state = None ):
40+ """Sample an n-D Gaussian distribution.
41+
42+ Parameters
43+ ----------
44+ *mu : array_like
45+ Mean parameters.
46+ cov_matrix : array_like
47+ Covariance matrix.
48+ n_obs : int, optional
49+ batch_size : int, optional
50+ random_state : np.random.RandomState, optional
51+
52+ Returns
53+ -------
54+ y_obs : array_like
55+ n-D observation.
56+
57+ """
58+ n_dim = len (mu )
59+
60+ # Handling batching.
61+ batches_mu = np .zeros (shape = (batch_size , n_dim ))
62+ for idx_dim , param_mu in enumerate (mu ):
63+ batches_mu [:, idx_dim ] = param_mu
64+ batches_cov = np .zeros (shape = (batch_size , n_dim , n_dim ))
65+ for idx_batch in range (batch_size ):
66+ batches_cov [idx_batch , :, :] = cov_matrix
67+
68+ # Sampling the observations.
69+ y_obs = np .zeros (shape = (batch_size , n_obs , n_dim ))
70+ for idx_batch in range (batch_size ):
71+ y_batch = ss .multivariate_normal .rvs (mean = batches_mu [idx_batch ],
72+ cov = batches_cov [idx_batch ],
73+ size = n_obs ,
74+ random_state = random_state )
75+ if n_dim == 1 :
76+ y_batch = y_batch [:, np .newaxis ]
77+ y_obs [idx_batch , :, :] = y_batch
78+ return y_obs
2879
2980
3081def ss_mean (x ):
@@ -39,36 +90,65 @@ def ss_var(x):
3990 return ss
4091
4192
42- def get_model (n_obs = 50 , true_params = None , seed_obs = None ):
43- """Return a complete Gaussian noise model.
93+ def get_model (n_obs = 50 , true_params = None , seed_obs = None , nd_mean = False , cov_matrix = None ):
94+ """Return a Gaussian noise model.
4495
4596 Parameters
4697 ----------
4798 n_obs : int, optional
48- the number of observations
4999 true_params : list, optional
50- true_params[0] corresponds to the mean,
51- true_params[1] corresponds to the standard deviation
100+ Default parameter settings.
52101 seed_obs : int, optional
53- seed for the observed data generation
102+ Seed for the observed data generation.
103+ nd_mean : bool, optional
104+ Option to use an n-D mean Gaussian noise model.
105+ cov_matrix : None, optional
106+ Covariance matrix, a requirement for the nd_mean model.
54107
55108 Returns
56109 -------
57110 m : elfi.ElfiModel
58111
59112 """
113+ # Defining the default settings.
60114 if true_params is None :
61- true_params = [10 , 2 ]
115+ if nd_mean :
116+ true_params = [4 , 4 ] # 2-D mean.
117+ else :
118+ true_params = [4 , .4 ] # mean and standard deviation.
119+
120+ # Choosing the simulator for both observations and simulations.
121+ if nd_mean :
122+ sim_fn = partial (gauss_nd_mean , cov_matrix = cov_matrix , n_obs = n_obs )
123+ else :
124+ sim_fn = partial (gauss , n_obs = n_obs )
62125
63- y_obs = Gauss ( * true_params , n_obs = n_obs , random_state = np . random . RandomState ( seed_obs ))
64- sim_fn = partial ( Gauss , n_obs = n_obs )
126+ # Obtaining the observations.
127+ y_obs = sim_fn ( * true_params , n_obs = n_obs , random_state = np . random . RandomState ( seed_obs ) )
65128
66129 m = elfi .ElfiModel ()
67- elfi .Prior ('uniform' , - 10 , 50 , model = m , name = 'mu' )
68- elfi .Prior ('truncnorm' , 0.01 , 5 , model = m , name = 'sigma' )
69- elfi .Simulator (sim_fn , m ['mu' ], m ['sigma' ], observed = y_obs , name = 'Gauss' )
70- elfi .Summary (ss_mean , m ['Gauss' ], name = 'S1' )
71- elfi .Summary (ss_var , m ['Gauss' ], name = 'S2' )
72- elfi .Distance ('euclidean' , m ['S1' ], m ['S2' ], name = 'd' )
130+ # Initialising the priors.
131+ priors = []
132+ if nd_mean :
133+ n_dim = len (true_params )
134+ for i in range (n_dim ):
135+ name_prior = 'mu_{}' .format (i )
136+ prior_mu = elfi .Prior ('uniform' , 0 , 8 , model = m , name = name_prior )
137+ priors .append (prior_mu )
138+ else :
139+ priors .append (elfi .Prior ('uniform' , 0 , 8 , model = m , name = 'mu' ))
140+ priors .append (elfi .Prior ('truncnorm' , 0.01 , 5 , model = m , name = 'sigma' ))
141+ elfi .Simulator (sim_fn , * priors , observed = y_obs , name = 'gauss' )
142+
143+ # Initialising the summary statistics.
144+ sumstats = []
145+ sumstats .append (elfi .Summary (ss_mean , m ['gauss' ], name = 'ss_mean' ))
146+ sumstats .append (elfi .Summary (ss_var , m ['gauss' ], name = 'ss_var' ))
147+
148+ # Choosing the discrepancy metric.
149+ if nd_mean :
150+ elfi .Discrepancy (euclidean_multidim , * sumstats , name = 'd' )
151+ else :
152+ elfi .Distance ('euclidean' , * sumstats , name = 'd' )
73153
74154 return m
0 commit comments