mergeron 2025.739319.2__tar.gz → 2025.739319.3__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 (22) hide show
  1. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/PKG-INFO +1 -1
  2. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/pyproject.toml +1 -1
  3. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/__init__.py +1 -1
  4. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/gen/__init__.py +9 -0
  5. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/gen/data_generation_functions.py +9 -13
  6. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/gen/enforcement_stats.py +7 -4
  7. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/README.rst +0 -0
  8. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/core/__init__.py +0 -0
  9. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/core/empirical_margin_distribution.py +0 -0
  10. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/core/ftc_merger_investigations_data.py +0 -0
  11. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/core/guidelines_boundaries.py +0 -0
  12. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/core/guidelines_boundary_functions.py +0 -0
  13. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/core/guidelines_boundary_functions_extra.py +0 -0
  14. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/core/pseudorandom_numbers.py +0 -0
  15. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/data/__init__.py +0 -0
  16. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/data/damodaran_margin_data.xls +0 -0
  17. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/data/ftc_merger_investigations_data.zip +0 -0
  18. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/demo/__init__.py +0 -0
  19. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/demo/visualize_empirical_margin_distribution.py +0 -0
  20. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/gen/data_generation.py +1 -1
  21. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/gen/upp_tests.py +0 -0
  22. {mergeron-2025.739319.2 → mergeron-2025.739319.3}/src/mergeron/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: mergeron
3
- Version: 2025.739319.2
3
+ Version: 2025.739319.3
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
@@ -13,7 +13,7 @@ keywords = [
13
13
  "upward pricing pressure",
14
14
  "GUPPI",
15
15
  ]
16
- version = "2025.739319.2"
16
+ version = "2025.739319.3"
17
17
 
18
18
  # Classifiers list: https://pypi.org/classifiers/
19
19
  classifiers = [
@@ -12,7 +12,7 @@ from ruamel import yaml
12
12
 
13
13
  _PKG_NAME: str = Path(__file__).parent.stem
14
14
 
15
- VERSION = "2025.739319.2"
15
+ VERSION = "2025.739319.3"
16
16
 
17
17
  __version__ = VERSION
18
18
 
@@ -405,6 +405,15 @@ class PCMSpec:
405
405
  pcm_restriction: PCMRestriction = field(kw_only=True, default=PCMRestriction.IID)
406
406
  """See :class:`PCMRestriction`"""
407
407
 
408
+ @pcm_restriction.validator
409
+ def __prv(_i: PCMSpec, _a: Attribute[PCMRestriction], _v: PCMRestriction) -> None:
410
+ if _v == PCMRestriction.MNL and _i.dist_type == PCMDistribution.EMPR:
411
+ print(
412
+ "NOTE: Estimated Firm 2 parameters will not be consistent with "
413
+ "the empirical distribution of margins in the source data. For "
414
+ "consistency, respecify pcm_spec.pcm_restriction = PCMRestriction.IID."
415
+ )
416
+
408
417
 
409
418
  @this_yaml.register_class
410
419
  @enum.unique
@@ -28,9 +28,9 @@ from ..core.pseudorandom_numbers import ( # noqa: TID252
28
28
  from . import (
29
29
  DEFAULT_BETA_BND_DIST_PARMS,
30
30
  DEFAULT_FCOUNT_WTS,
31
- PCMRestriction,
32
31
  MarginDataSample,
33
32
  PCMDistribution,
33
+ PCMRestriction,
34
34
  PCMSpec,
35
35
  PriceDataSample,
36
36
  PriceSpec,
@@ -665,9 +665,8 @@ def _gen_margin_data(
665
665
  _nthreads: int,
666
666
  /,
667
667
  ) -> MarginDataSample:
668
- dist_type_pcm, dist_parms_pcm, dist_firm2_pcm = (
669
- getattr(_pcm_spec, _f)
670
- for _f in ("dist_type", "dist_parms", "pcm_restriction")
668
+ dist_type_pcm, dist_parms_pcm, pcm_restriction_ = (
669
+ getattr(_pcm_spec, _f) for _f in ("dist_type", "dist_parms", "pcm_restriction")
671
670
  )
672
671
 
673
672
  pcm_array = (
@@ -680,7 +679,10 @@ def _gen_margin_data(
680
679
  beta_min, beta_max = [0.0] * 2 # placeholder
681
680
  if dist_type_pcm == PCMDistribution.EMPR:
682
681
  pcm_array = margin_data_resampler(
683
- dist_parms_pcm, sample_size=pcm_array.shape, seed_sequence=_pcm_rng_seed_seq, nthreads=_nthreads
682
+ dist_parms_pcm,
683
+ sample_size=pcm_array.shape,
684
+ seed_sequence=_pcm_rng_seed_seq,
685
+ nthreads=_nthreads,
684
686
  )
685
687
  else:
686
688
  dist_type_: Literal["Beta", "Uniform"]
@@ -721,16 +723,10 @@ def _gen_margin_data(
721
723
  pcm_array = (beta_max - beta_min) * pcm_array + beta_min
722
724
  del beta_min, beta_max
723
725
 
724
- if dist_firm2_pcm == PCMRestriction.SYM:
726
+ if pcm_restriction_ == PCMRestriction.SYM:
725
727
  pcm_array = np.hstack((pcm_array,) * _frmshr_array.shape[1])
726
- if dist_firm2_pcm == PCMRestriction.MNL:
728
+ if pcm_restriction_ == PCMRestriction.MNL:
727
729
  # Impose FOCs from profit-maximization with MNL demand
728
- if dist_type_pcm == PCMDistribution.EMPR:
729
- print(
730
- "NOTE: Estimated Firm 2 parameters will not be consistent with "
731
- "the empirical distribution of margins in the source data. For "
732
- "consistency, respecify pcm_spec.pcm_restriction = PCMRestriction.IID."
733
- )
734
730
  purchase_prob_array = _aggregate_purchase_prob * _frmshr_array
735
731
 
736
732
  pcm_array[:, [1]] = np.divide(
@@ -335,10 +335,13 @@ def enf_cnts_byconczone(_cnts_array: ArrayBIGINT, /) -> ArrayBIGINT:
335
335
  # Logical-and of multiple vectors:
336
336
  hhi_zone_test = (
337
337
  1
338
- * np.stack([
339
- cnts_byhhipostanddelta[:, _idx] == _val
340
- for _idx, _val in enumerate(zone_val)
341
- ], axis=1)
338
+ * np.stack(
339
+ [
340
+ cnts_byhhipostanddelta[:, _idx] == _val
341
+ for _idx, _val in enumerate(zone_val)
342
+ ],
343
+ axis=1,
344
+ )
342
345
  ).prod(axis=1) == 1
343
346
 
344
347
  cnts_byconczone = np.vstack((
@@ -26,10 +26,10 @@ from .. import ( # noqa: TID252 # noqa
26
26
  from ..core import guidelines_boundaries as gbl # noqa: TID252
27
27
  from ..core.guidelines_boundaries import HMGThresholds # noqa: TID252
28
28
  from . import (
29
- PCMRestriction,
30
29
  INVResolution, # noqa: F401
31
30
  MarketSampleData,
32
31
  PCMDistribution,
32
+ PCMRestriction,
33
33
  PCMSpec,
34
34
  PriceSpec,
35
35
  SeedSequenceData,