mergeron 2025.739265.2__py3-none-any.whl → 2025.739290.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/__init__.py +67 -2
- mergeron/core/guidelines_boundaries.py +85 -21
- mergeron/core/pseudorandom_numbers.py +61 -51
- mergeron/gen/__init__.py +222 -84
- mergeron/gen/data_generation.py +143 -182
- mergeron/gen/data_generation_functions.py +68 -118
- mergeron/gen/enforcement_stats.py +30 -6
- mergeron/gen/upp_tests.py +6 -7
- {mergeron-2025.739265.2.dist-info → mergeron-2025.739290.1.dist-info}/METADATA +2 -1
- {mergeron-2025.739265.2.dist-info → mergeron-2025.739290.1.dist-info}/RECORD +11 -11
- {mergeron-2025.739265.2.dist-info → mergeron-2025.739290.1.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: ArrayDouble = 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",
|
|
@@ -158,7 +168,7 @@ def gen_market_shares_uniform(
|
|
|
158
168
|
).T # faster than np.stack() and variants
|
|
159
169
|
|
|
160
170
|
# Keep only share combinations representing feasible mergers
|
|
161
|
-
# 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
|
|
162
172
|
_frmshr_array = _frmshr_array[_frmshr_array.min(axis=1) > 0]
|
|
163
173
|
|
|
164
174
|
# Let a third column have values of "np.nan", so HHI calculations return "np.nan"
|
|
@@ -173,7 +183,7 @@ def gen_market_shares_uniform(
|
|
|
173
183
|
)
|
|
174
184
|
|
|
175
185
|
# This array is meant to be ignored, so a sentinel value is fine
|
|
176
|
-
_fcounts.fill(-
|
|
186
|
+
_fcounts.fill(-1)
|
|
177
187
|
|
|
178
188
|
_nth_firm_share.fill(np.nan)
|
|
179
189
|
_aggregate_purchase_prob.fill(np.nan)
|
|
@@ -183,15 +193,15 @@ def gen_market_shares_uniform(
|
|
|
183
193
|
)
|
|
184
194
|
|
|
185
195
|
|
|
186
|
-
def
|
|
187
|
-
_s_size: int
|
|
188
|
-
_recapture_form: RECForm
|
|
189
|
-
_dist_type_dir: SHRDistribution
|
|
190
|
-
_dist_parms_dir: ArrayDouble
|
|
191
|
-
_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,
|
|
192
202
|
_fcount_rng_seed_seq: SeedSequence | None = None,
|
|
193
203
|
_mktshr_rng_seed_seq: SeedSequence | None = None,
|
|
194
|
-
_nthreads: int =
|
|
204
|
+
_nthreads: int = NTHREADS,
|
|
195
205
|
/,
|
|
196
206
|
) -> ShareDataSample:
|
|
197
207
|
"""Dirichlet-distributed shares with multiple firm-counts.
|
|
@@ -230,10 +240,11 @@ def gen_market_shares_dirichlet_multimarket(
|
|
|
230
240
|
|
|
231
241
|
"""
|
|
232
242
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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
|
+
)
|
|
237
248
|
|
|
238
249
|
_min_choice_wt = 0.03 if _dist_type_dir == SHRDistribution.DIR_FLAT_CONSTR else 0.00
|
|
239
250
|
_fcount_keys, _choice_wts = zip(
|
|
@@ -251,7 +262,7 @@ def gen_market_shares_dirichlet_multimarket(
|
|
|
251
262
|
|
|
252
263
|
_fc_max = _fcount_keys[-1]
|
|
253
264
|
_dir_alphas_full = (
|
|
254
|
-
[
|
|
265
|
+
_dist_parms_dir[:_fc_max] if len(_dist_parms_dir) else [1.0] * _fc_max
|
|
255
266
|
)
|
|
256
267
|
if _dist_type_dir == SHRDistribution.DIR_ASYM:
|
|
257
268
|
_dir_alphas_full = [2.0] * 6 + [1.5] * 5 + [1.25] * min(7, _fc_max)
|
|
@@ -262,12 +273,12 @@ def gen_market_shares_dirichlet_multimarket(
|
|
|
262
273
|
_dat = [2.5] * 2
|
|
263
274
|
if _fcv > len(_dat):
|
|
264
275
|
_dat += [1.0 / (_fcv - 2)] * (_fcv - 2)
|
|
265
|
-
return np.array(_dat,
|
|
276
|
+
return np.array(_dat, float)
|
|
266
277
|
|
|
267
278
|
else:
|
|
268
279
|
|
|
269
280
|
def _gen_dir_alphas(_fcv: int) -> ArrayDouble:
|
|
270
|
-
return np.array(_dir_alphas_full[:_fcv],
|
|
281
|
+
return np.array(_dir_alphas_full[:_fcv], float)
|
|
271
282
|
|
|
272
283
|
_fcounts = prng(_fcount_rng_seed_seq).choice(
|
|
273
284
|
_fcount_keys, size=(_s_size, 1), p=_choice_wts
|
|
@@ -282,7 +293,7 @@ def gen_market_shares_dirichlet_multimarket(
|
|
|
282
293
|
_aggregate_purchase_prob, _nth_firm_share = (
|
|
283
294
|
np.empty((_s_size, 1)) for _ in range(2)
|
|
284
295
|
)
|
|
285
|
-
_mktshr_array = np.empty((_s_size, _fc_max),
|
|
296
|
+
_mktshr_array = np.empty((_s_size, _fc_max), float)
|
|
286
297
|
for _f_val, _f_sseq in zip(_fcount_keys, _mktshr_seed_seq_ch, strict=True):
|
|
287
298
|
_fcounts_match_rows = np.where(_fcounts == _f_val)[0]
|
|
288
299
|
_dir_alphas_test = _gen_dir_alphas(_f_val)
|
|
@@ -328,10 +339,10 @@ def gen_market_shares_dirichlet_multimarket(
|
|
|
328
339
|
|
|
329
340
|
def gen_market_shares_dirichlet(
|
|
330
341
|
_dir_alphas: ArrayDouble,
|
|
331
|
-
_s_size: int
|
|
332
|
-
_recapture_form: RECForm
|
|
342
|
+
_s_size: int,
|
|
343
|
+
_recapture_form: RECForm,
|
|
333
344
|
_mktshr_rng_seed_seq: SeedSequence | None = None,
|
|
334
|
-
_nthreads: int =
|
|
345
|
+
_nthreads: int = NTHREADS,
|
|
335
346
|
/,
|
|
336
347
|
) -> ShareDataSample:
|
|
337
348
|
"""Dirichlet-distributed shares with fixed firm-count.
|
|
@@ -373,7 +384,7 @@ def gen_market_shares_dirichlet(
|
|
|
373
384
|
else SeedSequence(pool_size=8)
|
|
374
385
|
)
|
|
375
386
|
|
|
376
|
-
_mktshr_array = np.empty((_s_size, len(_dir_alphas)),
|
|
387
|
+
_mktshr_array = np.empty((_s_size, len(_dir_alphas)), float)
|
|
377
388
|
_mrng = MultithreadedRNG(
|
|
378
389
|
_mktshr_array,
|
|
379
390
|
dist_type="Dirichlet",
|
|
@@ -397,11 +408,11 @@ def gen_market_shares_dirichlet(
|
|
|
397
408
|
)
|
|
398
409
|
|
|
399
410
|
# If recapture_form == 'inside_out', further calculations downstream
|
|
400
|
-
_aggregate_purchase_prob = np.empty((_s_size, 1),
|
|
411
|
+
_aggregate_purchase_prob = np.empty((_s_size, 1), float)
|
|
401
412
|
_aggregate_purchase_prob.fill(np.nan)
|
|
402
413
|
if _recapture_form == RECForm.OUTIN:
|
|
403
414
|
_aggregate_purchase_prob = 1 - _mktshr_array[:, [-1]] # type: ignore
|
|
404
|
-
_mktshr_array = _mktshr_array[:, :-1] / _aggregate_purchase_prob
|
|
415
|
+
_mktshr_array = _mktshr_array[:, :-1] / _aggregate_purchase_prob
|
|
405
416
|
|
|
406
417
|
return ShareDataSample(
|
|
407
418
|
_mktshr_array,
|
|
@@ -415,7 +426,7 @@ def gen_divr_array(
|
|
|
415
426
|
_recapture_form: RECForm,
|
|
416
427
|
_recapture_ratio: float | None,
|
|
417
428
|
_frmshr_array: ArrayDouble,
|
|
418
|
-
_aggregate_purchase_prob: ArrayDouble
|
|
429
|
+
_aggregate_purchase_prob: ArrayDouble,
|
|
419
430
|
/,
|
|
420
431
|
) -> ArrayDouble:
|
|
421
432
|
"""
|
|
@@ -485,8 +496,8 @@ def gen_margin_price_data(
|
|
|
485
496
|
_price_spec: PriceSpec,
|
|
486
497
|
_hsr_filing_test_type: SSZConstant,
|
|
487
498
|
_pcm_rng_seed_seq: SeedSequence,
|
|
488
|
-
_pr_rng_seed_seq: SeedSequence | None
|
|
489
|
-
_nthreads: int =
|
|
499
|
+
_pr_rng_seed_seq: SeedSequence | None,
|
|
500
|
+
_nthreads: int = NTHREADS,
|
|
490
501
|
/,
|
|
491
502
|
) -> tuple[MarginDataSample, PriceDataSample]:
|
|
492
503
|
"""Generate margin and price data for mergers in the sample.
|
|
@@ -533,10 +544,8 @@ def gen_margin_price_data(
|
|
|
533
544
|
np.empty_like(_frmshr_array), np.ones(len(_frmshr_array)) == 0
|
|
534
545
|
)
|
|
535
546
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
np.empty_like(_frmshr_array, np.float64),
|
|
539
|
-
)
|
|
547
|
+
_nth_firm_price: ArrayDouble
|
|
548
|
+
_price_array: ArrayDouble = np.ones_like(_frmshr_array, np.float64)
|
|
540
549
|
|
|
541
550
|
_pr_max_ratio = 5.0
|
|
542
551
|
match _price_spec:
|
|
@@ -556,7 +565,7 @@ def gen_margin_price_data(
|
|
|
556
565
|
1 + np.arange(_pr_max_ratio), size=(len(_frmshr_array), 3)
|
|
557
566
|
)
|
|
558
567
|
_price_array = _price_array_gen[:, :2]
|
|
559
|
-
_nth_firm_price = _price_array_gen[:, [2]]
|
|
568
|
+
_nth_firm_price = _price_array_gen[:, [2]]
|
|
560
569
|
# del _price_array_gen
|
|
561
570
|
case PriceSpec.CSY:
|
|
562
571
|
# TODO:
|
|
@@ -617,7 +626,7 @@ def gen_margin_price_data(
|
|
|
617
626
|
_nthreads,
|
|
618
627
|
)
|
|
619
628
|
|
|
620
|
-
_price_array = _price_array.astype(np.float64)
|
|
629
|
+
# _price_array = _price_array.astype(np.float64)
|
|
621
630
|
_rev_array = _price_array * _frmshr_array
|
|
622
631
|
_nth_firm_rev = _nth_firm_price * _nth_firm_share
|
|
623
632
|
|
|
@@ -671,8 +680,8 @@ def _gen_margin_data(
|
|
|
671
680
|
_price_array: ArrayDouble,
|
|
672
681
|
_aggregate_purchase_prob: ArrayDouble,
|
|
673
682
|
_pcm_spec: PCMSpec,
|
|
674
|
-
_pcm_rng_seed_seq: SeedSequence,
|
|
675
|
-
_nthreads: int =
|
|
683
|
+
_pcm_rng_seed_seq: SeedSequence | None,
|
|
684
|
+
_nthreads: int = NTHREADS,
|
|
676
685
|
/,
|
|
677
686
|
) -> MarginDataSample:
|
|
678
687
|
_dist_type_pcm, _dist_firm2_pcm, _dist_parms_pcm = (
|
|
@@ -681,12 +690,13 @@ def _gen_margin_data(
|
|
|
681
690
|
)
|
|
682
691
|
|
|
683
692
|
_pcm_array = (
|
|
684
|
-
np.empty((len(_frmshr_array), 1),
|
|
693
|
+
np.empty((len(_frmshr_array), 1), float)
|
|
685
694
|
if _pcm_spec.firm2_pcm_constraint == FM2Constraint.SYM
|
|
686
|
-
else np.empty_like(_frmshr_array,
|
|
695
|
+
else np.empty_like(_frmshr_array, float)
|
|
687
696
|
)
|
|
688
697
|
|
|
689
|
-
|
|
698
|
+
_dist_parms: ArrayFloat
|
|
699
|
+
_beta_min, _beta_max = [0.0] * 2 # placeholder
|
|
690
700
|
if _dist_type_pcm == PCMDistribution.EMPR:
|
|
691
701
|
_pcm_array = mgn_data_resampler(
|
|
692
702
|
_pcm_array.shape, seed_sequence=_pcm_rng_seed_seq
|
|
@@ -697,11 +707,11 @@ def _gen_margin_data(
|
|
|
697
707
|
_dist_type = "Beta"
|
|
698
708
|
_dist_parms_pcm = (
|
|
699
709
|
(
|
|
700
|
-
np.array([0, 1, 0, 1],
|
|
701
|
-
if
|
|
702
|
-
else
|
|
710
|
+
np.array([0.5, 1, 0, 1], float)
|
|
711
|
+
if _dist_type_pcm == PCMDistribution.BETA_BND
|
|
712
|
+
else DEFAULT_BETA_DIST_PARMS
|
|
703
713
|
)
|
|
704
|
-
if _dist_parms_pcm is None
|
|
714
|
+
if _dist_parms_pcm is None or not len(_dist_parms_pcm)
|
|
705
715
|
else _dist_parms_pcm
|
|
706
716
|
)
|
|
707
717
|
_dist_parms = beta_located_bound(_dist_parms_pcm)
|
|
@@ -709,7 +719,9 @@ def _gen_margin_data(
|
|
|
709
719
|
else:
|
|
710
720
|
_dist_type = "Uniform"
|
|
711
721
|
_dist_parms = (
|
|
712
|
-
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
|
|
713
725
|
)
|
|
714
726
|
|
|
715
727
|
_pcm_rng = MultithreadedRNG(
|
|
@@ -780,7 +792,7 @@ def _beta_located(
|
|
|
780
792
|
"""
|
|
781
793
|
|
|
782
794
|
_mul = -1 + _mu * (1 - _mu) / _sigma**2
|
|
783
|
-
return np.array([_mu * _mul, (1 - _mu) * _mul],
|
|
795
|
+
return np.array([_mu * _mul, (1 - _mu) * _mul], float)
|
|
784
796
|
|
|
785
797
|
|
|
786
798
|
def beta_located_bound(_dist_parms: ArrayDouble, /) -> ArrayDouble:
|
|
@@ -813,65 +825,3 @@ def beta_located_bound(_dist_parms: ArrayDouble, /) -> ArrayDouble:
|
|
|
813
825
|
|
|
814
826
|
_bmu, _bsigma, _bmin, _bmax = _dist_parms
|
|
815
827
|
return _beta_located((_bmu - _bmin) / (_bmax - _bmin), _bsigma / (_bmax - _bmin))
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
def parse_seed_seq_list(
|
|
819
|
-
_sseq_list: Sequence[SeedSequence] | None,
|
|
820
|
-
_mktshr_dist_type: SHRDistribution,
|
|
821
|
-
_price_spec: PriceSpec,
|
|
822
|
-
/,
|
|
823
|
-
) -> SeedSequenceData:
|
|
824
|
-
"""Initialize RNG seed sequences to ensure independence of distinct random streams.
|
|
825
|
-
|
|
826
|
-
The tuple of SeedSequences, is parsed in the following order
|
|
827
|
-
for generating the relevant random variates:
|
|
828
|
-
1.) quantity shares
|
|
829
|
-
2.) price-cost margins
|
|
830
|
-
3.) firm-counts, if :code:`MarketSpec.share_spec.dist_type` is a Dirichlet distribution
|
|
831
|
-
4.) prices, if :code:`MarketSpec.price_spec ==`:attr:`mergeron.gen.PriceSpec.ZERO`.
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
Parameters
|
|
836
|
-
----------
|
|
837
|
-
_sseq_list
|
|
838
|
-
List of RNG seed sequences
|
|
839
|
-
|
|
840
|
-
_mktshr_dist_type
|
|
841
|
-
Market share distribution type
|
|
842
|
-
|
|
843
|
-
_price_spec
|
|
844
|
-
Price specification
|
|
845
|
-
|
|
846
|
-
Returns
|
|
847
|
-
-------
|
|
848
|
-
Seed sequence data
|
|
849
|
-
|
|
850
|
-
"""
|
|
851
|
-
_seed_count = 2 if _mktshr_dist_type == SHRDistribution.UNI else 3
|
|
852
|
-
_seed_count += 1 if _price_spec == PriceSpec.ZERO else 0
|
|
853
|
-
|
|
854
|
-
_fcount_rng_seed_seq: SeedSequence | None = None
|
|
855
|
-
_pr_rng_seed_seq: SeedSequence | None = None
|
|
856
|
-
|
|
857
|
-
_sseq_list = (
|
|
858
|
-
_sseq_list
|
|
859
|
-
if _sseq_list
|
|
860
|
-
else tuple(SeedSequence(pool_size=8) for _ in range(_seed_count))
|
|
861
|
-
)
|
|
862
|
-
|
|
863
|
-
if (_l := len(_sseq_list)) < _seed_count:
|
|
864
|
-
raise ValueError(
|
|
865
|
-
f"Seed sequence list must contain {_seed_count} seed sequences; "
|
|
866
|
-
f"only {_l} given."
|
|
867
|
-
)
|
|
868
|
-
|
|
869
|
-
_mktshr_rng_seed_seq, _pcm_rng_seed_seq = _sseq_list[:2]
|
|
870
|
-
_fcount_rng_seed_seq = (
|
|
871
|
-
None if _mktshr_dist_type == SHRDistribution.UNI else _sseq_list[2]
|
|
872
|
-
)
|
|
873
|
-
_pr_rng_seed_seq = _sseq_list[-1] if _price_spec == PriceSpec.ZERO else None
|
|
874
|
-
|
|
875
|
-
return SeedSequenceData(
|
|
876
|
-
_mktshr_rng_seed_seq, _pcm_rng_seed_seq, _fcount_rng_seed_seq, _pr_rng_seed_seq
|
|
877
|
-
)
|
|
@@ -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:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: mergeron
|
|
3
|
-
Version: 2025.
|
|
3
|
+
Version: 2025.739290.1
|
|
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)
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
mergeron/__init__.py,sha256=
|
|
1
|
+
mergeron/__init__.py,sha256=fxabxjXrodvYcQtmpl6jv21ZGl-RPBI18ECzPQ60MPY,3515
|
|
2
2
|
mergeron/core/__init__.py,sha256=qYRA1D4Gx-WSkICqiueWLWPedkWmb_CIn7fgvN7unk4,182
|
|
3
3
|
mergeron/core/empirical_margin_distribution.py,sha256=byO11ROGVQcmbZVWdVJkJ906WnHhx7jcoL5BbxPmX7I,8688
|
|
4
4
|
mergeron/core/ftc_merger_investigations_data.py,sha256=9AT-phfkn0NHJvn9lcpbH8ExWZStYW47KQjNjDGS3qc,28709
|
|
5
|
-
mergeron/core/guidelines_boundaries.py,sha256=
|
|
5
|
+
mergeron/core/guidelines_boundaries.py,sha256=4twCwb7see2nbBV5wSKPg-Let9huex3CxqgAY-JG-2g,17239
|
|
6
6
|
mergeron/core/guidelines_boundary_functions.py,sha256=4vMz5DQ72fgj7leUlVJvXBrxdZAeDJP7FoGBEVXDdeQ,34866
|
|
7
7
|
mergeron/core/guidelines_boundary_functions_extra.py,sha256=qL1zT-Xgj2qD2EyBRR87APoVc47MkGM02xYQhNgwEvg,11216
|
|
8
|
-
mergeron/core/pseudorandom_numbers.py,sha256=
|
|
8
|
+
mergeron/core/pseudorandom_numbers.py,sha256=8_MBHIvWjVZUN4Et7Tt3J1NzWxuzq9vtzFkycW5rBaQ,9918
|
|
9
9
|
mergeron/data/__init__.py,sha256=KtjBlZOl7jwBCAUhrTJB9PdrN39YLYytNiSUSM_gRmA,62
|
|
10
10
|
mergeron/data/damodaran_margin_data.xls,sha256=Qggl1p5nkOMJI8YUXhkwXQRz-OhRSqBTzz57N0JQyYA,79360
|
|
11
11
|
mergeron/data/damodaran_margin_data_dict.msgpack,sha256=sr6s4L69kposEpzGI7jpPb4ULz0UpY-bEYfeNi6UlRA,57621
|
|
12
12
|
mergeron/data/ftc_invdata.msgpack,sha256=WBFHgi7Ld4R-h2zL2Zc3TOIlKqVrbVFMH1LoI4-T-M0,264664
|
|
13
13
|
mergeron/demo/__init__.py,sha256=KtjBlZOl7jwBCAUhrTJB9PdrN39YLYytNiSUSM_gRmA,62
|
|
14
14
|
mergeron/demo/visualize_empirical_margin_distribution.py,sha256=kDwPfhsBjsQdYPyhe4KZG2guB_xHhPaCrvn8fezIz4M,2354
|
|
15
|
-
mergeron/gen/__init__.py,sha256=
|
|
16
|
-
mergeron/gen/data_generation.py,sha256=
|
|
17
|
-
mergeron/gen/data_generation_functions.py,sha256=
|
|
18
|
-
mergeron/gen/enforcement_stats.py,sha256=
|
|
19
|
-
mergeron/gen/upp_tests.py,sha256=
|
|
15
|
+
mergeron/gen/__init__.py,sha256=t1RswXk-L6olOhj5XqPekd8je8Za7NUFuSo3fuM2Wts,21787
|
|
16
|
+
mergeron/gen/data_generation.py,sha256=IBWo-Al2ApHnjVQyIUV35x0OnoMgliJfqy5YrbBCVgo,16101
|
|
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
20
|
mergeron/py.typed,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
21
|
-
mergeron-2025.
|
|
22
|
-
mergeron-2025.
|
|
23
|
-
mergeron-2025.
|
|
21
|
+
mergeron-2025.739290.1.dist-info/METADATA,sha256=Y7cBEZaZAuOWsdpYKSQjNOjebKCGtYLO1nz8AEwDGFE,14541
|
|
22
|
+
mergeron-2025.739290.1.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
|
|
23
|
+
mergeron-2025.739290.1.dist-info/RECORD,,
|
|
File without changes
|