mergeron 2024.738953.0__py3-none-any.whl → 2024.738953.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mergeron might be problematic. Click here for more details.

@@ -1,425 +0,0 @@
1
- """
2
- Analyze simulated data on merger enforcement under U.S. Horizontal Merger Guidelines.
3
-
4
- Format output as LaTeX tables (using TikZ).
5
-
6
- """
7
-
8
- import sys
9
- import warnings
10
- from collections.abc import Mapping, Sequence
11
- from dataclasses import fields
12
- from datetime import datetime, timedelta
13
- from io import TextIOWrapper
14
- from typing import Any
15
-
16
- import numpy as np
17
- from attrs import evolve
18
-
19
- import mergeron.core.ftc_merger_investigations_data as fid
20
- import mergeron.core.guidelines_boundaries as gbl
21
- import mergeron.gen.investigations_stats as isl
22
- import mergeron.gen.upp_tests as utl
23
- from mergeron import DATA_DIR, RECConstants, UPPAggrSelector
24
- from mergeron.core.proportions_tests import propn_ci
25
- from mergeron.gen import (
26
- FM2Constants,
27
- INVResolution,
28
- MarketSampleSpec,
29
- PCMConstants,
30
- PCMSpec,
31
- ShareSpec,
32
- SHRConstants,
33
- SSZConstants,
34
- UPPTestRegime,
35
- )
36
-
37
- if not sys.warnoptions:
38
- warnings.simplefilter("ignore") # , category="RuntimeWarning")
39
-
40
- dottex_format_str = "FTC{}RateCITables_{}_{}_SYM.tex"
41
- stats_table_content = isl.StatsContainer()
42
- stats_table_design = isl.latex_jinja_env.get_template(
43
- "clrrate_cis_summary_table_template.tex.jinja2"
44
- )
45
-
46
-
47
- def invres_stats_sim_setup(
48
- _invdata: fid.INVData,
49
- _data_period: str,
50
- _merger_class: isl.INDGRPConstants | isl.EVIDENConstants,
51
- _invres_parm_vec: gbl.HMGThresholds,
52
- _sample_spec: MarketSampleSpec,
53
- _invres_stats_kwargs: utl.IVNRESCntsArgs | None = None,
54
- /,
55
- ) -> str:
56
- _table_ind_group = (
57
- _merger_class
58
- if isinstance(_merger_class, isl.INDGRPConstants)
59
- else isl.INDGRPConstants.ALL
60
- )
61
- _table_evid_cond = (
62
- _merger_class
63
- if isinstance(_merger_class, isl.EVIDENConstants)
64
- else isl.EVIDENConstants.UR
65
- )
66
-
67
- _invres_stats_kwargs = _invres_stats_kwargs or {
68
- "sim_test_regime": UPPTestRegime(INVResolution.ENFT, UPPAggrSelector.MAX, None)
69
- }
70
- _sim_test_regime = _invres_stats_kwargs.get("sim_test_regime")
71
-
72
- _invres_spec, _guppi_weighting, _divr_weighting = (
73
- getattr(_sim_test_regime, _f.name)
74
- for _f in fields(_sim_test_regime) # type: ignore
75
- )
76
-
77
- # Get observed rates
78
- (
79
- _invres_cnts_obs_byfirmcount_array,
80
- _invres_cnts_obs_bydelta_array,
81
- _invres_cnts_obs_byconczone_array,
82
- ) = (
83
- isl.invres_stats_cnts_by_group(
84
- _invdata,
85
- _data_period,
86
- _table_ind_group,
87
- _table_evid_cond,
88
- _grp,
89
- _invres_spec,
90
- )
91
- for _grp in (
92
- isl.StatsGrpSelector.FC,
93
- isl.StatsGrpSelector.DL,
94
- isl.StatsGrpSelector.ZN,
95
- )
96
- )
97
-
98
- _sample_spec_here = evolve(
99
- _sample_spec,
100
- share_spec=ShareSpec(
101
- RECConstants.INOUT,
102
- SHRConstants.DIR_FLAT,
103
- None,
104
- _invres_cnts_obs_byfirmcount_array[:-1, 1],
105
- ),
106
- )
107
-
108
- # Generate simulated rates
109
- _start_time = datetime.now()
110
- _upp_tests_counts = utl.sim_invres_cnts_ll(
111
- _invres_parm_vec, _sample_spec_here, _invres_stats_kwargs
112
- )
113
- _total_duration = datetime.now() - _start_time
114
-
115
- print(
116
- f"estimations completed in {_total_duration / timedelta(seconds=1):.6f} secs."
117
- )
118
-
119
- # Prepare and write/print output tables
120
- _stats_group_dict = {
121
- isl.StatsGrpSelector.FC: {
122
- "desc": f"{_invres_spec.capitalize()} rates by firm count",
123
- "title_str": "By Number of Significant Competitors",
124
- "hval": "Firm Count",
125
- "hcol_width": 54,
126
- "notewidth": 0.63,
127
- "obs_array": _invres_cnts_obs_byfirmcount_array,
128
- "sim_array": _upp_tests_counts.by_firm_count,
129
- },
130
- isl.StatsGrpSelector.DL: {
131
- "desc": Rf"{_invres_spec.capitalize()} rates by range of $\Delta HHI$",
132
- "title_str": R"By Change in Concentration (\Deltah{})",
133
- "hval": R"$\Delta HHI$",
134
- "hval_plus": R"{ $[\Delta_L, \Delta_H)$ }",
135
- "hcol_width": 54,
136
- "notewidth": 0.63,
137
- "notestr_plus": " ".join((
138
- R"\(\cdot\) Ranges of $\Delta HHI$ are defined as",
139
- "half-open intervals with",
140
- R"$\Delta_L \leqslant \Delta HHI < \Delta_H$, except that",
141
- R"$2500 \text{ pts.} \leqslant \Delta HHI \leqslant 5000 \text{ pts.}$",
142
- R"in the closed interval [2500, 5000]",
143
- isl.LTX_ARRAY_LINEEND,
144
- isl.LTX_ARRAY_LINEEND,
145
- )),
146
- "obs_array": _invres_cnts_obs_bydelta_array,
147
- "sim_array": _upp_tests_counts.by_delta,
148
- },
149
- isl.StatsGrpSelector.ZN: {
150
- "desc": f"{_invres_spec.capitalize()} rates by Approximate Presumption Zone",
151
- "title_str": "{} {}".format(
152
- R"By Approximate \textit{2010 Guidelines}",
153
- "Concentration-Based Standards",
154
- ),
155
- "hval": "Approximate Standard",
156
- "hcol_width": 190,
157
- "notewidth": 0.96,
158
- "obs_array": _invres_cnts_obs_byconczone_array,
159
- "sim_array": _upp_tests_counts.by_conczone,
160
- },
161
- }
162
-
163
- _stats_table_name = dottex_format_str.format(
164
- _invres_spec.capitalize(),
165
- _merger_class.replace(" ", ""),
166
- _data_period.split("-")[1],
167
- )
168
- with (DATA_DIR / _stats_table_name).open(
169
- "w", encoding="UTF-8"
170
- ) as _stats_table_file:
171
- for _stats_group_key in _stats_group_dict:
172
- invres_stats_sim_render(
173
- _data_period,
174
- _merger_class,
175
- _stats_group_key,
176
- _stats_group_dict[_stats_group_key],
177
- _invres_parm_vec,
178
- _invres_stats_kwargs["sim_test_regime"],
179
- _stats_table_file,
180
- )
181
-
182
- return _stats_table_name
183
-
184
-
185
- def invres_stats_sim_render(
186
- _data_period: str,
187
- _merger_class: isl.INDGRPConstants | isl.EVIDENConstants,
188
- _stats_group: isl.StatsGrpSelector,
189
- _stats_group_dict_sub: Mapping[str, Any],
190
- _invres_parm_vec: gbl.HMGThresholds,
191
- _sim_test_regime: UPPTestRegime,
192
- _stats_table_file: TextIOWrapper,
193
- /,
194
- ) -> None:
195
- _stats_table_content = isl.StatsContainer()
196
-
197
- _obs_sample_sz, _sim_sample_sz = (
198
- np.einsum("i->", _stats_group_dict_sub[_g][:, _h]).astype(int)
199
- for _g, _h in (("obs_array", -2), ("sim_array", -5))
200
- )
201
-
202
- _invres_select = _sim_test_regime.resolution
203
- (
204
- _stats_table_content.test_res,
205
- _stats_table_content.obs_merger_class,
206
- _stats_table_content.obs_period,
207
- ) = (_invres_select.capitalize(), _merger_class, _data_period.split("-"))
208
-
209
- _r_bar = _invres_parm_vec.rec
210
- (
211
- _stats_table_content.rbar,
212
- _stats_table_content.guppi_bound,
213
- _stats_table_content.dbar,
214
- _stats_table_content.cmcr_bound,
215
- _stats_table_content.ipr_bound,
216
- ) = (
217
- rf"{_s * 100:.1f}\%"
218
- for _s in (
219
- getattr(_invres_parm_vec, _f)
220
- for _f in ("rec", "guppi", "divr", "cmcr", "ipr")
221
- )
222
- )
223
-
224
- # Prepare and write/print output tables
225
- _stats_cis_wilson_notestr = " ".join((
226
- R"Confidence intervals (95\% CI) are",
227
- R"estimated by the Wilson method, given the",
228
- "reported numbers of investigated mergers and cleared mergers",
229
- _stats_group_dict_sub["desc"].replace(
230
- f"{_stats_table_content.test_res} rates ", ""
231
- ),
232
- isl.LTX_ARRAY_LINEEND,
233
- ))
234
-
235
- _eg_count = int(_relfreq_eg := 0.01) * _sim_sample_sz
236
- _stats_sim_ci_eg = 100 * np.array(
237
- propn_ci(int(0.50 * _eg_count), _eg_count, method="Exact")
238
- )
239
- _stats_sim_notestr = " ".join((
240
- Rf"\(\cdot\) Simulated {_stats_table_content.test_res} rates are estimated by",
241
- "Monte Carlo integration over generated data representing",
242
- Rf"{_sim_sample_sz:,d} hypothetical mergers. Thus,",
243
- R"for a subset of simulations with a relative frequency",
244
- Rf"of, say, {100 * _relfreq_eg:.1f}\%,",
245
- R"and an estimated clearance rate of, for example, 50.0\%,",
246
- Rf"the margin of error (m.o.e.) is {isl.moe_tmpl.render(rv=_stats_sim_ci_eg)}."
247
- R"The m.o.e. is derived from the",
248
- R"Clopper-Pearson exact 95\% confidence interval, {}.".format( # noqa: UP032
249
- isl.ci_format_str.format(*_stats_sim_ci_eg).strip()
250
- ),
251
- R"(The m.o.e. for simulated clearance rates varies",
252
- R"as the reciprocal of the square root of the number",
253
- R"of hypothetical mergers.)",
254
- isl.LTX_ARRAY_LINEEND,
255
- ))
256
- del _relfreq_eg, _eg_count, _stats_sim_ci_eg
257
-
258
- print(
259
- f"Observed {_invres_select} proportion [95% CI]",
260
- _stats_group_dict_sub["desc"].replace(f"{_invres_select} rates ", ""),
261
- )
262
- print(f"\t with sample size (observed): {_obs_sample_sz:,d};")
263
-
264
- _stats_table_content.obs_summary_type = f"{_stats_group}"
265
- _stats_table_content.obs_summary_type_title = _stats_group_dict_sub["desc"]
266
- _stats_table_content.stats_cis_notewidth = _stats_group_dict_sub["notewidth"]
267
- _stats_cis_numobs_notestr = " ".join((
268
- R"\(\cdot\) Estimates for Proportion {} are based on".format(
269
- "Enforced" if _invres_select == INVResolution.ENFT else "Cleared"
270
- ),
271
- f"{_obs_sample_sz:,d} total observations (investigated mergers).",
272
- ))
273
-
274
- _spnum = 2 if _stats_group_dict_sub["notewidth"] < 0.90 else 1
275
- _stats_table_content.stats_cis_notestr = " ".join((
276
- _stats_cis_numobs_notestr,
277
- _stats_cis_wilson_notestr,
278
- *[isl.LTX_ARRAY_LINEEND] * _spnum,
279
- _stats_sim_notestr,
280
- *[isl.LTX_ARRAY_LINEEND] * (_spnum + 1),
281
- ))
282
- del _spnum
283
-
284
- if _nsp := _stats_group_dict_sub.get("notestr_plus", ""):
285
- _stats_table_content.stats_cis_notestr += "".join((isl.LTX_ARRAY_LINEEND, _nsp))
286
- del _nsp
287
-
288
- _invres_stats_report_func = (
289
- isl.latex_tbl_invres_stats_byzone
290
- if _stats_group == isl.StatsGrpSelector.ZN
291
- else isl.latex_tbl_invres_stats_1dim
292
- )
293
- _sort_order = (
294
- isl.SortSelector.UCH
295
- if _stats_group == isl.StatsGrpSelector.FC
296
- else isl.SortSelector.REV
297
- )
298
-
299
- _invres_stats_hdr_list, _invres_stats_dat_list = _invres_stats_report_func(
300
- _stats_group_dict_sub["obs_array"],
301
- return_type_sel=isl.StatsReturnSelector.RIN,
302
- sort_order=_sort_order,
303
- )
304
-
305
- if _stats_group == isl.StatsGrpSelector.FC:
306
- del _invres_stats_hdr_list[-2], _invres_stats_dat_list[-2]
307
-
308
- _stats_table_content.stats_numrows = len(_invres_stats_hdr_list)
309
- _stats_table_content.hdrcol_cis_width = f'{_stats_group_dict_sub["hcol_width"]}pt'
310
-
311
- _hs1 = _stats_group_dict_sub["hval"]
312
- _hs2 = _h if (_h := _stats_group_dict_sub.get("hval_plus", "")) else _hs1
313
- _stats_table_content.hdrcoldescstr = isl.latex_hrdcoldesc_format_str.format(
314
- "hdrcol_cis",
315
- f'{_stats_group_dict_sub["hcol_width"]}pt',
316
- "hdrcoldesc_cis",
317
- "center",
318
- " ".join((
319
- _hs1 if _hs1 != _hs2 else Rf"{{ \phantom{{{_hs1}}} }}",
320
- isl.LTX_ARRAY_LINEEND,
321
- _hs2,
322
- isl.LTX_ARRAY_LINEEND,
323
- )),
324
- )
325
- del _hs1, _hs2
326
-
327
- _stats_table_content.stats_hdrstr = "".join([
328
- f"{g} {isl.LTX_ARRAY_LINEEND}" for g in _invres_stats_hdr_list
329
- ])
330
- _stats_table_content.stats_cis = "".join([
331
- f"{" & ".join(g)} {isl.LTX_ARRAY_LINEEND}" for g in _invres_stats_dat_list
332
- ])
333
- # Print to console
334
- isl.stats_print_rows(_invres_stats_hdr_list, _invres_stats_dat_list)
335
- del _invres_stats_hdr_list, _invres_stats_dat_list
336
-
337
- print(f"Simulated {_invres_select} rates {_stats_group}:")
338
- print(f"\t with generated data size = {_sim_sample_sz:,d}:")
339
-
340
- _stats_sim_hdr_list, _stats_sim_dat_list = _invres_stats_report_func(
341
- _stats_group_dict_sub["sim_array"],
342
- return_type_sel=isl.StatsReturnSelector.RPT,
343
- sort_order=_sort_order,
344
- )
345
-
346
- # Exclude results of IPR tests
347
- _stats_sim_dat_list = [_f[:-1] for _f in _stats_sim_dat_list]
348
- _stats_table_content.stats_sim = "".join([
349
- f"{" & ".join(g)} {isl.LTX_ARRAY_LINEEND}" for g in _stats_sim_dat_list
350
- ])
351
- # Print to console
352
- isl.stats_print_rows(_stats_sim_hdr_list, _stats_sim_dat_list)
353
- del _stats_sim_hdr_list, _stats_sim_dat_list
354
-
355
- # Generate and write out LaTeX
356
- _stats_table_design = isl.latex_jinja_env.get_template(
357
- "clrrate_cis_summary_table_template.tex.jinja2"
358
- )
359
- # Write to dottex
360
- _stats_table_file.write(_stats_table_design.render(tmpl_data=_stats_table_content))
361
- print("\n", file=_stats_table_file)
362
-
363
-
364
- if __name__ == "__main__":
365
- invdata_array_dict = fid.construct_data(
366
- fid.INVDATA_ARCHIVE_PATH,
367
- flag_backward_compatibility=False,
368
- flag_pharma_for_exclusion=True,
369
- )
370
-
371
- data_periods = ("1996-2003", "2004-2011")
372
- merger_classes: Sequence[isl.INDGRPConstants | isl.EVIDENConstants] = (
373
- isl.INDGRPConstants.ALL,
374
- isl.EVIDENConstants.ED,
375
- )
376
-
377
- sample_sz_base = 10**7
378
- pcm_dist_type, pcm_dist_parms = PCMConstants.EMPR, None
379
-
380
- sim_test_regime = (
381
- UPPTestRegime(INVResolution.CLRN, UPPAggrSelector.MAX, None),
382
- UPPTestRegime(INVResolution.ENFT, UPPAggrSelector.OSD, None),
383
- )[1]
384
- invres_stats_kwargs = {"sim_test_regime": sim_test_regime}
385
-
386
- table_dottex_namelist = ()
387
- for merger_class in merger_classes:
388
- for study_period in data_periods:
389
- if study_period == data_periods[1]:
390
- continue
391
-
392
- print(
393
- f"{sim_test_regime.resolution.capitalize()} rates and c.i.s",
394
- f"for the class of mergers, '{merger_class}',",
395
- f"for study period, {study_period}:",
396
- )
397
- stats_table_content.obs_period = study_period.split("-")
398
-
399
- invres_parm_vec = (
400
- gbl.GuidelinesThresholds(2010).presumption
401
- if study_period.split("-")[1] == data_periods[1].split("-")[1]
402
- else gbl.GuidelinesThresholds(1992).presumption
403
- )
404
-
405
- mkt_sample_spec = MarketSampleSpec(
406
- sample_sz_base,
407
- invres_parm_vec.rec,
408
- pcm_spec=PCMSpec(pcm_dist_type, FM2Constants.MNL, pcm_dist_parms),
409
- hsr_filing_test_type=SSZConstants.HSR_NTH,
410
- )
411
-
412
- table_dottex_name = invres_stats_sim_setup(
413
- invdata_array_dict,
414
- study_period,
415
- merger_class,
416
- invres_parm_vec,
417
- mkt_sample_spec,
418
- invres_stats_kwargs, # type: ignore
419
- )
420
- table_dottex_namelist += (table_dottex_name,) # type: ignore
421
-
422
- isl.render_table_pdf(
423
- table_dottex_namelist,
424
- dottex_format_str.format(sim_test_regime.resolution.capitalize(), "All", "All"),
425
- )
@@ -1,53 +0,0 @@
1
- """
2
-
3
- Solve for, and plot, weighted-average GUPPI boundaries using sympy,
4
- as a check against the numerical solutions in mergeron.core.guidelines_boundaries
5
-
6
- """
7
-
8
- from collections.abc import Sequence
9
-
10
- from sympy import solve, symbols
11
- from sympy.plotting import plot as symplot
12
-
13
-
14
- def plot_safeharb_boundaries(
15
- _g_bar: float, _r_bar: float, _m_vals: Sequence[float]
16
- ) -> None:
17
- s1, s2, rbar, delta_star = symbols(r"s1 s2 \overline{r} \delta^*", real=True)
18
-
19
- for _m_val in _m_vals:
20
- s_m = round((dstar_val := _g_bar / (_r_bar * _m_val)) / (1 + dstar_val), 3)
21
-
22
- # Own-share-weighted average GUPPI, "inside-out" recapture
23
- s2_sol = solve( # type: ignore
24
- s1 * s2 / (1 - s1)
25
- + s2 * s1 / (1 - s2 * _r_bar - s1 * (1 - _r_bar))
26
- - (s1 + s2) * delta_star,
27
- s2,
28
- )
29
- symplot( # type: ignore
30
- s2_sol[0].subs({delta_star: dstar_val}),
31
- (s1, 0, s_m),
32
- ylabel=s2,
33
- xlim=(0.0, 1.0),
34
- ylim=(0.0, 1.0),
35
- axis_center=(0.0, 0.0),
36
- )
37
-
38
- # Cross-product-share-weighted average GUPPI, proportional recapture
39
- s2_sol = solve( # type: ignore
40
- s2 * s2 / (1 - s1) + s1 * s1 / (1 - s2) - delta_star * (s1 + s2), s2
41
- )
42
- symplot( # type: ignore
43
- s2_sol[1].subs({delta_star: dstar_val}),
44
- (s1, 0, s_m),
45
- ylabel=s2,
46
- xlim=(0.0, 1.0),
47
- ylim=(0.0, 1.0),
48
- axis_center=(0.0, 0.0),
49
- )
50
-
51
-
52
- if __name__ == "__main__":
53
- plot_safeharb_boundaries(0.06, 0.80, (1.00, 0.67, 0.30))
@@ -1,181 +0,0 @@
1
- from datetime import datetime, timedelta
2
- from itertools import product as iterprod
3
- from pathlib import Path
4
- from typing import Literal
5
-
6
- import numpy as np
7
-
8
- import mergeron.core.guidelines_boundaries as gbl
9
- import mergeron.gen.investigations_stats as isl
10
- import mergeron.gen.upp_tests as utl
11
- from mergeron import DATA_DIR, RECConstants, UPPAggrSelector
12
- from mergeron.core.pseudorandom_numbers import DIST_PARMS_DEFAULT
13
- from mergeron.gen import (
14
- FM2Constants,
15
- INVResolution,
16
- MarketSampleSpec,
17
- PCMConstants,
18
- PCMSpec,
19
- ShareSpec,
20
- SHRConstants,
21
- UPPTestRegime,
22
- )
23
-
24
- PROG_PATH = Path(__file__)
25
-
26
- tests_of_interest: tuple[UPPTestRegime, ...] = (
27
- UPPTestRegime(INVResolution.CLRN, UPPAggrSelector.MAX, UPPAggrSelector.MAX),
28
- UPPTestRegime(INVResolution.ENFT, UPPAggrSelector.MIN, UPPAggrSelector.MIN),
29
- )
30
-
31
-
32
- def analyze_invres_data(
33
- _sample_size: int = 10**6,
34
- _hmg_pub_year: Literal[1992, 2010, 2023] = 1992,
35
- _test_regime: UPPTestRegime = tests_of_interest[1],
36
- /,
37
- *,
38
- save_data_to_file_flag: bool = False,
39
- ) -> None:
40
- """
41
- Analyze intrinsic enforcement rates using a GUPPI criterion against
42
- intrinsic enforcement rates by Guidelines ∆HHI standard
43
-
44
- Parameters
45
- ----------
46
- _sample_size
47
- Number of draws (mergers) to analyze
48
-
49
- _hmg_pub_year
50
- Guidelines version for ∆HHI standard
51
-
52
- _test_regime
53
- Specifies analysis of enforcement rates or, alternatively, clearance rates
54
-
55
- save_data_to_file_flag
56
- If True, simulated data are save to file (hdf5 format)
57
-
58
- """
59
- _invres_parm_vec = gbl.GuidelinesThresholds(_hmg_pub_year).presumption
60
-
61
- _save_data_to_file: utl.SaveData = False
62
- if save_data_to_file_flag:
63
- _h5_path = DATA_DIR / PROG_PATH.with_suffix(".h5").name
64
- (_, _h5_file, _h5_group), _h5_subgroup_name = utl.initialize_hd5( # type: ignore
65
- _h5_path, _hmg_pub_year, _test_regime
66
- ) # type: ignore
67
-
68
- _h5_group = _h5_file.create_group(
69
- _h5_group, _h5_subgroup_name, f"{_invres_parm_vec}"
70
- )
71
- _save_data_to_file = (True, _h5_file, _h5_group)
72
-
73
- # ##
74
- # Print summaries of intrinsic clearance/enforcement rates by ∆HHI,
75
- # with asymmetric margins
76
- # ##
77
- for _recapture_spec_test, _pcm_dist_test, _pcm_dist_firm2_test in iterprod(
78
- (RECConstants.INOUT, RECConstants.FIXED),
79
- [
80
- tuple(
81
- zip(
82
- (PCMConstants.UNI, PCMConstants.BETA, PCMConstants.EMPR),
83
- (
84
- np.array((0, 1), dtype=np.float64),
85
- np.array((10, 10), dtype=np.float64),
86
- None,
87
- ),
88
- strict=True,
89
- )
90
- )[_s]
91
- for _s in [0, 2]
92
- ],
93
- (FM2Constants.IID, FM2Constants.MNL),
94
- ):
95
- if _recapture_spec_test == "proportional" and (
96
- _pcm_dist_test[0] != "Uniform" or _pcm_dist_firm2_test == "MNL-dep"
97
- ):
98
- continue
99
- # When margins are specified as symmetric, then
100
- # recapture_spec must be proportional and
101
- # margins distributions must be iid;
102
-
103
- _pcm_dist_type_test, _pcm_dist_parms_test = _pcm_dist_test
104
-
105
- print()
106
- print(
107
- f"Simulated {_test_regime.resolution.capitalize()} rates by range of ∆HHI",
108
- f'recapture-rate calibrated, "{_recapture_spec_test}"',
109
- f'Firm 2 margins, "{_pcm_dist_firm2_test}"',
110
- f"and margins distributed as, {_pcm_dist_type_test}{
111
- _pcm_dist_parms_test if _pcm_dist_type_test.name == "BETA" else ""
112
- }:",
113
- sep="; ",
114
- )
115
-
116
- _mkt_sample_spec = MarketSampleSpec(
117
- _sample_size,
118
- _invres_parm_vec.rec,
119
- share_spec=ShareSpec(
120
- _recapture_spec_test, SHRConstants.UNI, DIST_PARMS_DEFAULT, None
121
- ),
122
- pcm_spec=PCMSpec(
123
- _pcm_dist_type_test, _pcm_dist_firm2_test, _pcm_dist_parms_test
124
- ),
125
- )
126
-
127
- if _save_data_to_file:
128
- _h5_file.flush()
129
-
130
- _h5_subgrp_name = "invres_rec{}_pcm{}_fm2res{}".format( # noqa: UP032
131
- _recapture_spec_test.name,
132
- _pcm_dist_type_test.name,
133
- _pcm_dist_firm2_test.name,
134
- )
135
-
136
- _h5_subgroup = _h5_file.create_group(
137
- _h5_group, _h5_subgrp_name, title=f"{_mkt_sample_spec}"
138
- )
139
- _save_data_to_file = (True, _h5_file, _h5_subgroup)
140
-
141
- _invres_cnts_kwargs = utl.IVNRESCntsArgs(
142
- sim_test_regime=_test_regime, save_data_to_file=_save_data_to_file
143
- )
144
-
145
- _start_time = datetime.now()
146
-
147
- upp_test_counts = utl.sim_invres_cnts_ll(
148
- _invres_parm_vec, _mkt_sample_spec, _invres_cnts_kwargs
149
- )
150
- _run_duration = datetime.now() - _start_time
151
- print(
152
- f"Simulation completed in {_run_duration / timedelta(seconds=1):.6f} secs.",
153
- f"on {_mkt_sample_spec.sample_size:,d} draws",
154
- sep=", ",
155
- )
156
-
157
- _stats_hdr_list, _stats_dat_list = isl.latex_tbl_invres_stats_1dim(
158
- upp_test_counts.by_delta,
159
- return_type_sel=isl.StatsReturnSelector.RPT,
160
- sort_order=isl.SortSelector.REV,
161
- )
162
- _stats_teststr_val = "".join([
163
- "{} & {} {}".format(
164
- _stats_hdr_list[g],
165
- " & ".join(_stats_dat_list[g][:-2]), # [:-2]
166
- isl.LTX_ARRAY_LINEEND,
167
- )
168
- for g in range(len(_stats_hdr_list))
169
- ])
170
- print(_stats_teststr_val)
171
- del _stats_hdr_list, _stats_dat_list, _stats_teststr_val
172
- del _pcm_dist_test, _pcm_dist_firm2_test, _recapture_spec_test
173
- del _pcm_dist_type_test, _pcm_dist_parms_test
174
-
175
- if _save_data_to_file:
176
- _h5_file.flush()
177
- _save_data_to_file[1].close() # type: ignore
178
-
179
-
180
- if __name__ == "__main__":
181
- analyze_invres_data(10**7, 2023, tests_of_interest[1], save_data_to_file_flag=False)
@@ -1,44 +0,0 @@
1
- """
2
- Query FTC investigations data and display some basic statistics.
3
-
4
- """
5
-
6
- import numpy as np
7
-
8
- import mergeron.core.ftc_merger_investigations_data as fid
9
-
10
- invdata = fid.construct_data(fid.INVDATA_ARCHIVE_PATH)
11
-
12
- for data_period in invdata:
13
- print(data_period, "-->")
14
- for table_type in (isd1 := invdata[data_period]):
15
- leader_str = "\t"
16
- print(leader_str, table_type, "-->")
17
- leader_str += "\t"
18
- for table_no in (isd11 := isd1[table_type]):
19
- (invdata_ind_group, invdata_evid_cond, table_data_array) = isd11[table_no]
20
- print(
21
- leader_str,
22
- table_no,
23
- " \N{EM DASH} ",
24
- invdata_ind_group,
25
- f", {invdata_evid_cond or "N/A"}",
26
- ", ",
27
- sep="",
28
- end="",
29
- )
30
- print(
31
- "Odds ratio = {}/{}".format(
32
- *np.einsum("ij->j", table_data_array[:, -3:])
33
- )
34
- )
35
- print("\n")
36
-
37
- data_period, data_type, table_no = ("2004-2011", "HHI and Delta", "Table 3.3")
38
- # data_period, data_type, table_no = "2004-2011", "Firm Count", "Table 4.1"
39
- print(f"Investigations data, {data_period}, by {data_type}, {table_no}")
40
- print(
41
- "{}, {}\n{}".format(
42
- *invdata[data_period][f"By{data_type.replace(" ", "")}"][table_no]
43
- )
44
- )