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.
- {mergeron-2024.738953.0.dist-info → mergeron-2024.738953.1.dist-info}/METADATA +1 -1
- {mergeron-2024.738953.0.dist-info → mergeron-2024.738953.1.dist-info}/RECORD +3 -17
- mergeron/examples/__init__.py +0 -5
- mergeron/examples/concentration_as_diversion.py +0 -625
- mergeron/examples/enforcement_boundaries_for_mergers_with_asymmetric_shares.py +0 -493
- mergeron/examples/enforcement_boundaries_for_symmetric_firm_mergers.py +0 -206
- mergeron/examples/example_parameterizations.py +0 -143
- mergeron/examples/guidelines_enforcement_patterns.py +0 -74
- mergeron/examples/investigations_stats_obs_tables.py +0 -481
- mergeron/examples/investigations_stats_sim_tables.py +0 -425
- mergeron/examples/plotSafeHarbs_symbolically.py +0 -53
- mergeron/examples/sound_guppi_safeharbor.py +0 -181
- mergeron/examples/summarize_ftc_investigations_data.py +0 -44
- mergeron/examples/testIntrinsicClearanceRates.py +0 -135
- mergeron/examples/visualize_empirical_margin_distribution.py +0 -100
- mergeron/examples/visualize_guidelines_tests.py +0 -298
- {mergeron-2024.738953.0.dist-info → mergeron-2024.738953.1.dist-info}/WHEEL +0 -0
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
3
|
-
A few parameters/relations employed in policy analysis using this pacakage
|
|
4
|
-
are demonstrated here
|
|
5
|
-
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
from typing import NamedTuple
|
|
9
|
-
|
|
10
|
-
import numpy as np
|
|
11
|
-
from numpy.typing import NDArray
|
|
12
|
-
|
|
13
|
-
from mergeron.core.pseudorandom_numbers import prng
|
|
14
|
-
from mergeron.gen.data_generation import (
|
|
15
|
-
RECConstants,
|
|
16
|
-
_gen_market_shares_dirichlet,
|
|
17
|
-
_gen_market_shares_uniform,
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def gen_rval_mnl(
|
|
22
|
-
_ssz: int = 10**8, _r_bar: float = 0.80, *, pcm_dist_type: str = "Uniform"
|
|
23
|
-
) -> NamedTuple:
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
:param _ssz: sample size
|
|
27
|
-
:param _r_bar: recapture rate
|
|
28
|
-
:param pcm_dist_type: margin distribution name
|
|
29
|
-
:return:
|
|
30
|
-
"""
|
|
31
|
-
|
|
32
|
-
# Define output type
|
|
33
|
-
class RvalMNL(NamedTuple):
|
|
34
|
-
qtyshr_array: NDArray[np.floating]
|
|
35
|
-
pcm_array: NDArray[np.floating]
|
|
36
|
-
mnl_test_rows: NDArray[np.integer]
|
|
37
|
-
|
|
38
|
-
_qtyshr_array = _gen_market_shares_uniform(_ssz).mktshr_array[:, :2]
|
|
39
|
-
|
|
40
|
-
_qtyshr_min = _qtyshr_array.min(axis=1, keepdims=True, initial=None)
|
|
41
|
-
_cprob = np.divide(_r_bar, 1 - (1 - _r_bar) * _qtyshr_min)
|
|
42
|
-
del _qtyshr_min
|
|
43
|
-
|
|
44
|
-
_purchprob_array = _cprob * _qtyshr_array
|
|
45
|
-
|
|
46
|
-
_pcm0: NDArray[np.floating]
|
|
47
|
-
if pcm_dist_type == "Uniform":
|
|
48
|
-
_pcm0 = prng().uniform(size=(_ssz, 1))
|
|
49
|
-
elif pcm_dist_type == "Beta":
|
|
50
|
-
_pcm0 = prng().beta(10, 10, size=(_ssz, 1))
|
|
51
|
-
else:
|
|
52
|
-
raise ValueError("Invalid type for distribution of margins")
|
|
53
|
-
|
|
54
|
-
_pcm1 = np.divide(
|
|
55
|
-
_pcm0 * (1 - _purchprob_array[:, [0]]), (1 - _purchprob_array[:, [1]])
|
|
56
|
-
)
|
|
57
|
-
|
|
58
|
-
_mnl_test_rows = _pcm1.__gt__(0) & _pcm1.__lt__(1)
|
|
59
|
-
_pcm_array = np.column_stack((_pcm0, _pcm1))
|
|
60
|
-
|
|
61
|
-
return RvalMNL(_qtyshr_array, _pcm_array, _mnl_test_rows)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def gen_rval_ssp(_ssz: int = 10**6, _r_bar: float = 0.8) -> NamedTuple:
|
|
65
|
-
R"""Given r_1 (_r_bar), generates r_2 and diversion ratios under share proportionality
|
|
66
|
-
|
|
67
|
-
More testing with::
|
|
68
|
-
|
|
69
|
-
from sympy import solve, symbols
|
|
70
|
-
s1, s2, m1, mstar, rbar, dstar = symbols('s_1, s_2, m_1, m^{*}, \overline{r}, \delta^{*}')
|
|
71
|
-
infl2_pts = solve(
|
|
72
|
-
(
|
|
73
|
-
s2 - dstar + dstar * rbar * s1 + dstar * (1 - rbar) * s2,
|
|
74
|
-
s1 - (1 - s2) * dstar * mstar / m1
|
|
75
|
-
),
|
|
76
|
-
s1, s2)
|
|
77
|
-
|
|
78
|
-
Substitute various values into the solution to test against plots generated elsewhere
|
|
79
|
-
"""
|
|
80
|
-
|
|
81
|
-
# Define output type
|
|
82
|
-
class RvalSSP(NamedTuple):
|
|
83
|
-
"""Container for share, recapture ratio, and diversion rate arrays"""
|
|
84
|
-
|
|
85
|
-
qtyshr_array: NDArray[np.floating]
|
|
86
|
-
r_val: NDArray[np.floating]
|
|
87
|
-
divr_array: NDArray[np.floating]
|
|
88
|
-
|
|
89
|
-
_qtyshr_array = _gen_market_shares_uniform(_ssz).mktshr_array[:, :2]
|
|
90
|
-
|
|
91
|
-
_qtyshr_min = _qtyshr_array.min(axis=1, keepdims=True, initial=None)
|
|
92
|
-
_cprob = np.divide(_r_bar, 1 - (1 - _r_bar) * _qtyshr_min)
|
|
93
|
-
del _qtyshr_min
|
|
94
|
-
|
|
95
|
-
_r_val = np.divide(_cprob * (1 - _qtyshr_array), 1 - _cprob * _qtyshr_array)
|
|
96
|
-
|
|
97
|
-
_divr_array = _r_val * _qtyshr_array[:, ::-1] / (1 - _qtyshr_array)
|
|
98
|
-
|
|
99
|
-
return RvalSSP(_qtyshr_array, _r_val, _divr_array)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
def gen_implied_mkt_shr_1(_fcount: int = 5) -> NDArray[np.floating]:
|
|
103
|
-
"""
|
|
104
|
-
Generate implied market shares for firm 1 with all pairs of products
|
|
105
|
-
in a putative market of `_fcount` firms.
|
|
106
|
-
|
|
107
|
-
Parameters
|
|
108
|
-
----------
|
|
109
|
-
_fcount: Firm count for the given market
|
|
110
|
-
|
|
111
|
-
Returns
|
|
112
|
-
-------
|
|
113
|
-
Vector of implied market shares
|
|
114
|
-
|
|
115
|
-
"""
|
|
116
|
-
|
|
117
|
-
_mkt_sample = _gen_market_shares_dirichlet([1] * _fcount, 10, RECConstants.OUTIN)
|
|
118
|
-
|
|
119
|
-
_mktshr_array = _mkt_sample.mktshr_array
|
|
120
|
-
_chprob_outside_good = _mkt_sample.choice_prob_outgd
|
|
121
|
-
|
|
122
|
-
_recapture_array = np.divide(
|
|
123
|
-
(1 - _chprob_outside_good) * (1 - _mktshr_array),
|
|
124
|
-
1 - (1 - _chprob_outside_good) * _mktshr_array,
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
_divratio_1j = np.divide(
|
|
128
|
-
_recapture_array[:, :1] * _mktshr_array[:, 1:], 1 - _mktshr_array[:, :1]
|
|
129
|
-
)
|
|
130
|
-
_divratio_j1 = np.divide(
|
|
131
|
-
_recapture_array[:, 1:] * _mktshr_array[:, :1], 1 - _mktshr_array[:, 1:]
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
_implied_mkt_shr_1 = np.divide(
|
|
135
|
-
_divratio_j1 * (_recapture_array[:, :1] - _divratio_1j),
|
|
136
|
-
_recapture_array[:, :1] * _recapture_array[:, 1:] - _divratio_1j * _divratio_j1,
|
|
137
|
-
)
|
|
138
|
-
|
|
139
|
-
return _implied_mkt_shr_1
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if __name__ == "__main__":
|
|
143
|
-
print(gen_implied_mkt_shr_1(10))
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import numpy as np
|
|
4
|
-
|
|
5
|
-
import mergeron.core.proportions_tests as pcl
|
|
6
|
-
|
|
7
|
-
enf_counts = np.array(
|
|
8
|
-
(
|
|
9
|
-
(24, 25, 33, 33),
|
|
10
|
-
(30, 33, 27, 32),
|
|
11
|
-
(14, 15, 9, 11),
|
|
12
|
-
(13, 22, 6, 11),
|
|
13
|
-
(6, 8, 7, 9),
|
|
14
|
-
(1, 3, 2, 4),
|
|
15
|
-
(1, 3, 2, 4),
|
|
16
|
-
(1e-15, 1e-15, 1, 1),
|
|
17
|
-
),
|
|
18
|
-
np.int16,
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
if __name__ == "__main__":
|
|
22
|
-
adj_n = len(enf_counts)
|
|
23
|
-
|
|
24
|
-
print()
|
|
25
|
-
print("C.I.s for relative frequency of II Requests")
|
|
26
|
-
cis_1996_2003, cis_2004_2011 = (
|
|
27
|
-
pcl.propn_ci_multinomial(_c) for _c in (enf_counts[:, _i] for _i in (1, 3))
|
|
28
|
-
)
|
|
29
|
-
for cdx, ci in enumerate(cis_1996_2003):
|
|
30
|
-
print(ci, ";", cis_2004_2011[cdx, :])
|
|
31
|
-
|
|
32
|
-
print()
|
|
33
|
-
print(
|
|
34
|
-
"C.I.s for relative frequency of II Requests, 1996-2003",
|
|
35
|
-
"(Bonnferoni-adjusted Wilson C.I.s)",
|
|
36
|
-
)
|
|
37
|
-
for count in (ic_1996_2003 := enf_counts[:, 1]):
|
|
38
|
-
print(
|
|
39
|
-
pcl.propn_ci(
|
|
40
|
-
count, ic_1996_2003.sum(), alpha=0.05 / adj_n, method="Wilson"
|
|
41
|
-
)[2:]
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
print("Conf. intervals for relative frequency of II Requests (Goodman, 1965)")
|
|
45
|
-
for goodman_alternative in "default", "simplified":
|
|
46
|
-
for goodman_method in "goodman", "quesenberry-hurst":
|
|
47
|
-
print(f"Method, {goodman_method!r}; alternative, {goodman_alternative!r}")
|
|
48
|
-
for _cis in np.column_stack([
|
|
49
|
-
pcl.propn_ci_multinomial(
|
|
50
|
-
enf_counts[:, _cidx],
|
|
51
|
-
method=goodman_method,
|
|
52
|
-
alternative=goodman_alternative,
|
|
53
|
-
)
|
|
54
|
-
for _cidx in (1, 3)
|
|
55
|
-
]):
|
|
56
|
-
print(_cis)
|
|
57
|
-
print()
|
|
58
|
-
|
|
59
|
-
print()
|
|
60
|
-
print("Conf. intervals for differences in proportions enforced (Goodman, 1964)")
|
|
61
|
-
print(repr(pcl.propn_diff_ci_multinomial(enf_counts[:, [1, 3]])))
|
|
62
|
-
|
|
63
|
-
print()
|
|
64
|
-
print("Goodman's chi-squared test for homogeneity of enforcement patterns")
|
|
65
|
-
print(repr(pcl.propn_test_multinomial(enf_counts[:, [1, 3]])))
|
|
66
|
-
|
|
67
|
-
print()
|
|
68
|
-
print(
|
|
69
|
-
"C.I.s for differences in proportions enforced",
|
|
70
|
-
"(Bonnferoni-adjusted Newcombe C.I.s)",
|
|
71
|
-
)
|
|
72
|
-
for counts in enf_counts:
|
|
73
|
-
print(pcl.propn_diff_ci(*counts, alpha=0.05 / adj_n, method="Newcombe"))
|
|
74
|
-
print()
|
|
@@ -1,481 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
3
|
-
Construct observed clearance rates and enforcement rates, by specification,
|
|
4
|
-
from FTC merger investigations data
|
|
5
|
-
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import sys
|
|
9
|
-
import warnings
|
|
10
|
-
from collections.abc import Mapping, Sequence
|
|
11
|
-
|
|
12
|
-
from numpy import einsum, row_stack, unique
|
|
13
|
-
|
|
14
|
-
import mergeron.core.ftc_merger_investigations_data as fid
|
|
15
|
-
import mergeron.gen.investigations_stats as isl
|
|
16
|
-
from mergeron import DATA_DIR
|
|
17
|
-
from mergeron.gen import INVResolution
|
|
18
|
-
|
|
19
|
-
if not sys.warnoptions:
|
|
20
|
-
warnings.simplefilter("ignore")
|
|
21
|
-
|
|
22
|
-
INVRES_RATIO_FORMAT_STR = "{: >3.0f}/{:<3.0f}"
|
|
23
|
-
INVDATA_DOTTEX_FORMAT_STR = "{}.tex".format(
|
|
24
|
-
"_".join(("FTCMergerInvestigationsDataTables", "{}", "OBS"))
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def invres_stats_odds_ratio_byhhianddelta(
|
|
29
|
-
_data_array_dict: Mapping[str, Mapping[str, Mapping[str, fid.INVData]]],
|
|
30
|
-
_data_periods: tuple[str, str],
|
|
31
|
-
_merger_classes: Sequence[isl.INDGRPConstants | isl.EVIDENConstants],
|
|
32
|
-
/,
|
|
33
|
-
) -> tuple[str, ...]:
|
|
34
|
-
"""
|
|
35
|
-
Reconstruct tables by HHI and Delta.
|
|
36
|
-
|
|
37
|
-
Source tables as well as tables from constructed periods.
|
|
38
|
-
"""
|
|
39
|
-
if not all(_dpd in _data_array_dict for _dpd in _data_periods):
|
|
40
|
-
raise ValueError(
|
|
41
|
-
f"All given data periods, {_data_periods!r} must be contained "
|
|
42
|
-
f"in {tuple(_data_array_dict.keys())!r}"
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
print("Odds ratios by HHI and Delta:")
|
|
46
|
-
_stats_group = isl.StatsGrpSelector.HD
|
|
47
|
-
_invres_rate_table_content = isl.StatsContainer()
|
|
48
|
-
_invres_rate_table_design = isl.latex_jinja_env.get_template(
|
|
49
|
-
"ftcinvdata_byhhianddelta_table_template.tex.jinja2"
|
|
50
|
-
)
|
|
51
|
-
_invres_rate_table_content.obs_summary_type = f"{_stats_group}"
|
|
52
|
-
|
|
53
|
-
_output_dottex_pathlist: tuple[str, ...] = ()
|
|
54
|
-
for _merger_class in _merger_classes:
|
|
55
|
-
_table_ind_group = (
|
|
56
|
-
_merger_class
|
|
57
|
-
if isinstance(_merger_class, isl.INDGRPConstants)
|
|
58
|
-
else isl.INDGRPConstants.ALL
|
|
59
|
-
)
|
|
60
|
-
_table_evid_cond = (
|
|
61
|
-
_merger_class
|
|
62
|
-
if isinstance(_merger_class, isl.EVIDENConstants)
|
|
63
|
-
else isl.EVIDENConstants.UR
|
|
64
|
-
)
|
|
65
|
-
_invres_rate_table_content.obs_merger_class = f"{_merger_class}"
|
|
66
|
-
|
|
67
|
-
for _data_period in _data_periods:
|
|
68
|
-
_data_array_dict_sub = _data_array_dict[_data_period][f"{_stats_group}"]
|
|
69
|
-
_table_no = isl.table_no_lku(
|
|
70
|
-
_data_array_dict_sub, # type: ignore
|
|
71
|
-
_table_ind_group,
|
|
72
|
-
_table_evid_cond,
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
_invres_rate_table_content.table_ref = _table_no
|
|
76
|
-
|
|
77
|
-
_data_period_0, _data_period_1 = (int(f) for f in _data_period.split("-"))
|
|
78
|
-
if _data_period_0 != 1996:
|
|
79
|
-
_invres_rate_table_content.invdata_notestr = " ".join((
|
|
80
|
-
"NOTES:",
|
|
81
|
-
isl.LTX_ARRAY_LINEEND,
|
|
82
|
-
R"\(\cdot\) Data for period, {}".format(
|
|
83
|
-
_data_periods[1].replace("-", "--")
|
|
84
|
-
),
|
|
85
|
-
f"calculated by subtracting reported figures for 1996--{_data_period_0 - 1}",
|
|
86
|
-
R"from reported figures for 1996--2011",
|
|
87
|
-
isl.LTX_ARRAY_LINEEND,
|
|
88
|
-
isl.LTX_ARRAY_LINEEND,
|
|
89
|
-
))
|
|
90
|
-
|
|
91
|
-
_invres_rate_table_content.invdata_sourcestr = " ".join((
|
|
92
|
-
"\\(\\cdot\\) Fed. Trade Comm'n ({}), at~\\cref{{fn:{}}},".format(
|
|
93
|
-
_data_period_0, f"FTCInvData1996to{_data_period_0}"
|
|
94
|
-
),
|
|
95
|
-
isl.LTX_ARRAY_LINEEND,
|
|
96
|
-
))
|
|
97
|
-
_invres_rate_table_content.invdata_sourcestr += " ".join((
|
|
98
|
-
"\\(\\cdot\\) Fed. Trade Comm'n ({}), at~\\cref{{fn:{}}},".format(
|
|
99
|
-
_data_period_1, f"FTCInvData1996to{_data_period_1}"
|
|
100
|
-
),
|
|
101
|
-
isl.LTX_ARRAY_LINEEND,
|
|
102
|
-
))
|
|
103
|
-
else:
|
|
104
|
-
_invres_rate_table_content.invdata_sourcestr = " ".join((
|
|
105
|
-
"\\(\\cdot\\) Fed. Trade Comm'n ({}), at~\\cref{{fn:{}}},".format(
|
|
106
|
-
_data_period_1, f"FTCInvData1996to{_data_period_1}"
|
|
107
|
-
),
|
|
108
|
-
isl.LTX_ARRAY_LINEEND,
|
|
109
|
-
))
|
|
110
|
-
|
|
111
|
-
_invres_rate_table_content.obs_merger_class = f"{_merger_class}"
|
|
112
|
-
_invres_rate_table_content.obs_period = _data_period.split("-")
|
|
113
|
-
|
|
114
|
-
_invres_cnts_array = _data_array_dict_sub[_table_no][-1] # type: ignore
|
|
115
|
-
_odds_ratio_data_str = ""
|
|
116
|
-
for _hhi_range_it in unique(_invres_cnts_array[:, 0]): # type: ignore
|
|
117
|
-
_invres_cnts_row_for_hhi_range = _invres_cnts_array[
|
|
118
|
-
_invres_cnts_array[:, 0] == _hhi_range_it
|
|
119
|
-
][:, 2:] # type: ignore
|
|
120
|
-
_odds_ratio_data_str += " & ".join([
|
|
121
|
-
INVRES_RATIO_FORMAT_STR.format(*g) # type: ignore
|
|
122
|
-
for g in _invres_cnts_row_for_hhi_range
|
|
123
|
-
])
|
|
124
|
-
_odds_ratio_data_str += " & {}".format(
|
|
125
|
-
INVRES_RATIO_FORMAT_STR.format(
|
|
126
|
-
*einsum("ij->j", _invres_cnts_row_for_hhi_range)
|
|
127
|
-
)
|
|
128
|
-
)
|
|
129
|
-
_odds_ratio_data_str += isl.LTX_ARRAY_LINEEND
|
|
130
|
-
|
|
131
|
-
_invres_cnts_row_for_hhi_tots = row_stack([
|
|
132
|
-
einsum(
|
|
133
|
-
"ij->j", _invres_cnts_array[_invres_cnts_array[:, 1] == f][:, 2:]
|
|
134
|
-
)
|
|
135
|
-
for f in unique(_invres_cnts_array[:, 1])
|
|
136
|
-
])
|
|
137
|
-
_odds_ratio_data_str += " & ".join([
|
|
138
|
-
INVRES_RATIO_FORMAT_STR.format(*f)
|
|
139
|
-
for f in _invres_cnts_row_for_hhi_tots
|
|
140
|
-
])
|
|
141
|
-
_odds_ratio_data_str += " & {}".format(
|
|
142
|
-
INVRES_RATIO_FORMAT_STR.format(
|
|
143
|
-
*einsum("ij->j", _invres_cnts_row_for_hhi_tots)
|
|
144
|
-
)
|
|
145
|
-
)
|
|
146
|
-
_odds_ratio_data_str += isl.LTX_ARRAY_LINEEND
|
|
147
|
-
_invres_rate_table_content.invdata_byhhianddelta = _odds_ratio_data_str
|
|
148
|
-
|
|
149
|
-
_output_dottex_path = DATA_DIR / INVDATA_DOTTEX_FORMAT_STR.format(
|
|
150
|
-
f"{_stats_group}_{_data_period_1}_{_merger_class.replace(" ", "")}"
|
|
151
|
-
)
|
|
152
|
-
with _output_dottex_path.open(
|
|
153
|
-
"w", encoding="utf8"
|
|
154
|
-
) as _invres_rate_table_dottex:
|
|
155
|
-
_invres_rate_table_dottex.write(
|
|
156
|
-
_invres_rate_table_design.render(
|
|
157
|
-
tmpl_data=_invres_rate_table_content
|
|
158
|
-
)
|
|
159
|
-
)
|
|
160
|
-
print("\n", file=_invres_rate_table_dottex)
|
|
161
|
-
|
|
162
|
-
_output_dottex_pathlist += (_output_dottex_path.name,)
|
|
163
|
-
print(_odds_ratio_data_str)
|
|
164
|
-
print()
|
|
165
|
-
del _odds_ratio_data_str
|
|
166
|
-
|
|
167
|
-
return _output_dottex_pathlist
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
def invres_stats_obs_setup(
|
|
171
|
-
_data_array_dict: Mapping,
|
|
172
|
-
_data_periods: tuple[str, str],
|
|
173
|
-
_merger_classes: Sequence[isl.INDGRPConstants | isl.EVIDENConstants],
|
|
174
|
-
_invres_spec: INVResolution = INVResolution.CLRN,
|
|
175
|
-
/,
|
|
176
|
-
) -> tuple[str, ...]:
|
|
177
|
-
_notes_str_base = " ".join((
|
|
178
|
-
"NOTES:",
|
|
179
|
-
isl.LTX_ARRAY_LINEEND,
|
|
180
|
-
Rf"\(\cdot\) Data for period, {_data_periods[1].replace("-", "--")}",
|
|
181
|
-
"calculated by subtracting reported figures for 1996--{}".format(
|
|
182
|
-
int(_data_periods[1].split("-")[0]) - 1
|
|
183
|
-
),
|
|
184
|
-
"from reported figures for 1996--{}".format(_data_periods[1].split("-")[1]),
|
|
185
|
-
))
|
|
186
|
-
_stats_group_dict = {
|
|
187
|
-
isl.StatsGrpSelector.FC: {
|
|
188
|
-
"desc": f"{_invres_spec.capitalize()} rates by Firm Count",
|
|
189
|
-
"title_str": "By Number of Significant Competitors",
|
|
190
|
-
"hval": "Firm Count",
|
|
191
|
-
"hcol_width": 54,
|
|
192
|
-
"notewidth": 0.67,
|
|
193
|
-
"notestr": " ".join((
|
|
194
|
-
_notes_str_base,
|
|
195
|
-
isl.LTX_ARRAY_LINEEND,
|
|
196
|
-
isl.LTX_ARRAY_LINEEND,
|
|
197
|
-
isl.LTX_ARRAY_LINEEND,
|
|
198
|
-
)),
|
|
199
|
-
},
|
|
200
|
-
isl.StatsGrpSelector.DL: {
|
|
201
|
-
"desc": Rf"{_invres_spec.capitalize()} rates by range of \(\Delta HHI\)",
|
|
202
|
-
"title_str": R"By Change in Concentration (\Deltah{})",
|
|
203
|
-
"hval": R"$\Delta HHI$",
|
|
204
|
-
"hval_plus": R"{ $[\Delta_L, \Delta_H)$ pts.}",
|
|
205
|
-
"hcol_width": 54,
|
|
206
|
-
"notewidth": 0.67,
|
|
207
|
-
"notestr": " ".join((
|
|
208
|
-
_notes_str_base,
|
|
209
|
-
isl.LTX_ARRAY_LINEEND,
|
|
210
|
-
isl.LTX_ARRAY_LINEEND,
|
|
211
|
-
)),
|
|
212
|
-
"notestr_plus": " ".join((
|
|
213
|
-
R"\(\cdot\) Ranges of $\Delta HHI$ are defined as",
|
|
214
|
-
"half-open intervals with",
|
|
215
|
-
R"$\Delta_L \leqslant \Delta HHI < \Delta_H$, except that",
|
|
216
|
-
R"$2500 \text{ pts.} \leqslant \Delta HHI \leqslant 5000 \text{ pts.}$",
|
|
217
|
-
R"in the closed interval [2500, 5000] pts.",
|
|
218
|
-
isl.LTX_ARRAY_LINEEND,
|
|
219
|
-
isl.LTX_ARRAY_LINEEND,
|
|
220
|
-
)),
|
|
221
|
-
},
|
|
222
|
-
isl.StatsGrpSelector.ZN: {
|
|
223
|
-
"desc": f"{_invres_spec.capitalize()} rates by Approximate Presumption Zone",
|
|
224
|
-
"title_str": R"By Approximate \textit{2010 Guidelines} Concentration-Based Standards",
|
|
225
|
-
"hval": "Approximate Standard",
|
|
226
|
-
"hcol_width": 190,
|
|
227
|
-
"notewidth": 0.96,
|
|
228
|
-
"notestr": " ".join((
|
|
229
|
-
_notes_str_base,
|
|
230
|
-
isl.LTX_ARRAY_LINEEND,
|
|
231
|
-
isl.LTX_ARRAY_LINEEND,
|
|
232
|
-
)),
|
|
233
|
-
},
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
_output_dottex_pathlist = ()
|
|
237
|
-
for _stats_group_key in _stats_group_dict:
|
|
238
|
-
_output_dottex_path = _invres_stats_obs_render(
|
|
239
|
-
_data_array_dict,
|
|
240
|
-
_data_periods,
|
|
241
|
-
_merger_classes,
|
|
242
|
-
_stats_group_key,
|
|
243
|
-
_stats_group_dict[_stats_group_key],
|
|
244
|
-
_invres_spec,
|
|
245
|
-
)
|
|
246
|
-
_output_dottex_pathlist += (_output_dottex_path,) # type: ignore
|
|
247
|
-
|
|
248
|
-
return _output_dottex_pathlist
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
def _invres_stats_obs_render(
|
|
252
|
-
_data_array_dict: Mapping,
|
|
253
|
-
_data_periods: tuple[str, str],
|
|
254
|
-
_merger_classes: Sequence[isl.INDGRPConstants | isl.EVIDENConstants],
|
|
255
|
-
_stats_group: isl.StatsGrpSelector,
|
|
256
|
-
_stats_group_dict: Mapping,
|
|
257
|
-
_invres_spec: isl.INVResolution = INVResolution.CLRN,
|
|
258
|
-
/,
|
|
259
|
-
) -> str:
|
|
260
|
-
_invres_rate_table_content = isl.StatsContainer()
|
|
261
|
-
_invres_rate_table_design = isl.latex_jinja_env.get_template(
|
|
262
|
-
"ftcinvdata_summarypaired_table_template.tex.jinja2"
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
print(
|
|
266
|
-
f'{_stats_group_dict["desc"]}:', ", ".join([f'"{g}"' for g in _merger_classes])
|
|
267
|
-
)
|
|
268
|
-
_invres_rate_table_content.test_regime = _invres_spec.capitalize()
|
|
269
|
-
_invres_rate_table_content.obs_summary_type = f"{_stats_group}"
|
|
270
|
-
_invres_rate_table_content.obs_summary_type_title = _stats_group_dict.get(
|
|
271
|
-
"title_str"
|
|
272
|
-
)
|
|
273
|
-
_invres_rate_table_content.hdrcol_raw_width = f'{_stats_group_dict["hcol_width"]}pt'
|
|
274
|
-
|
|
275
|
-
_hs1 = _stats_group_dict["hval"]
|
|
276
|
-
_hs2 = _h if (_h := _stats_group_dict.get("hval_plus", "")) else _hs1
|
|
277
|
-
_invres_rate_table_content.invdata_hdrcoldescstr = (
|
|
278
|
-
isl.latex_hrdcoldesc_format_str.format(
|
|
279
|
-
"hdrcol_raw",
|
|
280
|
-
f'{_stats_group_dict["hcol_width"]}pt',
|
|
281
|
-
"hdrcoldesc_raw",
|
|
282
|
-
"center",
|
|
283
|
-
" ".join((
|
|
284
|
-
_hs1 if _hs1 != _hs2 else Rf"{{ \phantom{{{_hs1}}} }}",
|
|
285
|
-
isl.LTX_ARRAY_LINEEND,
|
|
286
|
-
_hs2,
|
|
287
|
-
isl.LTX_ARRAY_LINEEND,
|
|
288
|
-
)),
|
|
289
|
-
)
|
|
290
|
-
)
|
|
291
|
-
del _hs1, _hs2
|
|
292
|
-
|
|
293
|
-
_invres_rate_table_content.obs_merger_class_0 = f"{_merger_classes[0]}"
|
|
294
|
-
_invres_rate_table_content.obs_merger_class_1 = f"{_merger_classes[1]}"
|
|
295
|
-
_invres_rate_table_content.obs_periods_str = (
|
|
296
|
-
Rf"{" & ".join(_data_periods)} \\".replace("-", "--")
|
|
297
|
-
)
|
|
298
|
-
|
|
299
|
-
_invres_rate_table_content.invdata_notewidth = _stats_group_dict["notewidth"]
|
|
300
|
-
_invres_rate_table_content.invdata_notestr = _stats_group_dict["notestr"]
|
|
301
|
-
if _n2 := _stats_group_dict.get("notestr_plus", ""):
|
|
302
|
-
_invres_rate_table_content.invdata_notestr += _n2
|
|
303
|
-
del _n2
|
|
304
|
-
|
|
305
|
-
_invdata_sourcestr_format_str = "{} {}".format(
|
|
306
|
-
R"\(\cdot\) Fed. Trade Comm'n ({}), at note~\cref{{fn:{}}}",
|
|
307
|
-
isl.LTX_ARRAY_LINEEND,
|
|
308
|
-
)
|
|
309
|
-
|
|
310
|
-
_table_nos = get_table_nos(
|
|
311
|
-
_data_array_dict, _merger_classes, _stats_group, _data_periods[0]
|
|
312
|
-
)
|
|
313
|
-
_src_table_nos_str = (
|
|
314
|
-
f'{", ".join(_table_nos[:-1])} and {_table_nos[-1]}'
|
|
315
|
-
if _merger_classes[0] != isl.EVIDENConstants.NE
|
|
316
|
-
else "Table~{0}.1, Table~{1}.1, and Table~{1}.2".format(
|
|
317
|
-
*(4, 10) if _stats_group == "ByFirmCount" else (3, 9)
|
|
318
|
-
)
|
|
319
|
-
)
|
|
320
|
-
_invres_rate_table_content.invdata_sourcestr = _invdata_sourcestr_format_str.format(
|
|
321
|
-
"2003", "FTCInvData1996to2003"
|
|
322
|
-
)
|
|
323
|
-
_invres_rate_table_content.invdata_sourcestr += (
|
|
324
|
-
_invdata_sourcestr_format_str.format("2011", "FTCInvData1996to2011")
|
|
325
|
-
)
|
|
326
|
-
|
|
327
|
-
_invdata_hdr_list: list[str] = []
|
|
328
|
-
_invdata_dat_list: list[list[str]] = []
|
|
329
|
-
_invres_cnt_totals: list[str] = []
|
|
330
|
-
_sort_order = (
|
|
331
|
-
isl.SortSelector.UCH
|
|
332
|
-
if _stats_group == isl.StatsGrpSelector.FC
|
|
333
|
-
else isl.SortSelector.REV
|
|
334
|
-
)
|
|
335
|
-
|
|
336
|
-
for _merger_class in _merger_classes:
|
|
337
|
-
_table_ind_group = (
|
|
338
|
-
_merger_class
|
|
339
|
-
if isinstance(_merger_class, isl.INDGRPConstants)
|
|
340
|
-
else isl.INDGRPConstants.ALL
|
|
341
|
-
)
|
|
342
|
-
_table_evid_cond = (
|
|
343
|
-
_merger_class
|
|
344
|
-
if isinstance(_merger_class, isl.EVIDENConstants)
|
|
345
|
-
else isl.EVIDENConstants.UR
|
|
346
|
-
)
|
|
347
|
-
for _data_period in _data_periods:
|
|
348
|
-
_invres_cnt_totals += [
|
|
349
|
-
isl.invres_stats_output(
|
|
350
|
-
_data_array_dict,
|
|
351
|
-
_data_period,
|
|
352
|
-
_table_ind_group,
|
|
353
|
-
_table_evid_cond,
|
|
354
|
-
_stats_group,
|
|
355
|
-
_invres_spec,
|
|
356
|
-
return_type_sel=isl.StatsReturnSelector.CNT,
|
|
357
|
-
print_to_screen=False,
|
|
358
|
-
)[1][-1][0]
|
|
359
|
-
]
|
|
360
|
-
|
|
361
|
-
_invdata_hdr_list_it, _invdata_dat_list_it = isl.invres_stats_output(
|
|
362
|
-
_data_array_dict,
|
|
363
|
-
_data_period,
|
|
364
|
-
_table_ind_group,
|
|
365
|
-
_table_evid_cond,
|
|
366
|
-
_stats_group,
|
|
367
|
-
_invres_spec,
|
|
368
|
-
return_type_sel=isl.StatsReturnSelector.RPT,
|
|
369
|
-
sort_order=_sort_order,
|
|
370
|
-
print_to_screen=False,
|
|
371
|
-
)
|
|
372
|
-
_invdata_hdr_list = _invdata_hdr_list_it
|
|
373
|
-
_invdata_dat_list = (
|
|
374
|
-
_invdata_dat_list_it[:]
|
|
375
|
-
if not _invdata_dat_list
|
|
376
|
-
else [
|
|
377
|
-
_invdata_dat_list[_r][:] + _invdata_dat_list_it[_r][:]
|
|
378
|
-
for _r in range(len(_invdata_dat_list))
|
|
379
|
-
]
|
|
380
|
-
)
|
|
381
|
-
|
|
382
|
-
isl.stats_print_rows(_invdata_hdr_list, _invdata_dat_list)
|
|
383
|
-
|
|
384
|
-
_invdata_hdrstr = "".join([
|
|
385
|
-
f"{_invdata_hdr_list[g]} {isl.LTX_ARRAY_LINEEND}"
|
|
386
|
-
for g in range(len(_invdata_hdr_list))
|
|
387
|
-
])
|
|
388
|
-
|
|
389
|
-
_invdata_datstr = "".join([
|
|
390
|
-
f"{" & ".join(_invdata_dat_list[g])} {isl.LTX_ARRAY_LINEEND}"
|
|
391
|
-
for g in range(len(_invdata_dat_list))
|
|
392
|
-
])
|
|
393
|
-
|
|
394
|
-
(
|
|
395
|
-
_invres_rate_table_content.mkt_counts_str_class_0,
|
|
396
|
-
_invres_rate_table_content.mkt_counts_str_class_1,
|
|
397
|
-
) = (
|
|
398
|
-
R"{} \\".format(" & ".join([f"Obs. = {f}" for f in g]))
|
|
399
|
-
for g in [
|
|
400
|
-
_invres_cnt_totals[: len(_data_periods)],
|
|
401
|
-
_invres_cnt_totals[len(_data_periods) :],
|
|
402
|
-
]
|
|
403
|
-
)
|
|
404
|
-
|
|
405
|
-
_invres_rate_table_content.invdata_numrows = len(_invdata_hdr_list)
|
|
406
|
-
_invres_rate_table_content.invdata_hdrstr = _invdata_hdrstr
|
|
407
|
-
_invres_rate_table_content.invdata_datstr = _invdata_datstr
|
|
408
|
-
|
|
409
|
-
_output_dottex_path = DATA_DIR / INVDATA_DOTTEX_FORMAT_STR.format(_stats_group)
|
|
410
|
-
with _output_dottex_path.open("w", encoding="UTF-8") as _output_dottex_file:
|
|
411
|
-
_output_dottex_file.write(
|
|
412
|
-
_invres_rate_table_design.render(tmpl_data=_invres_rate_table_content)
|
|
413
|
-
)
|
|
414
|
-
print("\n", file=_output_dottex_file)
|
|
415
|
-
del _invdata_hdrstr, _invdata_datstr
|
|
416
|
-
|
|
417
|
-
return _output_dottex_path.name
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
def get_table_nos(
|
|
421
|
-
_data_array_dict: Mapping[str, fid.INVData],
|
|
422
|
-
_merger_classes: Sequence[isl.INDGRPConstants | isl.EVIDENConstants],
|
|
423
|
-
_stats_group: isl.StatsGrpSelector,
|
|
424
|
-
_data_period: str,
|
|
425
|
-
/,
|
|
426
|
-
) -> list[str]:
|
|
427
|
-
_stats_group_major = (
|
|
428
|
-
"ByFirmCount" if _stats_group == isl.StatsGrpSelector.FC else "ByHHIandDelta"
|
|
429
|
-
)
|
|
430
|
-
|
|
431
|
-
_table_ind_groups = tuple(
|
|
432
|
-
(_m if isinstance(_m, isl.INDGRPConstants) else isl.INDGRPConstants.ALL)
|
|
433
|
-
for _m in _merger_classes
|
|
434
|
-
)
|
|
435
|
-
_table_evid_conds = tuple(
|
|
436
|
-
(_m if isinstance(_m, isl.EVIDENConstants) else isl.EVIDENConstants.UR)
|
|
437
|
-
for _m in _merger_classes
|
|
438
|
-
)
|
|
439
|
-
|
|
440
|
-
return list(
|
|
441
|
-
dict.fromkeys(
|
|
442
|
-
isl.table_no_lku(
|
|
443
|
-
_data_array_dict[_data_period][_stats_group_major],
|
|
444
|
-
_table_ind_group,
|
|
445
|
-
_table_evid_cond,
|
|
446
|
-
)
|
|
447
|
-
for _table_ind_group in _table_ind_groups
|
|
448
|
-
for _table_evid_cond in _table_evid_conds
|
|
449
|
-
)
|
|
450
|
-
)
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
if __name__ == "__main__":
|
|
454
|
-
invdata_array_dict = fid.construct_data(
|
|
455
|
-
fid.INVDATA_ARCHIVE_PATH,
|
|
456
|
-
flag_backward_compatibility=False,
|
|
457
|
-
flag_pharma_for_exclusion=True,
|
|
458
|
-
)
|
|
459
|
-
|
|
460
|
-
merger_classes = (
|
|
461
|
-
isl.EVIDENConstants.NE,
|
|
462
|
-
isl.EVIDENConstants.ED,
|
|
463
|
-
) # clstl.INDGRPConstants.IID)
|
|
464
|
-
data_periods = ("1996-2003", "2004-2011")
|
|
465
|
-
test_regime = INVResolution.ENFT
|
|
466
|
-
|
|
467
|
-
# Now generate the various tables summarizing merger investigations data
|
|
468
|
-
invres_stats_byhhianddelta_pathlist = invres_stats_odds_ratio_byhhianddelta(
|
|
469
|
-
invdata_array_dict, data_periods, merger_classes
|
|
470
|
-
)
|
|
471
|
-
print(invres_stats_byhhianddelta_pathlist)
|
|
472
|
-
invres_stats_allothers_pathlist = invres_stats_obs_setup(
|
|
473
|
-
invdata_array_dict, data_periods, merger_classes, test_regime
|
|
474
|
-
)
|
|
475
|
-
isl.render_table_pdf(
|
|
476
|
-
invres_stats_byhhianddelta_pathlist,
|
|
477
|
-
INVDATA_DOTTEX_FORMAT_STR.format("ByHHIandDelta"),
|
|
478
|
-
)
|
|
479
|
-
isl.render_table_pdf(
|
|
480
|
-
invres_stats_allothers_pathlist, INVDATA_DOTTEX_FORMAT_STR.format("AllOthers")
|
|
481
|
-
)
|