def simulated_problem(request: Any) -> SimulatedProblemFixture: """Configure and solve a simulated problem, either with or without supply-side data. Preclude overflow with rho bounds that are more conservative than the default ones. """ name, supply = request.param simulation, simulation_results, simulated_data_override, simulated_micro_moments = ( request.getfixturevalue(f'{name}_simulation') ) # override the simulated data product_data = None if simulated_data_override: product_data = update_matrices( simulation_results.product_data, {k: (v, v.dtype) for k, v in simulated_data_override.items()} ) # compute micro moments micro_moments: List[Any] = [] if simulated_micro_moments: micro_values = simulation_results.compute_micro(simulated_micro_moments) for moment, value in zip(simulated_micro_moments, micro_values): if isinstance(moment, DemographicExpectationMoment): micro_moments.append(DemographicExpectationMoment( moment.product_id, moment.demographics_index, value, moment.market_ids )) elif isinstance(moment, DemographicCovarianceMoment): micro_moments.append(DemographicCovarianceMoment( moment.X2_index, moment.demographics_index, value, moment.market_ids )) elif isinstance(moment, DiversionProbabilityMoment): micro_moments.append(DiversionProbabilityMoment( moment.product_id1, moment.product_id2, value, moment.market_ids )) else: assert isinstance(moment, DiversionCovarianceMoment) micro_moments.append(DiversionCovarianceMoment( moment.X2_index1, moment.X2_index2, value, moment.market_ids )) # initialize and solve the problem problem = simulation_results.to_problem(simulation.product_formulations[:2 + int(supply)], product_data) solve_options = { 'sigma': simulation.sigma, 'pi': simulation.pi, 'rho': simulation.rho, 'beta': np.where(simulation._parameters.alpha_index, simulation.beta if supply else np.nan, np.nan), 'rho_bounds': (np.zeros_like(simulation.rho), np.minimum(0.9, 1.5 * simulation.rho)), 'method': '1s', 'check_optimality': 'gradient', 'micro_moments': micro_moments } problem_results = problem.solve(**solve_options) return simulation, simulation_results, problem, solve_options, problem_results
def large_blp_simulation() -> SimulationFixture: """Solve a simulation with 20 markets, varying numbers of products per market, a linear constant, linear/nonlinear prices, a linear/nonlinear/cost characteristic, another three linear characteristics, another two cost characteristics, demographics interacted with prices and the linear/nonlinear/cost characteristic, dense parameter matrices, a log-linear cost specification, and local differentiation instruments on the demand side. """ id_data = build_id_data(T=20, J=20, F=9) keep = np.arange(id_data.size) np.random.RandomState(0).shuffle(keep) id_data = id_data[keep[:int(0.5 * id_data.size)]] simulation = Simulation( product_formulations=(Formulation('1 + prices + x + y + z + q'), Formulation('0 + prices + x'), Formulation('0 + log(x) + log(a) + log(b)')), beta=[1, -10, 1, 2, 3, 1], sigma=[[1, -0.1], [0, +2.0]], gamma=[0.1, 0.2, 0.3], product_data={ 'market_ids': id_data.market_ids, 'firm_ids': id_data.firm_ids, 'clustering_ids': np.random.RandomState(2).choice(range(30), id_data.size) }, agent_formulation=Formulation('0 + f + g'), pi=[[1, 0], [0, 2]], integration=Integration('product', 4), xi_variance=0.00001, omega_variance=0.00001, correlation=0.9, costs_type='log', seed=2) simulation_results = simulation.solve() differentiation_instruments = np.c_[ build_differentiation_instruments(Formulation('0 + x + y + z + q'), simulation_results.product_data), build_matrix(Formulation('0 + a + b'), simulation_results.product_data )] simulation_results.product_data = update_matrices( simulation_results.product_data, { 'demand_instruments': (differentiation_instruments, simulation_results.product_data.demand_instruments.dtype) }) return simulation, simulation_results
def simulated_problem(request: Any) -> SimulatedProblemFixture: """Configure and solve a simulated problem, either with or without supply-side data. Preclude overflow with rho bounds that are more conservative than the default ones. """ name, supply = request.param simulation, simulation_results, simulated_data_override, simulated_micro_moments = ( request.getfixturevalue(f'{name}_simulation')) # override the simulated data product_data = None if simulated_data_override: product_data = update_matrices( simulation_results.product_data, {k: (v, v.dtype) for k, v in simulated_data_override.items()}) # initialize and solve the problem problem = simulation_results.to_problem( simulation.product_formulations[:2 + int(supply)], product_data) solve_options = { 'sigma': simulation.sigma, 'pi': simulation.pi, 'rho': simulation.rho, 'beta': np.where(simulation._parameters.alpha_index, simulation.beta if supply else np.nan, np.nan), 'rho_bounds': (np.zeros_like(simulation.rho), np.minimum(0.9, 1.5 * simulation.rho)), 'method': '1s', 'check_optimality': 'gradient', 'micro_moments': simulated_micro_moments } problem_results = problem.solve(**solve_options) return simulation, simulation_results, problem, solve_options, problem_results