mergeron 2024.739099.0__py3-none-any.whl → 2024.739099.2__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 +15 -1
- mergeron/core/damodaran_margin_data.py +3 -4
- mergeron/core/ftc_merger_investigations_data.py +8 -11
- mergeron/core/guidelines_boundaries.py +3 -4
- mergeron/core/guidelines_boundary_functions.py +8 -9
- mergeron/core/guidelines_boundary_functions_extra.py +2 -3
- mergeron/core/pseudorandom_numbers.py +5 -6
- mergeron/gen/__init__.py +38 -32
- mergeron/gen/_data_generation_functions.py +22 -28
- mergeron/gen/data_generation.py +5 -6
- mergeron/gen/enforcement_stats.py +125 -15
- mergeron/gen/upp_tests.py +22 -20
- {mergeron-2024.739099.0.dist-info → mergeron-2024.739099.2.dist-info}/METADATA +1 -1
- {mergeron-2024.739099.0.dist-info → mergeron-2024.739099.2.dist-info}/RECORD +15 -15
- {mergeron-2024.739099.0.dist-info → mergeron-2024.739099.2.dist-info}/WHEEL +0 -0
mergeron/__init__.py
CHANGED
|
@@ -2,12 +2,14 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import enum
|
|
4
4
|
from pathlib import Path
|
|
5
|
+
from typing import TypeAlias, TypeVar
|
|
5
6
|
|
|
6
7
|
import numpy as np
|
|
8
|
+
from numpy.typing import NBitBase, NDArray
|
|
7
9
|
|
|
8
10
|
_PKG_NAME: str = Path(__file__).parent.stem
|
|
9
11
|
|
|
10
|
-
VERSION = "2024.739099.
|
|
12
|
+
VERSION = "2024.739099.2"
|
|
11
13
|
|
|
12
14
|
__version__ = VERSION
|
|
13
15
|
|
|
@@ -24,6 +26,18 @@ if not DATA_DIR.is_dir():
|
|
|
24
26
|
np.set_printoptions(precision=18)
|
|
25
27
|
|
|
26
28
|
|
|
29
|
+
TI = TypeVar("TI", bound=NBitBase)
|
|
30
|
+
ArrayINT = NDArray[np.integer[TI]]
|
|
31
|
+
TF = TypeVar("TF", bound=NBitBase)
|
|
32
|
+
ArrayFloat = NDArray[np.floating[TF]]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
ArrayBoolean: TypeAlias = NDArray[np.bool_]
|
|
36
|
+
|
|
37
|
+
ArrayDouble: TypeAlias = NDArray[np.float64]
|
|
38
|
+
ArrayBIGINT: TypeAlias = NDArray[np.int64]
|
|
39
|
+
|
|
40
|
+
|
|
27
41
|
@enum.unique
|
|
28
42
|
class RECConstants(enum.StrEnum):
|
|
29
43
|
"""Recapture rate - derivation methods."""
|
|
@@ -43,11 +43,10 @@ import msgpack # type:ignore
|
|
|
43
43
|
import numpy as np
|
|
44
44
|
import urllib3
|
|
45
45
|
from numpy.random import PCG64DXSM, Generator, SeedSequence
|
|
46
|
-
from numpy.typing import NDArray
|
|
47
46
|
from scipy import stats # type: ignore
|
|
48
47
|
from xlrd import open_workbook # type: ignore
|
|
49
48
|
|
|
50
|
-
from .. import _PKG_NAME, DATA_DIR, VERSION # noqa: TID252
|
|
49
|
+
from .. import _PKG_NAME, DATA_DIR, VERSION, ArrayDouble # noqa: TID252
|
|
51
50
|
|
|
52
51
|
__version__ = VERSION
|
|
53
52
|
|
|
@@ -137,7 +136,7 @@ def mgn_data_getter( # noqa: PLR0912
|
|
|
137
136
|
|
|
138
137
|
def mgn_data_builder(
|
|
139
138
|
_mgn_tbl_dict: Mapping[str, Mapping[str, float | int]] | None = None, /
|
|
140
|
-
) -> tuple[
|
|
139
|
+
) -> tuple[ArrayDouble, ArrayDouble, ArrayDouble]:
|
|
141
140
|
if _mgn_tbl_dict is None:
|
|
142
141
|
_mgn_tbl_dict = mgn_data_getter()
|
|
143
142
|
|
|
@@ -190,7 +189,7 @@ def mgn_data_resampler(
|
|
|
190
189
|
/,
|
|
191
190
|
*,
|
|
192
191
|
seed_sequence: SeedSequence | None = None,
|
|
193
|
-
) ->
|
|
192
|
+
) -> ArrayDouble:
|
|
194
193
|
"""
|
|
195
194
|
Generate draws from the empirical distribution bassed on Prof. Damodaran's margin data.
|
|
196
195
|
|
|
@@ -23,9 +23,8 @@ import re2 as re # type: ignore
|
|
|
23
23
|
import urllib3
|
|
24
24
|
from bs4 import BeautifulSoup
|
|
25
25
|
from numpy.testing import assert_array_equal
|
|
26
|
-
from numpy.typing import NDArray
|
|
27
26
|
|
|
28
|
-
from .. import _PKG_NAME, DATA_DIR, VERSION # noqa: TID252
|
|
27
|
+
from .. import _PKG_NAME, DATA_DIR, VERSION, ArrayBIGINT # noqa: TID252
|
|
29
28
|
|
|
30
29
|
__version__ = VERSION
|
|
31
30
|
|
|
@@ -93,7 +92,7 @@ CNT_FCOUNT_DICT = {
|
|
|
93
92
|
class INVTableData(NamedTuple):
|
|
94
93
|
industry_group: str
|
|
95
94
|
additional_evidence: str
|
|
96
|
-
data_array:
|
|
95
|
+
data_array: ArrayBIGINT
|
|
97
96
|
|
|
98
97
|
|
|
99
98
|
INVData: TypeAlias = Mapping[str, dict[str, dict[str, INVTableData]]]
|
|
@@ -585,12 +584,12 @@ def _identify_table_type(_tnstr: str = CONC_TABLE_ALL, /) -> tuple[str, int, str
|
|
|
585
584
|
|
|
586
585
|
def _process_table_blks_conc_type(
|
|
587
586
|
_table_blocks: Sequence[Sequence[str]], /
|
|
588
|
-
) ->
|
|
587
|
+
) -> ArrayBIGINT:
|
|
589
588
|
_conc_row_pat = re.compile(r"((?:0|\d,\d{3}) (?:- \d+,\d{3}|\+)|TOTAL)")
|
|
590
589
|
|
|
591
590
|
_col_titles_array = tuple(CONC_DELTA_DICT.values())
|
|
592
|
-
_col_totals:
|
|
593
|
-
_invdata_array:
|
|
591
|
+
_col_totals: ArrayBIGINT = np.zeros(len(_col_titles_array), np.int64)
|
|
592
|
+
_invdata_array: ArrayBIGINT = np.array(None)
|
|
594
593
|
|
|
595
594
|
for _tbl_blk in _table_blocks:
|
|
596
595
|
if _conc_row_pat.match(_blk_str := _tbl_blk[-3]):
|
|
@@ -642,13 +641,11 @@ def _process_table_blks_conc_type(
|
|
|
642
641
|
|
|
643
642
|
def _process_table_blks_cnt_type(
|
|
644
643
|
_table_blocks: Sequence[Sequence[str]], /
|
|
645
|
-
) ->
|
|
644
|
+
) -> ArrayBIGINT:
|
|
646
645
|
_cnt_row_pat = re.compile(r"(\d+ (?:to \d+|\+)|TOTAL)")
|
|
647
646
|
|
|
648
|
-
_invdata_array:
|
|
649
|
-
_col_totals:
|
|
650
|
-
3, np.int64
|
|
651
|
-
) # "enforced", "closed", "total"
|
|
647
|
+
_invdata_array: ArrayBIGINT = np.array(None)
|
|
648
|
+
_col_totals: ArrayBIGINT = np.zeros(3, np.int64) # "enforced", "closed", "total"
|
|
652
649
|
|
|
653
650
|
for _tbl_blk in _table_blocks:
|
|
654
651
|
if _cnt_row_pat.match(_blk_str := _tbl_blk[-3]):
|
|
@@ -12,9 +12,8 @@ from typing import Literal, TypeAlias
|
|
|
12
12
|
import numpy as np
|
|
13
13
|
from attrs import Attribute, field, frozen, validators
|
|
14
14
|
from mpmath import mp, mpf # type: ignore
|
|
15
|
-
from numpy.typing import NDArray
|
|
16
15
|
|
|
17
|
-
from .. import VERSION, RECConstants, UPPAggrSelector # noqa: TID252
|
|
16
|
+
from .. import VERSION, ArrayDouble, RECConstants, UPPAggrSelector # noqa: TID252
|
|
18
17
|
from . import guidelines_boundary_functions as gbfn
|
|
19
18
|
|
|
20
19
|
__version__ = VERSION
|
|
@@ -191,7 +190,7 @@ class ConcentrationBoundary:
|
|
|
191
190
|
validator=(validators.instance_of(str), _concentration_measure_name_validator),
|
|
192
191
|
)
|
|
193
192
|
|
|
194
|
-
coordinates:
|
|
193
|
+
coordinates: ArrayDouble = field(init=False, kw_only=True)
|
|
195
194
|
"""Market-share pairs as Cartesian coordinates of points on the concentration boundary."""
|
|
196
195
|
|
|
197
196
|
area: float = field(init=False, kw_only=True)
|
|
@@ -321,7 +320,7 @@ class DiversionRatioBoundary:
|
|
|
321
320
|
|
|
322
321
|
"""
|
|
323
322
|
|
|
324
|
-
coordinates:
|
|
323
|
+
coordinates: ArrayDouble = field(init=False, kw_only=True)
|
|
325
324
|
"""Market-share pairs as Cartesian coordinates of points on the diversion ratio boundary."""
|
|
326
325
|
|
|
327
326
|
area: float = field(init=False, kw_only=True)
|
|
@@ -4,9 +4,8 @@ from typing import Any, Literal, TypedDict
|
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
from mpmath import mp, mpf # type: ignore
|
|
7
|
-
from numpy.typing import NDArray
|
|
8
7
|
|
|
9
|
-
from .. import VERSION # noqa: TID252
|
|
8
|
+
from .. import VERSION, ArrayBIGINT, ArrayDouble # noqa: TID252
|
|
10
9
|
|
|
11
10
|
__version__ = VERSION
|
|
12
11
|
|
|
@@ -27,7 +26,7 @@ class ShareRatioBoundaryKeywords(TypedDict, total=False):
|
|
|
27
26
|
class GuidelinesBoundary:
|
|
28
27
|
"""Output of a Guidelines boundary function."""
|
|
29
28
|
|
|
30
|
-
coordinates:
|
|
29
|
+
coordinates: ArrayDouble
|
|
31
30
|
"""Market-share pairs as Cartesian coordinates of points on the boundary."""
|
|
32
31
|
|
|
33
32
|
area: float
|
|
@@ -668,7 +667,7 @@ def shrratio_boundary_max(
|
|
|
668
667
|
"""
|
|
669
668
|
|
|
670
669
|
# _r_val is not needed for max boundary, but is specified for consistency
|
|
671
|
-
# of function call with other
|
|
670
|
+
# of function call with other share-ratio boundary functions
|
|
672
671
|
del _r_val
|
|
673
672
|
_delta_star = mpf(f"{_delta_star}")
|
|
674
673
|
_s_intcpt = _delta_star
|
|
@@ -718,11 +717,11 @@ def _shrratio_boundary_intcpt(
|
|
|
718
717
|
|
|
719
718
|
|
|
720
719
|
def lerp(
|
|
721
|
-
_x1: int | float | mpf |
|
|
722
|
-
_x2: int | float | mpf |
|
|
720
|
+
_x1: int | float | mpf | ArrayDouble | ArrayBIGINT = 3,
|
|
721
|
+
_x2: int | float | mpf | ArrayDouble | ArrayBIGINT = 1,
|
|
723
722
|
_r: float | mpf = 0.25,
|
|
724
723
|
/,
|
|
725
|
-
) -> float | mpf |
|
|
724
|
+
) -> float | mpf | ArrayDouble:
|
|
726
725
|
"""
|
|
727
726
|
From the function of the same name in the C++ standard [2]_
|
|
728
727
|
|
|
@@ -884,9 +883,9 @@ def boundary_plot(*, mktshares_plot_flag: bool = True) -> tuple[Any, ...]:
|
|
|
884
883
|
mktshares_plot_flag: bool = False,
|
|
885
884
|
mktshares_axlbls_flag: bool = False,
|
|
886
885
|
) -> mpa.Axes:
|
|
887
|
-
# Set the width of axis
|
|
886
|
+
# Set the width of axis grid lines, and tick marks:
|
|
888
887
|
# both axes, both major and minor ticks
|
|
889
|
-
# Frame, grid, and
|
|
888
|
+
# Frame, grid, and face color
|
|
890
889
|
for _spos0 in "left", "bottom":
|
|
891
890
|
_ax1.spines[_spos0].set_linewidth(0.5)
|
|
892
891
|
_ax1.spines[_spos0].set_zorder(5)
|
|
@@ -13,11 +13,10 @@ from typing import Literal
|
|
|
13
13
|
|
|
14
14
|
import numpy as np
|
|
15
15
|
from mpmath import mp, mpf # type: ignore
|
|
16
|
-
from numpy.typing import NDArray
|
|
17
16
|
from scipy.spatial.distance import minkowski as distance_function # type: ignore
|
|
18
17
|
from sympy import lambdify, simplify, solve, symbols # type: ignore
|
|
19
18
|
|
|
20
|
-
from .. import VERSION # noqa: TID252
|
|
19
|
+
from .. import VERSION, ArrayDouble # noqa: TID252
|
|
21
20
|
from .guidelines_boundary_functions import (
|
|
22
21
|
GuidelinesBoundary,
|
|
23
22
|
_shrratio_boundary_intcpt,
|
|
@@ -33,7 +32,7 @@ mp.trap_complex = True
|
|
|
33
32
|
|
|
34
33
|
@dataclass(slots=True, frozen=True)
|
|
35
34
|
class GuidelinesBoundaryCallable:
|
|
36
|
-
boundary_function: Callable[[
|
|
35
|
+
boundary_function: Callable[[ArrayDouble], ArrayDouble]
|
|
37
36
|
area: float
|
|
38
37
|
s_naught: float = 0
|
|
39
38
|
|
|
@@ -13,9 +13,8 @@ from typing import Literal
|
|
|
13
13
|
|
|
14
14
|
import numpy as np
|
|
15
15
|
from numpy.random import PCG64DXSM, Generator, SeedSequence
|
|
16
|
-
from numpy.typing import NDArray
|
|
17
16
|
|
|
18
|
-
from .. import VERSION # noqa: TID252
|
|
17
|
+
from .. import VERSION, ArrayDouble # noqa: TID252
|
|
19
18
|
|
|
20
19
|
__version__ = VERSION
|
|
21
20
|
|
|
@@ -134,13 +133,13 @@ class MultithreadedRNG:
|
|
|
134
133
|
|
|
135
134
|
def __init__(
|
|
136
135
|
self,
|
|
137
|
-
_out_array:
|
|
136
|
+
_out_array: ArrayDouble,
|
|
138
137
|
/,
|
|
139
138
|
*,
|
|
140
139
|
dist_type: Literal[
|
|
141
140
|
"Beta", "Dirichlet", "Gaussian", "Normal", "Random", "Uniform"
|
|
142
141
|
] = "Uniform",
|
|
143
|
-
dist_parms:
|
|
142
|
+
dist_parms: ArrayDouble | None = DIST_PARMS_DEFAULT,
|
|
144
143
|
seed_sequence: SeedSequence | None = None,
|
|
145
144
|
nthreads: int = NTHREADS,
|
|
146
145
|
):
|
|
@@ -206,8 +205,8 @@ class MultithreadedRNG:
|
|
|
206
205
|
def _fill(
|
|
207
206
|
_rng: np.random.Generator,
|
|
208
207
|
_dist_type: str,
|
|
209
|
-
_dist_parms:
|
|
210
|
-
_out:
|
|
208
|
+
_dist_parms: ArrayDouble,
|
|
209
|
+
_out: ArrayDouble,
|
|
211
210
|
_first: int,
|
|
212
211
|
_last: int,
|
|
213
212
|
/,
|
mergeron/gen/__init__.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Defines constants and containers for industry data generation and testing
|
|
2
|
+
Defines constants and containers for industry data generation and testing.
|
|
3
3
|
|
|
4
4
|
"""
|
|
5
5
|
|
|
@@ -11,9 +11,15 @@ from typing import ClassVar, Protocol
|
|
|
11
11
|
|
|
12
12
|
import numpy as np
|
|
13
13
|
from attrs import Attribute, cmp_using, define, field, frozen, validators
|
|
14
|
-
from numpy.typing import NDArray
|
|
15
14
|
|
|
16
|
-
from .. import
|
|
15
|
+
from .. import ( # noqa: TID252
|
|
16
|
+
VERSION,
|
|
17
|
+
ArrayBIGINT,
|
|
18
|
+
ArrayBoolean,
|
|
19
|
+
ArrayDouble,
|
|
20
|
+
RECConstants,
|
|
21
|
+
UPPAggrSelector,
|
|
22
|
+
)
|
|
17
23
|
from ..core.pseudorandom_numbers import DIST_PARMS_DEFAULT # noqa: TID252
|
|
18
24
|
|
|
19
25
|
__version__ = VERSION
|
|
@@ -128,7 +134,7 @@ class ShareSpec:
|
|
|
128
134
|
dist_type: SHRConstants
|
|
129
135
|
"""See :class:`SHRConstants`"""
|
|
130
136
|
|
|
131
|
-
dist_parms:
|
|
137
|
+
dist_parms: ArrayDouble | None = field(
|
|
132
138
|
default=None, eq=cmp_using(eq=np.array_equal)
|
|
133
139
|
)
|
|
134
140
|
"""Parameters for tailoring market-share distribution
|
|
@@ -139,9 +145,9 @@ class ShareSpec:
|
|
|
139
145
|
type of Dirichlet-distribution specified.
|
|
140
146
|
|
|
141
147
|
"""
|
|
142
|
-
firm_counts_weights:
|
|
143
|
-
|
|
144
|
-
)
|
|
148
|
+
firm_counts_weights: (
|
|
149
|
+
ArrayDouble | ArrayBIGINT | ArrayDouble | ArrayBIGINT | None
|
|
150
|
+
) = field(default=None, eq=cmp_using(eq=np.array_equal))
|
|
145
151
|
"""Relative or absolute frequencies of firm counts
|
|
146
152
|
|
|
147
153
|
|
|
@@ -193,7 +199,7 @@ class PCMSpec:
|
|
|
193
199
|
dist_type: PCMConstants
|
|
194
200
|
"""See :class:`PCMConstants`"""
|
|
195
201
|
|
|
196
|
-
dist_parms:
|
|
202
|
+
dist_parms: ArrayDouble | None
|
|
197
203
|
"""Parameter specification for tailoring PCM distribution
|
|
198
204
|
|
|
199
205
|
For Uniform distribution, bounds of the distribution; defaults to `(0, 1)`;
|
|
@@ -356,39 +362,39 @@ class MarketSpec:
|
|
|
356
362
|
class MarketDataSample:
|
|
357
363
|
"""Container for generated markets data sample."""
|
|
358
364
|
|
|
359
|
-
frmshr_array:
|
|
365
|
+
frmshr_array: ArrayDouble
|
|
360
366
|
"""Merging-firm shares (with two merging firms)"""
|
|
361
367
|
|
|
362
|
-
pcm_array:
|
|
368
|
+
pcm_array: ArrayDouble
|
|
363
369
|
"""Merging-firms' prices (normalized to 1, in default specification)"""
|
|
364
370
|
|
|
365
|
-
price_array:
|
|
371
|
+
price_array: ArrayDouble
|
|
366
372
|
"""Merging-firms' price-cost margins (PCM)"""
|
|
367
373
|
|
|
368
|
-
fcounts:
|
|
374
|
+
fcounts: ArrayBIGINT
|
|
369
375
|
"""Number of firms in market"""
|
|
370
376
|
|
|
371
|
-
aggregate_purchase_prob:
|
|
377
|
+
aggregate_purchase_prob: ArrayDouble
|
|
372
378
|
"""
|
|
373
379
|
One (1) minus probability that the outside good is chosen
|
|
374
380
|
|
|
375
381
|
Converts market shares to choice probabilities by multiplication.
|
|
376
382
|
"""
|
|
377
383
|
|
|
378
|
-
nth_firm_share:
|
|
384
|
+
nth_firm_share: ArrayDouble
|
|
379
385
|
"""Market-share of n-th firm
|
|
380
386
|
|
|
381
387
|
Relevant for testing for draws the do or
|
|
382
388
|
do not meet HSR filing thresholds.
|
|
383
389
|
"""
|
|
384
390
|
|
|
385
|
-
divr_array:
|
|
391
|
+
divr_array: ArrayDouble
|
|
386
392
|
"""Diversion ratio between the merging firms"""
|
|
387
393
|
|
|
388
|
-
hhi_post:
|
|
394
|
+
hhi_post: ArrayDouble
|
|
389
395
|
"""Post-merger change in Herfindahl-Hirschmann Index (HHI)"""
|
|
390
396
|
|
|
391
|
-
hhi_delta:
|
|
397
|
+
hhi_delta: ArrayDouble
|
|
392
398
|
"""Change in HHI from combination of merging firms"""
|
|
393
399
|
|
|
394
400
|
|
|
@@ -400,16 +406,16 @@ class ShareDataSample:
|
|
|
400
406
|
and aggregate purchase probability.
|
|
401
407
|
"""
|
|
402
408
|
|
|
403
|
-
mktshr_array:
|
|
409
|
+
mktshr_array: ArrayDouble
|
|
404
410
|
"""All-firm shares (with two merging firms)"""
|
|
405
411
|
|
|
406
|
-
fcounts:
|
|
412
|
+
fcounts: ArrayBIGINT
|
|
407
413
|
"""All-firm-count for each draw"""
|
|
408
414
|
|
|
409
|
-
nth_firm_share:
|
|
415
|
+
nth_firm_share: ArrayDouble
|
|
410
416
|
"""Market-share of n-th firm"""
|
|
411
417
|
|
|
412
|
-
aggregate_purchase_prob:
|
|
418
|
+
aggregate_purchase_prob: ArrayDouble
|
|
413
419
|
"""Converts market shares to choice probabilities by multiplication."""
|
|
414
420
|
|
|
415
421
|
|
|
@@ -417,10 +423,10 @@ class ShareDataSample:
|
|
|
417
423
|
class PriceDataSample:
|
|
418
424
|
"""Container for generated price array, and related."""
|
|
419
425
|
|
|
420
|
-
price_array:
|
|
426
|
+
price_array: ArrayDouble
|
|
421
427
|
"""Merging-firms' prices"""
|
|
422
428
|
|
|
423
|
-
hsr_filing_test:
|
|
429
|
+
hsr_filing_test: ArrayBoolean
|
|
424
430
|
"""Flags draws as meeting HSR filing thresholds or not"""
|
|
425
431
|
|
|
426
432
|
|
|
@@ -428,10 +434,10 @@ class PriceDataSample:
|
|
|
428
434
|
class MarginDataSample:
|
|
429
435
|
"""Container for generated margin array and related MNL test array."""
|
|
430
436
|
|
|
431
|
-
pcm_array:
|
|
437
|
+
pcm_array: ArrayDouble
|
|
432
438
|
"""Merging-firms' PCMs"""
|
|
433
439
|
|
|
434
|
-
mnl_test_array:
|
|
440
|
+
mnl_test_array: ArrayBoolean
|
|
435
441
|
"""Flags infeasible observations as False and rest as True
|
|
436
442
|
|
|
437
443
|
Applying restrictions from Bertrand-Nash oligopoly
|
|
@@ -476,18 +482,18 @@ class UPPTestsRaw:
|
|
|
476
482
|
:func:`enforcement_stats.gen_upp_arrays`.
|
|
477
483
|
"""
|
|
478
484
|
|
|
479
|
-
guppi_test_simple:
|
|
485
|
+
guppi_test_simple: ArrayBoolean
|
|
480
486
|
"""True if GUPPI estimate meets criterion"""
|
|
481
487
|
|
|
482
|
-
guppi_test_compound:
|
|
488
|
+
guppi_test_compound: ArrayBoolean
|
|
483
489
|
"""True if both GUPPI estimate and diversion ratio estimate
|
|
484
490
|
meet criterion
|
|
485
491
|
"""
|
|
486
492
|
|
|
487
|
-
cmcr_test:
|
|
493
|
+
cmcr_test: ArrayBoolean
|
|
488
494
|
"""True if CMCR estimate meets criterion"""
|
|
489
495
|
|
|
490
|
-
ipr_test:
|
|
496
|
+
ipr_test: ArrayBoolean
|
|
491
497
|
"""True if IPR (partial price-simulation) estimate meets criterion"""
|
|
492
498
|
|
|
493
499
|
|
|
@@ -498,9 +504,9 @@ class UPPTestsCounts:
|
|
|
498
504
|
Resolution may be either :attr:`INVResolution.ENFT` or :attr:`INVResolution.CLRN`.
|
|
499
505
|
"""
|
|
500
506
|
|
|
501
|
-
by_firm_count:
|
|
502
|
-
by_delta:
|
|
503
|
-
by_conczone:
|
|
507
|
+
by_firm_count: ArrayBIGINT
|
|
508
|
+
by_delta: ArrayBIGINT
|
|
509
|
+
by_conczone: ArrayBIGINT
|
|
504
510
|
"""Zones are "unoncentrated", "moderately concentrated", and "highly concentrated"
|
|
505
511
|
"""
|
|
506
512
|
|
|
@@ -9,9 +9,8 @@ from typing import Literal
|
|
|
9
9
|
import numpy as np
|
|
10
10
|
from attrs import evolve
|
|
11
11
|
from numpy.random import SeedSequence
|
|
12
|
-
from numpy.typing import NDArray
|
|
13
12
|
|
|
14
|
-
from .. import VERSION, RECConstants # noqa: TID252
|
|
13
|
+
from .. import VERSION, ArrayBIGINT, ArrayDouble, RECConstants # noqa: TID252
|
|
15
14
|
from ..core.damodaran_margin_data import mgn_data_resampler # noqa: TID252
|
|
16
15
|
from ..core.pseudorandom_numbers import ( # noqa: TID252
|
|
17
16
|
DIST_PARMS_DEFAULT,
|
|
@@ -112,7 +111,7 @@ def _gen_share_data(
|
|
|
112
111
|
|
|
113
112
|
def _gen_market_shares_uniform(
|
|
114
113
|
_s_size: int = 10**6,
|
|
115
|
-
_dist_parms_mktshr:
|
|
114
|
+
_dist_parms_mktshr: ArrayDouble | None = DIST_PARMS_DEFAULT,
|
|
116
115
|
_mktshr_rng_seed_seq: SeedSequence | None = None,
|
|
117
116
|
_nthreads: int = 16,
|
|
118
117
|
/,
|
|
@@ -137,7 +136,7 @@ def _gen_market_shares_uniform(
|
|
|
137
136
|
"""
|
|
138
137
|
|
|
139
138
|
_frmshr_array = np.empty((_s_size, 2), dtype=np.float64)
|
|
140
|
-
_dist_parms_mktshr:
|
|
139
|
+
_dist_parms_mktshr: ArrayDouble = (
|
|
141
140
|
DIST_PARMS_DEFAULT if _dist_parms_mktshr is None else _dist_parms_mktshr
|
|
142
141
|
)
|
|
143
142
|
_mrng = MultithreadedRNG(
|
|
@@ -149,7 +148,7 @@ def _gen_market_shares_uniform(
|
|
|
149
148
|
)
|
|
150
149
|
_mrng.fill()
|
|
151
150
|
# Convert draws on U[0, 1] to Uniformly-distributed draws on simplex, s_1 + s_2 <= 1
|
|
152
|
-
_frmshr_array
|
|
151
|
+
_frmshr_array.sort(axis=1)
|
|
153
152
|
_frmshr_array = np.column_stack((
|
|
154
153
|
_frmshr_array[:, 0],
|
|
155
154
|
_frmshr_array[:, 1] - _frmshr_array[:, 0],
|
|
@@ -163,7 +162,7 @@ def _gen_market_shares_uniform(
|
|
|
163
162
|
_frmshr_array, ((0, 0), (0, 1)), "constant", constant_values=np.nan
|
|
164
163
|
)
|
|
165
164
|
|
|
166
|
-
_fcounts:
|
|
165
|
+
_fcounts: ArrayBIGINT = np.ones((_s_size, 1), np.int64) * np.nan # type: ignore
|
|
167
166
|
_nth_firm_share, _aggregate_purchase_prob = (
|
|
168
167
|
np.nan * np.ones((_s_size, 1), np.float64) for _ in range(2)
|
|
169
168
|
)
|
|
@@ -177,8 +176,8 @@ def _gen_market_shares_dirichlet_multisample(
|
|
|
177
176
|
_s_size: int = 10**6,
|
|
178
177
|
_recapture_form: RECConstants = RECConstants.INOUT,
|
|
179
178
|
_dist_type_dir: SHRConstants = SHRConstants.DIR_FLAT,
|
|
180
|
-
_dist_parms_dir:
|
|
181
|
-
_firm_count_wts:
|
|
179
|
+
_dist_parms_dir: ArrayDouble | None = None,
|
|
180
|
+
_firm_count_wts: ArrayDouble | None = None,
|
|
182
181
|
_fcount_rng_seed_seq: SeedSequence | None = None,
|
|
183
182
|
_mktshr_rng_seed_seq: SeedSequence | None = None,
|
|
184
183
|
_nthreads: int = 16,
|
|
@@ -216,7 +215,7 @@ def _gen_market_shares_dirichlet_multisample(
|
|
|
216
215
|
|
|
217
216
|
"""
|
|
218
217
|
|
|
219
|
-
_firm_count_wts:
|
|
218
|
+
_firm_count_wts: ArrayDouble = (
|
|
220
219
|
FCOUNT_WTS_DEFAULT if _firm_count_wts is None else _firm_count_wts
|
|
221
220
|
)
|
|
222
221
|
|
|
@@ -243,7 +242,7 @@ def _gen_market_shares_dirichlet_multisample(
|
|
|
243
242
|
|
|
244
243
|
if _dist_type_dir == SHRConstants.DIR_COND:
|
|
245
244
|
|
|
246
|
-
def _gen_dir_alphas(_fcv: int) ->
|
|
245
|
+
def _gen_dir_alphas(_fcv: int) -> ArrayDouble:
|
|
247
246
|
_dat = [2.5] * 2
|
|
248
247
|
if _fcv > len(_dat):
|
|
249
248
|
_dat += [1.0 / (_fcv - 2)] * (_fcv - 2)
|
|
@@ -251,7 +250,7 @@ def _gen_market_shares_dirichlet_multisample(
|
|
|
251
250
|
|
|
252
251
|
else:
|
|
253
252
|
|
|
254
|
-
def _gen_dir_alphas(_fcv: int) ->
|
|
253
|
+
def _gen_dir_alphas(_fcv: int) -> ArrayDouble:
|
|
255
254
|
return np.array(_dir_alphas_full[:_fcv], dtype=np.float64) # type: ignore
|
|
256
255
|
|
|
257
256
|
_fcounts = prng(_fcount_rng_seed_seq).choice(
|
|
@@ -312,7 +311,7 @@ def _gen_market_shares_dirichlet_multisample(
|
|
|
312
311
|
|
|
313
312
|
|
|
314
313
|
def _gen_market_shares_dirichlet(
|
|
315
|
-
_dir_alphas:
|
|
314
|
+
_dir_alphas: ArrayDouble,
|
|
316
315
|
_s_size: int = 10**6,
|
|
317
316
|
_recapture_form: RECConstants = RECConstants.INOUT,
|
|
318
317
|
_mktshr_rng_seed_seq: SeedSequence | None = None,
|
|
@@ -394,9 +393,9 @@ def _gen_market_shares_dirichlet(
|
|
|
394
393
|
|
|
395
394
|
|
|
396
395
|
def _gen_margin_price_data(
|
|
397
|
-
_frmshr_array:
|
|
398
|
-
_nth_firm_share:
|
|
399
|
-
_aggregate_purchase_prob:
|
|
396
|
+
_frmshr_array: ArrayDouble,
|
|
397
|
+
_nth_firm_share: ArrayDouble,
|
|
398
|
+
_aggregate_purchase_prob: ArrayDouble,
|
|
400
399
|
_pcm_spec: PCMSpec,
|
|
401
400
|
_price_spec: PriceConstants,
|
|
402
401
|
_hsr_filing_test_type: SSZConstants,
|
|
@@ -472,11 +471,6 @@ def _gen_margin_price_data(
|
|
|
472
471
|
1 + _m1_nr,
|
|
473
472
|
)
|
|
474
473
|
_mnl_test_array = (_pcm_array[:, [1]] >= 0) & (_pcm_array[:, [1]] <= 1)
|
|
475
|
-
else:
|
|
476
|
-
# Generate i.i.d. PCMs
|
|
477
|
-
# Construct price_array = 1/ (1 - pcm_array)
|
|
478
|
-
# Rgenerate MNL test
|
|
479
|
-
pass
|
|
480
474
|
|
|
481
475
|
_margin_data = MarginDataSample(_pcm_array[:, :2], _mnl_test_array)
|
|
482
476
|
del _price_array_here
|
|
@@ -543,8 +537,8 @@ def _gen_margin_price_data(
|
|
|
543
537
|
|
|
544
538
|
# marked for deletion
|
|
545
539
|
def _gen_price_data(
|
|
546
|
-
_frmshr_array:
|
|
547
|
-
_nth_firm_share:
|
|
540
|
+
_frmshr_array: ArrayDouble,
|
|
541
|
+
_nth_firm_share: ArrayDouble,
|
|
548
542
|
_price_spec: PriceConstants,
|
|
549
543
|
_hsr_filing_test_type: SSZConstants,
|
|
550
544
|
_seed_seq: SeedSequence | None = None,
|
|
@@ -630,9 +624,9 @@ def _gen_price_data(
|
|
|
630
624
|
|
|
631
625
|
|
|
632
626
|
def _gen_margin_data(
|
|
633
|
-
_frmshr_array:
|
|
634
|
-
_price_array:
|
|
635
|
-
_aggregate_purchase_prob:
|
|
627
|
+
_frmshr_array: ArrayDouble,
|
|
628
|
+
_price_array: ArrayDouble,
|
|
629
|
+
_aggregate_purchase_prob: ArrayDouble,
|
|
636
630
|
_pcm_spec: PCMSpec,
|
|
637
631
|
_pcm_rng_seed_seq: SeedSequence,
|
|
638
632
|
_nthreads: int = 16,
|
|
@@ -719,8 +713,8 @@ def _gen_margin_data(
|
|
|
719
713
|
|
|
720
714
|
|
|
721
715
|
def _beta_located(
|
|
722
|
-
_mu: float |
|
|
723
|
-
) ->
|
|
716
|
+
_mu: float | ArrayDouble, _sigma: float | ArrayDouble, /
|
|
717
|
+
) -> ArrayDouble:
|
|
724
718
|
"""
|
|
725
719
|
Given mean and stddev, return shape parameters for corresponding Beta distribution
|
|
726
720
|
|
|
@@ -743,7 +737,7 @@ def _beta_located(
|
|
|
743
737
|
return np.array([_mu * _mul, (1 - _mu) * _mul], dtype=np.float64)
|
|
744
738
|
|
|
745
739
|
|
|
746
|
-
def beta_located_bound(_dist_parms:
|
|
740
|
+
def beta_located_bound(_dist_parms: ArrayDouble, /) -> ArrayDouble:
|
|
747
741
|
R"""
|
|
748
742
|
Return shape parameters for a non-standard beta, given the mean, stddev, range
|
|
749
743
|
|
mergeron/gen/data_generation.py
CHANGED
|
@@ -10,9 +10,8 @@ from typing import NamedTuple
|
|
|
10
10
|
|
|
11
11
|
import numpy as np
|
|
12
12
|
from numpy.random import SeedSequence
|
|
13
|
-
from numpy.typing import NDArray
|
|
14
13
|
|
|
15
|
-
from .. import VERSION, RECConstants # noqa: TID252
|
|
14
|
+
from .. import VERSION, ArrayDouble, RECConstants # noqa: TID252
|
|
16
15
|
from . import (
|
|
17
16
|
EMPTY_ARRAY_DEFAULT,
|
|
18
17
|
FM2Constants,
|
|
@@ -227,10 +226,10 @@ def parse_seed_seq_list(
|
|
|
227
226
|
def gen_divr_array(
|
|
228
227
|
_recapture_form: RECConstants,
|
|
229
228
|
_recapture_rate: float | None,
|
|
230
|
-
_frmshr_array:
|
|
231
|
-
_aggregate_purchase_prob:
|
|
229
|
+
_frmshr_array: ArrayDouble,
|
|
230
|
+
_aggregate_purchase_prob: ArrayDouble = EMPTY_ARRAY_DEFAULT,
|
|
232
231
|
/,
|
|
233
|
-
) ->
|
|
232
|
+
) -> ArrayDouble:
|
|
234
233
|
"""
|
|
235
234
|
Given merging-firm shares and related parameters, return diverion ratios.
|
|
236
235
|
|
|
@@ -259,7 +258,7 @@ def gen_divr_array(
|
|
|
259
258
|
|
|
260
259
|
"""
|
|
261
260
|
|
|
262
|
-
_divr_array:
|
|
261
|
+
_divr_array: ArrayDouble
|
|
263
262
|
if _recapture_form == RECConstants.FIXED:
|
|
264
263
|
_divr_array = _recapture_rate * _frmshr_array[:, ::-1] / (1 - _frmshr_array) # type: ignore
|
|
265
264
|
|
|
@@ -15,12 +15,19 @@ from typing import Literal
|
|
|
15
15
|
import numpy as np
|
|
16
16
|
import re2 as re # type: ignore
|
|
17
17
|
from jinja2 import Environment, FileSystemLoader, Template, select_autoescape
|
|
18
|
-
from numpy.typing import NDArray
|
|
19
18
|
from scipy.interpolate import interp1d # type: ignore
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
from scipy.stats import beta, norm # type: ignore
|
|
20
|
+
|
|
21
|
+
from .. import ( # noqa: TID252
|
|
22
|
+
_PKG_NAME,
|
|
23
|
+
DATA_DIR,
|
|
24
|
+
TI,
|
|
25
|
+
VERSION,
|
|
26
|
+
ArrayBIGINT,
|
|
27
|
+
ArrayDouble,
|
|
28
|
+
ArrayINT,
|
|
29
|
+
)
|
|
22
30
|
from ..core import ftc_merger_investigations_data as fid # noqa: TID252
|
|
23
|
-
from ..core.proportions_tests import propn_ci # noqa: TID252
|
|
24
31
|
from . import INVResolution
|
|
25
32
|
|
|
26
33
|
__version__ = VERSION
|
|
@@ -114,7 +121,7 @@ if not (_out_path := DATA_DIR.joinpath(f"{_PKG_NAME}.cls")).is_file():
|
|
|
114
121
|
|
|
115
122
|
|
|
116
123
|
if not (_DOTTEX := DATA_DIR / Rf"{_PKG_NAME}_TikZTableSettings.tex").is_file():
|
|
117
|
-
# Write to
|
|
124
|
+
# Write to LaTeX table settings file
|
|
118
125
|
with resources.as_file(
|
|
119
126
|
resources.files(f"{_PKG_NAME}.data.jinja2_LaTeX_templates").joinpath(
|
|
120
127
|
"setup_tikz_tables.tex"
|
|
@@ -293,7 +300,7 @@ def enf_stats_listing_by_group(
|
|
|
293
300
|
_stats_group: StatsGrpSelector,
|
|
294
301
|
_enf_spec: INVResolution,
|
|
295
302
|
/,
|
|
296
|
-
) ->
|
|
303
|
+
) -> ArrayBIGINT:
|
|
297
304
|
if _stats_group == StatsGrpSelector.HD:
|
|
298
305
|
raise ValueError(
|
|
299
306
|
f"Clearance/enforcement statistics, '{_stats_group}' not valied here."
|
|
@@ -328,7 +335,7 @@ def enf_cnts_listing_byfirmcount(
|
|
|
328
335
|
_table_evid_cond: EVIDENConstants = EVIDENConstants.UR,
|
|
329
336
|
_enf_spec: INVResolution = INVResolution.CLRN,
|
|
330
337
|
/,
|
|
331
|
-
) ->
|
|
338
|
+
) -> ArrayBIGINT:
|
|
332
339
|
if _data_period not in _data_array_dict:
|
|
333
340
|
raise ValueError(
|
|
334
341
|
f"Invalid value of data period, {f'"{_data_period}"'}."
|
|
@@ -364,7 +371,7 @@ def enf_cnts_listing_byhhianddelta(
|
|
|
364
371
|
_table_evid_cond: EVIDENConstants = EVIDENConstants.UR,
|
|
365
372
|
_enf_spec: INVResolution = INVResolution.CLRN,
|
|
366
373
|
/,
|
|
367
|
-
) ->
|
|
374
|
+
) -> ArrayBIGINT:
|
|
368
375
|
if _data_period not in _data_array_dict:
|
|
369
376
|
raise ValueError(
|
|
370
377
|
f"Invalid value of data period, {f'"{_data_period}"'}."
|
|
@@ -419,7 +426,7 @@ def table_no_lku(
|
|
|
419
426
|
return _tno
|
|
420
427
|
|
|
421
428
|
|
|
422
|
-
def enf_cnts_byfirmcount(_cnts_array:
|
|
429
|
+
def enf_cnts_byfirmcount(_cnts_array: ArrayBIGINT, /) -> ArrayBIGINT:
|
|
423
430
|
_ndim_in = 1
|
|
424
431
|
return np.vstack([
|
|
425
432
|
np.concatenate([
|
|
@@ -430,7 +437,7 @@ def enf_cnts_byfirmcount(_cnts_array: NDArray[np.int64], /) -> NDArray[np.int64]
|
|
|
430
437
|
])
|
|
431
438
|
|
|
432
439
|
|
|
433
|
-
def enf_cnts_bydelta(_cnts_array:
|
|
440
|
+
def enf_cnts_bydelta(_cnts_array: ArrayBIGINT, /) -> ArrayBIGINT:
|
|
434
441
|
_ndim_in = 2
|
|
435
442
|
return np.vstack([
|
|
436
443
|
np.concatenate([
|
|
@@ -441,7 +448,7 @@ def enf_cnts_bydelta(_cnts_array: NDArray[np.int64], /) -> NDArray[np.int64]:
|
|
|
441
448
|
])
|
|
442
449
|
|
|
443
450
|
|
|
444
|
-
def enf_cnts_byconczone(_cnts_array:
|
|
451
|
+
def enf_cnts_byconczone(_cnts_array: ArrayBIGINT, /) -> ArrayBIGINT:
|
|
445
452
|
# Prepare to tag clearance stats by presumption zone
|
|
446
453
|
_hhi_zone_post_ranged = hhi_zone_post_ranger(_cnts_array[:, 0] / 1e4)
|
|
447
454
|
_hhi_delta_ranged = hhi_delta_ranger(_cnts_array[:, 1] / 1e4)
|
|
@@ -513,7 +520,7 @@ def enf_cnts_byconczone(_cnts_array: NDArray[np.int64], /) -> NDArray[np.int64]:
|
|
|
513
520
|
|
|
514
521
|
|
|
515
522
|
def enf_stats_table_onedim(
|
|
516
|
-
_inparr:
|
|
523
|
+
_inparr: ArrayDouble | ArrayBIGINT | ArrayDouble | ArrayBIGINT,
|
|
517
524
|
_totals_row: int | None = None,
|
|
518
525
|
/,
|
|
519
526
|
*,
|
|
@@ -568,7 +575,7 @@ def enf_stats_table_onedim(
|
|
|
568
575
|
|
|
569
576
|
|
|
570
577
|
def enf_stats_table_byzone(
|
|
571
|
-
_inparr:
|
|
578
|
+
_inparr: ArrayDouble | ArrayBIGINT | ArrayDouble | ArrayBIGINT,
|
|
572
579
|
_totals_row: int | None = None,
|
|
573
580
|
/,
|
|
574
581
|
*,
|
|
@@ -650,8 +657,8 @@ def enf_stats_table_byzone(
|
|
|
650
657
|
|
|
651
658
|
|
|
652
659
|
def _stats_formatted_row(
|
|
653
|
-
_stats_row_cnt:
|
|
654
|
-
_stats_row_tot:
|
|
660
|
+
_stats_row_cnt: ArrayBIGINT,
|
|
661
|
+
_stats_row_tot: ArrayBIGINT,
|
|
655
662
|
_return_type_sel: StatsReturnSelector,
|
|
656
663
|
/,
|
|
657
664
|
) -> list[list[str]]:
|
|
@@ -715,6 +722,109 @@ def stats_print_rows(
|
|
|
715
722
|
print()
|
|
716
723
|
|
|
717
724
|
|
|
725
|
+
def propn_ci(
|
|
726
|
+
_npos: ArrayINT[TI] | int = 4,
|
|
727
|
+
_nobs: ArrayINT[TI] | int = 10,
|
|
728
|
+
/,
|
|
729
|
+
*,
|
|
730
|
+
alpha: float = 0.05,
|
|
731
|
+
method: Literal[
|
|
732
|
+
"Agresti-Coull", "Clopper-Pearson", "Exact", "Wilson", "Score"
|
|
733
|
+
] = "Wilson",
|
|
734
|
+
) -> tuple[
|
|
735
|
+
ArrayDouble | float, ArrayDouble | float, ArrayDouble | float, ArrayDouble | float
|
|
736
|
+
]:
|
|
737
|
+
"""Returns point estimates and confidence interval for a proportion
|
|
738
|
+
|
|
739
|
+
Methods "Clopper-Pearson" and "Exact" are synoymous [3]_. Similarly,
|
|
740
|
+
"Wilson" and "Score" are synonyms here.
|
|
741
|
+
|
|
742
|
+
Parameters
|
|
743
|
+
----------
|
|
744
|
+
_npos
|
|
745
|
+
Number of positives
|
|
746
|
+
|
|
747
|
+
_nobs
|
|
748
|
+
Number of observed values
|
|
749
|
+
|
|
750
|
+
alpha
|
|
751
|
+
Significance level
|
|
752
|
+
|
|
753
|
+
method
|
|
754
|
+
Method to use for estimating confidence interval
|
|
755
|
+
|
|
756
|
+
Returns
|
|
757
|
+
-------
|
|
758
|
+
Raw and estimated proportions, and bounds of the confidence interval
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
References
|
|
762
|
+
----------
|
|
763
|
+
|
|
764
|
+
.. [3] Alan Agresti & Brent A. Coull (1998) Approximate is Better
|
|
765
|
+
than “Exact” for Interval Estimation of Binomial Proportions,
|
|
766
|
+
The American Statistician, 52:2, 119-126,
|
|
767
|
+
https://doi.org/10.1080/00031305.1998.10480550
|
|
768
|
+
|
|
769
|
+
"""
|
|
770
|
+
|
|
771
|
+
for _f in _npos, _nobs:
|
|
772
|
+
if not isinstance(_f, int | np.integer):
|
|
773
|
+
raise ValueError(
|
|
774
|
+
f"Count, {_f!r} must have type that is a subtype of np.integer."
|
|
775
|
+
)
|
|
776
|
+
|
|
777
|
+
if not _nobs:
|
|
778
|
+
return (np.nan, np.nan, np.nan, np.nan)
|
|
779
|
+
|
|
780
|
+
_raw_phat: ArrayDouble | float = _npos / _nobs
|
|
781
|
+
_est_phat: ArrayDouble | float
|
|
782
|
+
_est_ci_l: ArrayDouble | float
|
|
783
|
+
_est_ci_u: ArrayDouble | float
|
|
784
|
+
|
|
785
|
+
match method:
|
|
786
|
+
case "Clopper-Pearson" | "Exact":
|
|
787
|
+
_est_ci_l, _est_ci_u = (
|
|
788
|
+
beta.ppf(*_f)
|
|
789
|
+
for _f in (
|
|
790
|
+
(alpha / 2, _npos, _nobs - _npos + 1),
|
|
791
|
+
(1 - alpha / 2, _npos + 1, _nobs - _npos),
|
|
792
|
+
)
|
|
793
|
+
)
|
|
794
|
+
_est_phat = 1 / 2 * (_est_ci_l + _est_ci_u)
|
|
795
|
+
|
|
796
|
+
case "Agresti-Coull":
|
|
797
|
+
_zsc = norm.ppf(1 - alpha / 2)
|
|
798
|
+
_zscsq = _zsc * _zsc
|
|
799
|
+
_adjmt = 4 if alpha == 0.05 else _zscsq
|
|
800
|
+
_est_phat = (_npos + _adjmt / 2) / (_nobs + _adjmt)
|
|
801
|
+
_est_ci_l, _est_ci_u = (
|
|
802
|
+
_est_phat + _g
|
|
803
|
+
for _g in [
|
|
804
|
+
_f * _zsc * np.sqrt(_est_phat * (1 - _est_phat) / (_nobs + _adjmt))
|
|
805
|
+
for _f in (-1, 1)
|
|
806
|
+
]
|
|
807
|
+
)
|
|
808
|
+
|
|
809
|
+
case "Wilson" | "Score":
|
|
810
|
+
_zsc = norm.ppf(1 - alpha / 2)
|
|
811
|
+
_zscsq = _zsc * _zsc
|
|
812
|
+
_est_phat = (_npos + _zscsq / 2) / (_nobs + _zscsq)
|
|
813
|
+
_est_ci_l, _est_ci_u = (
|
|
814
|
+
_est_phat
|
|
815
|
+
+ _f
|
|
816
|
+
* _zsc
|
|
817
|
+
* np.sqrt(_nobs * _raw_phat * (1 - _raw_phat) + _zscsq / 4)
|
|
818
|
+
/ (_nobs + _zscsq)
|
|
819
|
+
for _f in (-1, 1)
|
|
820
|
+
)
|
|
821
|
+
|
|
822
|
+
case _:
|
|
823
|
+
raise ValueError(f"Method, {f'"{method}"'} not yet implemented.")
|
|
824
|
+
|
|
825
|
+
return _raw_phat, _est_phat, _est_ci_l, _est_ci_u
|
|
826
|
+
|
|
827
|
+
|
|
718
828
|
def render_table_pdf(
|
|
719
829
|
_table_dottex_pathlist: Sequence[str], _table_coll_path: str, /
|
|
720
830
|
) -> None:
|
mergeron/gen/upp_tests.py
CHANGED
|
@@ -13,9 +13,19 @@ import numpy as np
|
|
|
13
13
|
import tables as ptb # type: ignore
|
|
14
14
|
from joblib import Parallel, cpu_count, delayed # type: ignore
|
|
15
15
|
from numpy.random import SeedSequence
|
|
16
|
-
from numpy.typing import NDArray
|
|
17
16
|
|
|
18
|
-
from .. import
|
|
17
|
+
from .. import ( # noqa: TID252
|
|
18
|
+
TF,
|
|
19
|
+
TI,
|
|
20
|
+
VERSION,
|
|
21
|
+
ArrayBIGINT,
|
|
22
|
+
ArrayBoolean,
|
|
23
|
+
ArrayDouble,
|
|
24
|
+
ArrayFloat,
|
|
25
|
+
ArrayINT,
|
|
26
|
+
RECConstants,
|
|
27
|
+
UPPAggrSelector,
|
|
28
|
+
)
|
|
19
29
|
from ..core import guidelines_boundaries as gbl # noqa: TID252
|
|
20
30
|
from . import (
|
|
21
31
|
EMPTY_ARRAY_DEFAULT,
|
|
@@ -250,7 +260,7 @@ def enf_cnts(
|
|
|
250
260
|
)
|
|
251
261
|
_enf_cnts_sim_byfirmcount_array[0] = 2
|
|
252
262
|
|
|
253
|
-
# Clearance/
|
|
263
|
+
# Clearance/enforcement counts --- by delta
|
|
254
264
|
_hhi_delta_ranged = esl.hhi_delta_ranger(_hhi_delta)
|
|
255
265
|
_enf_cnts_sim_bydelta_array = -1 * np.ones(_stats_rowlen, np.int64)
|
|
256
266
|
for _hhi_delta_lim in esl.HHI_DELTA_KNOTS[:-1]:
|
|
@@ -272,7 +282,7 @@ def enf_cnts(
|
|
|
272
282
|
|
|
273
283
|
_enf_cnts_sim_bydelta_array = _enf_cnts_sim_bydelta_array[1:]
|
|
274
284
|
|
|
275
|
-
# Clearance/
|
|
285
|
+
# Clearance/enforcement counts --- by zone
|
|
276
286
|
try:
|
|
277
287
|
_hhi_zone_post_ranged = esl.hhi_zone_post_ranger(_hhi_post)
|
|
278
288
|
except ValueError as _err:
|
|
@@ -357,23 +367,11 @@ def gen_upp_test_arrays(
|
|
|
357
367
|
out=_guppi_array,
|
|
358
368
|
)
|
|
359
369
|
|
|
360
|
-
_cmcr_array = np.empty_like(_market_data.divr_array)
|
|
361
|
-
np.divide(
|
|
362
|
-
np.einsum("ij,ij->ij", _market_data.pcm_array, _market_data.divr_array),
|
|
363
|
-
np.einsum("ij,ij->ij", 1 - _market_data.pcm_array, 1 - _market_data.divr_array),
|
|
364
|
-
out=_cmcr_array,
|
|
365
|
-
)
|
|
366
|
-
|
|
367
370
|
_ipr_array = np.empty_like(_market_data.divr_array)
|
|
368
|
-
np.divide(
|
|
369
|
-
np.einsum("ij,ij->ij", _market_data.pcm_array, _market_data.divr_array),
|
|
370
|
-
1 - _market_data.divr_array,
|
|
371
|
-
out=_ipr_array,
|
|
372
|
-
)
|
|
371
|
+
np.divide(_guppi_array, (1 - _market_data.divr_array[:, ::-1]), out=_ipr_array)
|
|
373
372
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
# np.divide(_guppi_array, (1 - _market_data.divr_array[:, ::-1]), out=_ipr_array_alt)
|
|
373
|
+
_cmcr_array = np.empty_like(_market_data.divr_array)
|
|
374
|
+
np.divide(_ipr_array, 1 - _market_data.pcm_array, out=_cmcr_array)
|
|
377
375
|
|
|
378
376
|
_test_measure_seq = (_market_data.divr_array, _guppi_array, _cmcr_array, _ipr_array)
|
|
379
377
|
|
|
@@ -496,7 +494,11 @@ def save_data_to_hdf5(
|
|
|
496
494
|
|
|
497
495
|
|
|
498
496
|
def save_array_to_hdf5(
|
|
499
|
-
_array_obj:
|
|
497
|
+
_array_obj: ArrayFloat[TF]
|
|
498
|
+
| ArrayINT[TI]
|
|
499
|
+
| ArrayDouble
|
|
500
|
+
| ArrayBIGINT
|
|
501
|
+
| ArrayBoolean,
|
|
500
502
|
_array_name: str,
|
|
501
503
|
_h5_group: ptb.Group,
|
|
502
504
|
_h5_file: ptb.File,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mergeron
|
|
3
|
-
Version: 2024.739099.
|
|
3
|
+
Version: 2024.739099.2
|
|
4
4
|
Summary: Merger Policy Analysis using Python
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: merger policy analysis,merger guidelines,merger screening,policy presumptions,concentration standards,upward pricing pressure,GUPPI
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
mergeron/License.txt,sha256=7iX-y0EyjkbVJKJLS4ZKzuuE1wd0lryfsD_IytLG8lQ,1246
|
|
2
|
-
mergeron/__init__.py,sha256=
|
|
2
|
+
mergeron/__init__.py,sha256=A0iVjdlUd_UZWbclyBnPrbCH-JYk_JaMxVv8Dp5y-yU,1541
|
|
3
3
|
mergeron/core/__init__.py,sha256=KtjBlZOl7jwBCAUhrTJB9PdrN39YLYytNiSUSM_gRmA,62
|
|
4
|
-
mergeron/core/damodaran_margin_data.py,sha256=
|
|
5
|
-
mergeron/core/ftc_merger_investigations_data.py,sha256=
|
|
6
|
-
mergeron/core/guidelines_boundaries.py,sha256=
|
|
7
|
-
mergeron/core/guidelines_boundary_functions.py,sha256=
|
|
8
|
-
mergeron/core/guidelines_boundary_functions_extra.py,sha256=
|
|
9
|
-
mergeron/core/pseudorandom_numbers.py,sha256=
|
|
4
|
+
mergeron/core/damodaran_margin_data.py,sha256=rMrgN1Qtw572a0ftY97OOj4otq8ldlLrcOi-bcE-org,8554
|
|
5
|
+
mergeron/core/ftc_merger_investigations_data.py,sha256=oL_4yrNPpjuNIluBsDc51lYd2Z4NBBrd7-sHKd3FCbg,28129
|
|
6
|
+
mergeron/core/guidelines_boundaries.py,sha256=Lv-7EE7b2SiudpRjW3gFY1uHu-K0UdesewwiqaqjcOw,15585
|
|
7
|
+
mergeron/core/guidelines_boundary_functions.py,sha256=gohb7Uj1AjJQtD5ew7bVZZjGhJEYCjNNAPB1o6TsA9M,29683
|
|
8
|
+
mergeron/core/guidelines_boundary_functions_extra.py,sha256=t84dMsaMKnYUNuvvGrMCP6vI8MDn88PJOgGZlNe1Zts,11280
|
|
9
|
+
mergeron/core/pseudorandom_numbers.py,sha256=cJEWDTfy9CUTzR_di6Fm1Vl1Le6xWoU8wFHbYVMEuLI,9225
|
|
10
10
|
mergeron/data/__init__.py,sha256=KtjBlZOl7jwBCAUhrTJB9PdrN39YLYytNiSUSM_gRmA,62
|
|
11
11
|
mergeron/data/damodaran_margin_data.xls,sha256=Qggl1p5nkOMJI8YUXhkwXQRz-OhRSqBTzz57N0JQyYA,79360
|
|
12
12
|
mergeron/data/damodaran_margin_data_dict.msgpack,sha256=sr6s4L69kposEpzGI7jpPb4ULz0UpY-bEYfeNi6UlRA,57621
|
|
@@ -20,13 +20,13 @@ mergeron/data/jinja2_LaTeX_templates/mergeron_table_collection_template.tex.jinj
|
|
|
20
20
|
mergeron/data/jinja2_LaTeX_templates/setup_tikz_tables.tex,sha256=1hw3RINDtBrh9ZEToMIiNFIu9rozcPwRly69-5O_0UQ,3207
|
|
21
21
|
mergeron/demo/__init__.py,sha256=KtjBlZOl7jwBCAUhrTJB9PdrN39YLYytNiSUSM_gRmA,62
|
|
22
22
|
mergeron/demo/visualize_empirical_margin_distribution.py,sha256=v1xFJumBX2Ooye82kSSgly-_GpFVkYSDqBwM__rcmZY,2363
|
|
23
|
-
mergeron/gen/__init__.py,sha256=
|
|
24
|
-
mergeron/gen/_data_generation_functions.py,sha256=
|
|
25
|
-
mergeron/gen/data_generation.py,sha256=
|
|
26
|
-
mergeron/gen/enforcement_stats.py,sha256=
|
|
23
|
+
mergeron/gen/__init__.py,sha256=a60dpqC8G8J518Tb3qEJvTvFnVTYSmgZfhciVckokfw,17051
|
|
24
|
+
mergeron/gen/_data_generation_functions.py,sha256=tBdzpo-6WjwnHTB3uy2B6TE0e0Ajx0rgi6fVtW9I1b4,27386
|
|
25
|
+
mergeron/gen/data_generation.py,sha256=dj9otFi1OE3Eo7f32BD0ZXm9Xvlg0fCp4DDQ_XhDN_w,8479
|
|
26
|
+
mergeron/gen/enforcement_stats.py,sha256=p-CgaOo2qh5G9QZjCxZdbVazXeb_AJ_ABDOc2Kdtt-Q,27438
|
|
27
27
|
mergeron/gen/market_sample.py,sha256=HkzRFTKBXYIs2HbAyVDUiUHo9nCtAciSn5sohR-34cM,4282
|
|
28
|
-
mergeron/gen/upp_tests.py,sha256=
|
|
28
|
+
mergeron/gen/upp_tests.py,sha256=ZnV_x2TQqhJuWnnG9aTLnw1OBisgHCwHYxy94OK8W9E,16846
|
|
29
29
|
mergeron/py.typed,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
30
|
-
mergeron-2024.739099.
|
|
31
|
-
mergeron-2024.739099.
|
|
32
|
-
mergeron-2024.739099.
|
|
30
|
+
mergeron-2024.739099.2.dist-info/METADATA,sha256=dyRrp-CAzkssNWLw44aQ-AbKKeuPFleWqEYaRPxaLG0,10922
|
|
31
|
+
mergeron-2024.739099.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
32
|
+
mergeron-2024.739099.2.dist-info/RECORD,,
|
|
File without changes
|