def _propagate_distr_impl(self, distr0, time_delta, assume_distr=False): if not isinstance(distr0, distrs.LogNormalDistr) and not assume_distr: raise ValueError('Do not know how to propagate a distribution that is not log-normal') # Note: the sum of two independent log-normal distributions is only approximately log-normal mean = np.log(distr0.mean) + (self._pct_drift - .5 * npu.col([self._pct_cov[i, i] for i in range(self.process_dim)])) * time_delta cov = distr0.cov + time_delta * self._pct_cov return distrs.LogNormalDistr(mean_of_log=mean, cov_of_log=cov)
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]])