def construct_iv_estimand(self, estimand_type, treatment_name, outcome_name, instrument_names): expr = None if estimand_type == "ate": sym_outcome = spstats.Normal(outcome_name, 0, 1) sym_treatment = spstats.Normal(treatment_name, 0, 1) sym_instrument = sp.Symbol(instrument_names[0]) # ",".join(instrument_names)) sym_outcome_derivative = sp.Derivative(sym_outcome, sym_instrument) sym_treatment_derivative = sp.Derivative(sym_treatment, sym_instrument) sym_effect = spstats.Expectation(sym_outcome_derivative / sym_treatment_derivative) sym_assumptions = { "As-if-random": ( "If U\N{RIGHTWARDS ARROW}\N{RIGHTWARDS ARROW}{0} then " "\N{NOT SIGN}(U \N{RIGHTWARDS ARROW}\N{RIGHTWARDS ARROW}{1})" ).format(outcome_name, ",".join(instrument_names)), "Exclusion": ( u"If we remove {{{0}}}\N{RIGHTWARDS ARROW}{1}, then " u"\N{NOT SIGN}({0}\N{RIGHTWARDS ARROW}{2})" ).format(",".join(instrument_names), treatment_name, outcome_name) } estimand = { 'estimand': sym_effect, 'assumptions': sym_assumptions } return estimand
def construct_frontdoor_estimand(self, estimand_type, treatment_name, outcome_name, frontdoor_variables_names): # TODO: support multivariate treatments better. expr = None outcome_name = outcome_name[0] sym_outcome = spstats.Normal(outcome_name, 0, 1) sym_treatment_symbols = [spstats.Normal(t, 0, 1) for t in treatment_name] sym_treatment = sp.Array(sym_treatment_symbols) sym_frontdoor_symbols = [sp.Symbol(inst) for inst in frontdoor_variables_names] sym_frontdoor = sp.Array(sym_frontdoor_symbols) # ",".join(instrument_names)) sym_outcome_derivative = sp.Derivative(sym_outcome, sym_frontdoor) sym_treatment_derivative = sp.Derivative(sym_frontdoor, sym_treatment) sym_effect = spstats.Expectation(sym_treatment_derivative * sym_outcome_derivative) sym_assumptions = { "Full-mediation": ( "{2} intercepts (blocks) all directed paths from {0} to {1}." ).format(",".join(treatment_name), ",".join(outcome_name), ",".join(frontdoor_variables_names)), "First-stage-unconfoundedness": ( u"If U\N{RIGHTWARDS ARROW}{{{0}}} and U\N{RIGHTWARDS ARROW}{{{1}}}" " then P({1}|{0},U) = P({1}|{0})" ).format(",".join(treatment_name), ",".join(frontdoor_variables_names)), "Second-stage-unconfoundedness": ( u"If U\N{RIGHTWARDS ARROW}{{{2}}} and U\N{RIGHTWARDS ARROW}{1}" " then P({1}|{2}, {0}, U) = P({1}|{2}, {0})" ).format(",".join(treatment_name), outcome_name, ",".join(frontdoor_variables_names)) } estimand = { 'estimand': sym_effect, 'assumptions': sym_assumptions } return estimand
def construct_symbolic_estimator(self, estimand): sym_outcome = (spstats.Normal(",".join(estimand.outcome_variable), 0, 1)) sym_treatment = (spstats.Normal(",".join(estimand.treatment_variable), 0, 1)) sym_instrument = sp.Symbol(estimand.instrumental_variables[0]) sym_outcome_derivative = sp.Derivative(sym_outcome, sym_instrument) sym_treatment_derivative = sp.Derivative(sym_treatment, sym_instrument) sym_effect = (spstats.Expectation(sym_outcome_derivative) / sp.stats.Expectation(sym_treatment_derivative)) estimator_assumptions = { "treatment_effect_homogeneity": ("Each unit's treatment {0} is".format(self._treatment_name) + "affected in the same way by common causes of " "{0} and {1}".format(self._treatment_name, self._outcome_name)), "outcome_effect_homogeneity": ("Each unit's outcome {0} is".format(self._outcome_name) + "affected in the same way by common causes of " "{0} and {1}".format(self._treatment_name, self._outcome_name)), } sym_assumptions = { **estimand.estimands["iv"]["assumptions"], **estimator_assumptions } symbolic_estimand = RealizedEstimand(estimand, estimator_name="Wald Estimator") symbolic_estimand.update_assumptions(sym_assumptions) symbolic_estimand.update_estimand_expression(sym_effect) return symbolic_estimand
def construct_iv_estimand(self, estimand_type, treatment_name, outcome_name, instrument_names): # TODO: support multivariate treatments better. expr = None outcome_name = outcome_name[0] sym_outcome = spstats.Normal(outcome_name, 0, 1) sym_treatment_symbols = [ spstats.Normal(t, 0, 1) for t in treatment_name ] sym_treatment = sp.Array(sym_treatment_symbols) sym_instrument_symbols = [sp.Symbol(inst) for inst in instrument_names] sym_instrument = sp.Array( sym_instrument_symbols) # ",".join(instrument_names)) sym_outcome_derivative = sp.Derivative(sym_outcome, sym_instrument) sym_treatment_derivative = sp.Derivative(sym_treatment, sym_instrument) sym_effect = spstats.Expectation(sym_outcome_derivative / sym_treatment_derivative) sym_assumptions = { "As-if-random": ("If U\N{RIGHTWARDS ARROW}\N{RIGHTWARDS ARROW}{0} then " "\N{NOT SIGN}(U \N{RIGHTWARDS ARROW}\N{RIGHTWARDS ARROW}{{{1}}})" ).format(outcome_name, ",".join(instrument_names)), "Exclusion": (u"If we remove {{{0}}}\N{RIGHTWARDS ARROW}{{{1}}}, then " u"\N{NOT SIGN}({{{0}}}\N{RIGHTWARDS ARROW}{2})").format( ",".join(instrument_names), ",".join(treatment_name), outcome_name) } estimand = {'estimand': sym_effect, 'assumptions': sym_assumptions} return estimand
def construct_mediation_estimand(self, estimand_type, treatment_name, outcome_name, mediators_names): # TODO: support multivariate treatments better. expr = None if estimand_type in (CausalIdentifier.NONPARAMETRIC_NDE, CausalIdentifier.NONPARAMETRIC_NIE): outcome_name = outcome_name[0] sym_outcome = spstats.Normal(outcome_name, 0, 1) sym_treatment_symbols = [ spstats.Normal(t, 0, 1) for t in treatment_name ] sym_treatment = sp.Array(sym_treatment_symbols) sym_mediators_symbols = [ sp.Symbol(inst) for inst in mediators_names ] sym_mediators = sp.Array(sym_mediators_symbols) sym_outcome_derivative = sp.Derivative(sym_outcome, sym_mediators) sym_treatment_derivative = sp.Derivative(sym_mediators, sym_treatment) # For direct effect num_expr_str = outcome_name if len(mediators_names) > 0: num_expr_str += "|" + ",".join(mediators_names) sym_mu = sp.Symbol("mu") sym_sigma = sp.Symbol("sigma", positive=True) sym_conditional_outcome = spstats.Normal(num_expr_str, sym_mu, sym_sigma) sym_directeffect_derivative = sp.Derivative( sym_conditional_outcome, sym_treatment) if estimand_type == CausalIdentifier.NONPARAMETRIC_NIE: sym_effect = spstats.Expectation(sym_treatment_derivative * sym_outcome_derivative) elif estimand_type == CausalIdentifier.NONPARAMETRIC_NDE: sym_effect = spstats.Expectation(sym_directeffect_derivative) sym_assumptions = { "Mediation": ("{2} intercepts (blocks) all directed paths from {0} to {1} except the path {{{0}}}\N{RIGHTWARDS ARROW}{{{1}}}." ).format(",".join(treatment_name), ",".join(outcome_name), ",".join(mediators_names)), "First-stage-unconfoundedness": (u"If U\N{RIGHTWARDS ARROW}{{{0}}} and U\N{RIGHTWARDS ARROW}{{{1}}}" " then P({1}|{0},U) = P({1}|{0})").format( ",".join(treatment_name), ",".join(mediators_names)), "Second-stage-unconfoundedness": (u"If U\N{RIGHTWARDS ARROW}{{{2}}} and U\N{RIGHTWARDS ARROW}{1}" " then P({1}|{2}, {0}, U) = P({1}|{2}, {0})").format( ",".join(treatment_name), outcome_name, ",".join(mediators_names)) } else: raise ValueError( "Estimand type not supported. Supported estimand types are {0} or {1}'." .format(CausalIdentifier.NONPARAMETRIC_NDE, CausalIdentifier.NONPARAMETRIC_NIE)) estimand = {'estimand': sym_effect, 'assumptions': sym_assumptions} return estimand
def extract_from_block(self, rv_to_extract): """ Extracts single random variable from joint distribution and creates new distribution. A new distribution will be created for remaining RVs, single normal distribution if one remains, joint normal otherwise. Parameters ---------- rv_to_extract : RandomSymbol Random symbol to create new single distribution for.""" associated_rvs = self.get_rvs_from_same_dist(rv_to_extract) cov = associated_rvs.covariance_matrix() rv_extracted = None index_to_remove = None names = [] for i, rv in enumerate(associated_rvs): if rv.name == rv_to_extract.name: rv_extracted = stats.Normal(rv.name, 0, sympy.sqrt(cov[i, i])) rv_extracted.variability_level = VariabilityLevel.IIV index_to_remove = i else: names.append(rv.name) cov.row_del(index_to_remove) cov.col_del(index_to_remove) if len(cov) == 1: rv_remaining = stats.Normal(names[0], 0, sympy.sqrt(cov[0])) rv_remaining.variability_level = VariabilityLevel.IIV else: means = sympy.zeros(cov.shape[0] - 1) rv_remaining = JointNormalSeparate(names, means, cov) for rv in rv_remaining: rv.variability_level = VariabilityLevel.IIV split_block = [rv_extracted, rv_remaining] split_block = split_block.reverse() if index_to_remove != 0 else split_block rvs_new = RandomVariables() has_added_changed_block = False for rv in self: if rv in associated_rvs: if not has_added_changed_block: {rvs_new.add(rv_block) for rv_block in split_block} has_added_changed_block = True else: rvs_new.add(rv) self.discard(rv) self.update(rvs_new) return rv_extracted
def test_all_parameters(): omega1 = symbol('OMEGA(1,1)') eta1 = stats.Normal('ETA(1)', 0, sympy.sqrt(omega1)) omega2 = symbol('OMEGA(2,2)') eta2 = stats.Normal('ETA(2)', 0, sympy.sqrt(omega2)) sigma = symbol('SIGMA(1,1)') eps = stats.Normal('EPS(1)', 0, sympy.sqrt(sigma)) rvs = RandomVariables([eta1, eta2, eps]) assert len(rvs) == 3 params = rvs.all_parameters() assert len(params) == 3 assert params == ['OMEGA(1,1)', 'OMEGA(2,2)', 'SIGMA(1,1)']
def test_has_same_order(): omega1 = symbol('OMEGA(1,1)') eta1 = stats.Normal('ETA(1)', 0, sympy.sqrt(omega1)) omega2 = symbol('OMEGA(2,2)') eta2 = stats.Normal('ETA(2)', 0, sympy.sqrt(omega2)) omega3 = symbol('OMEGA(1,1)') eta3 = stats.Normal('ETA(3)', 0, sympy.sqrt(omega3)) rvs_full = RandomVariables([eta1, eta2, eta3]) assert rvs_full.are_consecutive(rvs_full) rvs_sub = RandomVariables([eta1, eta2]) assert rvs_full.are_consecutive(rvs_sub) rvs_rev = RandomVariables([eta3, eta2, eta1]) assert not rvs_full.are_consecutive(rvs_rev)
def test_choose_param_init(pheno_path, testdata): model = Model(pheno_path) params = (model.parameters['OMEGA(1,1)'], model.parameters['OMEGA(2,2)']) rvs = RandomVariables(model.random_variables.etas) init = _choose_param_init(model, rvs, params) assert init == 0.0118179 model = Model(pheno_path) model.source.path = testdata # Path where there is no .ext-file init = _choose_param_init(model, rvs, params) assert init == 0.0031045 model = Model(pheno_path) omega1 = S('OMEGA(3,3)') x = stats.Normal('ETA(3)', 0, sympy.sqrt(omega1)) x.variability_level = VariabilityLevel.IIV rvs.add(x) ie = model.modelfit_results.individual_estimates ie['ETA(3)'] = ie['ETA(1)'] model.modelfit_results = ModelfitResults(individual_estimates=ie) init = _choose_param_init(model, rvs, params) assert init == 0.0118179
def construct_backdoor_estimand(self, estimand_type, treatment_name, outcome_name, common_causes): # TODO: outputs string for now, but ideally should do symbolic # expressions Mon 19 Feb 2018 04:54:17 PM DST # TODO Better support for multivariate treatments expr = None outcome_name = outcome_name[0] num_expr_str = outcome_name if len(common_causes) > 0: num_expr_str += "|" + ",".join(common_causes) expr = "d(" + num_expr_str + ")/d" + ",".join(treatment_name) sym_mu = sp.Symbol("mu") sym_sigma = sp.Symbol("sigma", positive=True) sym_outcome = spstats.Normal(num_expr_str, sym_mu, sym_sigma) sym_treatment_symbols = [sp.Symbol(t) for t in treatment_name] sym_treatment = sp.Array(sym_treatment_symbols) sym_conditional_outcome = spstats.Expectation(sym_outcome) sym_effect = sp.Derivative(sym_conditional_outcome, sym_treatment) sym_assumptions = { 'Unconfoundedness': (u"If U\N{RIGHTWARDS ARROW}{{{0}}} and U\N{RIGHTWARDS ARROW}{1}" " then P({1}|{0},{2},U) = P({1}|{0},{2})").format( ",".join(treatment_name), outcome_name, ",".join(common_causes)) } estimand = {'estimand': sym_effect, 'assumptions': sym_assumptions} return estimand
def construct_backdoor_estimand(self, estimand_type, treatment_name, outcome_name, common_causes): # TODO: outputs string for now, but ideally should do symbolic # expressions Mon 19 Feb 2018 04:54:17 PM DST expr = None if estimand_type == "ate": num_expr_str = outcome_name + "|" num_expr_str += ",".join(common_causes) expr = "d(" + num_expr_str + ")/d" + treatment_name sym_mu = sp.Symbol("mu") sym_sigma = sp.Symbol("sigma", positive=True) sym_outcome = spstats.Normal(num_expr_str, sym_mu, sym_sigma) # sym_common_causes = [sp.stats.Normal(common_cause, sym_mu, sym_sigma) for common_cause in common_causes] sym_treatment = sp.Symbol(treatment_name) sym_conditional_outcome = spstats.Expectation(sym_outcome) sym_effect = sp.Derivative(sym_conditional_outcome, sym_treatment) sym_assumptions = { 'Unconfoundedness': ( u"If U\N{RIGHTWARDS ARROW}{0} and U\N{RIGHTWARDS ARROW}{1}" " then P({1}|{0},{2},U) = P({1}|{0},{2})" ).format(treatment_name, outcome_name, ",".join(common_causes)) } estimand = { 'estimand': sym_effect, 'assumptions': sym_assumptions } return estimand
def _create_eta(pset, number): omega = S(f'IIV_RUV{number}') pset.add(Parameter(str(omega), 0.09)) eta = stats.Normal(f'RV{number}', 0, sympy.sqrt(omega)) eta.variability_level = VariabilityLevel.IIV return eta
def test_rv(): omega1 = sympy.Symbol('OMEGA(1,1)') x = stats.Normal('ETA(1)', 0, sympy.sqrt(omega1)) rvs = RandomVariables([x]) assert len(rvs) == 1 retrieved = rvs['ETA(1)'] assert retrieved.name == 'ETA(1)' assert retrieved.pspace.distribution.mean == 0
def test_validate_parameters(): a, b, c, d = (symbol('a'), symbol('b'), symbol('c'), symbol('d')) rvs = JointNormalSeparate(['ETA(1)', 'ETA(2)'], [0, 0], [[a, b], [b, c]]) rvs = RandomVariables(rvs) rvs.add(stats.Normal('ETA(3)', 0.5, d)) params = {'a': 2, 'b': 0.1, 'c': 1, 'd': 23} assert rvs.validate_parameters(params) params2 = {'a': 2, 'b': 2, 'c': 1, 'd': 23} assert not rvs.validate_parameters(params2)
def expression(self, expr, parameters): """Replace all symbols with same names as rvs with the corresponding rvs or indexed variables for joint distributions and replace parameter values """ d = dict() i = 1 for rvs, dist in self.distributions(): if len(rvs) > 1: joint_name = f'__J{i}' mu = dist.mu.subs(parameters) sigma = dist.sigma.subs(parameters) x = stats.Normal(joint_name, mu, sigma) d.update({symbol(rv.name): x[n] for n, rv in enumerate(rvs)}) i += 1 else: mean = dist.mean.subs(parameters) std = dist.std.subs(parameters) d[symbol(rvs[0].name)] = stats.Normal(rvs[0].name, mean, std) return expr.subs(d)
def test_distributions(): rvs = JointNormalSeparate(['ETA(1)', 'ETA(2)'], [0, 0], [[3, 0.25], [0.25, 1]]) rvs = RandomVariables(rvs) rvs.add(stats.Normal('ETA(3)', 0.5, 2)) dists = rvs.distributions() symbols, dist = dists[0] assert symbols[0].name == 'ETA(1)' assert symbols[1].name == 'ETA(2)' assert len(symbols) == 2 assert dist == rvs[0].pspace.distribution symbols, dist = dists[1] assert symbols[0].name == 'ETA(3)' assert len(symbols) == 1 assert dist == rvs[2].pspace.distribution
def test_distributions(): rvs = JointNormalSeparate(['ETA(1)', 'ETA(2)'], [0, 0], [[3, 0.25], [0.25, 1]]) rvs = RandomVariables(rvs) rvs.add(stats.Normal('ETA(3)', 0.5, 2)) gen = rvs.distributions() symbols, dist = next(gen) assert symbols[0].name == 'ETA(1)' assert symbols[1].name == 'ETA(2)' assert len(symbols) == 2 assert dist == rvs[0].pspace.distribution symbols, dist = next(gen) assert symbols[0].name == 'ETA(3)' assert len(symbols) == 1 assert dist == rvs[2].pspace.distribution with pytest.raises(StopIteration): symbols, dist = next(gen)
def test_extract_from_block(): etas = JointNormalSeparate(['ETA(1)', 'ETA(2)'], [0, 0], [[3, 0.25], [0.25, 1]]) for rv in etas: rv.variability_level = VariabilityLevel.IIV rvs = RandomVariables(etas) eta3 = stats.Normal('ETA(3)', 0.5, 2) eta3.variability_level = VariabilityLevel.IIV rvs.add(eta3) dists = rvs.distributions() assert len(dists) == 2 rvs.extract_from_block(etas[0]) dists = rvs.distributions() assert len(dists) == 3 assert rvs[0].name == 'ETA(1)' assert rvs[2].name == 'ETA(3)'
def test_merge_normal_distributions(): rvs = JointNormalSeparate(['ETA(1)', 'ETA(2)'], [0, 0], [[3, 0.25], [0.25, 1]]) rvs = RandomVariables(rvs) rvs.add(stats.Normal('ETA(3)', 0.5, 2)) rvs.merge_normal_distributions() assert len(rvs) == 3 assert rvs['ETA(1)'].name == 'ETA(1)' assert rvs[1].name == 'ETA(2)' assert rvs[2].name == 'ETA(3)' assert rvs[0].pspace is rvs[1].pspace assert rvs[0].pspace is rvs[2].pspace dist = rvs[0].pspace.distribution assert dist.mu == sympy.Matrix([0, 0, 0.5]) assert dist.sigma == sympy.Matrix([[3, 0.25, 0], [0.25, 1, 0], [0, 0, 4]]) rvs.merge_normal_distributions(fill=1) dist = rvs[0].pspace.distribution assert dist.sigma == sympy.Matrix([[3, 0.25, 1], [0.25, 1, 1], [1, 1, 4]])
def test_merge_normal_distributions(): rvs = JointNormalSeparate(['ETA(1)', 'ETA(2)'], [0, 0], [[3, 0.25], [0.25, 1]]) for rv in rvs: rv.variability_level = VariabilityLevel.IIV rvs = RandomVariables(rvs) eta3 = stats.Normal('ETA(3)', 0.5, 2) eta3.variability_level = VariabilityLevel.IIV rvs.add(eta3) rvs.merge_normal_distributions() assert len(rvs) == 3 assert rvs['ETA(1)'].name == 'ETA(1)' assert rvs[1].name == 'ETA(2)' assert rvs[2].name == 'ETA(3)' assert rvs[0].pspace is rvs[1].pspace assert rvs[0].pspace is rvs[2].pspace dist = rvs[0].pspace.distribution assert dist.mu == sympy.Matrix([0, 0, 0.5]) assert dist.sigma == sympy.Matrix([[3, 0.25, 0], [0.25, 1, 0], [0, 0, 4]])
def add_etas(model, parameter, expression, operation='*'): """ Adds etas to :class:`pharmpy.model`. Effects that currently have templates are: - Additive (*add*) - Proportional (*prop*) - Exponential (*exp*) - Logit (*logit*) For all except exponential the operation input is not needed. Otherwise user specified input is supported. Initial estimates for new etas are 0.09. Parameters ---------- model : Model Pharmpy model to add new etas to. parameter : str Name of parameter to add new etas to. expression : str Effect on eta. Either abbreviated (see above) or custom. operation : str, optional Whether the new eta should be added or multiplied (default). """ rvs, pset, sset = model.random_variables, model.parameters, model.statements omega = S(f'IIV_{parameter}') eta = stats.Normal(f'ETA_{parameter}', 0, sympy.sqrt(omega)) eta.variability_level = VariabilityLevel.IIV rvs.add(eta) pset.add(Parameter(str(omega), init=0.09)) statement = sset.find_assignment(parameter) eta_addition = _create_template(expression, operation) eta_addition.apply(statement.expression, eta.name) statement.expression = eta_addition.template model.random_variables = rvs model.parameters = pset model.statements = sset return model
''' import sympy.stats as stats coin = stats.Die('coin',2) P=stats.P E=stats.E import numpy as np rd = np.random.random(1000)*2+1 z = rd.astype(int) import sympy as sym x, y = sym.symbols('x y') normal = stats.Normal('N', 2, 3) z = 1 import numpy as np import scipy import sympy as sym import matplotlib sym.init_printing() x = sym.symbols('x') a = sym.Integral(sym.cos(x)*sym.exp(x), x) a.doit() sym.Eq(a, a.doit()) z = 1
def gaussian_to_sympy(node, input_vars=None, log=False): result = get_density(st.Normal("Node%s" % node.id, node.mean, node.stdev), node, input_vars) if log: result = sp.log(result) return result
def process(self): self.outputs['normal'] = stats.Normal(self.inputs['name'], self.inputs['mean'], self.inputs['variance']) return super().process()
def test_fit_hyperpriors(self): # carry out fit S = bl.ChangepointStudy() S.loadData(np.array([1, 2, 3, 4, 5])) S.setOM( bl.om.Gaussian('mean', bl.cint(0, 6, 20), 'sigma', bl.oint(0, 2, 20), prior=lambda m, s: 1 / s**3)) T = bl.tm.SerialTransitionModel( bl.tm.Static(), bl.tm.ChangePoint('ChangePoint', [0, 1], prior=np.array([0.3, 0.7])), bl.tm.CombinedTransitionModel( bl.tm.GaussianRandomWalk('sigma', bl.oint(0, 0.2, 2), target='mean', prior=lambda s: 1. / s), bl.tm.RegimeSwitch('log10pMin', [-3, -1])), bl.tm.BreakPoint('BreakPoint', 'all', prior=stats.Normal('Normal', 3., 1.)), bl.tm.Static()) S.setTM(T) S.fit() # test parameter distributions np.testing.assert_allclose( S.getParameterDistributions('mean', density=False)[1][:, 5], [0.03372851, 0.05087598, 0.02024129, 0.00020918, 0.00020918], rtol=1e-04, err_msg='Erroneous posterior distribution values.') # test parameter mean values np.testing.assert_allclose( S.getParameterMeanValues('mean'), [0.9894398, 1.92805399, 3.33966456, 4.28759449, 4.28759449], rtol=1e-05, err_msg='Erroneous posterior mean values.') # test model evidence value np.testing.assert_almost_equal(S.logEvidence, -15.709534690217343, decimal=5, err_msg='Erroneous log-evidence value.') # test hyper-parameter distribution x, p = S.getHyperParameterDistribution('sigma') np.testing.assert_allclose( np.array([x, p]), [[0.06666667, 0.13333333], [0.66515107, 0.33484893]], rtol=1e-05, err_msg='Erroneous values in hyper-parameter distribution.') # test duration distribution d, p = S.getDurationDistribution(['ChangePoint', 'BreakPoint']) np.testing.assert_allclose( np.array([d, p]), [[1., 2., 3.], [0.00373717, 0.40402616, 0.59223667]], rtol=1e-05, err_msg='Erroneous values in duration distribution.')
def test_prob(): def emit(name, iname, cdf, args, no_small=False): V = [] for arg in sorted(args): y = cdf(*arg) if isinstance(y, mpf): e = sp.nsimplify(y, rational=True) if e.is_Rational and e.q <= 1000 and \ mp.almosteq(mp.mpf(e), y, 1e-25): y = e else: y = N(y) V.append(arg + (y, )) for v in V: if name: test(name, *v) for v in V: if iname and (not no_small or 1 / 1000 <= v[-1] <= 999 / 1000): test(iname, *(v[:-2] + v[:-3:-1])) x = sp.Symbol("x") emit("ncdf", "nicdf", sp.Lambda(x, st.cdf(st.Normal("X", 0, 1))(x)), zip(exparg)) # using cdf() for anything more complex is too slow df = FiniteSet(1, S(3) / 2, 2, S(5) / 2, 5, 25) emit("c2cdf", "c2icdf", lambda k, x: sp.lowergamma(k / 2, x / 2) / sp.gamma(k / 2), ProductSet(df, posarg), no_small=True) dfint = df & sp.fancysets.Naturals() def cdf(k, x): k, x = map(mpf, (k, x)) return .5 + .5 * mp.sign(x) * mp.betainc( k / 2, .5, x1=1 / (1 + x**2 / k), regularized=True) emit("stcdf", "sticdf", cdf, ProductSet(dfint, exparg)) def cdf(d1, d2, x): d1, d2, x = map(mpf, (d1, d2, x)) return mp.betainc(d1 / 2, d2 / 2, x2=x / (x + d2 / d1), regularized=True) emit("fcdf", "ficdf", cdf, ProductSet(dfint, dfint, posarg)) kth = ProductSet(sp.ImageSet(lambda x: x / 5, df), posarg - FiniteSet(0)) emit("gcdf", "gicdf", lambda k, th, x: sp.lowergamma(k, x / th) / sp.gamma(k), ProductSet(kth, posarg), no_small=True) karg = FiniteSet(0, 1, 2, 5, 10, 15, 40) knparg = [(k, n, p) for k, n, p in ProductSet(karg, karg, posarg & Interval(0, 1, True, True)) if k <= n and n > 0] def cdf(k, n, p): return st.P(st.Binomial("X", n, p) <= k) emit("bncdf", "bnicdf", cdf, knparg, no_small=True) def cdf(k, lamda): return sp.uppergamma(k + 1, lamda) / sp.gamma(k + 1) emit("pscdf", "psicdf", cdf, ProductSet(karg, posarg + karg - FiniteSet(0)), no_small=True) x, i = sp.symbols("x i") def smcdf(n, e): return 1 - sp.Sum( sp.binomial(n, i) * e * (e + i / n)**(i - 1) * (1 - e - i / n)**(n - i), (i, 0, sp.floor(n * (1 - e)))).doit() kcdf = sp.Lambda( x, sp.sqrt(2 * pi) / x * sp.Sum(sp.exp(-pi**2 / 8 * (2 * i - 1)**2 / x**2), (i, 1, oo))) smarg = ProductSet(karg - FiniteSet(0), posarg & Interval(0, 1, True, True)) karg = FiniteSet(S(1) / 100, S(1) / 10) + (posarg & Interval(S(1) / 4, oo, True)) for n, e in sorted(smarg): test("smcdf", n, e, N(smcdf(n, e))) prec("1e-10") for x in sorted(karg): test("kcdf", x, N(kcdf(x))) prec("1e-9") for n, e in sorted(smarg): p = smcdf(n, e) if p < S(9) / 10: test("smicdf", n, N(p), e) prec("1e-6") for x in sorted(karg): p = kcdf(x) if N(p) > S(10)**-8: test("kicdf", N(p), x)
def JointNormalSeparate(names, mean, cov): """Conveniently create a joint normal distribution and create separate random variables""" x = stats.Normal('__DUMMY__', mean, cov) rvs = [JointDistributionSeparate(name, x) for name in names] return rvs