mergeron 2024.738953.1__py3-none-any.whl → 2024.738972.0__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,5 +1,5 @@
1
1
  """
2
- Routines to generate data for analyzing merger enforcement policy.
2
+ Methods to generate data for analyzing merger enforcement policy.
3
3
 
4
4
  """
5
5
 
@@ -7,7 +7,6 @@ from __future__ import annotations
7
7
 
8
8
  from importlib.metadata import version
9
9
 
10
- import attrs
11
10
  import numpy as np
12
11
  from numpy.random import SeedSequence
13
12
  from numpy.typing import NDArray
@@ -15,19 +14,18 @@ from numpy.typing import NDArray
15
14
  from .. import _PKG_NAME, RECConstants # noqa: TID252
16
15
  from . import (
17
16
  EMPTY_ARRAY_DEFAULT,
18
- TF,
19
17
  FM2Constants,
20
18
  MarketDataSample,
21
- MarketSampleSpec,
19
+ MarketSpec,
22
20
  PRIConstants,
23
21
  SHRConstants,
24
22
  SSZConstants,
25
23
  )
26
- from ._data_generation_functions_nonpublic import (
24
+ from ._data_generation_functions import (
27
25
  _gen_market_shares_dirichlet, # noqa: F401 easter-egg for external modules
28
26
  _gen_market_shares_uniform, # noqa: F401 easter-egg for external modules
29
27
  _gen_pcm_data,
30
- _gen_pr_data,
28
+ _gen_price_data,
31
29
  _gen_share_data,
32
30
  )
33
31
 
@@ -35,9 +33,10 @@ __version__ = version(_PKG_NAME)
35
33
 
36
34
 
37
35
  def gen_market_sample(
38
- _mkt_sample_spec: MarketSampleSpec,
36
+ _mkt_sample_spec: MarketSpec,
39
37
  /,
40
38
  *,
39
+ sample_size: int = 10**6,
41
40
  seed_seq_list: list[SeedSequence] | None = None,
42
41
  nthreads: int = 16,
43
42
  ) -> MarketDataSample:
@@ -45,7 +44,7 @@ def gen_market_sample(
45
44
  Generate share, diversion ratio, price, and margin data based on supplied parameters
46
45
 
47
46
  Diversion ratios generated assuming share-proportionality, unless
48
- `recapture_spec` = "proportional", in which case both firms' recapture rate
47
+ `recapture_form` = "proportional", in which case both firms' recapture rate
49
48
  is set to `r_bar`.
50
49
 
51
50
  The tuple of SeedSequences, if specified, is parsed in the following order
@@ -54,12 +53,14 @@ def gen_market_sample(
54
53
  2.) price-cost margins
55
54
  3.) firm-counts, from :code:`[2, 2 + len(firm_counts_weights)]`,
56
55
  weighted by :code:`firm_counts_weights`, where relevant
57
- 4.) prices, if :code:`pr_sym_spec == PRIConstants.ZERO`.
56
+ 4.) prices, if :code:`price_spec == PRIConstants.ZERO`.
58
57
 
59
58
  Parameters
60
59
  ----------
61
60
  _mkt_sample_spec
62
61
  class specifying parameters for data generation
62
+ sample_size
63
+ number of draws to generate
63
64
  seed_seq_list
64
65
  tuple of SeedSequences to ensure replicable data generation with
65
66
  appropriately independent random streams
@@ -73,9 +74,10 @@ def gen_market_sample(
73
74
 
74
75
  """
75
76
 
76
- _mkt_sample_spec = _mkt_sample_spec or MarketSampleSpec()
77
+ _mkt_sample_spec = _mkt_sample_spec or MarketSpec()
77
78
 
78
- _recapture_spec = _mkt_sample_spec.share_spec.recapture_spec
79
+ _recapture_form = _mkt_sample_spec.share_spec.recapture_form
80
+ _recapture_rate = _mkt_sample_spec.share_spec.recapture_rate
79
81
  _dist_type_mktshr = _mkt_sample_spec.share_spec.dist_type
80
82
  _dist_firm2_pcm = _mkt_sample_spec.pcm_spec.firm2_pcm_constraint
81
83
  _hsr_filing_test_type = _mkt_sample_spec.hsr_filing_test_type
@@ -86,22 +88,23 @@ def gen_market_sample(
86
88
  _fcount_rng_seed_seq,
87
89
  _pr_rng_seed_seq,
88
90
  ) = parse_seed_seq_list(
89
- seed_seq_list, _dist_type_mktshr, _mkt_sample_spec.pr_sym_spec
91
+ seed_seq_list, _dist_type_mktshr, _mkt_sample_spec.price_spec
90
92
  )
91
93
 
92
- _shr_sample_size = 1.0 * _mkt_sample_spec.sample_size
94
+ _shr_sample_size = 1.0 * sample_size
93
95
  # Scale up sample size to offset discards based on specified criteria
94
96
  _shr_sample_size *= _hsr_filing_test_type
95
97
  if _dist_firm2_pcm == FM2Constants.MNL:
96
98
  _shr_sample_size *= SSZConstants.MNL_DEP
97
- _mkt_sample_spec_here = attrs.evolve(
98
- _mkt_sample_spec, sample_size=int(_shr_sample_size)
99
- )
100
- del _shr_sample_size
99
+ _shr_sample_size = int(_shr_sample_size)
101
100
 
102
101
  # Generate share data
103
102
  _mktshr_data = _gen_share_data(
104
- _mkt_sample_spec_here, _fcount_rng_seed_seq, _mktshr_rng_seed_seq, nthreads
103
+ _shr_sample_size,
104
+ _mkt_sample_spec,
105
+ _fcount_rng_seed_seq,
106
+ _mktshr_rng_seed_seq,
107
+ nthreads,
105
108
  )
106
109
 
107
110
  _mktshr_array, _fcounts, _aggregate_purchase_prob, _nth_firm_share = (
@@ -115,8 +118,8 @@ def gen_market_sample(
115
118
  )
116
119
 
117
120
  # Generate merging-firm price data
118
- _price_data = _gen_pr_data(
119
- _mktshr_array[:, :2], _nth_firm_share, _mkt_sample_spec_here, _pr_rng_seed_seq
121
+ _price_data = _gen_price_data(
122
+ _mktshr_array[:, :2], _nth_firm_share, _mkt_sample_spec, _pr_rng_seed_seq
120
123
  )
121
124
 
122
125
  _price_array, _hsr_filing_test = (
@@ -132,16 +135,13 @@ def gen_market_sample(
132
135
 
133
136
  # Calculate diversion ratios
134
137
  _divr_array = gen_divr_array(
135
- _mktshr_array[:, :2],
136
- _mkt_sample_spec_here.recapture_rate or 0.8,
137
- _recapture_spec,
138
- _aggregate_purchase_prob,
138
+ _recapture_form, _recapture_rate, _mktshr_array[:, :2], _aggregate_purchase_prob
139
139
  )
140
140
 
141
141
  # Generate margin data
142
142
  _pcm_data = _gen_pcm_data(
143
143
  _mktshr_array[:, :2],
144
- _mkt_sample_spec_here,
144
+ _mkt_sample_spec,
145
145
  _price_array,
146
146
  _aggregate_purchase_prob,
147
147
  _pcm_rng_seed_seq,
@@ -151,7 +151,7 @@ def gen_market_sample(
151
151
  getattr(_pcm_data, _f) for _f in ("pcm_array", "mnl_test_array")
152
152
  )
153
153
 
154
- _s_size = _mkt_sample_spec.sample_size # originally-specified sample size
154
+ _s_size = sample_size # originally-specified sample size
155
155
  if _dist_firm2_pcm == FM2Constants.MNL:
156
156
  _mktshr_array = _mktshr_array[_mnl_test_rows][:_s_size]
157
157
  _pcm_array = _pcm_array[_mnl_test_rows][:_s_size]
@@ -185,18 +185,18 @@ def gen_market_sample(
185
185
 
186
186
  def parse_seed_seq_list(
187
187
  _sseq_list: list[SeedSequence] | None,
188
- _dist_type_mktshr: SHRConstants,
189
- _pr_sym_spec: PRIConstants,
188
+ _mktshr_dist_type: SHRConstants,
189
+ _price_spec: PRIConstants,
190
190
  /,
191
191
  ) -> tuple[SeedSequence, SeedSequence, SeedSequence | None, SeedSequence | None]:
192
192
  """Initialize RNG seed sequences to ensure independence of distinct random streams."""
193
193
  _fcount_rng_seed_seq: SeedSequence | None = None
194
194
  _pr_rng_seed_seq: SeedSequence | None = None
195
195
 
196
- if _pr_sym_spec == PRIConstants.ZERO:
196
+ if _price_spec == PRIConstants.ZERO:
197
197
  _pr_rng_seed_seq = _sseq_list.pop() if _sseq_list else SeedSequence(pool_size=8)
198
198
 
199
- if _dist_type_mktshr == SHRConstants.UNI:
199
+ if _mktshr_dist_type == SHRConstants.UNI:
200
200
  _fcount_rng_seed_seq = None
201
201
  _seed_count = 2
202
202
  _mktshr_rng_seed_seq, _pcm_rng_seed_seq = (
@@ -221,10 +221,10 @@ def parse_seed_seq_list(
221
221
 
222
222
 
223
223
  def gen_divr_array(
224
- _frmshr_array: NDArray[np.floating[TF]],
225
- _r_bar: float,
226
- _recapture_spec: RECConstants = RECConstants.INOUT,
227
- _aggregate_purchase_prob: NDArray[np.floating[TF]] = EMPTY_ARRAY_DEFAULT,
224
+ _recapture_form: RECConstants,
225
+ _recapture_rate: float | None,
226
+ _frmshr_array: NDArray[np.float64],
227
+ _aggregate_purchase_prob: NDArray[np.float64] = EMPTY_ARRAY_DEFAULT,
228
228
  /,
229
229
  ) -> NDArray[np.float64]:
230
230
  """
@@ -235,20 +235,20 @@ def gen_divr_array(
235
235
 
236
236
  Parameters
237
237
  ----------
238
- _frmshr_array
239
- Merging-firm shares.
238
+ _recapture_form
239
+ Enum specifying Fixed (proportional), Inside-out, or Outside-in
240
240
 
241
- _r_bar
241
+ _recapture_rate
242
242
  If recapture is proportional or inside-out, the recapture rate
243
243
  for the firm with the smaller share.
244
244
 
245
+ _frmshr_array
246
+ Merging-firm shares.
247
+
245
248
  _aggregate_purchase_prob
246
249
  1 minus probability that the outside good is chosen; converts
247
250
  market shares to choice probabilities by multiplication.
248
251
 
249
- _recapture_spec
250
- Enum specifying Fixed (proportional), Inside-out, or Outside-in
251
-
252
252
  Returns
253
253
  -------
254
254
  Merging-firm diversion ratios for mergers in the sample.
@@ -256,8 +256,8 @@ def gen_divr_array(
256
256
  """
257
257
 
258
258
  _divr_array: NDArray[np.float64]
259
- if _recapture_spec == RECConstants.FIXED:
260
- _divr_array = _r_bar * _frmshr_array[:, ::-1] / (1 - _frmshr_array)
259
+ if _recapture_form == RECConstants.FIXED:
260
+ _divr_array = _recapture_rate * _frmshr_array[:, ::-1] / (1 - _frmshr_array) # type: ignore
261
261
 
262
262
  else:
263
263
  _purchprob_array = _aggregate_purchase_prob * _frmshr_array
@@ -1,5 +1,5 @@
1
1
  """
2
- Routines to format and print summary data on merger enforcement patterns.
2
+ Methods to format and print summary data on merger enforcement patterns.
3
3
 
4
4
  """
5
5
 
@@ -0,0 +1,79 @@
1
+ """
2
+ Methods to generate data for analyzing merger enforcement policy.
3
+
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from importlib.metadata import version
9
+
10
+ from attrs import define
11
+ from numpy.random import SeedSequence
12
+
13
+ from .. import _PKG_NAME # noqa: TID252
14
+ from ..core import guidelines_boundaries as gbl # noqa: TID252
15
+ from . import MarketSpec, UPPTestRegime
16
+ from .data_generation import gen_market_sample
17
+ from .upp_tests import SaveData, invres_cnts, save_data_to_hdf5, sim_invres_cnts_ll
18
+
19
+ __version__ = version(_PKG_NAME)
20
+
21
+
22
+ @define(slots=False)
23
+ class MarketSample(MarketSpec):
24
+ def generate_sample(
25
+ self,
26
+ /,
27
+ *,
28
+ sample_size: int = 10**6,
29
+ seed_seq_list: list[SeedSequence] | None,
30
+ nthreads: int,
31
+ save_data_to_file: SaveData = False,
32
+ ) -> None:
33
+ self.data = gen_market_sample(
34
+ self,
35
+ sample_size=sample_size,
36
+ seed_seq_list=seed_seq_list,
37
+ nthreads=nthreads,
38
+ )
39
+ _invalid_array_names = (
40
+ ("fcounts", "choice_prob_outgd", "nth_firm_share", "hhi_post")
41
+ if self.share_spec.dist_type == "Uniform"
42
+ else ()
43
+ )
44
+ if save_data_to_file:
45
+ save_data_to_hdf5(
46
+ self.data,
47
+ excluded_attrs=_invalid_array_names,
48
+ save_data_to_file=save_data_to_file,
49
+ )
50
+
51
+ def estimate_invres_counts(
52
+ self,
53
+ _invres_parm_vec: gbl.HMGThresholds,
54
+ _upp_test_regime: UPPTestRegime,
55
+ /,
56
+ *,
57
+ sample_size: int = 10**6,
58
+ seed_seq_list: list[SeedSequence] | None,
59
+ nthreads: int,
60
+ save_data_to_file: SaveData = False,
61
+ ) -> None:
62
+ if getattr(self, "market_data_sample", None) is None:
63
+ self.invres_counts = sim_invres_cnts_ll(
64
+ self,
65
+ _invres_parm_vec,
66
+ _upp_test_regime,
67
+ save_data_to_file=save_data_to_file,
68
+ sample_size=sample_size,
69
+ seed_seq_list=seed_seq_list,
70
+ nthreads=nthreads,
71
+ )
72
+ else:
73
+ self.invres_counts = invres_cnts(
74
+ self.data, _invres_parm_vec, _upp_test_regime
75
+ )
76
+ if save_data_to_file:
77
+ save_data_to_hdf5(
78
+ self.invres_counts, save_data_to_file=save_data_to_file
79
+ )