Пример #1
0
def medium_blp_simulation() -> SimulationFixture:
    """Solve a simulation with four markets, linear/nonlinear/cost constants, two linear characteristics, two cost
    characteristics, a demographic interacted with second-degree prices, and an alternative ownership structure.
    """
    id_data = build_id_data(T=4, J=25, F=6)
    simulation = Simulation(
        product_formulations=(Formulation('1 + x + y'),
                              Formulation('1 + I(prices ** 2)'),
                              Formulation('1 + a + b')),
        beta=[1, 2, 1],
        sigma=[
            [0.5, 0],
            [0.0, 0],
        ],
        gamma=[1, 1, 2],
        product_data={
            'market_ids':
            id_data.market_ids,
            'firm_ids':
            id_data.firm_ids,
            'clustering_ids':
            np.random.RandomState(1).choice(range(20), id_data.size),
            'ownership':
            build_ownership(
                id_data, lambda f, g: 1
                if f == g else (0.1 if f > 3 and g > 3 else 0))
        },
        agent_formulation=Formulation('0 + f'),
        pi=[[+0], [-3]],
        integration=Integration('product', 4),
        xi_variance=0.0001,
        omega_variance=0.0001,
        correlation=0.8,
        seed=1)
    return simulation, simulation.solve()
Пример #2
0
def medium_simulation():
    """Solve a simulation with four markets, a nonlinear/cost constant, two linear characteristics, two cost
    characteristics, a demographic interacted with prices, a double acquisition, and a non-standard ownership structure.
    """
    id_data = build_id_data(T=4, J=25, F=6, mergers=[{f: 2 for f in range(2)}])
    simulation = Simulation(
        product_formulations=(
            Formulation('0 + x + y'),
            Formulation('1 + prices'),
            Formulation('1 + a + b')
        ),
        beta=[2, 1],
        sigma=[
            [0.5, 0],
            [0,   0],
        ],
        gamma=[1, 1, 2],
        product_data={
            'market_ids': id_data.market_ids,
            'firm_ids': id_data.firm_ids,
            'ownership': build_ownership(id_data, lambda f, g: 1 if f == g else (0.1 if f > 3 and g > 3 else 0))
        },
        agent_formulation=Formulation('0 + f'),
        pi=[
            [ 0],
            [-3]
        ],
        integration=Integration('product', 4),
        xi_variance=0.0001,
        omega_variance=0.0001,
        correlation=0.8,
        seed=1
    )
    return simulation, simulation.solve()
Пример #3
0
def test_merger(simulated_problem: SimulatedProblemFixture, ownership: bool,
                compute_prices_options: Options) -> None:
    """Test that prices and shares simulated under changed firm IDs are reasonably close to prices and shares computed
    from the results of a solved problem. In particular, test that unchanged prices and shares are farther from their
    simulated counterparts than those computed by approximating a merger, which in turn are farther from their simulated
    counterparts than those computed by fully solving a merger. Also test that simple acquisitions increase HHI. These
    inequalities are only guaranteed because of the way in which the simulations are configured.
    """
    simulation, simulation_results, _, _, results = simulated_problem

    # create changed ownership or firm IDs associated with a merger
    merger_ids = merger_ownership = None
    product_data = simulation_results.product_data
    if ownership:
        merger_ownership = build_ownership(
            product_data, lambda f, g: 1 if f == g or (f < 2 and g < 2) else 0)
    else:
        merger_ids = np.where(product_data.firm_ids < 2, 0,
                              product_data.firm_ids)

    # get changed prices and shares
    changed_product_data = simulation.solve(merger_ids,
                                            merger_ownership).product_data

    # solve for approximate and actual changed prices and shares
    approximated_prices = results.compute_approximate_prices(
        merger_ids, merger_ownership)
    estimated_prices = results.compute_prices(merger_ids, merger_ownership,
                                              **compute_prices_options)
    approximated_shares = results.compute_shares(approximated_prices)
    estimated_shares = results.compute_shares(estimated_prices)

    # test that estimated prices are closer to changed prices than approximate prices
    approximated_prices_error = np.linalg.norm(changed_product_data.prices -
                                               approximated_prices)
    estimated_prices_error = np.linalg.norm(changed_product_data.prices -
                                            estimated_prices)
    np.testing.assert_array_less(estimated_prices_error,
                                 approximated_prices_error,
                                 verbose=True)

    # test that estimated shares are closer to changed shares than approximate shares
    approximated_shares_error = np.linalg.norm(changed_product_data.shares -
                                               approximated_shares)
    estimated_shares_error = np.linalg.norm(changed_product_data.shares -
                                            estimated_shares)
    np.testing.assert_array_less(estimated_shares_error,
                                 approximated_shares_error,
                                 verbose=True)

    # test that median HHI increases
    if not ownership:
        hhi = results.compute_hhi()
        changed_hhi = results.compute_hhi(merger_ids, estimated_shares)
        np.testing.assert_array_less(np.median(hhi),
                                     np.median(changed_hhi),
                                     verbose=True)
Пример #4
0
def medium_blp_simulation() -> SimulationFixture:
    """Solve a simulation with four markets, linear/nonlinear/cost constants, two linear characteristics, two cost
    characteristics, a demographic interacted with second-degree prices, an alternative ownership structure, and a
    scaled epsilon.
    """
    id_data = build_id_data(T=10, J=25, F=6)
    simulation = Simulation(
        product_formulations=(Formulation('1 + x + prices'),
                              Formulation('1 + I(prices**2)'),
                              Formulation('1 + a + b')),
        product_data={
            'market_ids':
            id_data.market_ids,
            'firm_ids':
            id_data.firm_ids,
            'clustering_ids':
            np.random.RandomState(1).choice(range(20), id_data.size),
            'ownership':
            build_ownership(
                id_data, lambda f, g: 1
                if f == g else (0.1 if f > 3 and g > 3 else 0))
        },
        beta=[1, 2, -3],
        sigma=[
            [0.5, 0],
            [0.0, 0],
        ],
        pi=[[+0.0], [-0.1]],
        gamma=[1, 1, 2],
        agent_formulation=Formulation('0 + f'),
        integration=Integration('product', 4),
        xi_variance=0.00001,
        omega_variance=0.00001,
        correlation=0.8,
        epsilon_scale=0.7,
        seed=1,
    )
    simulation_results = simulation.replace_endogenous()

    simulated_micro_moments = simulation_results.replace_micro_moment_values([
        MicroMoment(
            name="demographic interaction",
            dataset=MicroDataset(
                name="inside",
                observations=simulation.N,
                compute_weights=lambda _, p, a: np.ones((a.size, p.size)),
                market_ids=[simulation.unique_market_ids[2]],
            ),
            value=0,
            compute_values=lambda _, p, a: p.X2[:, [0]].T * a.
            demographics[:, [0]],
        )
    ])

    return simulation, simulation_results, {}, simulated_micro_moments
Пример #5
0
def test_merger(simulated_problem: SimulatedProblemFixture, ownership: bool, solve_options: Options) -> None:
    """Test that prices and shares simulated under changed firm IDs are reasonably close to prices and shares computed
    from the results of a solved problem. In particular, test that unchanged prices and shares are farther from their
    simulated counterparts than those computed by approximating a merger, which in turn are farther from their simulated
    counterparts than those computed by fully solving a merger. Also test that simple acquisitions increase HHI. These
    inequalities are only guaranteed because of the way in which the simulations are configured. Finally, test that we
    get the same results when we initialize a solve a simulation instead of using the convenient results methods.
    """
    simulation, simulation_results, problem, _, results = simulated_problem

    # create changed ownership or firm IDs associated with a merger
    merger_ids = merger_ownership = None
    product_data = simulation_results.product_data
    if ownership:
        merger_ownership = build_ownership(product_data, lambda f, g: 1 if f == g or (f < 2 and g < 2) else 0)
    else:
        merger_ids = np.where(product_data.firm_ids < 2, 0, product_data.firm_ids)

    # get changed prices and shares
    changed_product_data = simulation.solve(merger_ids, merger_ownership).product_data

    # compute marginal costs and create a simulation with the results
    costs = results.compute_costs()
    results_simulation = Simulation(
        product_formulations=simulation.product_formulations[:2], product_data=simulation_results.product_data,
        beta=results.beta, sigma=results.sigma, pi=results.pi, rho=results.rho,
        agent_formulation=simulation.agent_formulation, agent_data=simulation.agent_data, xi=results.xi, costs=costs
    )

    # solve for actual and approximate changed prices and shares
    estimated = results_simulation.solve(merger_ids, merger_ownership, problem.products.prices, **solve_options)
    estimated_prices = results.compute_prices(merger_ids, merger_ownership, costs, **solve_options)
    approximated_prices = results.compute_approximate_prices(merger_ids, merger_ownership, costs)
    estimated_shares = results.compute_shares(estimated_prices)
    approximated_shares = results.compute_shares(approximated_prices)

    # test that estimated prices are closer to changed prices than approximate prices
    approximated_prices_error = np.linalg.norm(changed_product_data.prices - approximated_prices)
    estimated_prices_error = np.linalg.norm(changed_product_data.prices - estimated_prices)
    np.testing.assert_array_less(estimated_prices_error, approximated_prices_error, verbose=True)

    # test that estimated shares are closer to changed shares than approximate shares
    approximated_shares_error = np.linalg.norm(changed_product_data.shares - approximated_shares)
    estimated_shares_error = np.linalg.norm(changed_product_data.shares - estimated_shares)
    np.testing.assert_array_less(estimated_shares_error, approximated_shares_error, verbose=True)

    # test that median HHI increases
    if not ownership:
        hhi = results.compute_hhi()
        changed_hhi = results.compute_hhi(merger_ids, estimated_shares)
        np.testing.assert_array_less(np.median(hhi), np.median(changed_hhi), verbose=True)

    # test that we get the same results from solving the simulation
    np.testing.assert_allclose(estimated_prices, estimated.product_data.prices, atol=1e-14, rtol=0, verbose=True)
    np.testing.assert_allclose(estimated_shares, estimated.product_data.shares, atol=1e-14, rtol=0, verbose=True)
Пример #6
0
def medium_blp_simulation() -> SimulationFixture:
    """Solve a simulation with four markets, linear/nonlinear/cost constants, two linear characteristics, two cost
    characteristics, a demographic interacted with second-degree prices, an alternative ownership structure, and a
    scaled epsilon.
    """
    id_data = build_id_data(T=4, J=25, F=6)
    simulation = Simulation(
        product_formulations=(Formulation('1 + x + y'),
                              Formulation('1 + I(prices**2)'),
                              Formulation('1 + a + b')),
        product_data={
            'market_ids':
            id_data.market_ids,
            'firm_ids':
            id_data.firm_ids,
            'clustering_ids':
            np.random.RandomState(1).choice(range(20), id_data.size),
            'ownership':
            build_ownership(
                id_data, lambda f, g: 1
                if f == g else (0.1 if f > 3 and g > 3 else 0))
        },
        beta=[1, 2, 1],
        sigma=[
            [0.5, 0],
            [0.0, 0],
        ],
        pi=[[+0], [-3]],
        gamma=[1, 1, 2],
        agent_formulation=Formulation('0 + f'),
        integration=Integration('product', 4),
        xi_variance=0.0001,
        omega_variance=0.0001,
        correlation=0.8,
        epsilon_scale=0.7,
        seed=1,
    )
    simulation_results = simulation.replace_endogenous()
    simulated_micro_moments = [
        DemographicCovarianceMoment(
            X2_index=0,
            demographics_index=0,
            value=0,
            observations=simulation.N,
            market_ids=[simulation.unique_market_ids[2]])
    ]
    return simulation, simulation_results, {}, simulated_micro_moments