mergeron 2024.739099.2__tar.gz → 2024.739105.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.

Files changed (35) hide show
  1. mergeron-2024.739105.2/PKG-INFO +115 -0
  2. mergeron-2024.739105.2/README.rst +73 -0
  3. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/pyproject.toml +1 -1
  4. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/__init__.py +7 -10
  5. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/core/ftc_merger_investigations_data.py +4 -2
  6. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/core/guidelines_boundaries.py +11 -11
  7. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/gen/__init__.py +142 -162
  8. mergeron-2024.739105.2/src/mergeron/gen/data_generation.py +527 -0
  9. mergeron-2024.739099.2/src/mergeron/gen/_data_generation_functions.py → mergeron-2024.739105.2/src/mergeron/gen/data_generation_functions.py +239 -145
  10. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/gen/enforcement_stats.py +40 -42
  11. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/gen/upp_tests.py +75 -206
  12. mergeron-2024.739099.2/PKG-INFO +0 -102
  13. mergeron-2024.739099.2/README.rst +0 -60
  14. mergeron-2024.739099.2/src/mergeron/gen/data_generation.py +0 -283
  15. mergeron-2024.739099.2/src/mergeron/gen/market_sample.py +0 -143
  16. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/License.txt +0 -0
  17. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/core/__init__.py +0 -0
  18. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/core/damodaran_margin_data.py +0 -0
  19. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/core/guidelines_boundary_functions.py +0 -0
  20. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/core/guidelines_boundary_functions_extra.py +0 -0
  21. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/core/pseudorandom_numbers.py +0 -0
  22. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/data/__init__.py +0 -0
  23. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/data/damodaran_margin_data.xls +0 -0
  24. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/data/damodaran_margin_data_dict.msgpack +0 -0
  25. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/data/ftc_invdata.msgpack +0 -0
  26. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/data/jinja2_LaTeX_templates/clrrate_cis_summary_table_template.tex.jinja2 +0 -0
  27. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/data/jinja2_LaTeX_templates/ftcinvdata_byhhianddelta_table_template.tex.jinja2 +0 -0
  28. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/data/jinja2_LaTeX_templates/ftcinvdata_summary_table_template.tex.jinja2 +0 -0
  29. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/data/jinja2_LaTeX_templates/ftcinvdata_summarypaired_table_template.tex.jinja2 +0 -0
  30. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/data/jinja2_LaTeX_templates/mergeron.cls +0 -0
  31. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/data/jinja2_LaTeX_templates/mergeron_table_collection_template.tex.jinja2 +0 -0
  32. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/data/jinja2_LaTeX_templates/setup_tikz_tables.tex +0 -0
  33. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/demo/__init__.py +0 -0
  34. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/demo/visualize_empirical_margin_distribution.py +0 -0
  35. {mergeron-2024.739099.2 → mergeron-2024.739105.2}/src/mergeron/py.typed +0 -0
@@ -0,0 +1,115 @@
1
+ Metadata-Version: 2.1
2
+ Name: mergeron
3
+ Version: 2024.739105.2
4
+ Summary: Merger Policy Analysis using Python
5
+ License: MIT
6
+ Keywords: merger policy analysis,merger guidelines,merger screening,policy presumptions,concentration standards,upward pricing pressure,GUPPI
7
+ Author: Murthy Kambhampaty
8
+ Author-email: smk@capeconomics.com
9
+ Requires-Python: >=3.12,<4.0
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: End Users/Desktop
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Programming Language :: Python :: Implementation :: CPython
21
+ Requires-Dist: aenum (>=3.1.15,<4.0.0)
22
+ Requires-Dist: attrs (>=23.2)
23
+ Requires-Dist: bs4 (>=0.0.1)
24
+ Requires-Dist: certifi (>=2023.11.17)
25
+ Requires-Dist: google-re2 (>=1.1)
26
+ Requires-Dist: jinja2 (>=3.1)
27
+ Requires-Dist: joblib (>=1.3)
28
+ Requires-Dist: matplotlib (>=3.8)
29
+ Requires-Dist: mpmath (>=1.3)
30
+ Requires-Dist: msgpack (>=1.0)
31
+ Requires-Dist: msgpack-numpy (>=0.4)
32
+ Requires-Dist: numpy (>=1.26,<2)
33
+ Requires-Dist: scipy (>=1.12)
34
+ Requires-Dist: sympy (>=1.12)
35
+ Requires-Dist: tables (>=3.8)
36
+ Requires-Dist: types-beautifulsoup4 (>=4.11.2)
37
+ Requires-Dist: urllib3 (>=2.2.2,<3.0.0)
38
+ Requires-Dist: xlrd (>=2.0.1,<3.0.0)
39
+ Requires-Dist: xlsxwriter (>=3.1)
40
+ Description-Content-Type: text/x-rst
41
+
42
+ mergeron: Merger Policy Analysis using Python
43
+ =============================================
44
+
45
+ Analyze the sets of mergers conforming to concentration and diversion ratio bounds. Analyze intrinsic enforcement rates, and intrinsic clearance rates, under concentration, diversion ratio, GUPPI, CMCR, and IPR bounds using generated data with specified distributions of market shares, price-cost margins, firm counts, and prices, optionally imposing restrictions implied by statutory filing thresholds and/or Bertrand-Nash oligopoly with MNL demand. Download and analyze merger investigations data published by the U.S. Federal Trade Commission in various reports on extended merger investigations (Second Requests) during 1996 to 2011.
46
+
47
+ Here, enforcement rates derived with merger enforcement as being exogenous to firm conduct are defined as intrinsic enforcement rates, and similarly intrinsic clearance rates. Depending on the merger enforcement regime, or merger control regime, intrinsic enforcement rates may also not be the complement of intrinsic clearance rates, i.e, it is not necessarily true that the intrinsic clearance rate estimate for a given enforcement regime is 1 minus the intrinsic enforcement rate. In contrast, observed enforcement rates reflect the deterrent effects of merger enforcement on firm conduct as well as the effects of merger screening on the level of enforcement; and, by definition, the observed clearance rate is 1 minus the observed enforcement rate.
48
+
49
+ Introduction
50
+ ------------
51
+
52
+ Module :code:`.core.guidelines_boundaries` includes classes for specifying concentration bounds (:code:`..core.guidelines_boundaries.ConcentrationBoundary`) and diversion-ratio bounds (:code:`..core.guidelines_boundaries.DiversionRatioBoundary`), with automatic generation of boundary (as an array of share-pairs) and area. This module also includes a function for generating plots of concentration and diversion-ratio boundaries, and functions for mapping GUPPI standards to concentration (ΔHHI) standards, and vice-versa.
53
+
54
+ Module :code:`.gen.data_generation` includes the :code:`.gen.data_generation.MarketSample` which provides for a rich specification of shares and diversion ratios (:code:`.gen.data_generation.MarketSample.share_spec`), margins (:code:`.gen.data_generation.MarketSample.pcm_spec`, prices (:code:`.gen.data_generation.MarketSample.price_spec`), and HSR filing requirements (:code:`.gen.data_generation.MarketSample.hsr_filing_test_type`), and with methods for, (i) generating sample data (:code:`.gen.data_generation.MarketSample.generate_sample`), and (ii) estimating enforcement or clearance rates under specified enforcement regimes given a method of aggregating diversion ratio or GUPPI estimates for the firms in a merger (:code:`.gen.data_generation.MarketSample.estimate_enf_counts`). While the latter populate the properties, :code:`.gen.data_generation.MarketSample.data`
55
+ and :code:`.gen.data_generation.MarketSample.enf_counts`, respectively, the underlying methods for generating standalone :code:`MarketDataSample` and :code:`UPPTestCounts` objects are included in the class definition, with helper functions defined in the modules, :code:`.gen.data_generation_functions` and :code:`.gen.upp_tests`. Notably, market shares are generated for a sample of markets with firm-count distributed as specified in :code:`.gen.data_generation.MarketSample.ShareSpec.firm_count_weights`, with defaults as discussed below (also see, :code:`.gen.ShareSpec.firm_count_weights`.
56
+
57
+ By default, merging-firm shares are drawn with uniform distribution over the space :math:`s_1 + s_2 \leqslant 1` for an unspecified number of firms. Alternatively, shares may be drawn from the Dirichlet distribution, with specified shape parameters (see :code:`.gen.data_generation.MarketSample.ShareSpec`, and, specifically, :code:`.gen.SHRDistribution`). When drawing shares from the Dirichlet distribution, the user passes, using :code:`.gen.data_generation.MarketSample.ShareSpec.firm_count_weights`, a vector of weights specifying the frequency distribution over sequential firm counts, e.g., :code:`[133, 184, 134, 52, 32, 10, 12, 4, 3]` to specify shares drawn from Dirichlet distributions with 2 to 10 pre-merger firms distributed as in data for FTC merger investigations during 1996--2003 (See, for example, Table 4.1 of `FTC, Horizontal Merger Investigations Data, Fiscal Years 1996--2003 (Revised: August 31, 2004) <https://www.ftc.gov/sites/default/files/documents/reports/horizontal-merger-investigation-data-fiscal-years-1996-2003/040831horizmergersdata96-03.pdf>`_). If :code:`.gen.data_generation.MarketSample.ShareSpec.firm_count_weights` is not explicitly assigned a value when defining :code:`.gen.data_generation.MarketSample.ShareSpec`, the default values is used, which results in a sample of markets with 2 to 7 firms with relative frequency in inverse proportion to firm-count, with 2-firm markets being 6 times as likely to be drawn as 7-firm markets.
58
+
59
+ Recapture rates can be specified as, "proportional", "inside-out", "outside-in" (see :code:`.RECForm`. The "inside-out" specification (:code:`.gen.data_generation.MarketSample.ShareSpec.recapture_form`:code:` = `:code:`.RECForm.INOUT`) results in recapture ratios consistent with merging-firms' in-market shares and a default recapture rate. The "outside-in" specification (:code:`.gen.data_generation.MarketSample.ShareSpec.recapture_form`:code:` = `:code:`.RECForm.INOUT`) yields diversion ratios from purchase probabilities drawn at random for :math:`N+1` goods, from which are derived market shares and recapture rates for the :math:`N` goods in the putative market (see, :code:`.gen.ShareSpec`). The "outside-in" specification is invalid when the distribution of markets over firm-count is unspecified, i.e., when :code:`.gen.data_generation.MarketSample.ShareSpec.dist_type`:code:` ==`:code:`.gen.ShareDistributions.UNI`, thus raising a :code:`ValueError` exception. The "proportional" form (:code:`.gen.data_generation.MarketSample.ShareSpec.recapture_form`:code:` = `:code:`.RECForm.FIXED`) is often used in the literature, as an approximation to the "inside-out" form. See, for example, Coate (2011).
60
+
61
+ Price-cost-margins may be specified as having uniform distribution, Beta distribution (including a bounded Beta distribution with specified mean and variance), or an empirical distribution (see, :code:`.gen.PCMSpec`). The empirical margin distribution is based on resampling margin data published by Prof. Damodaran of NYU Stern School of Business (see Notes), using an estimated Gaussian KDE. The second merging firm's margin (:code:`.gen.data_generation.MarketSample.PCMSpec.firm2_pcm_constraint`) may be specified as symmetric, i.i.d., or subject to equilibrium conditions for (profit-maximization in) Bertrand-Nash oligopoly with MNL demand (:code:`.gen.FM2Constraint`).
62
+
63
+ Prices may be specified as symmetric or asymmetric, and in the latter case, the direction of correlation between merging firm prices, if any, can also be specified (see, :code:`.gen.PriceSpec`). Prices may also be defined by imposing cost symmetry on firms in the sample, with fixed unit marginal costs normalized to 1 unit, such that price equal :math:`1 / (1 - \pmb{m})`, where :math:`\pmb{m}` represents the array of margins for firms in the sample.
64
+
65
+ The market sample may be restricted to mergers meeting the HSR filing requirement under two alternative approaches: in the one, the smaller of the two merging firms meets the lower HSR size threshold ($10 million, as adjusted) and the larger of the two merging firms meets the size test if it's share is no less than 10 times the share of the smaller firm. In the other, the :math:`n`-th firm's size is maintained as $10 million, as adjusted (see, :code:`.gen.SSZConstant`), and a merger meets the HSR filing test if either, (a.) the smaller merging firm is no smaller than the n-th firm and the larger merging firm is at 10-times as large as the n-th firm, or (b.) the smaller merging firm's market share is in excess of 10%; in effect this version of the test maintains that if the smaller merging firm's market share exceeds 10%, the value of the transaction exceeds $200 million, as adjusted, and the size-of-person test is eliminated (see, FTC (2008, p. 12); the above are simplifications of the statutory HSR filing requirements). The second assumption avoids the unfortunate assumption in the first that, within the resulting sample, the larger merging firm be at least 10 times as large as the smaller merging firm, as a consequence of the full definition of the HSR filing requirement.
66
+
67
+ The full specification of a market sample is given in a :code:`.gen.data_generation.MarketSample` object, including the above parameters. Data are drawn by invoking :code:`.gen.data_generation.MarketSample.generate_sample` which adds a :code:`data` property of class, :code:`.gen.MarketDataSample`. Enforcement or clearance counts are computed by invoking :code:`.gen.data_generation.MarketSample.estimate_enf_counts`, which adds an :code:`enf_counts` property of class :code:`.gen.UPPTestsCounts`. For fast, parallel generation of enforcement or clearance counts over large market data samples that ordinarily would exceed available limits on machine memory, the user can invoke the method :code:`.gen.data_generation.MarketSample.estimate_enf_counts` on a :code:`.gen.data_generation.MarketSample` object without first invoking :code:`.gen.data_generation.MarketSample.generate_sample`. Note, however, that this strategy does not retain the market sample in memory in the interests of conserving memory and maintaining high performance (the user can specify that the market sample and enforcement statistics be stored to permanent storage; when saving to current PCIe NVMe storage, the performance penalty is slight, but can be considerable if saving to SATA storage).
68
+
69
+ Enforcement statistics based on FTC investigations data and test data are printed to screen or rendered to LaTex files (for processing into publication-quality tables) using methods provided in :code:`.gen.enforcement_stats`.
70
+
71
+ Programs demonstrating the use of this package are included in the sub-package, :code:`.demo`.
72
+
73
+ This package includes a class, :code:`.core.pseudorandom_numbers.MulithreadedRNG` for generating random numbers with selected continuous distribution over specified parameters, and with CPU multithreading on machines with multiple virtual, logical, or physical CPU cores. This class is an adaptation from the documentation of the :code:`numpy` package, from the discussion on `multithreaded random-number generation <https://numpy.org/doc/stable/reference/random/multithreading.html>_`; the version included here permits selection of the distribution with pre-tests to catch and inform on common errors. To access these directly:
74
+
75
+ .. code-block:: python
76
+
77
+ import mergeron.core.pseudorandom_numbers as prng
78
+
79
+ Documentation for this package is in the form of the API Reference. Documentation for individual functions and classes is accessible within a python shell. For example:
80
+
81
+ .. code-block:: python
82
+
83
+ import mergeron.core.market_sample as market_sample
84
+
85
+ help(market_sample.MarketSample)
86
+
87
+ .. rubric:: References
88
+
89
+ .. _coate2011:
90
+
91
+ Coate, M. B. (2011). Benchmarking the upward pricing pressure model with Federal Trade
92
+ Commission evidence. Journal of Competition Law & Economics, 7(4), 825--846. URL: https://doi.org/10.1093/joclec/nhr014.
93
+
94
+ .. _ftc_premerger_guide2:
95
+
96
+ FTC Premerger Notification Office. “To File or Not to File: When You Must File a Premerger Notification Report Form”. 2008 (September, revised). URL: https://www.ftc.gov/sites/default/files/attachments/premerger-introductory-guides/guide2.pdf
97
+
98
+
99
+ .. image:: https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json
100
+ :alt: Poetry
101
+ :target: https://python-poetry.org/
102
+
103
+ .. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
104
+ :alt: Ruff
105
+ :target: https://github.com/astral-sh/ruff
106
+
107
+ .. image:: https://www.mypy-lang.org/static/mypy_badge.svg
108
+ :alt: Checked with mypy
109
+ :target: https://mypy-lang.org/
110
+
111
+ .. image:: https://img.shields.io/badge/License-MIT-yellow.svg
112
+ :alt: License: MIT
113
+ :target: https://opensource.org/licenses/MIT
114
+
115
+
@@ -0,0 +1,73 @@
1
+ mergeron: Merger Policy Analysis using Python
2
+ =============================================
3
+
4
+ Analyze the sets of mergers conforming to concentration and diversion ratio bounds. Analyze intrinsic enforcement rates, and intrinsic clearance rates, under concentration, diversion ratio, GUPPI, CMCR, and IPR bounds using generated data with specified distributions of market shares, price-cost margins, firm counts, and prices, optionally imposing restrictions implied by statutory filing thresholds and/or Bertrand-Nash oligopoly with MNL demand. Download and analyze merger investigations data published by the U.S. Federal Trade Commission in various reports on extended merger investigations (Second Requests) during 1996 to 2011.
5
+
6
+ Here, enforcement rates derived with merger enforcement as being exogenous to firm conduct are defined as intrinsic enforcement rates, and similarly intrinsic clearance rates. Depending on the merger enforcement regime, or merger control regime, intrinsic enforcement rates may also not be the complement of intrinsic clearance rates, i.e, it is not necessarily true that the intrinsic clearance rate estimate for a given enforcement regime is 1 minus the intrinsic enforcement rate. In contrast, observed enforcement rates reflect the deterrent effects of merger enforcement on firm conduct as well as the effects of merger screening on the level of enforcement; and, by definition, the observed clearance rate is 1 minus the observed enforcement rate.
7
+
8
+ Introduction
9
+ ------------
10
+
11
+ Module :code:`.core.guidelines_boundaries` includes classes for specifying concentration bounds (:code:`..core.guidelines_boundaries.ConcentrationBoundary`) and diversion-ratio bounds (:code:`..core.guidelines_boundaries.DiversionRatioBoundary`), with automatic generation of boundary (as an array of share-pairs) and area. This module also includes a function for generating plots of concentration and diversion-ratio boundaries, and functions for mapping GUPPI standards to concentration (ΔHHI) standards, and vice-versa.
12
+
13
+ Module :code:`.gen.data_generation` includes the :code:`.gen.data_generation.MarketSample` which provides for a rich specification of shares and diversion ratios (:code:`.gen.data_generation.MarketSample.share_spec`), margins (:code:`.gen.data_generation.MarketSample.pcm_spec`, prices (:code:`.gen.data_generation.MarketSample.price_spec`), and HSR filing requirements (:code:`.gen.data_generation.MarketSample.hsr_filing_test_type`), and with methods for, (i) generating sample data (:code:`.gen.data_generation.MarketSample.generate_sample`), and (ii) estimating enforcement or clearance rates under specified enforcement regimes given a method of aggregating diversion ratio or GUPPI estimates for the firms in a merger (:code:`.gen.data_generation.MarketSample.estimate_enf_counts`). While the latter populate the properties, :code:`.gen.data_generation.MarketSample.data`
14
+ and :code:`.gen.data_generation.MarketSample.enf_counts`, respectively, the underlying methods for generating standalone :code:`MarketDataSample` and :code:`UPPTestCounts` objects are included in the class definition, with helper functions defined in the modules, :code:`.gen.data_generation_functions` and :code:`.gen.upp_tests`. Notably, market shares are generated for a sample of markets with firm-count distributed as specified in :code:`.gen.data_generation.MarketSample.ShareSpec.firm_count_weights`, with defaults as discussed below (also see, :code:`.gen.ShareSpec.firm_count_weights`.
15
+
16
+ By default, merging-firm shares are drawn with uniform distribution over the space :math:`s_1 + s_2 \leqslant 1` for an unspecified number of firms. Alternatively, shares may be drawn from the Dirichlet distribution, with specified shape parameters (see :code:`.gen.data_generation.MarketSample.ShareSpec`, and, specifically, :code:`.gen.SHRDistribution`). When drawing shares from the Dirichlet distribution, the user passes, using :code:`.gen.data_generation.MarketSample.ShareSpec.firm_count_weights`, a vector of weights specifying the frequency distribution over sequential firm counts, e.g., :code:`[133, 184, 134, 52, 32, 10, 12, 4, 3]` to specify shares drawn from Dirichlet distributions with 2 to 10 pre-merger firms distributed as in data for FTC merger investigations during 1996--2003 (See, for example, Table 4.1 of `FTC, Horizontal Merger Investigations Data, Fiscal Years 1996--2003 (Revised: August 31, 2004) <https://www.ftc.gov/sites/default/files/documents/reports/horizontal-merger-investigation-data-fiscal-years-1996-2003/040831horizmergersdata96-03.pdf>`_). If :code:`.gen.data_generation.MarketSample.ShareSpec.firm_count_weights` is not explicitly assigned a value when defining :code:`.gen.data_generation.MarketSample.ShareSpec`, the default values is used, which results in a sample of markets with 2 to 7 firms with relative frequency in inverse proportion to firm-count, with 2-firm markets being 6 times as likely to be drawn as 7-firm markets.
17
+
18
+ Recapture rates can be specified as, "proportional", "inside-out", "outside-in" (see :code:`.RECForm`. The "inside-out" specification (:code:`.gen.data_generation.MarketSample.ShareSpec.recapture_form`:code:` = `:code:`.RECForm.INOUT`) results in recapture ratios consistent with merging-firms' in-market shares and a default recapture rate. The "outside-in" specification (:code:`.gen.data_generation.MarketSample.ShareSpec.recapture_form`:code:` = `:code:`.RECForm.INOUT`) yields diversion ratios from purchase probabilities drawn at random for :math:`N+1` goods, from which are derived market shares and recapture rates for the :math:`N` goods in the putative market (see, :code:`.gen.ShareSpec`). The "outside-in" specification is invalid when the distribution of markets over firm-count is unspecified, i.e., when :code:`.gen.data_generation.MarketSample.ShareSpec.dist_type`:code:` ==`:code:`.gen.ShareDistributions.UNI`, thus raising a :code:`ValueError` exception. The "proportional" form (:code:`.gen.data_generation.MarketSample.ShareSpec.recapture_form`:code:` = `:code:`.RECForm.FIXED`) is often used in the literature, as an approximation to the "inside-out" form. See, for example, Coate (2011).
19
+
20
+ Price-cost-margins may be specified as having uniform distribution, Beta distribution (including a bounded Beta distribution with specified mean and variance), or an empirical distribution (see, :code:`.gen.PCMSpec`). The empirical margin distribution is based on resampling margin data published by Prof. Damodaran of NYU Stern School of Business (see Notes), using an estimated Gaussian KDE. The second merging firm's margin (:code:`.gen.data_generation.MarketSample.PCMSpec.firm2_pcm_constraint`) may be specified as symmetric, i.i.d., or subject to equilibrium conditions for (profit-maximization in) Bertrand-Nash oligopoly with MNL demand (:code:`.gen.FM2Constraint`).
21
+
22
+ Prices may be specified as symmetric or asymmetric, and in the latter case, the direction of correlation between merging firm prices, if any, can also be specified (see, :code:`.gen.PriceSpec`). Prices may also be defined by imposing cost symmetry on firms in the sample, with fixed unit marginal costs normalized to 1 unit, such that price equal :math:`1 / (1 - \pmb{m})`, where :math:`\pmb{m}` represents the array of margins for firms in the sample.
23
+
24
+ The market sample may be restricted to mergers meeting the HSR filing requirement under two alternative approaches: in the one, the smaller of the two merging firms meets the lower HSR size threshold ($10 million, as adjusted) and the larger of the two merging firms meets the size test if it's share is no less than 10 times the share of the smaller firm. In the other, the :math:`n`-th firm's size is maintained as $10 million, as adjusted (see, :code:`.gen.SSZConstant`), and a merger meets the HSR filing test if either, (a.) the smaller merging firm is no smaller than the n-th firm and the larger merging firm is at 10-times as large as the n-th firm, or (b.) the smaller merging firm's market share is in excess of 10%; in effect this version of the test maintains that if the smaller merging firm's market share exceeds 10%, the value of the transaction exceeds $200 million, as adjusted, and the size-of-person test is eliminated (see, FTC (2008, p. 12); the above are simplifications of the statutory HSR filing requirements). The second assumption avoids the unfortunate assumption in the first that, within the resulting sample, the larger merging firm be at least 10 times as large as the smaller merging firm, as a consequence of the full definition of the HSR filing requirement.
25
+
26
+ The full specification of a market sample is given in a :code:`.gen.data_generation.MarketSample` object, including the above parameters. Data are drawn by invoking :code:`.gen.data_generation.MarketSample.generate_sample` which adds a :code:`data` property of class, :code:`.gen.MarketDataSample`. Enforcement or clearance counts are computed by invoking :code:`.gen.data_generation.MarketSample.estimate_enf_counts`, which adds an :code:`enf_counts` property of class :code:`.gen.UPPTestsCounts`. For fast, parallel generation of enforcement or clearance counts over large market data samples that ordinarily would exceed available limits on machine memory, the user can invoke the method :code:`.gen.data_generation.MarketSample.estimate_enf_counts` on a :code:`.gen.data_generation.MarketSample` object without first invoking :code:`.gen.data_generation.MarketSample.generate_sample`. Note, however, that this strategy does not retain the market sample in memory in the interests of conserving memory and maintaining high performance (the user can specify that the market sample and enforcement statistics be stored to permanent storage; when saving to current PCIe NVMe storage, the performance penalty is slight, but can be considerable if saving to SATA storage).
27
+
28
+ Enforcement statistics based on FTC investigations data and test data are printed to screen or rendered to LaTex files (for processing into publication-quality tables) using methods provided in :code:`.gen.enforcement_stats`.
29
+
30
+ Programs demonstrating the use of this package are included in the sub-package, :code:`.demo`.
31
+
32
+ This package includes a class, :code:`.core.pseudorandom_numbers.MulithreadedRNG` for generating random numbers with selected continuous distribution over specified parameters, and with CPU multithreading on machines with multiple virtual, logical, or physical CPU cores. This class is an adaptation from the documentation of the :code:`numpy` package, from the discussion on `multithreaded random-number generation <https://numpy.org/doc/stable/reference/random/multithreading.html>_`; the version included here permits selection of the distribution with pre-tests to catch and inform on common errors. To access these directly:
33
+
34
+ .. code-block:: python
35
+
36
+ import mergeron.core.pseudorandom_numbers as prng
37
+
38
+ Documentation for this package is in the form of the API Reference. Documentation for individual functions and classes is accessible within a python shell. For example:
39
+
40
+ .. code-block:: python
41
+
42
+ import mergeron.core.market_sample as market_sample
43
+
44
+ help(market_sample.MarketSample)
45
+
46
+ .. rubric:: References
47
+
48
+ .. _coate2011:
49
+
50
+ Coate, M. B. (2011). Benchmarking the upward pricing pressure model with Federal Trade
51
+ Commission evidence. Journal of Competition Law & Economics, 7(4), 825--846. URL: https://doi.org/10.1093/joclec/nhr014.
52
+
53
+ .. _ftc_premerger_guide2:
54
+
55
+ FTC Premerger Notification Office. “To File or Not to File: When You Must File a Premerger Notification Report Form”. 2008 (September, revised). URL: https://www.ftc.gov/sites/default/files/attachments/premerger-introductory-guides/guide2.pdf
56
+
57
+
58
+ .. image:: https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json
59
+ :alt: Poetry
60
+ :target: https://python-poetry.org/
61
+
62
+ .. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
63
+ :alt: Ruff
64
+ :target: https://github.com/astral-sh/ruff
65
+
66
+ .. image:: https://www.mypy-lang.org/static/mypy_badge.svg
67
+ :alt: Checked with mypy
68
+ :target: https://mypy-lang.org/
69
+
70
+ .. image:: https://img.shields.io/badge/License-MIT-yellow.svg
71
+ :alt: License: MIT
72
+ :target: https://opensource.org/licenses/MIT
73
+
@@ -13,7 +13,7 @@ keywords = [
13
13
  "upward pricing pressure",
14
14
  "GUPPI",
15
15
  ]
16
- version = "2024.739099.2"
16
+ version = "2024.739105.2"
17
17
 
18
18
  # Classifiers list: https://pypi.org/classifiers/
19
19
  classifiers = [
@@ -2,14 +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
+ from typing import TypeAlias
6
6
 
7
7
  import numpy as np
8
- from numpy.typing import NBitBase, NDArray
8
+ from numpy.typing import NDArray
9
9
 
10
10
  _PKG_NAME: str = Path(__file__).parent.stem
11
11
 
12
- VERSION = "2024.739099.2"
12
+ VERSION = "2024.739105.2"
13
13
 
14
14
  __version__ = VERSION
15
15
 
@@ -22,24 +22,21 @@ If the subdirectory doesn't exist, it is created on package invocation.
22
22
  if not DATA_DIR.is_dir():
23
23
  DATA_DIR.mkdir(parents=False)
24
24
 
25
-
26
25
  np.set_printoptions(precision=18)
27
26
 
28
27
 
29
- TI = TypeVar("TI", bound=NBitBase)
30
- ArrayINT = NDArray[np.integer[TI]]
31
- TF = TypeVar("TF", bound=NBitBase)
32
- ArrayFloat = NDArray[np.floating[TF]]
28
+ ArrayINT = NDArray[np.intp]
29
+ ArrayFloat = NDArray[np.half | np.single | np.double]
33
30
 
34
31
 
35
32
  ArrayBoolean: TypeAlias = NDArray[np.bool_]
36
33
 
37
- ArrayDouble: TypeAlias = NDArray[np.float64]
34
+ ArrayDouble: TypeAlias = NDArray[np.double]
38
35
  ArrayBIGINT: TypeAlias = NDArray[np.int64]
39
36
 
40
37
 
41
38
  @enum.unique
42
- class RECConstants(enum.StrEnum):
39
+ class RECForm(enum.StrEnum):
43
40
  """Recapture rate - derivation methods."""
44
41
 
45
42
  INOUT = "inside-out"
@@ -285,7 +285,7 @@ def _construct_new_period_data(
285
285
  # Consistency here means that the number of investigations reported
286
286
  # in each period is no less than the number reported in
287
287
  # any prior period.Although the time periods for table 3.2 through 3.5
288
- # are not the samein the data for 1996-2005 and 1996-2007 as in
288
+ # are not the same in the data for 1996-2005 and 1996-2007 as in
289
289
  # the data for the other periods, they are nonetheless shorter than
290
290
  # the period 1996-2011, and hence the counts reported for 1996-2011
291
291
  # cannot be less than those reported in these prior periods. Note that
@@ -337,7 +337,8 @@ def _construct_new_period_data(
337
337
  _invdata_cuml_array[:, -3:-1] - _invdata_base_array[:, -3:-1] # type: ignore
338
338
  )
339
339
 
340
- # To examine the number of corrected values per table,
340
+ # # // spellchecker: disable
341
+ # To examine the number of corrected values per table, // spellchecker: disable
341
342
  # uncomment the statements below
342
343
  # _invdata_array_bld_tbc = where(
343
344
  # _invdata_array_bld_enfcls < 0, _invdata_array_bld_enfcls, 0
@@ -347,6 +348,7 @@ def _construct_new_period_data(
347
348
  # f"{_data_period}, {_table_no}, {_invdata_ind_group}:",
348
349
  # abs(np.einsum('ij->', invdata_array_bld_tbc))
349
350
  # )
351
+ # # // spellchecker: disable
350
352
 
351
353
  # Enforce non-negativity
352
354
  _invdata_array_bld_enfcls = np.stack((
@@ -13,7 +13,7 @@ import numpy as np
13
13
  from attrs import Attribute, field, frozen, validators
14
14
  from mpmath import mp, mpf # type: ignore
15
15
 
16
- from .. import VERSION, ArrayDouble, RECConstants, UPPAggrSelector # noqa: TID252
16
+ from .. import VERSION, ArrayDouble, RECForm, UPPAggrSelector # noqa: TID252
17
17
  from . import guidelines_boundary_functions as gbfn
18
18
 
19
19
  __version__ = VERSION
@@ -223,14 +223,14 @@ def _divr_value_validator(
223
223
 
224
224
  def _rec_spec_validator(
225
225
  _instance: DiversionRatioBoundary,
226
- _attribute: Attribute[RECConstants],
227
- _value: RECConstants,
226
+ _attribute: Attribute[RECForm],
227
+ _value: RECForm,
228
228
  /,
229
229
  ) -> None:
230
- if _value == RECConstants.OUTIN and _instance.recapture_rate:
230
+ if _value == RECForm.OUTIN and _instance.recapture_rate:
231
231
  raise ValueError(
232
232
  f"Invalid recapture specification, {_value!r}. "
233
- "You may consider specifying `mergeron.RECConstants.INOUT` here, and "
233
+ "You may consider specifying `mergeron.RECForm.INOUT` here, and "
234
234
  'assigning the default recapture rate as attribute, "recapture_rate" of '
235
235
  "this `DiversionRatioBoundarySpec` object."
236
236
  )
@@ -265,24 +265,24 @@ class DiversionRatioBoundary:
265
265
  kw_only=False, default=0.85, validator=validators.instance_of(float)
266
266
  )
267
267
 
268
- recapture_form: RECConstants | None = field(
268
+ recapture_form: RECForm | None = field(
269
269
  kw_only=True,
270
- default=RECConstants.INOUT,
270
+ default=RECForm.INOUT,
271
271
  validator=(
272
- validators.instance_of((type(None), RECConstants)),
272
+ validators.instance_of((type(None), RECForm)),
273
273
  _rec_spec_validator,
274
274
  ),
275
275
  )
276
276
  """
277
277
  The form of the recapture rate.
278
278
 
279
- When :attr:`mergeron.RECConstants.INOUT`, the recapture rate for
279
+ When :attr:`mergeron.RECForm.INOUT`, the recapture rate for
280
280
  he product having the smaller market-share is assumed to equal the default,
281
281
  and the recapture rate for the product with the larger market-share is
282
282
  computed assuming MNL demand. Fixed recapture rates are specified as
283
- :attr:`mergeron.RECConstants.FIXED`. (To specify that recapture rates be
283
+ :attr:`mergeron.RECForm.FIXED`. (To specify that recapture rates be
284
284
  constructed from the generated purchase-probabilities for products in
285
- the market and for the outside good, specify :attr:`mergeron.RECConstants.OUTIN`.)
285
+ the market and for the outside good, specify :attr:`mergeron.RECForm.OUTIN`.)
286
286
 
287
287
  The GUPPI boundary is a continuum of diversion ratio boundaries conditional on
288
288
  price-cost margins, :math:`d_{ij} = g_i * p_i / (m_j * p_j)`,