def test_mc_integration(chunksize, limits): # simpel example zfit.run.chunking.active = True zfit.run.chunking.max_n_points = chunksize num_integral = zintegrate.mc_integrate(func=func1_5deps, limits=Space(limits=limits_simple_5deps, axes=tuple(range(5))), n_axes=5) if isinstance(limits, list): spaces = [Space(limits=limit, axes=tuple(range(1))) for limit in limits] space2 = spaces[0] + spaces[1] else: space2 = Space(limits=limits2, axes=tuple(range(1))) num_integral2 = zintegrate.mc_integrate(func=func2_1deps, limits=space2, n_axes=1) num_integral3 = zintegrate.mc_integrate(func=func3_2deps, limits=Space(limits=limits3, axes=(0, 1)), n_axes=2) integral = num_integral.numpy() integral2 = num_integral2.numpy() integral3 = num_integral3.numpy() assert integral.shape == (1,) assert integral2.shape == (1,) assert integral3.shape == (1,) assert func1_5deps_fully_integrated(limits_simple_5deps) == pytest.approx(integral, rel=0.1) assert func2_1deps_fully_integrated(limits2) == pytest.approx(integral2, rel=0.03) assert func3_2deps_fully_integrated( Space(limits=limits3, axes=(0, 1))).numpy() == pytest.approx(integral3, rel=0.03)
def test_mc_partial_integration(): values = z.convert_to_tensor(func4_values) data1 = zfit.Data.from_tensor(obs='obs2', tensor=tf.expand_dims(values, axis=-1)) limits1 = Space(limits=limits4_2dim, obs=['obs1', 'obs3'], axes=(0, 2)) num_integral = zintegrate.mc_integrate(x=data1, func=func4_3deps, limits=limits1) vals_tensor = z.convert_to_tensor(func4_2values) vals_reshaped = tf.transpose(a=vals_tensor) data2 = zfit.Data.from_tensor(obs=['obs1', 'obs3'], tensor=vals_reshaped) limits2 = Space(limits=limits4_1dim, obs=['obs2'], axes=1) num_integral2 = zintegrate.mc_integrate(x=data2, func=func4_3deps, limits=limits2, draws_per_dim=100) integral = num_integral.numpy() integral2 = num_integral2.numpy() # print("DEBUG", value:", vals_reshaped) assert len(integral) == len(func4_values) assert len(integral2) == len(func4_2values[0]) assert func4_3deps_0and2_integrated( x=func4_values, limits=limits4_2dim) == pytest.approx(integral, rel=0.05) assert func4_3deps_1_integrated( x=func4_2values, limits=limits4_1dim) == pytest.approx(integral2, rel=0.05)
def test_analytic_integral(): class DistFunc3(zbasepdf.BasePDF): def _unnormalized_pdf(self, x): return func3_2deps(x) mu_true = 1.4 sigma_true = 1.8 limits = -4.3, 1.9 mu = Parameter("mu_1414", mu_true, mu_true - 2., mu_true + 7.) sigma = Parameter("sigma_1414", sigma_true, sigma_true - 10., sigma_true + 5.) gauss_params1 = CustomGaussOLD(mu=mu, sigma=sigma, obs=obs1, name="gauss_params1") normal_params1 = Gauss(mu=mu, sigma=sigma, obs=obs1, name="gauss_params1") try: infinity = mt.inf except AttributeError: # py34 infinity = float('inf') gauss_integral_infs = gauss_params1.integrate(limits=(-8 * sigma_true, 8 * sigma_true), norm_range=False) normal_integral_infs = normal_params1.integrate(limits=(-8 * sigma_true, 8 * sigma_true), norm_range=False) DistFunc3.register_analytic_integral(func=func3_2deps_fully_integrated, limits=Space(limits=limits3, axes=(0, 1))) dist_func3 = DistFunc3(obs=['obs1', 'obs2']) normal_integral_infs = normal_integral_infs func3_integrated = dist_func3.integrate(limits=Space(limits=limits3, axes=(0, 1)), norm_range=False).numpy() assert func3_integrated == pytest.approx( func3_2deps_fully_integrated(limits=Space(limits=limits3, axes=(0, 1))).numpy()) assert gauss_integral_infs.numpy() == pytest.approx(np.sqrt(np.pi * 2.) * sigma_true, rel=0.0001) assert normal_integral_infs.numpy() == pytest.approx(1, rel=0.0001)
def test_sub_space(): sub_space2_true_axes = Space(axes=sub_limit2_axes, limits=sub_limit2) assert sub_space2_true_axes == space2_subbed_axes sub_space2_true = Space(obs=sub_limit2_obs, limits=sub_limit2) space2_subbed = space2_obs.get_subspace(obs=sub_limit2_obs) assert space2_subbed == sub_space2_true
def test_add(): param1 = zfit.Parameter("param1", 1.) param2 = zfit.Parameter("param2", 2.) pdfs = [0] * 4 pdfs[0] = Gauss(param1, 4, obs=obs1) pdfs[1] = Gauss(param2, 5, obs=obs1) pdfs[2] = Gauss(3, 6, obs=obs1) pdfs[3] = Gauss(4, 7, obs=obs1) datas = [0] * 4 datas[0] = z.constant(1.) datas[1] = z.constant(2.) datas[2] = z.constant(3.) datas[3] = z.constant(4.) ranges = [0] * 4 ranges[0] = (1, 4) ranges[1] = Space(limits=(2, 5), obs=obs1) ranges[2] = Space(limits=(3, 6), obs=obs1) ranges[3] = Space(limits=(4, 7), obs=obs1) constraint1 = zfit.constraint.nll_gaussian(params=param1, observation=1., uncertainty=0.5) constraint2 = zfit.constraint.nll_gaussian(params=param2, observation=2., uncertainty=0.25) merged_contraints = [constraint1, constraint2] nll1 = UnbinnedNLL(model=pdfs[0], data=datas[0], fit_range=ranges[0], constraints=constraint1) nll2 = UnbinnedNLL(model=pdfs[1], data=datas[1], fit_range=ranges[1], constraints=constraint2) nll3 = UnbinnedNLL(model=[pdfs[2], pdfs[3]], data=[datas[2], datas[3]], fit_range=[ranges[2], ranges[3]]) simult_nll = nll1 + nll2 + nll3 assert simult_nll.model == pdfs assert simult_nll.data == datas ranges[0] = Space( limits=ranges[0], obs='obs1', axes=(0, )) # for comparison, Space can only compare with Space ranges[1].coords._axes = (0, ) ranges[2].coords._axes = (0, ) ranges[3].coords._axes = (0, ) assert simult_nll.fit_range == ranges def eval_constraint(constraints): return z.reduce_sum([c.value() for c in constraints]).numpy() assert eval_constraint( simult_nll.constraints) == eval_constraint(merged_contraints)
def normalization_testing(pdf, limits=None): limits = (low, high) if limits is None else limits space = Space(obs=obs1, limits=limits) with pdf.set_norm_range(space): samples = tf.cast(np.random.uniform(low=space.lower, high=space.upper, size=(40000, pdf.n_obs)), dtype=tf.float64) samples = zfit.Data.from_tensor(obs=space, tensor=samples) probs = pdf.pdf(samples) result = probs.numpy() result = zfit.run(np.average(result) * space.rect_area()) assert pytest.approx(result, rel=0.03) == 1
def test_extract_limits(): obs1 = ['a'] space1 = Space('a', (0, 1)) obs2 = ['b', 'c'] limit2 = Limit(limit_fn=lambda x: x, rect_limits=([1, 2], [2, 3]), n_obs=2) obs3 = ['d', 'e', 'f'] limits3_dict = { 'obs': {ob: Limit((i, i + 10)) for i, ob in enumerate(obs3)} } space3 = Space(obs3, limits=limits3_dict) limits_dict = { 'obs': { tuple(obs1): space1, tuple(obs2): limit2, tuple(obs3): space3, } } space = Space(obs1 + obs2 + obs3, limits_dict) extracted_limits = space.get_limits(obs1)['obs'] assert list(extracted_limits.values())[0] == space1 extracted_limits = space.get_limits(obs2)['obs'] assert list(extracted_limits.values())[0] == limit2 extracted_limits = space.get_limits(obs3)['obs'] assert list(extracted_limits.values())[0] == space3 extracted_limits = space.get_limits(obs3[0])
def test_extract_limits(): obs1 = ["a"] space1 = Space("a", (0, 1)) obs2 = ["b", "c"] limit2 = Limit(limit_fn=lambda x: x, rect_limits=([1, 2], [2, 3]), n_obs=2) obs3 = ["d", "e", "f"] limits3_dict = { "obs": {ob: Limit((i, i + 10)) for i, ob in enumerate(obs3)} } space3 = Space(obs3, limits=limits3_dict) limits_dict = { "obs": { tuple(obs1): space1, tuple(obs2): limit2, tuple(obs3): space3, } } space = Space(obs1 + obs2 + obs3, limits_dict) extracted_limits = space.get_limits(obs1)["obs"] assert list(extracted_limits.values())[0] == space1 extracted_limits = space.get_limits(obs2)["obs"] assert list(extracted_limits.values())[0] == limit2 extracted_limits = space.get_limits(obs3)["obs"] assert list(extracted_limits.values())[0] == space3 extracted_limits = space.get_limits(obs3[0])
def test_multiple_limits(): gauss_params1 = create_gauss1() dims = (0, ) simple_limits = (-3.2, 9.1) multiple_limits_lower = ((-3.2, ), (1.1, ), (2.1, )) multiple_limits_upper = ((1.1, ), (2.1, ), (9.1, )) multiple_limits_range = MultiSpace([ Space(limits=(low, up), axes=dims) for low, up in zip(multiple_limits_lower, multiple_limits_upper) ]) integral_simp = gauss_params1.integrate(limits=simple_limits, norm_range=False) integral_mult = gauss_params1.integrate(limits=multiple_limits_range, norm_range=False) integral_simp_num = gauss_params1.numeric_integrate(limits=simple_limits, norm_range=False) integral_mult_num = gauss_params1.numeric_integrate( limits=multiple_limits_range, norm_range=False) integral_simp, integral_mult = [ integral_simp.numpy(), integral_mult.numpy() ] integral_simp_num, integral_mult_num = [ integral_simp_num.numpy(), integral_mult_num.numpy() ] assert integral_simp == pytest.approx( integral_mult, rel=1e-2) # big tolerance as mc is used assert integral_simp == pytest.approx( integral_simp_num, rel=1e-2) # big tolerance as mc is used assert integral_simp_num == pytest.approx( integral_mult_num, rel=1e-2) # big tolerance as mc is used
def probs_4d(values): true_prob = [gauss1.pdf(values[:, 3])] true_prob += [gauss2.pdf(values[:, 0])] true_prob += [gauss3.pdf(values[:, 2])] true_prob += [prod_gauss_3d.pdf(values[:, 0:3], norm_range=Space(limits=(((-5,) * 3,), ((4,) * 3,)), obs=['obs1', 'obs2', 'obs3']))] return tf.math.reduce_prod(true_prob, axis=0)
def test_prod_gauss_nd_mixed(): norm = (-5, 4) low, high = norm test_values = np.random.uniform(low=low, high=high, size=(1000, 4)) obs4d = ["obs1", "obs2", "obs3", "obs4"] test_values_data = Data.from_tensor(obs=obs4d, tensor=test_values) limits_4d = Space(limits=(((-5, ) * 4, ), ((4, ) * 4, )), obs=obs4d) prod_gauss_4d = product_gauss_4d() prod_gauss_4d.set_norm_range(limits_4d) probs = prod_gauss_4d.pdf(x=test_values_data, norm=limits_4d) gausses = create_gaussians() for gauss in gausses: gauss.set_norm_range(norm) gauss1, gauss2, gauss3 = gausses prod_gauss_3d = product_gauss_3d() def probs_4d(values): true_prob = [gauss1.pdf(values[:, 3])] true_prob += [gauss2.pdf(values[:, 0])] true_prob += [gauss3.pdf(values[:, 2])] true_prob += [ prod_gauss_3d.pdf( values[:, 0:3], norm=Space(limits=(((-5, ) * 3, ), ((4, ) * 3, )), obs=["obs1", "obs2", "obs3"]), ) ] return tf.math.reduce_prod(true_prob, axis=0) true_unnormalized_probs = probs_4d(values=test_values) normalization_probs = limits_4d.area() * probs_4d( tf.random.uniform(minval=low, maxval=high, shape=(40**4, 4))) true_probs = true_unnormalized_probs / tf.reduce_mean( input_tensor=normalization_probs) probs_np = probs.numpy() true_probs_np = true_probs.numpy() assert np.average(probs_np * limits_4d.area()) == pytest.approx( 1.0, rel=0.33) # low n mc np.testing.assert_allclose(true_probs_np, probs_np, rtol=2e-2)
def probs_4d(values): true_prob = [gauss1.pdf(values[:, 3])] true_prob += [gauss2.pdf(values[:, 0])] true_prob += [gauss3.pdf(values[:, 2])] true_prob += [ prod_gauss_3d.pdf( values[:, 0:3], norm=Space(limits=(((-5, ) * 3, ), ((4, ) * 3, )), obs=["obs1", "obs2", "obs3"]), ) ] return tf.math.reduce_prod(true_prob, axis=0)
def test_rect_limits(): obs1 = ['a'] axes1 = [0] space1 = Space('a', (0, 1)) space1_nolim = Space('a') assert not space1_nolim.has_limits assert space1.has_limits assert space1.has_rect_limits space1_lim = space1_nolim.with_limits((0, 1)) space1_ax = Space(axes=0, limits=(0, 1)) lower, upper = space1.rect_limits assert lower == 0 assert upper == 1 lower, upper = space1_ax.rect_limits assert lower == 0 assert upper == 1 lower, upper = space1_lim.rect_limits assert lower == 0 assert upper == 1
def test_analytic_integral_selection(): class DistFuncInts(zbasepdf.BasePDF): def _unnormalized_pdf(self, x): return x ** 2 int1 = lambda x: 1 # on purpose wrong signature but irrelevant (not called, only test bookkeeping) int2 = lambda x: 2 int22 = lambda x: 22 int3 = lambda x: 3 int4 = lambda x: 4 int5 = lambda x: 5 limits1 = (-1, 5) dims1 = (1,) limits1 = Space(axes=dims1, limits=limits1) limits2 = (Space.ANY_LOWER, 5) dims2 = (1,) limits2 = Space(axes=dims2, limits=limits2) limits3 = ((Space.ANY_LOWER, 1),), ((Space.ANY_UPPER, 5),) dims3 = (0, 1) limits3 = Space(axes=dims3, limits=limits3) limits4 = (((Space.ANY_LOWER, 0, Space.ANY_LOWER),), ((Space.ANY_UPPER, 5, 42),)) dims4 = (0, 1, 2) limits4 = Space(axes=dims4, limits=limits4) limits5 = (((Space.ANY_LOWER, 1),), ((10, Space.ANY_UPPER),)) dims5 = (1, 2) limits5 = Space(axes=dims5, limits=limits5) DistFuncInts.register_analytic_integral(int1, limits=limits1) DistFuncInts.register_analytic_integral(int2, limits=limits2) DistFuncInts.register_analytic_integral(int22, limits=limits2, priority=60) DistFuncInts.register_analytic_integral(int3, limits=limits3) DistFuncInts.register_analytic_integral(int4, limits=limits4) DistFuncInts.register_analytic_integral(int5, limits=limits5) dims = DistFuncInts._analytic_integral.get_max_axes(limits=Space(limits=(((-5, 1),), ((1, 5),)), axes=dims3)) assert dims3 == dims
def test_dimensions(): lower1, lower2 = 1, 2 upper1, upper2 = 2, 3 space = Space( obs=["obs1", "obs2"], limits=(((lower1, lower2),), ((upper1, upper2),)) ) assert space.n_obs == 2 assert space.n_limits == 1 low1, low2, up1, up2 = space.limit2d assert low1 == lower1 assert low2 == lower2 assert up1 == upper1 assert up2 == upper2 with pytest.raises(RuntimeError): space.limit1d with pytest.raises(LimitsIncompatibleError): _ = Space(obs="obs1", limits=(((1,), (2,)), ((2,), (3,)))) space = Space(obs=["obs1", "obs2"], limits=(((1, 5),), ((2, 13),))) assert space.n_obs == 2 with pytest.raises(RuntimeError): space.limit1d space = Space(obs="obs1", limits=(((1,),), ((2,),))) assert space.n_obs == 1 assert space.n_limits == 1 lower1 = 1 upper1 = 2 space = Space(axes=(1,), limits=(((lower1,),), ((upper1,),))) assert space.n_obs == 1 assert space.n_limits == 1 lower, upper = space.limit1d assert lower == lower1 assert upper == upper1
def test_setting_axes(space, obs): """ Args: space: obs: """ lower, upper = space.rect_limits axes = space.axes new_obs = list(copy.deepcopy(obs)) while len(obs) > 1 and new_obs == list(obs): random.shuffle(new_obs) new_obs = tuple(new_obs) true_lower = np.array( tuple(tuple(low[obs.index(o)] for o in new_obs) for low in lower) ) true_upper = np.array( tuple(tuple(up[obs.index(o)] for o in new_obs) for up in upper) ) new_axes = tuple(range(len(new_obs))) coords = Space(obs=new_obs, axes=new_axes) # obs_axes = OrderedDict((o, ax) for o, ax in zip(new_obs, new_axes)) if len(obs) > 1: # make sure it was shuffled assert new_obs != obs assert new_axes != axes assert np.any(true_lower != lower) assert np.any(true_upper != upper) new_space = space.with_coords(coords) # check new object assert new_axes == new_space.axes assert new_obs == new_space.obs assert np.all(true_lower == new_space.lower) assert np.all(true_upper == new_space.upper) # check that old object didn't change assert axes == space.axes assert obs == space.obs assert np.all(lower == space.lower) assert np.all(upper == space.upper) assert axes == space.axes assert obs == space.obs assert np.all(lower == space.lower) assert np.all(upper == space.upper)
def test_exception(): invalid_obs = (1, 4) with pytest.raises(TypeError): Space(obs=invalid_obs) with pytest.raises(CoordinatesUnderdefinedError): Space(obs=None, limits=limit2) with pytest.raises(CoordinatesUnderdefinedError): Space(axes=None, limits=limit2) with pytest.raises(ShapeIncompatibleError): # one obs only, but two dims Space(obs="obs1", limits=(((1, 2),), ((2, 3),))) with pytest.raises(ShapeIncompatibleError): # two obs but only 1 dim Space(obs=["obs1", "obs2"], limits=(((1,),), ((2,),))) with pytest.raises(ShapeIncompatibleError): # one axis but two dims Space(axes=(1,), limits=(((1, 2),), ((2, 3),))) with pytest.raises(ShapeIncompatibleError): # two axes but only 1 dim Space(axes=(1, 2), limits=(((1,),), ((2,),)))
def test_analytic_sampling(): class SampleGauss(TmpGaussian): pass SampleGauss.register_analytic_integral(func=lambda limits, params, model: 2 * limits.upper[0][0], limits=Space(limits=(-float("inf"), ANY_UPPER), axes=(0,))) # DUMMY! SampleGauss.register_inverse_analytic_integral(func=lambda x, params: x + 1000.) mu, sigma = create_mu_sigma_true_params() gauss1 = SampleGauss(obs=obs1, mu=mu, sigma=sigma) sample = gauss1.sample(n=10000, limits=(2., 5.)) sample.set_data_range((1002, 1005)) sample = sample.numpy() assert 1004. <= min(sample[0]) assert 10010. >= max(sample[0])
def test_normalization(pdf_factory): test_yield = 1524.3 dist = pdf_factory() samples = tf.cast(np.random.uniform(low=low, high=high, size=100000), dtype=tf.float64) small_samples = tf.cast(np.random.uniform(low=low, high=high, size=10), dtype=tf.float64) with dist.set_norm_range(Space(obs1, limits=(low, high))): probs = dist.pdf(samples) probs_small = dist.pdf(small_samples) log_probs = dist.log_pdf(small_samples) probs, log_probs = probs.numpy(), log_probs.numpy() probs = np.average(probs) * (high - low) assert probs == pytest.approx(1., rel=0.05) assert log_probs == pytest.approx(tf.math.log(probs_small).numpy(), rel=0.05) dist = dist.create_extended(z.constant(test_yield)) probs = dist.pdf(samples) probs_extended = dist.ext_pdf(samples) result = probs.numpy() result = np.average(result) * (high - low) result_ext = np.average(probs_extended) * (high - low) assert result == pytest.approx(1, rel=0.05) assert result_ext == pytest.approx(test_yield, rel=0.05)
def test_analytic_integral(): class DistFunc3(BasePDF): def _unnormalized_pdf(self, x): return func3_2deps(x) class CustomGaussOLD(BasePDF): def __init__(self, mu, sigma, obs, name="Gauss"): super().__init__(name=name, obs=obs, params=dict(mu=mu, sigma=sigma)) def _unnormalized_pdf(self, x): x = x.unstack_x() mu = self.params["mu"] sigma = self.params["sigma"] gauss = znp.exp(-0.5 * tf.square((x - mu) / sigma)) return gauss def _gauss_integral_from_inf_to_inf(limits, params, model): return tf.sqrt(2 * znp.pi) * params["sigma"] CustomGaussOLD.register_analytic_integral( func=_gauss_integral_from_inf_to_inf, limits=Space(limits=(-np.inf, np.inf), axes=(0, )), ) mu_true = 1.4 sigma_true = 1.8 mu = Parameter("mu_1414", mu_true, mu_true - 2.0, mu_true + 7.0) sigma = Parameter("sigma_1414", sigma_true, sigma_true - 10.0, sigma_true + 5.0) gauss_params1 = CustomGaussOLD(mu=mu, sigma=sigma, obs=obs1, name="gauss_params1") normal_params1 = Gauss(mu=mu, sigma=sigma, obs=obs1, name="gauss_params1") gauss_integral_infs = gauss_params1.integrate(limits=(-8 * sigma_true, 8 * sigma_true), norm=False) normal_integral_infs = normal_params1.integrate( limits=(-8 * sigma_true, 8 * sigma_true), norm=False, ) DistFunc3.register_analytic_integral(func=func3_2deps_fully_integrated, limits=Space(limits=limits3, axes=(0, 1))) dist_func3 = DistFunc3(obs=["obs1", "obs2"]) normal_integral_infs = normal_integral_infs func3_integrated = dist_func3.integrate( limits=Space(limits=limits3, axes=(0, 1)), norm=False, ).numpy() assert func3_integrated == pytest.approx( func3_2deps_fully_integrated( limits=Space(limits=limits3, axes=(0, 1))).numpy()) assert gauss_integral_infs.numpy() == pytest.approx(np.sqrt(np.pi * 2.0) * sigma_true, rel=0.0001) assert normal_integral_infs.numpy() == pytest.approx(1, rel=0.0001)
coords1obs = Coordinates(obs1) coords1 = Coordinates(obs1, axes1) coords1mixed = Coordinates(obs1, axes2) coords1axes = Coordinates(axes=axes1) coords2obs = Coordinates(obs2) coords2 = Coordinates(obs2, axes2) coords2mixed = Coordinates(obs2, axes1) coords2axes = Coordinates(axes=axes2) limits1 = ([-2, -1, 0, 1, 2], [3, 4, 5, 6, 7]) limits2 = ([0, -1, 1, 2, -2], [5, 4, 6, 7, 3]) limits1limit = Limit(limits1, n_obs=5) limits2limit = Limit(limits2, n_obs=5) limits1space = Space(obs=obs1, axes=axes1, limits=limits1) limits2space = Space(obs=obs2, axes=axes2, limits=limits2) limit_fn = lambda x: x limits1func = Space(obs=obs1, axes=axes1, limits=limit_fn, rect_limits=limits1) limits2func = limits1func.with_obs(obs2) limits3 = ([11, 12, 13, 14, 15], [31, 41, 51, 61, 71]) limits4 = ([13, 12, 14, 15, 11], [51, 41, 61, 71, 31]) limits1vector = ([[-21, -11, -91, 11, 21], [-22, -12, -92, 12, 22], [-23, -13, -93, 13, 23]], [[31, 41, 51, 61, 71], [32, 42, 52, 62, 72], [33, 43, 53, 63, 73]]) limits2vector = ([[-91, -11, 11, 21, -21], [-92, -12, 12, 22, -22], [-93, -13, 13, 23, -23]], [[51, 41, 61, 71, 31],
lower12 = 4 upper11 = 3 upper12 = 7 limit11 = lower11, upper11 limit12 = lower12, upper12 limit11_true = copy.deepcopy(limit11) limit12_true = copy.deepcopy(limit12) limit11_area = 2 limit12_area = 3 limit11_axes = (1,) limit12_axes = (1,) limit11_obs = ("obs1",) limit12_obs = ("obs1",) limit11_axes_true = limit11_axes limit12_axes_true = limit12_axes space11 = Space(limits=limit11, axes=limit11_axes) space12 = Space(limits=limit12, axes=limit12_axes) space1 = space11 + space12 space11_obs = Space(obs=limit11_obs, limits=limit11) space12_obs = Space(obs=limit12_obs, limits=limit12) space1_obs = space11_obs + space12_obs # arguments1 = (space1, lower1, upper1, limit1_true, limit1_axes, limit1_areas, 2) arguments1 = [] lower2 = (1, 2, 3) upper2 = (2, 4, 6) sub_lower2 = (1, 3) sub_upper2 = (2, 6) limit2 = lower2, upper2 sub_limit2 = sub_lower2, sub_upper2 limit2_areas = (6, 18)