mergeron 2025.739265.0__py3-none-any.whl → 2025.739290.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.
- mergeron/__init__.py +51 -2
- mergeron/core/__init__.py +2 -2
- mergeron/core/empirical_margin_distribution.py +2 -2
- mergeron/core/ftc_merger_investigations_data.py +1 -1
- mergeron/core/guidelines_boundaries.py +18 -15
- mergeron/core/guidelines_boundary_functions.py +1 -1
- mergeron/core/guidelines_boundary_functions_extra.py +4 -4
- mergeron/core/pseudorandom_numbers.py +146 -108
- mergeron/demo/visualize_empirical_margin_distribution.py +1 -1
- mergeron/gen/__init__.py +226 -88
- mergeron/gen/data_generation.py +144 -177
- mergeron/gen/data_generation_functions.py +73 -122
- mergeron/gen/enforcement_stats.py +30 -6
- mergeron/gen/upp_tests.py +9 -10
- {mergeron-2025.739265.0.dist-info → mergeron-2025.739290.0.dist-info}/METADATA +2 -1
- mergeron-2025.739290.0.dist-info/RECORD +23 -0
- mergeron-2025.739265.0.dist-info/RECORD +0 -23
- {mergeron-2025.739265.0.dist-info → mergeron-2025.739290.0.dist-info}/WHEEL +0 -0
|
@@ -4,22 +4,28 @@ Non-public functions called in data_generation.py
|
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
-
from collections.abc import Sequence
|
|
8
7
|
from typing import Literal
|
|
9
8
|
|
|
10
9
|
import numpy as np
|
|
11
10
|
from attrs import evolve
|
|
12
11
|
from numpy.random import SeedSequence
|
|
13
12
|
|
|
14
|
-
from .. import
|
|
13
|
+
from .. import ( # noqa: TID252
|
|
14
|
+
DEFAULT_REC_RATIO,
|
|
15
|
+
NTHREADS,
|
|
16
|
+
VERSION,
|
|
17
|
+
ArrayDouble,
|
|
18
|
+
ArrayFloat,
|
|
19
|
+
RECForm,
|
|
20
|
+
)
|
|
15
21
|
from ..core.empirical_margin_distribution import mgn_data_resampler # noqa: TID252
|
|
16
22
|
from ..core.pseudorandom_numbers import ( # noqa: TID252
|
|
23
|
+
DEFAULT_BETA_DIST_PARMS,
|
|
17
24
|
DEFAULT_DIST_PARMS,
|
|
18
25
|
MultithreadedRNG,
|
|
19
26
|
prng,
|
|
20
27
|
)
|
|
21
28
|
from . import (
|
|
22
|
-
DEFAULT_EMPTY_ARRAY,
|
|
23
29
|
DEFAULT_FCOUNT_WTS,
|
|
24
30
|
FM2Constraint,
|
|
25
31
|
MarginDataSample,
|
|
@@ -27,7 +33,6 @@ from . import (
|
|
|
27
33
|
PCMSpec,
|
|
28
34
|
PriceDataSample,
|
|
29
35
|
PriceSpec,
|
|
30
|
-
SeedSequenceData,
|
|
31
36
|
ShareDataSample,
|
|
32
37
|
ShareSpec,
|
|
33
38
|
SHRDistribution,
|
|
@@ -41,8 +46,8 @@ def gen_share_data(
|
|
|
41
46
|
_sample_size: int,
|
|
42
47
|
_share_spec: ShareSpec,
|
|
43
48
|
_fcount_rng_seed_seq: SeedSequence | None,
|
|
44
|
-
_mktshr_rng_seed_seq: SeedSequence,
|
|
45
|
-
_nthreads: int =
|
|
49
|
+
_mktshr_rng_seed_seq: SeedSequence | None = None,
|
|
50
|
+
_nthreads: int = NTHREADS,
|
|
46
51
|
/,
|
|
47
52
|
) -> ShareDataSample:
|
|
48
53
|
"""Helper function for generating share data.
|
|
@@ -70,6 +75,12 @@ def gen_share_data(
|
|
|
70
75
|
)
|
|
71
76
|
|
|
72
77
|
_ssz = _sample_size
|
|
78
|
+
if not len(_dist_parms_mktshr):
|
|
79
|
+
_dist_parms_mktshr = (
|
|
80
|
+
DEFAULT_DIST_PARMS
|
|
81
|
+
if _dist_type_mktshr == "Uniform"
|
|
82
|
+
else np.ones(1 + len(_firm_count_prob_wts), float)
|
|
83
|
+
)
|
|
73
84
|
|
|
74
85
|
if _dist_type_mktshr == SHRDistribution.UNI:
|
|
75
86
|
_mkt_share_sample = gen_market_shares_uniform(
|
|
@@ -80,9 +91,9 @@ def gen_share_data(
|
|
|
80
91
|
_firm_count_prob_wts = (
|
|
81
92
|
None
|
|
82
93
|
if _firm_count_prob_wts is None
|
|
83
|
-
else np.array(_firm_count_prob_wts,
|
|
94
|
+
else np.array(_firm_count_prob_wts, float)
|
|
84
95
|
)
|
|
85
|
-
_mkt_share_sample =
|
|
96
|
+
_mkt_share_sample = _gen_market_shares_dirichlet_multimarket(
|
|
86
97
|
_ssz,
|
|
87
98
|
_recapture_form,
|
|
88
99
|
_dist_type_mktshr,
|
|
@@ -113,10 +124,10 @@ def gen_share_data(
|
|
|
113
124
|
|
|
114
125
|
|
|
115
126
|
def gen_market_shares_uniform(
|
|
116
|
-
_s_size: int
|
|
117
|
-
_dist_parms_mktshr: ArrayDouble
|
|
127
|
+
_s_size: int,
|
|
128
|
+
_dist_parms_mktshr: ArrayDouble,
|
|
118
129
|
_mktshr_rng_seed_seq: SeedSequence | None = None,
|
|
119
|
-
_nthreads: int =
|
|
130
|
+
_nthreads: int = NTHREADS,
|
|
120
131
|
/,
|
|
121
132
|
) -> ShareDataSample:
|
|
122
133
|
"""Generate merging-firm shares from Uniform distribution on the 3-D simplex.
|
|
@@ -138,9 +149,8 @@ def gen_market_shares_uniform(
|
|
|
138
149
|
|
|
139
150
|
"""
|
|
140
151
|
|
|
141
|
-
_frmshr_array = np.empty((_s_size, 2),
|
|
152
|
+
_frmshr_array: ArrayDouble = np.empty((_s_size, 2), float)
|
|
142
153
|
|
|
143
|
-
_dist_parms_mktshr = _dist_parms_mktshr or DEFAULT_DIST_PARMS
|
|
144
154
|
_mrng = MultithreadedRNG(
|
|
145
155
|
_frmshr_array,
|
|
146
156
|
dist_type="Uniform",
|
|
@@ -151,13 +161,14 @@ def gen_market_shares_uniform(
|
|
|
151
161
|
_mrng.fill()
|
|
152
162
|
# Convert draws on U[0, 1] to Uniformly-distributed draws on simplex, s_1 + s_2 <= 1
|
|
153
163
|
_frmshr_array.sort(axis=1)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
_frmshr_array[:, 1] - _frmshr_array[:, 0],
|
|
157
|
-
|
|
164
|
+
|
|
165
|
+
_frmshr_array = np.array(
|
|
166
|
+
(_frmshr_array[:, 0], _frmshr_array[:, 1] - _frmshr_array[:, 0]),
|
|
167
|
+
_frmshr_array.dtype,
|
|
168
|
+
).T # faster than np.stack() and variants
|
|
158
169
|
|
|
159
170
|
# Keep only share combinations representing feasible mergers
|
|
160
|
-
# This is a no-op for 64-bit floats, but is necessary for
|
|
171
|
+
# This is a no-op for 64-bit floats, but is necessary for smaller floats
|
|
161
172
|
_frmshr_array = _frmshr_array[_frmshr_array.min(axis=1) > 0]
|
|
162
173
|
|
|
163
174
|
# Let a third column have values of "np.nan", so HHI calculations return "np.nan"
|
|
@@ -172,7 +183,7 @@ def gen_market_shares_uniform(
|
|
|
172
183
|
)
|
|
173
184
|
|
|
174
185
|
# This array is meant to be ignored, so a sentinel value is fine
|
|
175
|
-
_fcounts.fill(-
|
|
186
|
+
_fcounts.fill(-1)
|
|
176
187
|
|
|
177
188
|
_nth_firm_share.fill(np.nan)
|
|
178
189
|
_aggregate_purchase_prob.fill(np.nan)
|
|
@@ -182,15 +193,15 @@ def gen_market_shares_uniform(
|
|
|
182
193
|
)
|
|
183
194
|
|
|
184
195
|
|
|
185
|
-
def
|
|
186
|
-
_s_size: int
|
|
187
|
-
_recapture_form: RECForm
|
|
188
|
-
_dist_type_dir: SHRDistribution
|
|
189
|
-
_dist_parms_dir: ArrayDouble
|
|
190
|
-
_firm_count_wts: ArrayDouble
|
|
196
|
+
def _gen_market_shares_dirichlet_multimarket(
|
|
197
|
+
_s_size: int,
|
|
198
|
+
_recapture_form: RECForm,
|
|
199
|
+
_dist_type_dir: SHRDistribution,
|
|
200
|
+
_dist_parms_dir: ArrayDouble,
|
|
201
|
+
_firm_count_wts: ArrayDouble,
|
|
191
202
|
_fcount_rng_seed_seq: SeedSequence | None = None,
|
|
192
203
|
_mktshr_rng_seed_seq: SeedSequence | None = None,
|
|
193
|
-
_nthreads: int =
|
|
204
|
+
_nthreads: int = NTHREADS,
|
|
194
205
|
/,
|
|
195
206
|
) -> ShareDataSample:
|
|
196
207
|
"""Dirichlet-distributed shares with multiple firm-counts.
|
|
@@ -229,10 +240,11 @@ def gen_market_shares_dirichlet_multimarket(
|
|
|
229
240
|
|
|
230
241
|
"""
|
|
231
242
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
243
|
+
_firm_count_wts = (
|
|
244
|
+
DEFAULT_FCOUNT_WTS
|
|
245
|
+
if _firm_count_wts is None or not len(_firm_count_wts)
|
|
246
|
+
else _firm_count_wts
|
|
247
|
+
)
|
|
236
248
|
|
|
237
249
|
_min_choice_wt = 0.03 if _dist_type_dir == SHRDistribution.DIR_FLAT_CONSTR else 0.00
|
|
238
250
|
_fcount_keys, _choice_wts = zip(
|
|
@@ -250,7 +262,7 @@ def gen_market_shares_dirichlet_multimarket(
|
|
|
250
262
|
|
|
251
263
|
_fc_max = _fcount_keys[-1]
|
|
252
264
|
_dir_alphas_full = (
|
|
253
|
-
[
|
|
265
|
+
_dist_parms_dir[:_fc_max] if len(_dist_parms_dir) else [1.0] * _fc_max
|
|
254
266
|
)
|
|
255
267
|
if _dist_type_dir == SHRDistribution.DIR_ASYM:
|
|
256
268
|
_dir_alphas_full = [2.0] * 6 + [1.5] * 5 + [1.25] * min(7, _fc_max)
|
|
@@ -261,12 +273,12 @@ def gen_market_shares_dirichlet_multimarket(
|
|
|
261
273
|
_dat = [2.5] * 2
|
|
262
274
|
if _fcv > len(_dat):
|
|
263
275
|
_dat += [1.0 / (_fcv - 2)] * (_fcv - 2)
|
|
264
|
-
return np.array(_dat,
|
|
276
|
+
return np.array(_dat, float)
|
|
265
277
|
|
|
266
278
|
else:
|
|
267
279
|
|
|
268
280
|
def _gen_dir_alphas(_fcv: int) -> ArrayDouble:
|
|
269
|
-
return np.array(_dir_alphas_full[:_fcv],
|
|
281
|
+
return np.array(_dir_alphas_full[:_fcv], float)
|
|
270
282
|
|
|
271
283
|
_fcounts = prng(_fcount_rng_seed_seq).choice(
|
|
272
284
|
_fcount_keys, size=(_s_size, 1), p=_choice_wts
|
|
@@ -281,7 +293,7 @@ def gen_market_shares_dirichlet_multimarket(
|
|
|
281
293
|
_aggregate_purchase_prob, _nth_firm_share = (
|
|
282
294
|
np.empty((_s_size, 1)) for _ in range(2)
|
|
283
295
|
)
|
|
284
|
-
_mktshr_array = np.empty((_s_size, _fc_max),
|
|
296
|
+
_mktshr_array = np.empty((_s_size, _fc_max), float)
|
|
285
297
|
for _f_val, _f_sseq in zip(_fcount_keys, _mktshr_seed_seq_ch, strict=True):
|
|
286
298
|
_fcounts_match_rows = np.where(_fcounts == _f_val)[0]
|
|
287
299
|
_dir_alphas_test = _gen_dir_alphas(_f_val)
|
|
@@ -327,10 +339,10 @@ def gen_market_shares_dirichlet_multimarket(
|
|
|
327
339
|
|
|
328
340
|
def gen_market_shares_dirichlet(
|
|
329
341
|
_dir_alphas: ArrayDouble,
|
|
330
|
-
_s_size: int
|
|
331
|
-
_recapture_form: RECForm
|
|
342
|
+
_s_size: int,
|
|
343
|
+
_recapture_form: RECForm,
|
|
332
344
|
_mktshr_rng_seed_seq: SeedSequence | None = None,
|
|
333
|
-
_nthreads: int =
|
|
345
|
+
_nthreads: int = NTHREADS,
|
|
334
346
|
/,
|
|
335
347
|
) -> ShareDataSample:
|
|
336
348
|
"""Dirichlet-distributed shares with fixed firm-count.
|
|
@@ -372,7 +384,7 @@ def gen_market_shares_dirichlet(
|
|
|
372
384
|
else SeedSequence(pool_size=8)
|
|
373
385
|
)
|
|
374
386
|
|
|
375
|
-
_mktshr_array = np.empty((_s_size, len(_dir_alphas)),
|
|
387
|
+
_mktshr_array = np.empty((_s_size, len(_dir_alphas)), float)
|
|
376
388
|
_mrng = MultithreadedRNG(
|
|
377
389
|
_mktshr_array,
|
|
378
390
|
dist_type="Dirichlet",
|
|
@@ -396,11 +408,11 @@ def gen_market_shares_dirichlet(
|
|
|
396
408
|
)
|
|
397
409
|
|
|
398
410
|
# If recapture_form == 'inside_out', further calculations downstream
|
|
399
|
-
_aggregate_purchase_prob = np.empty((_s_size, 1),
|
|
411
|
+
_aggregate_purchase_prob = np.empty((_s_size, 1), float)
|
|
400
412
|
_aggregate_purchase_prob.fill(np.nan)
|
|
401
413
|
if _recapture_form == RECForm.OUTIN:
|
|
402
414
|
_aggregate_purchase_prob = 1 - _mktshr_array[:, [-1]] # type: ignore
|
|
403
|
-
_mktshr_array = _mktshr_array[:, :-1] / _aggregate_purchase_prob
|
|
415
|
+
_mktshr_array = _mktshr_array[:, :-1] / _aggregate_purchase_prob
|
|
404
416
|
|
|
405
417
|
return ShareDataSample(
|
|
406
418
|
_mktshr_array,
|
|
@@ -414,7 +426,7 @@ def gen_divr_array(
|
|
|
414
426
|
_recapture_form: RECForm,
|
|
415
427
|
_recapture_ratio: float | None,
|
|
416
428
|
_frmshr_array: ArrayDouble,
|
|
417
|
-
_aggregate_purchase_prob: ArrayDouble
|
|
429
|
+
_aggregate_purchase_prob: ArrayDouble,
|
|
418
430
|
/,
|
|
419
431
|
) -> ArrayDouble:
|
|
420
432
|
"""
|
|
@@ -484,8 +496,8 @@ def gen_margin_price_data(
|
|
|
484
496
|
_price_spec: PriceSpec,
|
|
485
497
|
_hsr_filing_test_type: SSZConstant,
|
|
486
498
|
_pcm_rng_seed_seq: SeedSequence,
|
|
487
|
-
_pr_rng_seed_seq: SeedSequence | None
|
|
488
|
-
_nthreads: int =
|
|
499
|
+
_pr_rng_seed_seq: SeedSequence | None,
|
|
500
|
+
_nthreads: int = NTHREADS,
|
|
489
501
|
/,
|
|
490
502
|
) -> tuple[MarginDataSample, PriceDataSample]:
|
|
491
503
|
"""Generate margin and price data for mergers in the sample.
|
|
@@ -532,10 +544,8 @@ def gen_margin_price_data(
|
|
|
532
544
|
np.empty_like(_frmshr_array), np.ones(len(_frmshr_array)) == 0
|
|
533
545
|
)
|
|
534
546
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
np.empty_like(_frmshr_array, np.float64),
|
|
538
|
-
)
|
|
547
|
+
_nth_firm_price: ArrayDouble
|
|
548
|
+
_price_array: ArrayDouble = np.ones_like(_frmshr_array, np.float64)
|
|
539
549
|
|
|
540
550
|
_pr_max_ratio = 5.0
|
|
541
551
|
match _price_spec:
|
|
@@ -555,7 +565,7 @@ def gen_margin_price_data(
|
|
|
555
565
|
1 + np.arange(_pr_max_ratio), size=(len(_frmshr_array), 3)
|
|
556
566
|
)
|
|
557
567
|
_price_array = _price_array_gen[:, :2]
|
|
558
|
-
_nth_firm_price = _price_array_gen[:, [2]]
|
|
568
|
+
_nth_firm_price = _price_array_gen[:, [2]]
|
|
559
569
|
# del _price_array_gen
|
|
560
570
|
case PriceSpec.CSY:
|
|
561
571
|
# TODO:
|
|
@@ -616,7 +626,7 @@ def gen_margin_price_data(
|
|
|
616
626
|
_nthreads,
|
|
617
627
|
)
|
|
618
628
|
|
|
619
|
-
_price_array = _price_array.astype(np.float64)
|
|
629
|
+
# _price_array = _price_array.astype(np.float64)
|
|
620
630
|
_rev_array = _price_array * _frmshr_array
|
|
621
631
|
_nth_firm_rev = _nth_firm_price * _nth_firm_share
|
|
622
632
|
|
|
@@ -670,8 +680,8 @@ def _gen_margin_data(
|
|
|
670
680
|
_price_array: ArrayDouble,
|
|
671
681
|
_aggregate_purchase_prob: ArrayDouble,
|
|
672
682
|
_pcm_spec: PCMSpec,
|
|
673
|
-
_pcm_rng_seed_seq: SeedSequence,
|
|
674
|
-
_nthreads: int =
|
|
683
|
+
_pcm_rng_seed_seq: SeedSequence | None,
|
|
684
|
+
_nthreads: int = NTHREADS,
|
|
675
685
|
/,
|
|
676
686
|
) -> MarginDataSample:
|
|
677
687
|
_dist_type_pcm, _dist_firm2_pcm, _dist_parms_pcm = (
|
|
@@ -680,12 +690,13 @@ def _gen_margin_data(
|
|
|
680
690
|
)
|
|
681
691
|
|
|
682
692
|
_pcm_array = (
|
|
683
|
-
np.empty((len(_frmshr_array), 1),
|
|
693
|
+
np.empty((len(_frmshr_array), 1), float)
|
|
684
694
|
if _pcm_spec.firm2_pcm_constraint == FM2Constraint.SYM
|
|
685
|
-
else np.empty_like(_frmshr_array,
|
|
695
|
+
else np.empty_like(_frmshr_array, float)
|
|
686
696
|
)
|
|
687
697
|
|
|
688
|
-
|
|
698
|
+
_dist_parms: ArrayFloat
|
|
699
|
+
_beta_min, _beta_max = [0.0] * 2 # placeholder
|
|
689
700
|
if _dist_type_pcm == PCMDistribution.EMPR:
|
|
690
701
|
_pcm_array = mgn_data_resampler(
|
|
691
702
|
_pcm_array.shape, seed_sequence=_pcm_rng_seed_seq
|
|
@@ -696,11 +707,11 @@ def _gen_margin_data(
|
|
|
696
707
|
_dist_type = "Beta"
|
|
697
708
|
_dist_parms_pcm = (
|
|
698
709
|
(
|
|
699
|
-
np.array([0, 1, 0, 1],
|
|
700
|
-
if
|
|
701
|
-
else
|
|
710
|
+
np.array([0.5, 1, 0, 1], float)
|
|
711
|
+
if _dist_type_pcm == PCMDistribution.BETA_BND
|
|
712
|
+
else DEFAULT_BETA_DIST_PARMS
|
|
702
713
|
)
|
|
703
|
-
if _dist_parms_pcm is None
|
|
714
|
+
if _dist_parms_pcm is None or not len(_dist_parms_pcm)
|
|
704
715
|
else _dist_parms_pcm
|
|
705
716
|
)
|
|
706
717
|
_dist_parms = beta_located_bound(_dist_parms_pcm)
|
|
@@ -708,7 +719,9 @@ def _gen_margin_data(
|
|
|
708
719
|
else:
|
|
709
720
|
_dist_type = "Uniform"
|
|
710
721
|
_dist_parms = (
|
|
711
|
-
DEFAULT_DIST_PARMS
|
|
722
|
+
DEFAULT_DIST_PARMS
|
|
723
|
+
if _dist_parms_pcm is None or not len(_dist_parms_pcm)
|
|
724
|
+
else _dist_parms_pcm
|
|
712
725
|
)
|
|
713
726
|
|
|
714
727
|
_pcm_rng = MultithreadedRNG(
|
|
@@ -779,7 +792,7 @@ def _beta_located(
|
|
|
779
792
|
"""
|
|
780
793
|
|
|
781
794
|
_mul = -1 + _mu * (1 - _mu) / _sigma**2
|
|
782
|
-
return np.array([_mu * _mul, (1 - _mu) * _mul],
|
|
795
|
+
return np.array([_mu * _mul, (1 - _mu) * _mul], float)
|
|
783
796
|
|
|
784
797
|
|
|
785
798
|
def beta_located_bound(_dist_parms: ArrayDouble, /) -> ArrayDouble:
|
|
@@ -812,65 +825,3 @@ def beta_located_bound(_dist_parms: ArrayDouble, /) -> ArrayDouble:
|
|
|
812
825
|
|
|
813
826
|
_bmu, _bsigma, _bmin, _bmax = _dist_parms
|
|
814
827
|
return _beta_located((_bmu - _bmin) / (_bmax - _bmin), _bsigma / (_bmax - _bmin))
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
def parse_seed_seq_list(
|
|
818
|
-
_sseq_list: Sequence[SeedSequence] | None,
|
|
819
|
-
_mktshr_dist_type: SHRDistribution,
|
|
820
|
-
_price_spec: PriceSpec,
|
|
821
|
-
/,
|
|
822
|
-
) -> SeedSequenceData:
|
|
823
|
-
"""Initialize RNG seed sequences to ensure independence of distinct random streams.
|
|
824
|
-
|
|
825
|
-
The tuple of SeedSequences, is parsed in the following order
|
|
826
|
-
for generating the relevant random variates:
|
|
827
|
-
1.) quantity shares
|
|
828
|
-
2.) price-cost margins
|
|
829
|
-
3.) firm-counts, if :code:`MarketSpec.share_spec.dist_type` is a Dirichlet distribution
|
|
830
|
-
4.) prices, if :code:`MarketSpec.price_spec ==`:attr:`mergeron.gen.PriceSpec.ZERO`.
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
Parameters
|
|
835
|
-
----------
|
|
836
|
-
_sseq_list
|
|
837
|
-
List of RNG seed sequences
|
|
838
|
-
|
|
839
|
-
_mktshr_dist_type
|
|
840
|
-
Market share distribution type
|
|
841
|
-
|
|
842
|
-
_price_spec
|
|
843
|
-
Price specification
|
|
844
|
-
|
|
845
|
-
Returns
|
|
846
|
-
-------
|
|
847
|
-
Seed sequence data
|
|
848
|
-
|
|
849
|
-
"""
|
|
850
|
-
_seed_count = 2 if _mktshr_dist_type == SHRDistribution.UNI else 3
|
|
851
|
-
_seed_count += 1 if _price_spec == PriceSpec.ZERO else 0
|
|
852
|
-
|
|
853
|
-
_fcount_rng_seed_seq: SeedSequence | None = None
|
|
854
|
-
_pr_rng_seed_seq: SeedSequence | None = None
|
|
855
|
-
|
|
856
|
-
_sseq_list = (
|
|
857
|
-
_sseq_list
|
|
858
|
-
if _sseq_list
|
|
859
|
-
else tuple(SeedSequence(pool_size=8) for _ in range(_seed_count))
|
|
860
|
-
)
|
|
861
|
-
|
|
862
|
-
if (_l := len(_sseq_list)) < _seed_count:
|
|
863
|
-
raise ValueError(
|
|
864
|
-
f"Seed sequence list must contain {_seed_count} seed sequences; "
|
|
865
|
-
f"only {_l} given."
|
|
866
|
-
)
|
|
867
|
-
|
|
868
|
-
_mktshr_rng_seed_seq, _pcm_rng_seed_seq = _sseq_list[:2]
|
|
869
|
-
_fcount_rng_seed_seq = (
|
|
870
|
-
None if _mktshr_dist_type == SHRDistribution.UNI else _sseq_list[2]
|
|
871
|
-
)
|
|
872
|
-
_pr_rng_seed_seq = _sseq_list[-1] if _price_spec == PriceSpec.ZERO else None
|
|
873
|
-
|
|
874
|
-
return SeedSequenceData(
|
|
875
|
-
_mktshr_rng_seed_seq, _pcm_rng_seed_seq, _fcount_rng_seed_seq, _pr_rng_seed_seq
|
|
876
|
-
)
|
|
@@ -9,7 +9,7 @@ from collections.abc import Mapping
|
|
|
9
9
|
import numpy as np
|
|
10
10
|
from scipy.interpolate import interp1d # type: ignore
|
|
11
11
|
|
|
12
|
-
from .. import VERSION, ArrayBIGINT # noqa: TID252
|
|
12
|
+
from .. import VERSION, ArrayBIGINT, this_yaml # noqa: TID252
|
|
13
13
|
from ..core import ftc_merger_investigations_data as fid # noqa: TID252
|
|
14
14
|
from . import INVResolution
|
|
15
15
|
|
|
@@ -291,10 +291,10 @@ def enf_cnts_byconczone(_cnts_array: ArrayBIGINT, /) -> ArrayBIGINT:
|
|
|
291
291
|
# in both cases does make life easier
|
|
292
292
|
_ndim_in = 2
|
|
293
293
|
_nkeys = 3
|
|
294
|
-
_cnts_byhhipostanddelta = -1 * np.ones(
|
|
295
|
-
_nkeys + _cnts_array.shape[1] - _ndim_in, dtype=
|
|
294
|
+
_cnts_byhhipostanddelta: ArrayBIGINT = -1 * np.ones(
|
|
295
|
+
_nkeys + _cnts_array.shape[1] - _ndim_in, dtype=int
|
|
296
296
|
)
|
|
297
|
-
_cnts_byconczone = -1 * np.ones_like(_cnts_byhhipostanddelta)
|
|
297
|
+
_cnts_byconczone: ArrayBIGINT = -1 * np.ones_like(_cnts_byhhipostanddelta)
|
|
298
298
|
for _hhi_zone_post_lim in HHI_POST_ZONE_KNOTS[:-1]:
|
|
299
299
|
_level_test = _hhi_zone_post_ranged == _hhi_zone_post_lim
|
|
300
300
|
|
|
@@ -318,7 +318,7 @@ def enf_cnts_byconczone(_cnts_array: ArrayBIGINT, /) -> ArrayBIGINT:
|
|
|
318
318
|
*_zone_val,
|
|
319
319
|
*np.einsum("ij->j", _cnts_array[:, _ndim_in:][_conc_test]),
|
|
320
320
|
),
|
|
321
|
-
dtype=
|
|
321
|
+
dtype=int,
|
|
322
322
|
),
|
|
323
323
|
))
|
|
324
324
|
_cnts_byhhipostanddelta = _cnts_byhhipostanddelta[1:]
|
|
@@ -342,13 +342,37 @@ def enf_cnts_byconczone(_cnts_array: ArrayBIGINT, /) -> ArrayBIGINT:
|
|
|
342
342
|
"ij->j", _cnts_byhhipostanddelta[_hhi_zone_test][:, _nkeys:]
|
|
343
343
|
),
|
|
344
344
|
),
|
|
345
|
-
dtype=
|
|
345
|
+
dtype=int,
|
|
346
346
|
),
|
|
347
347
|
))
|
|
348
348
|
|
|
349
349
|
return _cnts_byconczone[1:]
|
|
350
350
|
|
|
351
351
|
|
|
352
|
+
for _typ in (
|
|
353
|
+
IndustryGroup,
|
|
354
|
+
OtherEvidence,
|
|
355
|
+
StatsGrpSelector,
|
|
356
|
+
StatsReturnSelector,
|
|
357
|
+
SortSelector,
|
|
358
|
+
):
|
|
359
|
+
# NOTE: If additional enums are defined in this module,
|
|
360
|
+
# add themn to the list above
|
|
361
|
+
|
|
362
|
+
_, _ = (
|
|
363
|
+
this_yaml.representer.add_representer(
|
|
364
|
+
_typ,
|
|
365
|
+
lambda _r, _d: _r.represent_scalar(f"!{_d.__class__.__name__}", _d.name),
|
|
366
|
+
),
|
|
367
|
+
this_yaml.constructor.add_constructor(
|
|
368
|
+
f"!{_typ.__name__}",
|
|
369
|
+
lambda _c, _n, /: getattr(
|
|
370
|
+
globals().get(_n.tag.lstrip("!")), _c.construct_scalar(_n)
|
|
371
|
+
),
|
|
372
|
+
),
|
|
373
|
+
)
|
|
374
|
+
|
|
375
|
+
|
|
352
376
|
if __name__ == "__main__":
|
|
353
377
|
print(
|
|
354
378
|
"This module provides methods to aggregate statistics on merger enforcement patterns for reporting."
|
mergeron/gen/upp_tests.py
CHANGED
|
@@ -26,10 +26,9 @@ from .. import ( # noqa
|
|
|
26
26
|
)
|
|
27
27
|
from ..core import guidelines_boundaries as gbl # noqa: TID252
|
|
28
28
|
from . import (
|
|
29
|
-
DEFAULT_EMPTY_ARRAY,
|
|
30
29
|
DataclassInstance,
|
|
31
30
|
INVResolution,
|
|
32
|
-
|
|
31
|
+
MarketSampleData,
|
|
33
32
|
UPPTestRegime,
|
|
34
33
|
UPPTestsCounts,
|
|
35
34
|
UPPTestsRaw,
|
|
@@ -52,7 +51,7 @@ class INVRESCntsArgs(TypedDict, total=False):
|
|
|
52
51
|
|
|
53
52
|
|
|
54
53
|
def compute_upp_test_counts(
|
|
55
|
-
_market_data_sample:
|
|
54
|
+
_market_data_sample: MarketSampleData,
|
|
56
55
|
_upp_test_parms: gbl.HMGThresholds,
|
|
57
56
|
_upp_test_regime: UPPTestRegime,
|
|
58
57
|
/,
|
|
@@ -96,7 +95,7 @@ def compute_upp_test_counts(
|
|
|
96
95
|
if _firmcounts_list is not None and np.all(_firmcounts_list >= 0):
|
|
97
96
|
_max_firmcount = max(_firmcounts_list)
|
|
98
97
|
|
|
99
|
-
_enf_cnts_sim_byfirmcount_array = -1 * np.ones(_stats_rowlen,
|
|
98
|
+
_enf_cnts_sim_byfirmcount_array: ArrayBIGINT = -1 * np.ones(_stats_rowlen, int)
|
|
100
99
|
for _firmcount in np.arange(2, _max_firmcount + 1):
|
|
101
100
|
_firmcount_test = _fcounts == _firmcount
|
|
102
101
|
|
|
@@ -123,7 +122,7 @@ def compute_upp_test_counts(
|
|
|
123
122
|
|
|
124
123
|
# Clearance/enforcement counts --- by delta
|
|
125
124
|
_hhi_delta_ranged = esl.hhi_delta_ranger(_hhi_delta)
|
|
126
|
-
_enf_cnts_sim_bydelta_array = -1 * np.ones(_stats_rowlen,
|
|
125
|
+
_enf_cnts_sim_bydelta_array: ArrayBIGINT = -1 * np.ones(_stats_rowlen, int)
|
|
127
126
|
for _hhi_delta_lim in esl.HHI_DELTA_KNOTS[:-1]:
|
|
128
127
|
_hhi_delta_test = _hhi_delta_ranged == _hhi_delta_lim
|
|
129
128
|
|
|
@@ -190,7 +189,7 @@ def compute_upp_test_counts(
|
|
|
190
189
|
|
|
191
190
|
|
|
192
191
|
def compute_upp_test_arrays(
|
|
193
|
-
_market_data:
|
|
192
|
+
_market_data: MarketSampleData,
|
|
194
193
|
_upp_test_parms: gbl.HMGThresholds,
|
|
195
194
|
_sim_test_regime: UPPTestRegime,
|
|
196
195
|
/,
|
|
@@ -279,7 +278,7 @@ def _compute_test_array_seq(
|
|
|
279
278
|
UPPAggrSelector.OSA,
|
|
280
279
|
UPPAggrSelector.OSD,
|
|
281
280
|
)
|
|
282
|
-
else
|
|
281
|
+
else np.array([0.5, 0.5], float)
|
|
283
282
|
)
|
|
284
283
|
|
|
285
284
|
match _aggregator:
|
|
@@ -331,11 +330,11 @@ def initialize_hd5(
|
|
|
331
330
|
_h5_title = f"HMG version: {_hmg_pub_year}; Test regime: {_test_regime}"
|
|
332
331
|
if _h5_path.is_file():
|
|
333
332
|
_h5_path.unlink()
|
|
334
|
-
_h5_file = ptb.open_file(_h5_path, mode="w", title=_h5_title)
|
|
333
|
+
_h5_file = ptb.open_file(_h5_path, mode="w", title=_h5_title)
|
|
335
334
|
_save_data_to_file: SaveData = (True, _h5_file, _h5_file.root)
|
|
336
335
|
_next_subgroup_name_root = "enf_{}_{}_{}_{}".format(
|
|
337
336
|
_hmg_pub_year,
|
|
338
|
-
*(getattr(_test_regime, _f.name).name for _f in _test_regime.__attrs_attrs__),
|
|
337
|
+
*(getattr(_test_regime, _f.name).name for _f in _test_regime.__attrs_attrs__),
|
|
339
338
|
)
|
|
340
339
|
return _save_data_to_file, _next_subgroup_name_root
|
|
341
340
|
|
|
@@ -383,7 +382,7 @@ def save_array_to_hdf5(
|
|
|
383
382
|
_h5_array_name,
|
|
384
383
|
atom=ptb.Atom.from_dtype(_array_obj.dtype),
|
|
385
384
|
shape=_array_obj.shape,
|
|
386
|
-
filters=ptb.Filters(complevel=3, complib="blosc:lz4hc", fletcher32=True),
|
|
385
|
+
filters=ptb.Filters(complevel=3, complib="blosc:lz4hc", fletcher32=True),
|
|
387
386
|
)
|
|
388
387
|
_h5_array[:] = _array_obj
|
|
389
388
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: mergeron
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.739290.0
|
|
4
4
|
Summary: Analyze merger enforcement policy using Python
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: merger policy analysis,merger guidelines,merger screening,policy presumptions,concentration standards,upward pricing pressure,GUPPI
|
|
@@ -30,6 +30,7 @@ Requires-Dist: matplotlib (>=3.8)
|
|
|
30
30
|
Requires-Dist: mpmath (>=1.3)
|
|
31
31
|
Requires-Dist: msgpack (>=1.0)
|
|
32
32
|
Requires-Dist: msgpack-numpy (>=0.4)
|
|
33
|
+
Requires-Dist: ruamel-yaml (>=0.18.10,<0.19.0)
|
|
33
34
|
Requires-Dist: scipy (>=1.12)
|
|
34
35
|
Requires-Dist: sympy (>=1.12)
|
|
35
36
|
Requires-Dist: tables (>=3.10.1)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
mergeron/__init__.py,sha256=CJgJmTbFDmz9oNPWROam9rB1pikAKF1SdqsL9putg5M,3035
|
|
2
|
+
mergeron/core/__init__.py,sha256=qYRA1D4Gx-WSkICqiueWLWPedkWmb_CIn7fgvN7unk4,182
|
|
3
|
+
mergeron/core/empirical_margin_distribution.py,sha256=byO11ROGVQcmbZVWdVJkJ906WnHhx7jcoL5BbxPmX7I,8688
|
|
4
|
+
mergeron/core/ftc_merger_investigations_data.py,sha256=9AT-phfkn0NHJvn9lcpbH8ExWZStYW47KQjNjDGS3qc,28709
|
|
5
|
+
mergeron/core/guidelines_boundaries.py,sha256=U2SaG5SMV51nmBNe8n94RQPJCHyxFGKaQ5ncA-COe5g,15360
|
|
6
|
+
mergeron/core/guidelines_boundary_functions.py,sha256=4vMz5DQ72fgj7leUlVJvXBrxdZAeDJP7FoGBEVXDdeQ,34866
|
|
7
|
+
mergeron/core/guidelines_boundary_functions_extra.py,sha256=qL1zT-Xgj2qD2EyBRR87APoVc47MkGM02xYQhNgwEvg,11216
|
|
8
|
+
mergeron/core/pseudorandom_numbers.py,sha256=qmXErMPUlP769cItwxHBw1qW2kYMjcQ26P4Dr7McOnQ,10372
|
|
9
|
+
mergeron/data/__init__.py,sha256=KtjBlZOl7jwBCAUhrTJB9PdrN39YLYytNiSUSM_gRmA,62
|
|
10
|
+
mergeron/data/damodaran_margin_data.xls,sha256=Qggl1p5nkOMJI8YUXhkwXQRz-OhRSqBTzz57N0JQyYA,79360
|
|
11
|
+
mergeron/data/damodaran_margin_data_dict.msgpack,sha256=sr6s4L69kposEpzGI7jpPb4ULz0UpY-bEYfeNi6UlRA,57621
|
|
12
|
+
mergeron/data/ftc_invdata.msgpack,sha256=WBFHgi7Ld4R-h2zL2Zc3TOIlKqVrbVFMH1LoI4-T-M0,264664
|
|
13
|
+
mergeron/demo/__init__.py,sha256=KtjBlZOl7jwBCAUhrTJB9PdrN39YLYytNiSUSM_gRmA,62
|
|
14
|
+
mergeron/demo/visualize_empirical_margin_distribution.py,sha256=kDwPfhsBjsQdYPyhe4KZG2guB_xHhPaCrvn8fezIz4M,2354
|
|
15
|
+
mergeron/gen/__init__.py,sha256=t1RswXk-L6olOhj5XqPekd8je8Za7NUFuSo3fuM2Wts,21787
|
|
16
|
+
mergeron/gen/data_generation.py,sha256=0Z-TvQANvEjrmXm9QKdmcm9mieWx2iF91K_7Ij5B0zI,16254
|
|
17
|
+
mergeron/gen/data_generation_functions.py,sha256=LwqbCYSqK2PfFrHhZaTOaF7UtlsVnhm0Ykmfgf3P-G4,27187
|
|
18
|
+
mergeron/gen/enforcement_stats.py,sha256=z_Kjw1OwLue5B-tKFlmEoyGDusi9D6c77foRCmiNGqQ,11532
|
|
19
|
+
mergeron/gen/upp_tests.py,sha256=VTh0rDd0cJ70MwkvRDYx27LWMaA1BPThXfd3D1HKX-E,12489
|
|
20
|
+
mergeron/py.typed,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
21
|
+
mergeron-2025.739290.0.dist-info/METADATA,sha256=-Ib5QC5-mq2ItR_bS1s08BRGknEVbsPPfiDIJavzQbU,14541
|
|
22
|
+
mergeron-2025.739290.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
23
|
+
mergeron-2025.739290.0.dist-info/RECORD,,
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
mergeron/__init__.py,sha256=TA29lm9xq1AOShjbOs4dXujCClb_MMCLlKN6ej8VC08,1581
|
|
2
|
-
mergeron/core/__init__.py,sha256=jPGd0okmvNOdWnTu4biR4hqnL29IERaY4Olv8mS02ko,188
|
|
3
|
-
mergeron/core/empirical_margin_distribution.py,sha256=uDgXXNNL4ln_f1rnvfOxrpokeuha6qQXpi0c7ZGE58U,8726
|
|
4
|
-
mergeron/core/ftc_merger_investigations_data.py,sha256=_Qno1_oWcHmDd60j8YX6BLUSLeAn-DU6KpvMOcbCIaE,28728
|
|
5
|
-
mergeron/core/guidelines_boundaries.py,sha256=ci6bNVNKGynCnXFoQXit0jyhpQW8hw-Y37DpozuQETg,15245
|
|
6
|
-
mergeron/core/guidelines_boundary_functions.py,sha256=SoTamDsKrThqDfoNTHeGp2ntiwhzscWmkAbIWrBtUq4,34885
|
|
7
|
-
mergeron/core/guidelines_boundary_functions_extra.py,sha256=ytTWxYk7FkGLQubkQXrniwP_2ZlYssp4rmOxy4_7480,11292
|
|
8
|
-
mergeron/core/pseudorandom_numbers.py,sha256=VepI_YU5oMkTExjyN9OyfiB3UmTDR2cq4N1DAmYZbm4,9233
|
|
9
|
-
mergeron/data/__init__.py,sha256=KtjBlZOl7jwBCAUhrTJB9PdrN39YLYytNiSUSM_gRmA,62
|
|
10
|
-
mergeron/data/damodaran_margin_data.xls,sha256=Qggl1p5nkOMJI8YUXhkwXQRz-OhRSqBTzz57N0JQyYA,79360
|
|
11
|
-
mergeron/data/damodaran_margin_data_dict.msgpack,sha256=sr6s4L69kposEpzGI7jpPb4ULz0UpY-bEYfeNi6UlRA,57621
|
|
12
|
-
mergeron/data/ftc_invdata.msgpack,sha256=WBFHgi7Ld4R-h2zL2Zc3TOIlKqVrbVFMH1LoI4-T-M0,264664
|
|
13
|
-
mergeron/demo/__init__.py,sha256=KtjBlZOl7jwBCAUhrTJB9PdrN39YLYytNiSUSM_gRmA,62
|
|
14
|
-
mergeron/demo/visualize_empirical_margin_distribution.py,sha256=_1SWKqFJNqKV_yA3v2tmzl8Th3CC3SXpb6VGiwGGuN0,2373
|
|
15
|
-
mergeron/gen/__init__.py,sha256=6A1HVewEEwLo4JtZZ61ShzhU2phEeNfTxmTPlpi5LXY,17215
|
|
16
|
-
mergeron/gen/data_generation.py,sha256=nzCWVJBXYxloR6J6MamFM0MUbDzguhARCAEksYkX1Dw,16872
|
|
17
|
-
mergeron/gen/data_generation_functions.py,sha256=cIYkE4DcBXdEbEIeCk2lG9rLKblhdYZPDMJdGMS2dKE,29022
|
|
18
|
-
mergeron/gen/enforcement_stats.py,sha256=ZjrV_VkFMF0D1myc-fj-W99M1EhJMA9-nCfyE5g9e54,10890
|
|
19
|
-
mergeron/gen/upp_tests.py,sha256=bQfxigqHc8bdsd5SjMyKKa07weTEcAdJvLCiTrhgzAE,12547
|
|
20
|
-
mergeron/py.typed,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
21
|
-
mergeron-2025.739265.0.dist-info/METADATA,sha256=nkTdrTqjVT4tc6ljYRuCFykz0X-TsABN3zxyEe9ALnE,14494
|
|
22
|
-
mergeron-2025.739265.0.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
23
|
-
mergeron-2025.739265.0.dist-info/RECORD,,
|
|
File without changes
|