def test_get_random_value(self): """ Tests if one can get the a random value from the random variable. """ a = 2 b = 100 X = Gamma(a, b) assert all(np.array(X.rvs(100)) > 0)
def test_iterator (self): """ Tests if we can iterate through parameters. """ p1 = RandomParameter ('p1', Gamma (2, 2)) p2 = RandomParameter ('p2', Gamma (2, 2)) theta = RandomParameterList () theta.append (p1) theta.append (p2) for p in theta: assert (p.name == "p1" or p.name == "p2")
def test_get_pdf(self): """ Tests if we can get a point of the probability density function of this random variable. """ a = 2 b = 1 X = Gamma(a, b) x = 1 analytic = np.exp(-1) assert (abs(X.pdf(x) - analytic) / analytic < 1e-2)
def test_convergence_to_mean(self): """ Tests if random values has mean as Gamma should have. WARNING: this test can fail with some small probability. """ a = 2 b = 3 X = Gamma(a, b) N = 3000 sample = [X.rvs() for _ in range(N)] mean = statistics.mean(sample) assert (abs(mean - 6) / 6 < 5e-2)
def test_idexing (self): """ Tests if one can access a parameter with an index. """ p1 = RandomParameter ('p1', Gamma (2, 2)) p2 = RandomParameter ('p2', Gamma (3, 2)) p1.value = 1 p2.value = 2 theta = RandomParameterList () theta.append (p1) theta.append (p2) self.assertEqual (theta[0].name, 'p1') self.assertEqual (theta[1].name, 'p2')
def test_get_values (self): """ Tests if we can get only the values of the parameters. """ p1 = RandomParameter ('p1', Gamma (2, 2)) p2 = RandomParameter ('p2', Gamma (3, 2)) p1.value = 1 p2.value = 2 theta = RandomParameterList () theta.append (p1) theta.append (p2) values = theta.get_values () self.assertEqual (values[0], 1) self.assertEqual (values[1], 2)
def test_get_copy (self): """ Tests if an object can produce a copy of itself. """ p1 = RandomParameter ('p1', Gamma (2, 2)) p2 = RandomParameter ('p2', Gamma (2, 2)) theta = RandomParameterList () theta.append (p1) theta.append (p2) copy = theta.get_copy () self.assertEqual (copy.get_size (), 2) for p in copy: assert (p.name == "p1" or p.name == "p2") p1.name = "new_name" for p in copy: assert (p.name != "new_name")
def test_get_experimental_error (self): """ Tests if we can have an experimental error on the list of random parameters. """ p1 = RandomParameter ('p1', Gamma (2, 2)) p2 = RandomParameter ('p2', Gamma (3, 2)) p1.value = 1 p2.value = 2 sigma = RandomParameter ('sigma', Gamma (2, .1)) sigma.value = 123 theta = RandomParameterList () theta.append (p1) theta.set_experimental_error (sigma) theta.append (p2) self.assertEqual (theta.get_experimental_error (), 123)
def test_jumps_centered_on_current_theta(self): """ Tests if, when using suitable jump distribution, the proposed values are centered on the current theta. """ n = 10 N = 1000 theta_values = np.ones(n) / 3.2 theta = RandomParameterList() for p_val in theta_values: gamma = Gamma(2, 1) rand_par = RandomParameter('p', gamma) rand_par.value = p_val theta.append(rand_par) class JumpMock(AcceptingRateAMCMC): def __init__(self, theta): n = theta.get_size() self._jump_S = [0.001 for x in range(n)] mocked_mh = JumpMock(theta) mean_jump = np.zeros(n) for i in range(N): jump = mocked_mh.propose_jump(theta) mean_jump += jump.get_values() mean_jump /= N assert all(abs(mean_jump - theta_values) < 1e-1)
def test_append (self): """ Tests if one can append a parameter to the list. """ p = RandomParameter ('', Gamma (2, 2)) theta = RandomParameterList () theta.append (p) theta.append (p) theta.append (p) self.assertEqual (theta.get_size (), 3)
def test_get_param_log_p (self): """ Tests if the log p is what we expect when analytically calculating it. """ param = RandomParameter ("", Gamma (2, 1)) param.value = 5 log_p = param.get_log_p () analytic = np.log (param.value) - param.value assert (abs (log_p - analytic) < 1e-8)
def create_starting_sample (self): my_artificial_sample = [] log_likelihoods = [] sample_mean = [0.05, 0.1, 0.2, .3] S = np.eye (4) / 5 mu = np.log (np.array (sample_mean)) - S.diagonal () / 2 my_sample_dist = MultivariateLognormal (mu, S) for i in range (50): theta = RandomParameterList () values = my_sample_dist.rvs () for v in values[:-1]: p = RandomParameter ('p', Gamma (2, 2)) p.value = v theta.append (p) exp_error = RandomParameter ('sigma', Gamma (2, 2)) theta.set_experimental_error (exp_error) log_likelihoods.append (1) my_artificial_sample.append (theta) return (my_artificial_sample, log_likelihoods)
def test_get_iterator (self): """ Tests if we can get an iterator of the object. """ p1 = RandomParameter ('p1', Gamma (2, 2)) p2 = RandomParameter ('p2', Gamma (3, 2)) sigma = RandomParameter ('sigma', Gamma (2, .1)) p1.value = 1 p2.value = 2 sigma.value = 123 theta = RandomParameterList () theta.append (p1) theta.append (p2) theta.set_experimental_error (sigma) my_iterator = iter (theta) it_1 = next (my_iterator) assert (it_1.name == 'p1') it_2 = next (my_iterator) assert (it_2.name == 'p2') it_3 = next (my_iterator) assert (it_3.name == 'sigma')
def setUp(self): # dx1 (t)/dt = x1 (t), x1 (0) = 1 # x1 (t) = e ^ t self.odes = ODES() self.odes.add_equation("x1", "x1") self.odes.define_initial_value("x1", 1.0) self.theta = RandomParameterList() sigma_dist = Gamma(1, 1) sigma = RandomParameter("sigma", sigma_dist) sigma.value = 1.0 self.theta.set_experimental_error(sigma)
def test_get_last_sampled (self): """ Tests if one can get the last N sampled parameters. """ n = 10 N = 20 theta = RandomParameterList () for i in range (n): gamma = Gamma (2, 2) rand_par = RandomParameter ('p', gamma) theta.append (rand_par) mocked_mh = MHFullMock (theta) mocked_mh.start_sample_from_prior () mocked_mh.get_sample (2 * N) sample = mocked_mh.get_last_sampled (N)[0] assert (len (sample) > N * .25)
def test_acceptance_ratio (self): """ Tests if the acceptance ratio converges to 0.5 when the mh ratio in a jump proposal is always 0.5. """ n = 10 N = 3000 theta = RandomParameterList () for i in range (n): gamma = Gamma (2, 2) rand_par = RandomParameter ('p', gamma) theta.append (rand_par) mocked_mh = MHFullMock (theta) mocked_mh.start_sample_from_prior () mocked_mh.get_sample (N) acceptance_ratio = mocked_mh.get_acceptance_ratio () assert (abs (acceptance_ratio - .5) < 1e-1)
def __create_distribution(dist_type, args): """ Creates a distribution dist_type with arguments args. You can choose any of those options for dist_type and args, respectively: - gamma, [k, theta] - lognormal, [mu, sigma] """ if dist_type.lower() == 'gamma': dist = Gamma(args[0], args[1]) elif dist_type.lower() == 'lognormal': dist = Lognormal(args[0], args[1]) elif dist_type.lower() == 'uniform': dist = Uniform(args[0], args[1]) else: raise ValueError("The specified prior distribution, " + dist_type + ", is not available.") return dist
def test_manual_jump (self): """ Tests if one can perform a manual jump. """ n = 10 theta = RandomParameterList () for i in range (n): gamma = Gamma (2, 2) rand_par = RandomParameter ('p', gamma) theta.append (rand_par) mocked_mh = MHLikelihoodMock (theta) mocked_mh.start_sample_from_prior () mocked_mh.manual_jump (theta, 1) sample = mocked_mh.get_last_sampled (2)[0] last_theta = sample[-1] theta_vals = np.array (theta.get_values ()) last_theta_vals = np.array (last_theta.get_values ()) assert all (theta_vals == last_theta_vals)
def test_jumps_centered_on_current_theta (self): """ Tests if, when using suitable jump distribution, the proposed values are centered on the current theta. """ n = 10 N = 1000 theta_values = np.ones (n) / 3.2 theta = RandomParameterList () for p_val in theta_values: gamma = Gamma (2, 1) rand_par = RandomParameter ('p', gamma) rand_par.value = p_val theta.append (rand_par) mocked_mh = MHJumpMock (theta) mean_jump = np.zeros (n) for i in range (N): jump = mocked_mh.propose_jump (theta) mean_jump += jump.get_values () mean_jump /= N assert all (abs (mean_jump - theta_values) < 1e-1)
def read_priors_file(filename): """ Reads a priors definition file. Parameters filename: the path of the priors file. Returns a RandomParameterList object, containing all defined parameters and its prior distributions and also some experimental error. """ tree = etree.parse(filename) root = tree.getroot() if clean_tag(root) != "priors": print("Wrong experiment data syntax. Root tag should be " + "<dataset>") return None priors = RandomParameterList() for children in root.getchildren(): attribs = children.attrib if clean_tag(children) == "prior": name = attribs["name"] a = float(attribs["a"]) b = float(attribs["b"]) dist_type = attribs["distribution"] dist = __create_distribution(dist_type, [a, b]) priors.append(RandomParameter(name, dist)) elif clean_tag(children) == "experimental_error": name = attribs["name"] a = float(attribs["a"]) b = float(attribs["b"]) gamma = Gamma(a, b) priors.set_experimental_error(RandomParameter(name, gamma)) else: print("Warning: unindentified prior definition on " + filename) return priors
def test_sample_start (self): """ Tests if the start sample is centered on the mean of the prior distribution. """ n = 10 N = 1000 theta = RandomParameterList () for i in range (n): gamma = Gamma (2, 0.15) rand_par = RandomParameter ('p', gamma) theta.append (rand_par) start_mean = np.zeros (n) analytical_mean = np.ones (n) * 0.3 for i in range (N): mocked_mh = MHLikelihoodMock (theta) mocked_mh.start_sample_from_prior () sample = mocked_mh.get_last_sampled (1)[0] t = sample[0] start_mean += t.get_values () start_mean /= N assert all (abs (start_mean - analytical_mean) < 1e-1)
def copy(self): """ Return a copy of this object. """ cpy = Gamma(self.__N, self.__i) return cpy
def test_samples_target (self): """ With a controlled target distribution, tests if the MH successfully generates a sample from the target. """ n = 10 N = 5000 theta = RandomParameterList () for i in range (n): gamma = Gamma (1, 1) p = RandomParameter ('p', gamma) theta.append (p) class MHMultivariateLognormalTargetMock (MetropolisHastings): def __init__ (self, theta): super ().__init__ (theta, verbose=False) n = theta.get_size () mu = np.ones (n) Sigma = np.eye (n) / 10 self.target_distribution = MultivariateLognormal (mu, Sigma) def _calc_log_likelihood (self, t): t_values = t.get_values () l = self.target_distribution.pdf (t_values) return np.log (l) def _create_jump_dist (self, theta_t): n = theta_t.get_size () S = np.eye (n) / 100 variances = S.diagonal () theta_values = np.array (theta_t.get_values ()) mu = np.log (theta_values) - variances / 2 return MultivariateLognormal (mu, S) def _calc_mh_ratio (self, new_t, new_l, old_t, old_l): J_gv_new = self._create_jump_dist (new_t) J_gv_old = self._create_jump_dist (old_t) p_old_gv_new = J_gv_new.pdf (old_t.get_values ()) p_new_gv_old = J_gv_old.pdf (new_t.get_values ()) l_ratio = np.exp (new_l - old_l) r = (l_ratio) * (p_old_gv_new / p_new_gv_old) return r mocked_mh = MHMultivariateLognormalTargetMock (theta) mocked_mh.start_sample_from_prior () mocked_mh.get_sample (N)[0] # let's throw away the first 10% of samples sample = mocked_mh.get_last_sampled (int (N * .9))[0] mu = np.ones (n) S = np.eye (n) / 10 analytic_mean = np.exp (mu + S.diagonal () / 2) sample_mean = np.zeros (n) for t in sample: sample_mean += t.get_values () sample_mean /= len (sample) diff = analytic_mean - sample_mean diff_norm2 = np.sqrt (diff.dot (diff)) assert (diff_norm2 < 1)
def test_get_mean(self): """ Tests if one can get the mean of the random variable. """ a = 2 b = 2 X = Gamma(a, b) assert (abs(X.mean() - a * b) / (a * b) < 1e-2)