mergeron 2025.739290.0__tar.gz → 2025.739290.2__tar.gz
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-2025.739290.0 → mergeron-2025.739290.2}/PKG-INFO +1 -1
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/pyproject.toml +1 -1
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/__init__.py +17 -1
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/core/ftc_merger_investigations_data.py +28 -5
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/core/guidelines_boundaries.py +84 -8
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/core/pseudorandom_numbers.py +1 -17
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/gen/__init__.py +18 -1
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/gen/data_generation.py +5 -11
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/gen/data_generation_functions.py +18 -19
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/README.rst +0 -0
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/core/__init__.py +0 -0
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/core/empirical_margin_distribution.py +0 -0
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/core/guidelines_boundary_functions.py +0 -0
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/core/guidelines_boundary_functions_extra.py +0 -0
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/data/__init__.py +0 -0
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/data/damodaran_margin_data.xls +0 -0
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/data/damodaran_margin_data_dict.msgpack +0 -0
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/data/ftc_invdata.msgpack +0 -0
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/demo/__init__.py +0 -0
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/demo/visualize_empirical_margin_distribution.py +0 -0
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/gen/enforcement_stats.py +0 -0
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/gen/upp_tests.py +0 -0
- {mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: mergeron
|
|
3
|
-
Version: 2025.739290.
|
|
3
|
+
Version: 2025.739290.2
|
|
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
|
|
@@ -6,12 +6,13 @@ from pathlib import Path
|
|
|
6
6
|
from typing import Literal
|
|
7
7
|
|
|
8
8
|
import numpy as np
|
|
9
|
+
from numpy.random import SeedSequence
|
|
9
10
|
from numpy.typing import NDArray
|
|
10
11
|
from ruamel import yaml
|
|
11
12
|
|
|
12
13
|
_PKG_NAME: str = Path(__file__).parent.stem
|
|
13
14
|
|
|
14
|
-
VERSION = "2025.739290.
|
|
15
|
+
VERSION = "2025.739290.2"
|
|
15
16
|
|
|
16
17
|
__version__ = VERSION
|
|
17
18
|
|
|
@@ -66,6 +67,21 @@ type ArrayBIGINT = NDArray[np.int64]
|
|
|
66
67
|
),
|
|
67
68
|
)
|
|
68
69
|
|
|
70
|
+
# Add yaml representer, constructor for SeedSequence
|
|
71
|
+
this_yaml.representer.add_representer(
|
|
72
|
+
SeedSequence,
|
|
73
|
+
lambda _r, _d: _r.represent_mapping(
|
|
74
|
+
"!SeedSequence",
|
|
75
|
+
{
|
|
76
|
+
_a: getattr(_d, _a)
|
|
77
|
+
for _a in ("entropy", "spawn_key", "pool_size", "n_children_spawned")
|
|
78
|
+
},
|
|
79
|
+
),
|
|
80
|
+
)
|
|
81
|
+
this_yaml.constructor.add_constructor(
|
|
82
|
+
"!SeedSequence", lambda _c, _n, /: SeedSequence(**_c.construct_mapping(_n))
|
|
83
|
+
)
|
|
84
|
+
|
|
69
85
|
|
|
70
86
|
@enum.unique
|
|
71
87
|
class RECForm(enum.StrEnum):
|
|
@@ -8,13 +8,16 @@ Reported row and column totals from source data are not stored.
|
|
|
8
8
|
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
11
13
|
import shutil
|
|
12
14
|
from collections.abc import Mapping, Sequence
|
|
15
|
+
from dataclasses import dataclass
|
|
13
16
|
from importlib import resources
|
|
14
17
|
from operator import itemgetter
|
|
15
18
|
from pathlib import Path
|
|
16
19
|
from types import MappingProxyType
|
|
17
|
-
from typing import Any
|
|
20
|
+
from typing import Any
|
|
18
21
|
|
|
19
22
|
import msgpack # type: ignore
|
|
20
23
|
import msgpack_numpy as m # type: ignore
|
|
@@ -23,8 +26,9 @@ import re2 as re # type: ignore
|
|
|
23
26
|
import urllib3
|
|
24
27
|
from bs4 import BeautifulSoup
|
|
25
28
|
from numpy.testing import assert_array_equal
|
|
29
|
+
from ruamel import yaml
|
|
26
30
|
|
|
27
|
-
from .. import _PKG_NAME, DATA_DIR, VERSION, ArrayBIGINT # noqa: TID252
|
|
31
|
+
from .. import _PKG_NAME, DATA_DIR, EMPTY_ARRAYINT, VERSION, ArrayBIGINT # noqa: TID252
|
|
28
32
|
|
|
29
33
|
__version__ = VERSION
|
|
30
34
|
|
|
@@ -89,11 +93,27 @@ CNT_FCOUNT_DICT = {
|
|
|
89
93
|
}
|
|
90
94
|
|
|
91
95
|
|
|
92
|
-
|
|
96
|
+
@dataclass(slots=True, frozen=True)
|
|
97
|
+
class INVTableData:
|
|
93
98
|
industry_group: str
|
|
94
99
|
additional_evidence: str
|
|
95
100
|
data_array: ArrayBIGINT
|
|
96
101
|
|
|
102
|
+
@classmethod
|
|
103
|
+
def to_yaml(
|
|
104
|
+
cls, _r: yaml.representer.SafeRepresenter, _d: INVTableData
|
|
105
|
+
) -> yaml.MappingNode:
|
|
106
|
+
_ret: yaml.MappingNode = _r.represent_mapping(
|
|
107
|
+
f"!{cls.__name__}", {_a: getattr(_d, _a) for _a in _d.__dataclass_fields__}
|
|
108
|
+
)
|
|
109
|
+
return _ret
|
|
110
|
+
|
|
111
|
+
@classmethod
|
|
112
|
+
def from_yaml(
|
|
113
|
+
cls, _c: yaml.constructor.SafeConstructor, _n: yaml.MappingNode
|
|
114
|
+
) -> INVTableData:
|
|
115
|
+
return cls(**_c.construct_mapping(_n))
|
|
116
|
+
|
|
97
117
|
|
|
98
118
|
type INVData = Mapping[str, Mapping[str, Mapping[str, INVTableData]]]
|
|
99
119
|
type _INVData_in = dict[str, dict[str, dict[str, INVTableData]]]
|
|
@@ -278,10 +298,13 @@ def _construct_new_period_data(
|
|
|
278
298
|
_invdata_cuml_sub_table.data_array,
|
|
279
299
|
)
|
|
280
300
|
|
|
281
|
-
_invdata_base_sub_table = _invdata_base[_table_type].get(
|
|
301
|
+
_invdata_base_sub_table = _invdata_base[_table_type].get(
|
|
302
|
+
_table_no, INVTableData("", "", EMPTY_ARRAYINT)
|
|
303
|
+
)
|
|
282
304
|
|
|
283
305
|
(_invdata_base_ind_group, _invdata_base_evid_cond, _invdata_base_array) = (
|
|
284
|
-
_invdata_base_sub_table
|
|
306
|
+
getattr(_invdata_base_sub_table, _a)
|
|
307
|
+
for _a in ("industry_group", "additional_evidence", "data_array")
|
|
285
308
|
)
|
|
286
309
|
|
|
287
310
|
# Some tables can't be constructed due to inconsistencies in the data
|
{mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/core/guidelines_boundaries.py
RENAMED
|
@@ -13,6 +13,7 @@ from typing import Literal
|
|
|
13
13
|
import numpy as np
|
|
14
14
|
from attrs import Attribute, field, frozen, validators
|
|
15
15
|
from mpmath import mp, mpf # type: ignore
|
|
16
|
+
from ruamel import yaml
|
|
16
17
|
|
|
17
18
|
from .. import ( # noqa: TID252
|
|
18
19
|
DEFAULT_REC_RATIO,
|
|
@@ -21,6 +22,7 @@ from .. import ( # noqa: TID252
|
|
|
21
22
|
HMGPubYear,
|
|
22
23
|
RECForm,
|
|
23
24
|
UPPAggrSelector,
|
|
25
|
+
this_yaml,
|
|
24
26
|
)
|
|
25
27
|
from . import guidelines_boundary_functions as gbfn
|
|
26
28
|
|
|
@@ -41,7 +43,23 @@ class HMGThresholds:
|
|
|
41
43
|
cmcr: float
|
|
42
44
|
ipr: float
|
|
43
45
|
|
|
46
|
+
@classmethod
|
|
47
|
+
def to_yaml(
|
|
48
|
+
cls, _r: yaml.representer.SafeRepresenter, _d: HMGThresholds
|
|
49
|
+
) -> yaml.MappingNode:
|
|
50
|
+
_ret: yaml.MappingNode = _r.represent_mapping(
|
|
51
|
+
f"!{cls.__name__}", {_a: getattr(_d, _a) for _a in _d.__dataclass_fields__}
|
|
52
|
+
)
|
|
53
|
+
return _ret
|
|
54
|
+
|
|
55
|
+
@classmethod
|
|
56
|
+
def from_yaml(
|
|
57
|
+
cls, _c: yaml.constructor.SafeConstructor, _n: yaml.MappingNode
|
|
58
|
+
) -> HMGThresholds:
|
|
59
|
+
return cls(**_c.construct_mapping(_n))
|
|
44
60
|
|
|
61
|
+
|
|
62
|
+
@this_yaml.register_class
|
|
45
63
|
@frozen
|
|
46
64
|
class GuidelinesThresholds:
|
|
47
65
|
"""
|
|
@@ -147,7 +165,24 @@ class GuidelinesThresholds:
|
|
|
147
165
|
),
|
|
148
166
|
)
|
|
149
167
|
|
|
168
|
+
@classmethod
|
|
169
|
+
def to_yaml(
|
|
170
|
+
cls, _r: yaml.representer.SafeRepresenter, _d: GuidelinesThresholds
|
|
171
|
+
) -> yaml.MappingNode:
|
|
172
|
+
_ret: yaml.MappingNode = _r.represent_mapping(
|
|
173
|
+
f"!{cls.__name__}",
|
|
174
|
+
{_a.name: getattr(_d, _a.name) for _a in _d.__attrs_attrs__},
|
|
175
|
+
)
|
|
176
|
+
return _ret
|
|
150
177
|
|
|
178
|
+
@classmethod
|
|
179
|
+
def from_yaml(
|
|
180
|
+
cls, _c: yaml.constructor.SafeConstructor, _n: yaml.MappingNode
|
|
181
|
+
) -> GuidelinesThresholds:
|
|
182
|
+
return cls(**_c.construct_mapping(_n))
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@this_yaml.register_class
|
|
151
186
|
@frozen
|
|
152
187
|
class ConcentrationBoundary:
|
|
153
188
|
"""Concentration parameters, boundary coordinates, and area under concentration boundary."""
|
|
@@ -184,12 +219,12 @@ class ConcentrationBoundary:
|
|
|
184
219
|
kw_only=False, default=5, validator=validators.instance_of(int)
|
|
185
220
|
)
|
|
186
221
|
|
|
187
|
-
coordinates: ArrayDouble = field(init=False, kw_only=True)
|
|
188
|
-
"""Market-share pairs as Cartesian coordinates of points on the concentration boundary."""
|
|
189
|
-
|
|
190
222
|
area: float = field(init=False, kw_only=True)
|
|
191
223
|
"""Area under the concentration boundary."""
|
|
192
224
|
|
|
225
|
+
coordinates: ArrayDouble = field(init=False, kw_only=True)
|
|
226
|
+
"""Market-share pairs as Cartesian coordinates of points on the concentration boundary."""
|
|
227
|
+
|
|
193
228
|
def __attrs_post_init__(self, /) -> None:
|
|
194
229
|
match self.measure_name:
|
|
195
230
|
case "ΔHHI":
|
|
@@ -202,10 +237,31 @@ class ConcentrationBoundary:
|
|
|
202
237
|
_conc_fn = gbfn.hhi_post_contrib_boundary
|
|
203
238
|
|
|
204
239
|
_boundary = _conc_fn(self.threshold, dps=self.precision)
|
|
205
|
-
object.__setattr__(self, "coordinates", _boundary.coordinates)
|
|
206
240
|
object.__setattr__(self, "area", _boundary.area)
|
|
241
|
+
object.__setattr__(self, "coordinates", _boundary.coordinates)
|
|
207
242
|
|
|
243
|
+
@classmethod
|
|
244
|
+
def to_yaml(
|
|
245
|
+
cls, _r: yaml.representer.SafeRepresenter, _d: ConcentrationBoundary
|
|
246
|
+
) -> yaml.MappingNode:
|
|
247
|
+
_ret: yaml.MappingNode = _r.represent_mapping(
|
|
248
|
+
f"!{cls.__name__}",
|
|
249
|
+
{
|
|
250
|
+
_a.name: getattr(_d, _a.name)
|
|
251
|
+
for _a in _d.__attrs_attrs__
|
|
252
|
+
if _a.name not in ("area", "coordinates")
|
|
253
|
+
},
|
|
254
|
+
)
|
|
255
|
+
return _ret
|
|
256
|
+
|
|
257
|
+
@classmethod
|
|
258
|
+
def from_yaml(
|
|
259
|
+
cls, _c: yaml.constructor.SafeConstructor, _n: yaml.MappingNode
|
|
260
|
+
) -> ConcentrationBoundary:
|
|
261
|
+
return cls(**_c.construct_mapping(_n))
|
|
208
262
|
|
|
263
|
+
|
|
264
|
+
@this_yaml.register_class
|
|
209
265
|
@frozen
|
|
210
266
|
class DiversionRatioBoundary:
|
|
211
267
|
"""
|
|
@@ -310,12 +366,12 @@ class DiversionRatioBoundary:
|
|
|
310
366
|
|
|
311
367
|
"""
|
|
312
368
|
|
|
313
|
-
coordinates: ArrayDouble = field(init=False, kw_only=True)
|
|
314
|
-
"""Market-share pairs as Cartesian coordinates of points on the diversion ratio boundary."""
|
|
315
|
-
|
|
316
369
|
area: float = field(init=False, kw_only=True)
|
|
317
370
|
"""Area under the diversion ratio boundary."""
|
|
318
371
|
|
|
372
|
+
coordinates: ArrayDouble = field(init=False, kw_only=True)
|
|
373
|
+
"""Market-share pairs as Cartesian coordinates of points on the diversion ratio boundary."""
|
|
374
|
+
|
|
319
375
|
def __attrs_post_init__(self, /) -> None:
|
|
320
376
|
_share_ratio = critical_share_ratio(
|
|
321
377
|
self.diversion_ratio, r_bar=self.recapture_ratio
|
|
@@ -359,8 +415,28 @@ class DiversionRatioBoundary:
|
|
|
359
415
|
_upp_agg_kwargs |= {"agg_method": _aggregator, "weighting": _wgt_type}
|
|
360
416
|
|
|
361
417
|
_boundary = _upp_agg_fn(_share_ratio, self.recapture_ratio, **_upp_agg_kwargs)
|
|
362
|
-
object.__setattr__(self, "coordinates", _boundary.coordinates)
|
|
363
418
|
object.__setattr__(self, "area", _boundary.area)
|
|
419
|
+
object.__setattr__(self, "coordinates", _boundary.coordinates)
|
|
420
|
+
|
|
421
|
+
@classmethod
|
|
422
|
+
def to_yaml(
|
|
423
|
+
cls, _r: yaml.representer.SafeRepresenter, _d: DiversionRatioBoundary
|
|
424
|
+
) -> yaml.MappingNode:
|
|
425
|
+
_ret: yaml.MappingNode = _r.represent_mapping(
|
|
426
|
+
f"!{cls.__name__}",
|
|
427
|
+
{
|
|
428
|
+
_a.name: getattr(_d, _a.name)
|
|
429
|
+
for _a in _d.__attrs_attrs__
|
|
430
|
+
if _a.name not in ("area", "coordinates")
|
|
431
|
+
},
|
|
432
|
+
)
|
|
433
|
+
return _ret
|
|
434
|
+
|
|
435
|
+
@classmethod
|
|
436
|
+
def from_yaml(
|
|
437
|
+
cls, _c: yaml.constructor.SafeConstructor, _n: yaml.MappingNode
|
|
438
|
+
) -> DiversionRatioBoundary:
|
|
439
|
+
return cls(**_c.construct_mapping(_n))
|
|
364
440
|
|
|
365
441
|
|
|
366
442
|
def guppi_from_delta(
|
|
@@ -16,7 +16,7 @@ import numpy as np
|
|
|
16
16
|
from attrs import Attribute, Converter, define, field
|
|
17
17
|
from numpy.random import PCG64DXSM, Generator, SeedSequence
|
|
18
18
|
|
|
19
|
-
from .. import NTHREADS, VERSION, ArrayDouble, ArrayFloat
|
|
19
|
+
from .. import NTHREADS, VERSION, ArrayDouble, ArrayFloat # noqa: TID252
|
|
20
20
|
|
|
21
21
|
__version__ = VERSION
|
|
22
22
|
|
|
@@ -24,22 +24,6 @@ DEFAULT_DIST_PARMS: ArrayFloat = np.array([0.0, 1.0], float)
|
|
|
24
24
|
DEFAULT_BETA_DIST_PARMS: ArrayFloat = np.array([1.0, 1.0], float)
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
# Add yaml representer, constructor for SeedSequence
|
|
28
|
-
this_yaml.representer.add_representer(
|
|
29
|
-
SeedSequence,
|
|
30
|
-
lambda _r, _d: _r.represent_mapping(
|
|
31
|
-
"!SeedSequence",
|
|
32
|
-
{
|
|
33
|
-
_a: getattr(_d, _a)
|
|
34
|
-
for _a in ("entropy", "spawn_key", "pool_size", "n_children_spawned")
|
|
35
|
-
},
|
|
36
|
-
),
|
|
37
|
-
)
|
|
38
|
-
this_yaml.constructor.add_constructor(
|
|
39
|
-
"!SeedSequence", lambda _c, _n, /: SeedSequence(**_c.construct_mapping(_n))
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
|
|
43
27
|
def prng(_s: SeedSequence | None = None, /) -> np.random.Generator:
|
|
44
28
|
"""Adopt the PCG64DXSM bit-generator, the future default in numpy.default_rng().
|
|
45
29
|
|
|
@@ -40,7 +40,7 @@ __version__ = VERSION
|
|
|
40
40
|
DEFAULT_FCOUNT_WTS = np.asarray((_nr := np.arange(6, 0, -1)) / _nr.sum(), float)
|
|
41
41
|
|
|
42
42
|
|
|
43
|
-
@dataclass
|
|
43
|
+
@dataclass(slots=True, frozen=True)
|
|
44
44
|
class SeedSequenceData:
|
|
45
45
|
share: SeedSequence
|
|
46
46
|
pcm: SeedSequence
|
|
@@ -654,3 +654,20 @@ for _typ in (
|
|
|
654
654
|
),
|
|
655
655
|
),
|
|
656
656
|
)
|
|
657
|
+
|
|
658
|
+
for _typ in (MarketSampleData, SeedSequenceData, UPPTestsCounts):
|
|
659
|
+
_, _ = (
|
|
660
|
+
this_yaml.representer.add_representer(
|
|
661
|
+
_typ,
|
|
662
|
+
lambda _r, _d: _r.rpresent_mapping(
|
|
663
|
+
f"!{_d.__class__.__name__}",
|
|
664
|
+
{_a: getattr(_d, _a) for _a in _d.__dataclass_fields__},
|
|
665
|
+
),
|
|
666
|
+
),
|
|
667
|
+
this_yaml.constructor.add_constructor(
|
|
668
|
+
_typ,
|
|
669
|
+
lambda _c, _n: globals().get(
|
|
670
|
+
_n.tag.lstrip("!")(**_c.construct_mapping(_n))
|
|
671
|
+
),
|
|
672
|
+
),
|
|
673
|
+
)
|
|
@@ -34,7 +34,7 @@ from .data_generation_functions import (
|
|
|
34
34
|
gen_margin_price_data,
|
|
35
35
|
gen_share_data,
|
|
36
36
|
)
|
|
37
|
-
from .upp_tests import
|
|
37
|
+
from .upp_tests import compute_upp_test_counts
|
|
38
38
|
|
|
39
39
|
__version__ = VERSION
|
|
40
40
|
|
|
@@ -51,12 +51,6 @@ class SamplingFunctionKWArgs(TypedDict, total=False):
|
|
|
51
51
|
nthreads: int
|
|
52
52
|
"""number of parallel threads to use"""
|
|
53
53
|
|
|
54
|
-
save_data_to_file: SaveData
|
|
55
|
-
"""optionally save data to HDF5 file"""
|
|
56
|
-
|
|
57
|
-
saved_array_name_suffix: str
|
|
58
|
-
"""optionally specify a suffix for the HDF5 array names"""
|
|
59
|
-
|
|
60
54
|
|
|
61
55
|
def _seed_data_conv(_v: SeedSequenceData | None, _i: MarketSample) -> SeedSequenceData:
|
|
62
56
|
if isinstance(_v, SeedSequenceData):
|
|
@@ -104,9 +98,9 @@ class MarketSample:
|
|
|
104
98
|
and _v.firm2_pcm_constraint == FM2Constraint.MNL
|
|
105
99
|
):
|
|
106
100
|
raise ValueError(
|
|
107
|
-
f'Specification of "
|
|
108
|
-
|
|
109
|
-
f
|
|
101
|
+
f'Specification of "PCMSpec.firm2_pcm_constraint", as {FM2Constraint.MNL!r} '
|
|
102
|
+
f'requires that "ShareSpec.recapture_form" be {RECForm.INOUT!r} '
|
|
103
|
+
f"or {RECForm.OUTIN!r}, not {RECForm.FIXED!r} as presently specified"
|
|
110
104
|
)
|
|
111
105
|
|
|
112
106
|
price_spec: PriceSpec = field(
|
|
@@ -484,7 +478,7 @@ class MarketSample:
|
|
|
484
478
|
{
|
|
485
479
|
_a.name: getattr(_d, _a.name)
|
|
486
480
|
for _a in _d.__attrs_attrs__
|
|
487
|
-
if _a.
|
|
481
|
+
if _a.name not in ("data", "enf_counts")
|
|
488
482
|
},
|
|
489
483
|
)
|
|
490
484
|
return _ret
|
{mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/gen/data_generation_functions.py
RENAMED
|
@@ -46,8 +46,8 @@ def gen_share_data(
|
|
|
46
46
|
_sample_size: int,
|
|
47
47
|
_share_spec: ShareSpec,
|
|
48
48
|
_fcount_rng_seed_seq: SeedSequence | None,
|
|
49
|
-
_mktshr_rng_seed_seq: SeedSequence
|
|
50
|
-
_nthreads: int
|
|
49
|
+
_mktshr_rng_seed_seq: SeedSequence,
|
|
50
|
+
_nthreads: int,
|
|
51
51
|
/,
|
|
52
52
|
) -> ShareDataSample:
|
|
53
53
|
"""Helper function for generating share data.
|
|
@@ -69,9 +69,9 @@ def gen_share_data(
|
|
|
69
69
|
|
|
70
70
|
"""
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
_dist_type_mktshr, _firm_count_prob_wts, _dist_parms_mktshr, _recapture_form = (
|
|
73
73
|
getattr(_share_spec, _f)
|
|
74
|
-
for _f in ("
|
|
74
|
+
for _f in ("dist_type", "firm_counts_weights", "dist_parms", "recapture_form")
|
|
75
75
|
)
|
|
76
76
|
|
|
77
77
|
_ssz = _sample_size
|
|
@@ -126,8 +126,8 @@ def gen_share_data(
|
|
|
126
126
|
def gen_market_shares_uniform(
|
|
127
127
|
_s_size: int,
|
|
128
128
|
_dist_parms_mktshr: ArrayDouble,
|
|
129
|
-
_mktshr_rng_seed_seq: SeedSequence
|
|
130
|
-
_nthreads: int
|
|
129
|
+
_mktshr_rng_seed_seq: SeedSequence,
|
|
130
|
+
_nthreads: int,
|
|
131
131
|
/,
|
|
132
132
|
) -> ShareDataSample:
|
|
133
133
|
"""Generate merging-firm shares from Uniform distribution on the 3-D simplex.
|
|
@@ -159,13 +159,12 @@ def gen_market_shares_uniform(
|
|
|
159
159
|
nthreads=_nthreads,
|
|
160
160
|
)
|
|
161
161
|
_mrng.fill()
|
|
162
|
-
# Convert draws on U[0, 1] to Uniformly-distributed draws on simplex, s_1 + s_2 <= 1
|
|
163
|
-
_frmshr_array.sort(axis=1)
|
|
164
162
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
_frmshr_array.
|
|
168
|
-
|
|
163
|
+
# Convert draws on U[0, 1] to Uniformly-distributed draws on simplex, s_1 + s_2 <= 1
|
|
164
|
+
_frmshr_array = np.hstack((
|
|
165
|
+
_frmshr_array.min(axis=1, keepdims=True),
|
|
166
|
+
np.abs(np.diff(_frmshr_array, axis=1)),
|
|
167
|
+
))
|
|
169
168
|
|
|
170
169
|
# Keep only share combinations representing feasible mergers
|
|
171
170
|
# This is a no-op for 64-bit floats, but is necessary for smaller floats
|
|
@@ -199,8 +198,8 @@ def _gen_market_shares_dirichlet_multimarket(
|
|
|
199
198
|
_dist_type_dir: SHRDistribution,
|
|
200
199
|
_dist_parms_dir: ArrayDouble,
|
|
201
200
|
_firm_count_wts: ArrayDouble,
|
|
202
|
-
_fcount_rng_seed_seq: SeedSequence | None
|
|
203
|
-
_mktshr_rng_seed_seq: SeedSequence
|
|
201
|
+
_fcount_rng_seed_seq: SeedSequence | None,
|
|
202
|
+
_mktshr_rng_seed_seq: SeedSequence,
|
|
204
203
|
_nthreads: int = NTHREADS,
|
|
205
204
|
/,
|
|
206
205
|
) -> ShareDataSample:
|
|
@@ -341,8 +340,8 @@ def gen_market_shares_dirichlet(
|
|
|
341
340
|
_dir_alphas: ArrayDouble,
|
|
342
341
|
_s_size: int,
|
|
343
342
|
_recapture_form: RECForm,
|
|
344
|
-
_mktshr_rng_seed_seq: SeedSequence
|
|
345
|
-
_nthreads: int
|
|
343
|
+
_mktshr_rng_seed_seq: SeedSequence,
|
|
344
|
+
_nthreads: int,
|
|
346
345
|
/,
|
|
347
346
|
) -> ShareDataSample:
|
|
348
347
|
"""Dirichlet-distributed shares with fixed firm-count.
|
|
@@ -497,7 +496,7 @@ def gen_margin_price_data(
|
|
|
497
496
|
_hsr_filing_test_type: SSZConstant,
|
|
498
497
|
_pcm_rng_seed_seq: SeedSequence,
|
|
499
498
|
_pr_rng_seed_seq: SeedSequence | None,
|
|
500
|
-
_nthreads: int
|
|
499
|
+
_nthreads: int,
|
|
501
500
|
/,
|
|
502
501
|
) -> tuple[MarginDataSample, PriceDataSample]:
|
|
503
502
|
"""Generate margin and price data for mergers in the sample.
|
|
@@ -680,8 +679,8 @@ def _gen_margin_data(
|
|
|
680
679
|
_price_array: ArrayDouble,
|
|
681
680
|
_aggregate_purchase_prob: ArrayDouble,
|
|
682
681
|
_pcm_spec: PCMSpec,
|
|
683
|
-
_pcm_rng_seed_seq: SeedSequence
|
|
684
|
-
_nthreads: int
|
|
682
|
+
_pcm_rng_seed_seq: SeedSequence,
|
|
683
|
+
_nthreads: int,
|
|
685
684
|
/,
|
|
686
685
|
) -> MarginDataSample:
|
|
687
686
|
_dist_type_pcm, _dist_firm2_pcm, _dist_parms_pcm = (
|
|
File without changes
|
|
File without changes
|
{mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/core/empirical_margin_distribution.py
RENAMED
|
File without changes
|
{mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/core/guidelines_boundary_functions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mergeron-2025.739290.0 → mergeron-2025.739290.2}/src/mergeron/data/damodaran_margin_data.xls
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|