def test_euler_maruyama(self): rnd.random_state(np.random.RandomState(seed=42), force=True) W = proc.WienerProcess.create_2d(mean1=-.5, mean2=3., sd1=3., sd2=4., cor=.5) em = sim.EulerMaruyama(process=W) t, v = next(em) npt.assert_almost_equal(t, 0.) npt.assert_almost_equal(v, npu.col(0.0, 0.0)) t, v = next(em) npt.assert_almost_equal(t, 1.) npt.assert_almost_equal(v, npu.col(0.9901425, 3.5144667))
def propagate(self, time0, value0, time, variate=None, state0=None, random_state=None): if time == time0: return npu.to_ndim_2(value0, ndim_1_to_col=True, copy=True) value0 = npu.to_ndim_2(value0, ndim_1_to_col=True, copy=False) if variate is None: if random_state is None: random_state = rnd.random_state() variate = random_state.normal(size=self.noise_dim) variate = npu.to_ndim_2(variate, ndim_1_to_col=True, copy=False) time_delta = time - time0 if isinstance(time_delta, np.timedelta64): time_delta = time_delta.item() if isinstance(time_delta, dt.timedelta): time_delta = time_delta.total_seconds( ) / self._time_unit.total_seconds() mrf = self.mean_reversion_factor(time_delta) eye_minus_mrf = np.eye(self.process_dim) - mrf m = np.dot(mrf, value0) + np.dot(eye_minus_mrf, self._mean) c = self.noise_covariance(time_delta) return m + np.dot(np.linalg.cholesky(c), variate)
def propagate(self, time0, value0, time, variate=None, state0=None, random_state=None): if time == time0: return npu.to_ndim_2(value0, ndim_1_to_col=True, copy=True) value0 = npu.to_ndim_2(value0, ndim_1_to_col=True, copy=False) if variate is None: if random_state is None: random_state = rnd.random_state() variate = random_state.normal(size=self.noise_dim) variate = npu.to_ndim_2(variate, ndim_1_to_col=True, copy=False) time_delta = time - time0 if isinstance(time_delta, np.timedelta64): time_delta = time_delta.item() if isinstance(time_delta, dt.timedelta): time_delta = time_delta.total_seconds() / self._time_unit.total_seconds() final_time_minus_time0 = self.__final_time - time0 if isinstance(final_time_minus_time0, np.timedelta64): final_time_minus_time0 = final_time_minus_time0.item() if isinstance(final_time_minus_time0, dt.timedelta): final_time_minus_time0 = final_time_minus_time0.total_seconds() / self._time_unit.total_seconds() final_time_minus_time = self.__final_time - time if isinstance(final_time_minus_time, np.timedelta64): final_time_minus_time = time_delta.item() if isinstance(final_time_minus_time, dt.timedelta): final_time_minus_time = final_time_minus_time.total_seconds() / self._time_unit.total_seconds() mean = value0 + time_delta / final_time_minus_time0 * (self.__final_value - value0) cov_factor = time_delta * final_time_minus_time / final_time_minus_time0 vol_factor = np.sqrt(cov_factor) vol = vol_factor * self.__vol return mean + np.dot(vol, variate)
def test_random_state(self): rs = np.random.RandomState(seed=42) rnd.random_state(rs, force=True) self.assertEqual(rnd.random_state(), rs) with self.assertRaises(exc.NumericError): rnd.random_state(rs) rs = np.random.RandomState(seed=132) rnd.random_state(rs, force=True) self.assertEqual(rnd.random_state(), rs)
def test_run(self): rnd.random_state(np.random.RandomState(seed=42), force=True) W = proc.WienerProcess.create_2d(mean1=.25, mean2=.5, sd1=3., sd2=4., cor=.5) em = sim.EulerMaruyama(process=W) df = sim.run(em, nstep=10) pdt.assert_frame_equal(df, pd.DataFrame(data=[ [0.000000, 0.000000], [1.740142, 1.014467], [3.933208, 8.085774], [3.480748, 7.306393], [8.468386, 13.623291], [7.309963, 15.063825], [6.169710, 13.023654], [7.145597, 7.379782], [2.220843, 2.482125], [-0.567650, 2.045047]], index=[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]))
def __init__(self, time, state_distr, process, weighting_func=None, particle_count=1000, observation_dim=1, random_state=None, predicted_observation_sampler=None, outlier_threshold=None, name=None, pype=None, pype_options=frozenset(filtering.FilterPypeOptions)): super().__init__(name) self._pype = pype self._pype_options = frozenset() if (pype_options is None or pype is None) else frozenset(pype_options) if not checks.is_iterable(process): process = (process,) process = checks.check_iterable_over_instances(process, proc.SolvedItoProcess) if weighting_func is None: weighting_func = KDEWeightingFunction() self._time = time self._observation_dim = observation_dim self._state_distr = state_distr self._processes = tuple(process) self._state_dim = sum([p.process_dim for p in self._processes]) self._weighting_func = weighting_func self._particle_count = particle_count self._current_particle_idx = None self._random_state = rnd.random_state() if random_state is None else random_state self._predicted_observation_sampler = predicted_observation_sampler self._prior_particles = np.empty((self._particle_count, self._state_dim)) self._resampled_particles = np.empty((self._particle_count, self._state_dim)) self._unnormalised_weights = np.empty((self._particle_count,)) self._weights = np.empty((self._particle_count,)) self._resampled_particles_uptodate = False self._last_observation = None self._cached_prior_mean = None self._cached_prior_var = None self._cached_posterior_mean = None self._cached_posterior_var = None self._cached_resampled_mean = None self._cached_resampled_var = None self.log_likelihood = 0.0 self.effective_sample_size = np.NaN if self._predicted_observation_sampler is not None: self.predicted_observation_particles = None self.predicted_observation_kde = None self.predicted_observation = np.NaN self.innovation = np.NaN self.innovationvar = np.NaN assert self._predicted_observation_sampler is not None or outlier_threshold is None self._outlier_threshold = outlier_threshold self._context = OrderedDict() self._initialise()
def propagate(self, time0, value0, time, variate=None, state0=None, random_state=None): if self.noise_dim != self.process_dim: raise NotImplementedError('Cannot utilise the propagate_distr of the Markov process in propagate if noise_dim != process_dim; provide a custom implementation') if time == time0: return npu.to_ndim_2(value0, ndim_1_to_col=True, copy=True) value0 = npu.to_ndim_2(value0, ndim_1_to_col=True, copy=False) if variate is None: if random_state is None: random_state = rnd.random_state() variate = random_state.normal(size=self.noise_dim) variate = npu.to_ndim_2(variate, ndim_1_to_col=True, copy=False) distr = self.propagate_distr(time, time0, distrs.DiracDelta.create(value0), assume_distr=True) return distr.mean + np.dot(np.linalg.cholesky(distr.cov), variate)
def propagate(self, time0, value0, time, variate=None, state0=None, random_state=None): if time == time0: return npu.to_ndim_2(value0, ndim_1_to_col=True, copy=True) value0 = npu.to_ndim_2(value0, ndim_1_to_col=True, copy=False) if variate is None: if random_state is None: random_state = rnd.random_state() variate = random_state.normal(size=self.noise_dim) variate = npu.to_ndim_2(variate, ndim_1_to_col=True, copy=False) time_delta = time - time0 if isinstance(time_delta, np.timedelta64): time_delta = time_delta.item() if isinstance(time_delta, dt.timedelta): time_delta = time_delta.total_seconds() / self._time_unit.total_seconds() return value0 + self._mean * time_delta + np.dot(self._vol, np.sqrt(time_delta) * variate)
def test_exponential(self): rnd.random_state(np.random.RandomState(seed=42), force=True) values = rnd.exponential(.25, size=5) npt.assert_almost_equal( values, np.array([0.117317, 0.7525304, 0.3291864, 0.2282356, 0.0424062])) values = rnd.exponential(.25, size=1000000) npt.assert_almost_equal(np.mean(values), .25, decimal=3) values = rnd.exponential(dt.timedelta(minutes=25), size=5) values = [v.total_seconds() for v in values] npt.assert_almost_equal( values, np.array([ 1138.023383, 2274.520394, 265.023984, 221.528354, 3365.675561 ])) values = rnd.exponential(dt.timedelta(minutes=25), size=1000000) npt.assert_almost_equal(np.mean([v.total_seconds() for v in values]), 1497.6779794581771, decimal=3)
def multinomial_resample(empirical_distr, target_particle_count=None, random_state=None): if target_particle_count is None: target_particle_count = empirical_distr.particle_count if random_state is None: random_state = rnd.random_state() counts = rnd.multinomial(target_particle_count, npu.to_ndim_1(empirical_distr.normalised_weights)) assert np.sum(counts) == target_particle_count particle_idx = 0 resampled_particles = np.empty( (target_particle_count, np.shape(empirical_distr.particles)[1])) for i in range(empirical_distr.particle_count): for _ in range(counts[i]): resampled_particles[particle_idx, :] = npu.to_ndim_1( empirical_distr.particle(i)) particle_idx += 1 return EmpiricalDistr(particles=resampled_particles, weights=np.ones((target_particle_count, )))
def test_xtimes_random_step(self): rnd.random_state(np.random.RandomState(seed=42), force=True) npt.assert_almost_equal(list(sim.xtimes(-5., 5., step=lambda x: rnd.exponential(2.5))), [-5., -3.8268298, 3.6984738]) npt.assert_almost_equal(list(sim.xtimes(-5., 5., step=lambda x: rnd.exponential(3.25))), [-5.0, -4.448719170997375, -3.897531222274908, -3.703055224296696, 2.833445085263108]) npt.assert_almost_equal(list(sim.xtimes(5., -5., step=lambda x: -rnd.exponential(2.5))), [5.0, 4.9480017300021535, -3.8108919578936264]) npt.assert_almost_equal(list(sim.xtimes(5., -5., step=lambda x: -rnd.exponential(3.25))), [5.0, 4.347793286563594, 3.689306162358759, 2.5103565416122082, 0.09259109131443122, -1.7454043757216628, -2.8641291015219728]) self.assertEqual( list(sim.xtimes(dt.datetime(2017, 5, 5), dt.datetime(2017, 5, 10), lambda x: rnd.exponential(dt.timedelta(days=1)))), [dt.datetime(2017, 5, 5), dt.datetime(2017, 5, 5, 8, 17, 32, 540237), dt.datetime(2017, 5, 5, 19, 14, 34, 891891), dt.datetime(2017, 5, 6, 9, 51, 26, 848922), dt.datetime(2017, 5, 7, 22, 46, 4, 520275), dt.datetime(2017, 5, 8, 4, 6, 48, 898763), dt.datetime(2017, 5, 8, 21, 26, 32, 217758), dt.datetime(2017, 5, 9, 18, 58, 56, 625679), dt.datetime(2017, 5, 9, 20, 7, 26, 142298)]) self.assertEqual( list(sim.xtimes(dt.datetime(2017, 5, 10), dt.datetime(2017, 5, 5), lambda x: -rnd.exponential(dt.timedelta(days=1)))), [dt.datetime(2017, 5, 10), dt.datetime(2017, 5, 9, 22, 23, 8, 396372), dt.datetime(2017, 5, 6, 23, 1, 1, 771013)]) self.assertEqual( list(sim.xtimes(dt.datetime(2017, 5, 5, 8), dt.datetime(2017, 5, 5, 12), lambda x: rnd.exponential(dt.timedelta(minutes=30)))), [dt.datetime(2017, 5, 5, 8), dt.datetime(2017, 5, 5, 8, 10, 53, 918148), dt.datetime(2017, 5, 5, 8, 13, 58, 917315), dt.datetime(2017, 5, 5, 8, 48, 33, 868689), dt.datetime(2017, 5, 5, 9, 5, 58, 32206), dt.datetime(2017, 5, 5, 9, 9, 52, 306227), dt.datetime(2017, 5, 5, 9, 30, 22, 691238), dt.datetime(2017, 5, 5, 9, 31, 25, 679937), dt.datetime(2017, 5, 5, 10, 43, 26, 441134), dt.datetime(2017, 5, 5, 10, 52, 25, 465132), dt.datetime(2017, 5, 5, 11, 25, 0, 725569), dt.datetime(2017, 5, 5, 11, 36, 13, 109416), dt.datetime(2017, 5, 5, 11, 58, 14, 509029)]) self.assertEqual( list(sim.xtimes(dt.datetime(2017, 5, 5, 12), dt.datetime(2017, 5, 5, 8), lambda x: -rnd.exponential(dt.timedelta(minutes=30)))), [dt.datetime(2017, 5, 5, 12), dt.datetime(2017, 5, 5, 10, 15, 12, 947161), dt.datetime(2017, 5, 5, 9, 30, 26, 905482), dt.datetime(2017, 5, 5, 8, 6, 17, 735527)]) self.assertEqual( list(sim.xtimes(dt.datetime(2017, 5, 5, 8), dt.datetime(2017, 5, 5, 8, 0, 1), lambda x: rnd.exponential(dt.timedelta(milliseconds=100)))), [dt.datetime(2017, 5, 5, 8), dt.datetime(2017, 5, 5, 8, 0, 0, 254944), dt.datetime(2017, 5, 5, 8, 0, 0, 264210), dt.datetime(2017, 5, 5, 8, 0, 0, 286023), dt.datetime(2017, 5, 5, 8, 0, 0, 290651), dt.datetime(2017, 5, 5, 8, 0, 0, 330004), dt.datetime(2017, 5, 5, 8, 0, 0, 379217), dt.datetime(2017, 5, 5, 8, 0, 0, 410873), dt.datetime(2017, 5, 5, 8, 0, 0, 587329), dt.datetime(2017, 5, 5, 8, 0, 0, 631452), dt.datetime(2017, 5, 5, 8, 0, 0, 664432), dt.datetime(2017, 5, 5, 8, 0, 0, 742673), dt.datetime(2017, 5, 5, 8, 0, 0, 757863), dt.datetime(2017, 5, 5, 8, 0, 0, 919911), dt.datetime(2017, 5, 5, 8, 0, 0, 927659)]) self.assertEqual( list(sim.xtimes(dt.date(2017, 5, 5), dt.date(2017, 5, 10), lambda x: rnd.exponential(dt.timedelta(days=1)))), [dt.date(2017, 5, 5), dt.date(2017, 5, 5), dt.date(2017, 5, 5), dt.date(2017, 5, 6), dt.date(2017, 5, 7), dt.date(2017, 5, 8), dt.date(2017, 5, 9), dt.date(2017, 5, 9), dt.date(2017, 5, 9), dt.date(2017, 5, 9)]) self.assertEqual( list(sim.xtimes(dt.date(2017, 5, 10), dt.date(2017, 5, 5), lambda x: -rnd.exponential(dt.timedelta(days=1)))), [dt.date(2017, 5, 10), dt.date(2017, 5, 9), dt.date(2017, 5, 8), dt.date(2017, 5, 7), dt.date(2017, 5, 6)]) self.assertEqual( list(sim.xtimes(dt.time(8), dt.time(12), lambda x: rnd.exponential(dt.timedelta(minutes=30)))), [dt.time(8), dt.time(9, 5, 28, 53442), dt.time(9, 24, 38, 372482), dt.time(9, 28, 27, 642791), dt.time(10, 5, 56, 70211), dt.time(10, 48, 50, 777167), dt.time(11, 13, 33, 774658), dt.time(11, 57, 46, 776598)]) self.assertEqual( list(sim.xtimes(dt.time(12), dt.time(8), lambda x: -rnd.exponential(dt.timedelta(minutes=30)))), [dt.time(12), dt.time(11, 43, 15, 934451), dt.time(11, 42, 29, 588458), dt.time(11, 39, 4, 87075), dt.time(11, 38, 6, 606449), dt.time(11, 7, 45, 493257), dt.time(10, 56, 26, 179181), dt.time(10, 35, 7, 392262), dt.time(9, 23, 41, 114308), dt.time(9, 15, 4, 984427), dt.time(8, 59, 14, 76872), dt.time(8, 16, 58, 328406), dt.time(8, 9, 10, 679124), dt.time(8, 6, 46, 491423)]) # Since end is set to None, we have a potentially infinite iteration ts = sim.xtimes(dt.datetime(2017, 5, 10), None, lambda x: rnd.exponential(dt.timedelta(days=1))) self.assertEqual(dt.datetime(2017, 5, 10), next(ts)) self.assertEqual(dt.datetime(2017, 5, 12, 15, 43, 7, 687420), next(ts)) self.assertEqual(dt.datetime(2017, 5, 14, 7, 20, 24, 331174), next(ts)) ts = sim.xtimes(dt.date(2017, 5, 10), None, lambda x: -rnd.exponential(dt.timedelta(days=1))) self.assertEqual(dt.date(2017, 5, 10), next(ts)) self.assertEqual(dt.date(2017, 5, 7), next(ts)) self.assertEqual(dt.date(2017, 5, 5), next(ts))
def test_multinomial_resample(self): rnd.random_state(np.random.RandomState(seed=42), force=True) normal_distr = distrs.NormalDistr(mean=[10., 100.], cov=[[4., -3.], [-3., 9.]]) particles = normal_distr.sample(size=100000) approx_normal_empirical_2d = distrs.EmpiricalDistr(particles=particles, weights=np.ones((100000,))) self.assertEqual(approx_normal_empirical_2d.particle_count, 100000) npt.assert_almost_equal(approx_normal_empirical_2d.effective_particle_count, 100000.) self.assertEqual(approx_normal_empirical_2d.dim, 2) npt.assert_almost_equal(approx_normal_empirical_2d.particles, particles) npt.assert_almost_equal(approx_normal_empirical_2d.particle(0), npu.col(*particles[0])) npt.assert_almost_equal(approx_normal_empirical_2d.weights, npu.col(*np.ones((100000,)))) npt.assert_almost_equal(approx_normal_empirical_2d.weight(0), 1.) npt.assert_almost_equal(approx_normal_empirical_2d.normalised_weights, npu.col(*np.ones((100000,))) / 100000.) npt.assert_almost_equal(approx_normal_empirical_2d.normalised_weight(0), .00001) self.assertEqual(approx_normal_empirical_2d.weight_sum, 100000.) npt.assert_almost_equal(approx_normal_empirical_2d.mean, [[ 9.9866994], [ 100.0141095]]) npt.assert_almost_equal(approx_normal_empirical_2d.var_n, [[ 3.9902435], [ 9.0362717]]) npt.assert_almost_equal(approx_normal_empirical_2d.var_n_minus_1, [[ 3.9902834], [ 9.036362 ]]) npt.assert_almost_equal(approx_normal_empirical_2d.cov_n, [[ 3.9902435, -3.011222 ], [-3.011222 , 9.0362717]]) npt.assert_almost_equal(approx_normal_empirical_2d.cov_n_minus_1, [[ 3.9902834, -3.0112521], [-3.0112521, 9.036362 ]]) npt.assert_almost_equal(approx_normal_empirical_2d.cov, [[ 3.9902435, -3.011222 ], [-3.011222 , 9.0362717]]) npt.assert_almost_equal(approx_normal_empirical_2d.vol_n, [[ 1.9975594, 0. ], [-1.5074505, 2.6007431]]) npt.assert_almost_equal(approx_normal_empirical_2d.vol_n_minus_1, [[ 1.9975694, 0. ], [-1.5074581, 2.6007561]]) npt.assert_almost_equal(approx_normal_empirical_2d.vol, [[ 1.9975594, 0. ], [-1.5074505, 2.6007431]]) rnd.random_state(np.random.RandomState(seed=43), force=True) resampled_approx_normal_empirical_2d = distrs.multinomial_resample(approx_normal_empirical_2d) self.assertEqual(resampled_approx_normal_empirical_2d.particle_count, 100000) npt.assert_almost_equal(resampled_approx_normal_empirical_2d.effective_particle_count, 100000.) self.assertEqual(resampled_approx_normal_empirical_2d.dim, 2) # The resampled particles should ("almost certainly") be different from the original ones: self.assertFalse(np.sum(resampled_approx_normal_empirical_2d.particles) == np.sum(particles)) npt.assert_almost_equal(resampled_approx_normal_empirical_2d.particle(0), npu.col(*particles[1])) npt.assert_almost_equal(resampled_approx_normal_empirical_2d.weights, npu.col(*np.ones((100000,)))) npt.assert_almost_equal(resampled_approx_normal_empirical_2d.weight(0), 1.) npt.assert_almost_equal(resampled_approx_normal_empirical_2d.normalised_weights, npu.col(*np.ones((100000,))) / 100000.) npt.assert_almost_equal(resampled_approx_normal_empirical_2d.normalised_weight(0), .00001) self.assertEqual(resampled_approx_normal_empirical_2d.weight_sum, 100000.) # But the stats should be pretty close to those of the original empirical distribution, though not to seven # decimal places: npt.assert_almost_equal(resampled_approx_normal_empirical_2d.mean, [[ 9.9866994], [ 100.0141095]], decimal=1) npt.assert_almost_equal(resampled_approx_normal_empirical_2d.var_n, [[ 3.9902435], [ 9.0362717]], decimal=1) npt.assert_almost_equal(resampled_approx_normal_empirical_2d.var_n_minus_1, [[ 3.9902834], [ 9.036362 ]], decimal=1) npt.assert_almost_equal(resampled_approx_normal_empirical_2d.cov_n, [[ 3.9902435, -3.011222 ], [-3.011222 , 9.0362717]], decimal=1) npt.assert_almost_equal(resampled_approx_normal_empirical_2d.cov_n_minus_1, [[ 3.9902834, -3.0112521], [-3.0112521, 9.036362 ]], decimal=1) npt.assert_almost_equal(resampled_approx_normal_empirical_2d.cov, [[ 3.9902435, -3.011222 ], [-3.011222 , 9.0362717]], decimal=1) npt.assert_almost_equal(resampled_approx_normal_empirical_2d.vol_n, [[ 1.9975594, 0. ], [-1.5074505, 2.6007431]], decimal=1) npt.assert_almost_equal(resampled_approx_normal_empirical_2d.vol_n_minus_1, [[ 1.9975694, 0. ], [-1.5074581, 2.6007561]], decimal=1) npt.assert_almost_equal(resampled_approx_normal_empirical_2d.vol, [[ 1.9975594, 0. ], [-1.5074505, 2.6007431]], decimal=1) rnd.random_state(np.random.RandomState(seed=43), force=True) resampled_approx_normal_empirical_2d_particles = approx_normal_empirical_2d.sample(size=100000) npt.assert_almost_equal(resampled_approx_normal_empirical_2d_particles, resampled_approx_normal_empirical_2d.particles) subsampled_approx_normal_empirical_2d = distrs.multinomial_resample(approx_normal_empirical_2d, target_particle_count=40000) self.assertEqual(subsampled_approx_normal_empirical_2d.particle_count, 40000) npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.effective_particle_count, 40000.) self.assertEqual(subsampled_approx_normal_empirical_2d.dim, 2) # The resampled particles should ("almost certainly") be different from the original ones: self.assertFalse(np.sum(subsampled_approx_normal_empirical_2d.particles) == np.sum(particles)) npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.particle(0), npu.col(*particles[1])) npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.weights, npu.col(*np.ones((40000,)))) npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.weight(0), 1.) npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.normalised_weights, npu.col(*np.ones((40000,))) / 40000.) npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.normalised_weight(0), .000025) self.assertEqual(subsampled_approx_normal_empirical_2d.weight_sum, 40000.) # But the stats should be pretty close to those of the original empirical distribution, though not to seven # decimal places: npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.mean, [[ 9.9866994], [ 100.0141095]], decimal=1) npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.var_n, [[ 3.9902435], [ 9.0362717]], decimal=1) npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.var_n_minus_1, [[ 3.9902834], [ 9.036362 ]], decimal=1) npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.cov_n, [[ 3.9902435, -3.011222 ], [-3.011222 , 9.0362717]], decimal=1) npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.cov_n_minus_1, [[ 3.9902834, -3.0112521], [-3.0112521, 9.036362 ]], decimal=1) npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.cov, [[ 3.9902435, -3.011222 ], [-3.011222 , 9.0362717]], decimal=1) npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.vol_n, [[ 1.9975594, 0. ], [-1.5074505, 2.6007431]], decimal=1) npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.vol_n_minus_1, [[ 1.9975694, 0. ], [-1.5074581, 2.6007561]], decimal=1) npt.assert_almost_equal(subsampled_approx_normal_empirical_2d.vol, [[ 1.9975594, 0. ], [-1.5074505, 2.6007431]], decimal=1) supersampled_approx_normal_empirical_2d = distrs.multinomial_resample(approx_normal_empirical_2d, target_particle_count=300000) self.assertEqual(supersampled_approx_normal_empirical_2d.particle_count, 300000) npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.effective_particle_count, 300000.) self.assertEqual(supersampled_approx_normal_empirical_2d.dim, 2) # The resampled particles should ("almost certainly") be different from the original ones: self.assertFalse(np.sum(supersampled_approx_normal_empirical_2d.particles) == np.sum(particles)) npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.particle(0), npu.col(*particles[0])) npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.weights, npu.col(*np.ones((300000,)))) npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.weight(0), 1.) npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.normalised_weights, npu.col(*np.ones((300000,))) / 300000.) npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.normalised_weight(0), 3.3333333333333333e-06) self.assertEqual(supersampled_approx_normal_empirical_2d.weight_sum, 300000.) # But the stats should be pretty close to those of the original empirical distribution, though not to seven # decimal places: npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.mean, [[ 9.9866994], [ 100.0141095]], decimal=1) npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.var_n, [[ 3.9902435], [ 9.0362717]], decimal=1) npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.var_n_minus_1, [[ 3.9902834], [ 9.036362 ]], decimal=1) npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.cov_n, [[ 3.9902435, -3.011222 ], [-3.011222 , 9.0362717]], decimal=1) npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.cov_n_minus_1, [[ 3.9902834, -3.0112521], [-3.0112521, 9.036362 ]], decimal=1) npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.cov, [[ 3.9902435, -3.011222 ], [-3.011222 , 9.0362717]], decimal=1) npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.vol_n, [[ 1.9975594, 0. ], [-1.5074505, 2.6007431]], decimal=1) npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.vol_n_minus_1, [[ 1.9975694, 0. ], [-1.5074581, 2.6007561]], decimal=1) npt.assert_almost_equal(supersampled_approx_normal_empirical_2d.vol, [[ 1.9975594, 0. ], [-1.5074505, 2.6007431]], decimal=1)
def test_normal_distr(self): rnd.random_state(np.random.RandomState(seed=42), force=True) std_normal_1d = distrs.NormalDistr(dim=1) npt.assert_almost_equal(std_normal_1d.mean, 0.) npt.assert_almost_equal(std_normal_1d.cov, 1.) npt.assert_almost_equal(std_normal_1d.vol, 1.) sample = std_normal_1d.sample() self.assertEqual(np.shape(sample), (1, 1)) npt.assert_almost_equal(sample, [[ 0.49671415]]) sample = std_normal_1d.sample(size=10) self.assertEqual(np.shape(sample), (10, 1)) npt.assert_almost_equal(sample, [ [-0.1382643 ], [ 0.64768854], [ 1.52302986], [-0.23415337], [-0.23413696], [ 1.57921282], [ 0.76743473], [-0.46947439], [ 0.54256004], [-0.46341769]]) std_normal_2d = distrs.NormalDistr(dim=2) npt.assert_almost_equal(std_normal_2d.mean, npu.col_of(2, 0.)) npt.assert_almost_equal(std_normal_2d.cov, np.eye(2)) npt.assert_almost_equal(std_normal_2d.vol, np.eye(2)) sample = std_normal_2d.sample(size=10) self.assertEqual(np.shape(sample), (10, 2)) npt.assert_almost_equal(sample, [ [-0.46572975, 0.24196227], [-1.91328024, -1.72491783], [-0.56228753, -1.01283112], [ 0.31424733, -0.90802408], [-1.4123037 , 1.46564877], [-0.2257763 , 0.0675282 ], [-1.42474819, -0.54438272], [ 0.11092259, -1.15099358], [ 0.37569802, -0.60063869], [-0.29169375, -0.60170661]]) sd1=3.; sd2=4.; cor=-.5 normal_2d = distrs.NormalDistr(mean=[1., 2.], cov=stats.make_cov_2d(sd1=sd1, sd2=sd2, cor=cor)) npt.assert_almost_equal(normal_2d.mean, npu.col(1., 2.)) npt.assert_almost_equal(normal_2d.cov, [[sd1*sd1, cor*sd1*sd2], [cor*sd1*sd2, sd2*sd2]]) npt.assert_almost_equal(normal_2d.vol, [[sd1, 0.], [cor*sd2, np.sqrt(1.-cor*cor)*sd2]]) sample = normal_2d.sample(size=10) self.assertEqual(np.shape(sample), (10, 2)) npt.assert_almost_equal(sample, [ [-3.09581812, 9.06710684], [ 5.00400357, -1.07912958], [ 4.10821238, -2.42324481], [ 2.58989516, -7.05256838], [ 2.07671635, 3.61955714], [ 0.38728403, 2.5195548 ], [-1.36010204, -0.88681309], [ 1.63968707, -1.29329703], [-0.61960168, 6.44566548], [ 5.53451941, -4.36131646]]) normal_2d = distrs.NormalDistr(mean=[1., 2.], vol=stats.make_vol_2d(sd1=sd1, sd2=sd2, cor=cor)) npt.assert_almost_equal(normal_2d.mean, npu.col(1., 2.)) npt.assert_almost_equal(normal_2d.cov, [[sd1*sd1, cor*sd1*sd2], [cor*sd1*sd2, sd2*sd2]]) npt.assert_almost_equal(normal_2d.vol, [[sd1, 0.], [cor*sd2, np.sqrt(1.-cor*cor)*sd2]]) sample = normal_2d.sample(size=10) self.assertEqual(np.shape(sample), (10, 2)) npt.assert_almost_equal(sample, [ [ 0.4624506 , -0.26705979], [ 1.76344545, 5.54913479], [-2.76038957, 4.57609973], [ 2.35608833, 1.20642031], [-2.1218454 , 5.16796697], [-0.85307657, -0.00850715], [ 5.28771297, -1.62048489], [-2.12592264, 7.1016208 ], [-0.46508111, 6.26189296], [ 3.15543223, -0.04269231]])
def test_empirical_distr(self): rnd.random_state(np.random.RandomState(seed=42), force=True) trivial_empirical_1d = distrs.EmpiricalDistr(particles=[[0.]], weights=[1.]) self.assertEqual(trivial_empirical_1d.particle_count, 1) npt.assert_almost_equal(trivial_empirical_1d.effective_particle_count, 1.) self.assertEqual(trivial_empirical_1d.dim, 1) npt.assert_almost_equal(trivial_empirical_1d.particles, np.array([[0.]])) npt.assert_almost_equal(trivial_empirical_1d.particle(0), np.array([[0.]])) npt.assert_almost_equal(trivial_empirical_1d.weights, np.array([[1.]])) npt.assert_almost_equal(trivial_empirical_1d.weight(0), 1.) npt.assert_almost_equal(trivial_empirical_1d.normalised_weights, np.array([[1.]])) npt.assert_almost_equal(trivial_empirical_1d.normalised_weight(0), 1.) self.assertEqual(trivial_empirical_1d.weight_sum, 1.) self.assertEqual(trivial_empirical_1d.mean, 0.) self.assertEqual(trivial_empirical_1d.var_n, 0.) npt.assert_almost_equal(trivial_empirical_1d.var_n_minus_1, np.nan) self.assertEqual(trivial_empirical_1d.var, 0.) self.assertEqual(trivial_empirical_1d.cov_n, 0.) npt.assert_almost_equal(trivial_empirical_1d.cov_n_minus_1, np.nan) self.assertEqual(trivial_empirical_1d.cov, 0.) with self.assertRaises(np.linalg.LinAlgError): # Matrix is not positive definite trivial_empirical_1d.vol_n with self.assertRaises(np.linalg.LinAlgError): # Matrix is not positive definite trivial_empirical_1d.vol_n_minus_1 with self.assertRaises(np.linalg.LinAlgError): # Matrix is not positive definite trivial_empirical_1d.vol simple_empirical_1d = distrs.EmpiricalDistr(particles=[[-1.], [1.]], weights=[.5, .5]) self.assertEqual(simple_empirical_1d.particle_count, 2) npt.assert_almost_equal(simple_empirical_1d.effective_particle_count, 2.) self.assertEqual(simple_empirical_1d.dim, 1) npt.assert_almost_equal(simple_empirical_1d.particles, np.array([[-1.], [1.]])) npt.assert_almost_equal(simple_empirical_1d.particle(0), np.array([[-1.]])) npt.assert_almost_equal(simple_empirical_1d.weights, np.array([[.5], [.5]])) npt.assert_almost_equal(simple_empirical_1d.weight(0), .5) npt.assert_almost_equal(simple_empirical_1d.normalised_weights, np.array([[.5], [.5]])) npt.assert_almost_equal(simple_empirical_1d.normalised_weight(0), .5) self.assertEqual(simple_empirical_1d.weight_sum, 1.) self.assertEqual(simple_empirical_1d.mean, 0.) self.assertEqual(simple_empirical_1d.var_n, 1.) # "n minus 1" (unbiased) stats don't make sense as we are not using "repeat"-type weights, meaning that each # weight represents the number of occurrences of one observation: npt.assert_almost_equal(simple_empirical_1d.var_n_minus_1, np.inf) self.assertEqual(simple_empirical_1d.cov_n, 1.) # "n minus 1" (unbiased) stats don't make sense as we are not using "repeat"-type weights, meaning that each # weight represents the number of occurrences of one observation: npt.assert_almost_equal(simple_empirical_1d.cov_n_minus_1, np.inf) self.assertEqual(simple_empirical_1d.cov, 1.) self.assertEqual(simple_empirical_1d.vol_n, 1.) # "n minus 1" (unbiased) stats don't make sense as we are not using "repeat"-type weights, meaning that each # weight represents the number of occurrences of one observation: self.assertEqual(simple_empirical_1d.vol_n_minus_1, np.inf) self.assertEqual(simple_empirical_1d.vol, 1.) # The weights can be specified as a one-dimensional array... simple_empirical_1d = distrs.EmpiricalDistr(particles=[[-1.], [1.]], weights=[.5, .5]) self.assertEqual(simple_empirical_1d.particle_count, 2) npt.assert_almost_equal(simple_empirical_1d.effective_particle_count, 2.) self.assertEqual(simple_empirical_1d.dim, 1) npt.assert_almost_equal(simple_empirical_1d.particles, np.array([[-1.], [1.]])) # ...but they come back as a (two-dimensional) column vector: npt.assert_almost_equal(simple_empirical_1d.weights, np.array([[.5], [.5]])) # ...alternatively, the weights can be specified as a (two-dimensional) column vector: simple_empirical_1d = distrs.EmpiricalDistr(particles=[[-1.], [1.]], weights=[[.5], [.5]]) self.assertEqual(simple_empirical_1d.particle_count, 2) npt.assert_almost_equal(simple_empirical_1d.effective_particle_count, 2.) self.assertEqual(simple_empirical_1d.dim, 1) npt.assert_almost_equal(simple_empirical_1d.particles, np.array([[-1.], [1.]])) # ...they always come back as a (two-dimensional) column vector: npt.assert_almost_equal(simple_empirical_1d.weights, np.array([[.5], [.5]])) # If the particles are specified as a one-dimensional array, they are interpreted as... simple_empirical_1d = distrs.EmpiricalDistr(particles=[-1., 1.], weights=[.5, .5]) self.assertEqual(simple_empirical_1d.particle_count, 2) npt.assert_almost_equal(simple_empirical_1d.effective_particle_count, 2.) self.assertEqual(simple_empirical_1d.dim, 1) # ...multiple one-dimensional particles (each row corresponds to a particle, each column to a dimension): npt.assert_almost_equal(simple_empirical_1d.particles, np.array([[-1.], [1.]])) npt.assert_almost_equal(simple_empirical_1d.weights, np.array([[.5], [.5]])) # Now we shall be using "repeat"-type weights: repeat_empirical_1d = distrs.EmpiricalDistr(particles=[[-1.], [1.]], weights=[2., 1.]) self.assertEqual(repeat_empirical_1d.particle_count, 2) npt.assert_almost_equal(repeat_empirical_1d.effective_particle_count, 1.7999999999999998) self.assertEqual(repeat_empirical_1d.dim, 1) npt.assert_almost_equal(repeat_empirical_1d.particles, np.array([[-1.], [1.]])) npt.assert_almost_equal(repeat_empirical_1d.particle(0), np.array([[-1.]])) npt.assert_almost_equal(repeat_empirical_1d.weights, np.array([[2.], [1.]])) npt.assert_almost_equal(repeat_empirical_1d.weight(0), 2.) npt.assert_almost_equal(repeat_empirical_1d.normalised_weights, np.array([[ 0.6666667], [ 0.3333333]])) npt.assert_almost_equal(repeat_empirical_1d.normalised_weight(0), 0.6666667) self.assertEqual(repeat_empirical_1d.weight_sum, 3.) npt.assert_almost_equal(repeat_empirical_1d.mean, -0.33333333) npt.assert_almost_equal(repeat_empirical_1d.var_n, 0.88888889) npt.assert_almost_equal(repeat_empirical_1d.var_n_minus_1, 1.3333333) npt.assert_almost_equal(repeat_empirical_1d.cov_n, 0.88888889) npt.assert_almost_equal(repeat_empirical_1d.cov_n_minus_1, 1.3333333) npt.assert_almost_equal(repeat_empirical_1d.cov, 0.88888889) npt.assert_almost_equal(repeat_empirical_1d.vol_n, 0.94280904) npt.assert_almost_equal(repeat_empirical_1d.vol_n_minus_1, 1.15470054) npt.assert_almost_equal(repeat_empirical_1d.vol, 0.94280904) # Now we shall be using "repeat"-type weights. There are three two-dimensional particles: repeat_empirical_2d = distrs.EmpiricalDistr(particles=[[-2., 2.], [0., 0.], [1., -1.]], weights=[2., 1., 1.]) self.assertEqual(repeat_empirical_2d.particle_count, 3) npt.assert_almost_equal(repeat_empirical_2d.effective_particle_count, 2.6666666666666665) self.assertEqual(repeat_empirical_2d.dim, 2) npt.assert_almost_equal(repeat_empirical_2d.particles, np.array([[-2., 2.], [0., 0.], [1., -1.]])) npt.assert_almost_equal(repeat_empirical_2d.particle(0), np.array([[-2.], [2.]])) npt.assert_almost_equal(repeat_empirical_2d.weights, np.array([[2.], [1.], [1.]])) npt.assert_almost_equal(repeat_empirical_2d.weight(0), 2.) npt.assert_almost_equal(repeat_empirical_2d.normalised_weights, np.array([[ 0.5 ], [ 0.25], [ 0.25]])) npt.assert_almost_equal(repeat_empirical_2d.normalised_weight(0), .5) self.assertEqual(repeat_empirical_2d.weight_sum, 4.) npt.assert_almost_equal(repeat_empirical_2d.mean, [[-0.75], [ 0.75]]) npt.assert_almost_equal(repeat_empirical_2d.var_n, [[ 1.6875], [ 1.6875]]) npt.assert_almost_equal(repeat_empirical_2d.var_n_minus_1, [[ 2.25], [ 2.25]]) npt.assert_almost_equal(repeat_empirical_2d.cov_n, [[ 1.6875, -1.6875], [-1.6875, 1.6875]]) npt.assert_almost_equal(repeat_empirical_2d.cov_n_minus_1, [[ 2.25, -2.25], [-2.25, 2.25]]) npt.assert_almost_equal(repeat_empirical_2d.cov, [[ 1.6875, -1.6875], [-1.6875, 1.6875]]) with self.assertRaises(np.linalg.LinAlgError): # Matrix is not positive definite repeat_empirical_2d.vol_n with self.assertRaises(np.linalg.LinAlgError): # Matrix is not positive definite repeat_empirical_2d.vol_n_minus_1 with self.assertRaises(np.linalg.LinAlgError): # Matrix is not positive definite repeat_empirical_2d.vol normal_distr = distrs.NormalDistr(mean=[10., 100.], cov=[[4., -3.], [-3., 9.]]) particles = normal_distr.sample(size=100) approx_normal_empirical_2d = distrs.EmpiricalDistr(particles=particles, weights=np.ones((100,))) self.assertEqual(approx_normal_empirical_2d.particle_count, 100) npt.assert_almost_equal(approx_normal_empirical_2d.effective_particle_count, 100.) self.assertEqual(approx_normal_empirical_2d.dim, 2) npt.assert_almost_equal(approx_normal_empirical_2d.particles, particles) npt.assert_almost_equal(approx_normal_empirical_2d.particle(0), npu.col(*particles[0])) npt.assert_almost_equal(approx_normal_empirical_2d.weights, npu.col(*np.ones((100,)))) npt.assert_almost_equal(approx_normal_empirical_2d.weight(0), 1.) npt.assert_almost_equal(approx_normal_empirical_2d.normalised_weights, npu.col(*np.ones((100,))) / 100.) npt.assert_almost_equal(approx_normal_empirical_2d.normalised_weight(0), .01) self.assertEqual(approx_normal_empirical_2d.weight_sum, 100.) npt.assert_almost_equal(approx_normal_empirical_2d.mean, [[ 10.2077457], [ 99.6856645]]) npt.assert_almost_equal(approx_normal_empirical_2d.var_n, [[ 3.3516275], [ 6.7649298]]) npt.assert_almost_equal(approx_normal_empirical_2d.var_n_minus_1, [[ 3.3854823], [ 6.8332624]]) npt.assert_almost_equal(approx_normal_empirical_2d.cov_n, [[ 3.3516275, -1.8258307], [-1.8258307, 6.7649298]]) npt.assert_almost_equal(approx_normal_empirical_2d.cov_n_minus_1, [[ 3.3854823, -1.8442735], [-1.8442735, 6.8332624]]) npt.assert_almost_equal(approx_normal_empirical_2d.cov, [[ 3.3516275, -1.8258307], [-1.8258307, 6.7649298]]) npt.assert_almost_equal(approx_normal_empirical_2d.vol_n, [[ 1.8307451, 0. ], [-0.9973157, 2.4021431]]) npt.assert_almost_equal(approx_normal_empirical_2d.vol_n_minus_1, [[ 1.839968 , 0. ], [-1.00234 , 2.4142446]]) npt.assert_almost_equal(approx_normal_empirical_2d.vol, [[ 1.8307451, 0. ], [-0.9973157, 2.4021431]]) # Using more particles more faithfully approximates the mean and covariance of the normal distribution: normal_distr = distrs.NormalDistr(mean=[10., 100.], cov=[[4., -3.], [-3., 9.]]) particles = normal_distr.sample(size=100000) approx_normal_empirical_2d = distrs.EmpiricalDistr(particles=particles, weights=np.ones((100000,))) self.assertEqual(approx_normal_empirical_2d.particle_count, 100000) npt.assert_almost_equal(approx_normal_empirical_2d.effective_particle_count, 100000.) self.assertEqual(approx_normal_empirical_2d.dim, 2) npt.assert_almost_equal(approx_normal_empirical_2d.particles, particles) npt.assert_almost_equal(approx_normal_empirical_2d.particle(0), npu.col(*particles[0])) npt.assert_almost_equal(approx_normal_empirical_2d.weights, npu.col(*np.ones((100000,)))) npt.assert_almost_equal(approx_normal_empirical_2d.weight(0), 1.) npt.assert_almost_equal(approx_normal_empirical_2d.normalised_weights, npu.col(*np.ones((100000,))) / 100000.) npt.assert_almost_equal(approx_normal_empirical_2d.normalised_weight(0), .00001) self.assertEqual(approx_normal_empirical_2d.weight_sum, 100000.) npt.assert_almost_equal(approx_normal_empirical_2d.mean, [[ 9.9863195], [ 100.0145412]]) npt.assert_almost_equal(approx_normal_empirical_2d.var_n, [[ 3.9901799], [ 9.0390325]]) npt.assert_almost_equal(approx_normal_empirical_2d.var_n_minus_1, [[ 3.9902198], [ 9.0391229]]) npt.assert_almost_equal(approx_normal_empirical_2d.cov_n, [[ 3.9901799, -3.0120428], [-3.0120428, 9.0390325]]) npt.assert_almost_equal(approx_normal_empirical_2d.cov_n_minus_1, [[ 3.9902198, -3.0120729], [-3.0120729, 9.0391229]]) npt.assert_almost_equal(approx_normal_empirical_2d.cov, [[ 3.9901799, -3.0120428], [-3.0120428, 9.0390325]]) npt.assert_almost_equal(approx_normal_empirical_2d.vol_n, [[ 1.9975435, 0. ], [-1.5078735, 2.6010287]]) npt.assert_almost_equal(approx_normal_empirical_2d.vol_n_minus_1, [[ 1.9975535, 0. ], [-1.507881 , 2.6010417]]) npt.assert_almost_equal(approx_normal_empirical_2d.vol, [[ 1.9975435, 0. ], [-1.5078735, 2.6010287]])
def test_log_normal_distr(self): rnd.random_state(np.random.RandomState(seed=42), force=True) std_log_normal_1d = distrs.LogNormalDistr(dim=1) npt.assert_almost_equal(std_log_normal_1d.mean, [[ 1.6487213]]) npt.assert_almost_equal(std_log_normal_1d.cov, [[ 4.6707743]]) npt.assert_almost_equal(std_log_normal_1d.vol, [[ 2.1611974]]) sample = std_log_normal_1d.sample(size=1) self.assertEqual(np.shape(sample), (1, 1)) npt.assert_almost_equal(sample, [[ 1.6433127]]) sample = std_log_normal_1d.sample(size=10) self.assertEqual(np.shape(sample), (10, 1)) npt.assert_almost_equal(sample, [ [ 0.87086849], [ 1.91111824], [ 4.58609939], [ 0.79124045], [ 0.79125344], [ 4.85113557], [ 2.15423297], [ 0.62533086], [ 1.72040554], [ 0.62912979]]) std_log_normal_2d = distrs.LogNormalDistr(dim=2) npt.assert_almost_equal(std_log_normal_2d.mean, [ [ 1.6487213], [ 1.6487213]]) npt.assert_almost_equal(std_log_normal_2d.cov, [ [ 4.6707743, 0. ], [ 0. , 4.6707743]]) npt.assert_almost_equal(std_log_normal_2d.vol, [ [ 2.1611974, 0. ], [ 0. , 2.1611974]]) sample = std_log_normal_2d.sample(size=10) self.assertEqual(np.shape(sample), (10, 2)) npt.assert_almost_equal(sample, [ [ 0.62767689, 1.27374614], [ 0.14759544, 0.17818769], [ 0.5699039 , 0.36318929], [ 1.36922835, 0.40332037], [ 0.2435815 , 4.33035173], [ 0.79789657, 1.06986043], [ 0.24056903, 0.58019982], [ 1.11730841, 0.31632232], [ 1.45600738, 0.54846123], [ 0.74699727, 0.54787583]]) sd1=.4; sd2=.4; cor=-.5 log_normal_2d = distrs.LogNormalDistr(mean_of_log=[1., 1.3], cov_of_log=stats.make_cov_2d(sd1=sd1, sd2=sd2, cor=cor)) npt.assert_almost_equal(log_normal_2d.mean_of_log, npu.col(1., 1.3)) npt.assert_almost_equal(log_normal_2d.cov_of_log, [[sd1*sd1, cor*sd1*sd2], [cor*sd1*sd2, sd2*sd2]]) npt.assert_almost_equal(log_normal_2d.vol_of_log, [[sd1, 0.], [cor*sd2, np.sqrt(1.-cor*cor)*sd2]]) npt.assert_almost_equal(log_normal_2d.mean, [[ 2.9446796], [ 3.9749016]]) npt.assert_almost_equal(log_normal_2d.cov, [[ 1.5045366, -0.8999087], [-0.8999087, 2.7414445]]) npt.assert_almost_equal(log_normal_2d.vol, [[ 1.2265956, 0. ], [-0.7336637, 1.484312 ]]) sample = log_normal_2d.sample(size=10) self.assertEqual(np.shape(sample), (10, 2)) npt.assert_almost_equal(sample, [ [ 1.42711164, 6.95143797], [ 4.62238496, 2.99848502], [ 4.32618186, 2.50643161], [ 4.10913455, 1.42691268], [ 2.94320341, 4.55346303], [ 2.50304159, 3.80468825], [ 2.24476532, 2.45957906], [ 3.18112082, 2.60781028], [ 2.01884543, 5.66848303], [ 5.34174201, 2.12565878]]) log_normal_2d = distrs.LogNormalDistr(mean_of_log=[1., 1.3], vol_of_log=stats.make_vol_2d(sd1=sd1, sd2=sd2, cor=cor)) npt.assert_almost_equal(log_normal_2d.mean_of_log, npu.col(1., 1.3)) npt.assert_almost_equal(log_normal_2d.cov_of_log, [[sd1*sd1, cor*sd1*sd2], [cor*sd1*sd2, sd2*sd2]]) npt.assert_almost_equal(log_normal_2d.vol_of_log, [[sd1, 0.], [cor*sd2, np.sqrt(1.-cor*cor)*sd2]]) npt.assert_almost_equal(log_normal_2d.mean, npu.col(2.9446796, 3.9749016)) npt.assert_almost_equal(log_normal_2d.cov, [[ 1.5045366, -0.8999087], [-0.8999087, 2.7414445]]) npt.assert_almost_equal(log_normal_2d.vol, [[ 1.2265956, 0. ], [-0.7336637, 1.484312 ]]) sample = log_normal_2d.sample(size=10) self.assertEqual(np.shape(sample), (10, 2)) npt.assert_almost_equal(sample, [ [ 2.71288329, 2.80448293], [ 2.70285608, 5.57387658], [ 1.66454464, 4.28346127], [ 3.23285936, 3.52238521], [ 1.76160691, 4.67441442], [ 2.32343609, 2.75776026], [ 4.8398479 , 2.85230385], [ 1.67494888, 5.78583855], [ 2.06409776, 5.58431178], [ 3.6537541 , 3.15441508]])