mergeron 2024.738940.0__py3-none-any.whl → 2024.738949.0__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.

Files changed (24) hide show
  1. mergeron/core/excel_helper.py +38 -25
  2. mergeron/core/ftc_merger_investigations_data.py +33 -30
  3. mergeron/core/{guidelines_standards.py → guidelines_boundaries.py} +35 -29
  4. mergeron/core/proportions_tests.py +12 -10
  5. mergeron/examples/concentration_as_diversion.py +30 -26
  6. mergeron/examples/{safeharbor_boundaries_for_mergers_with_asymmetric_shares.py → enforcement_boundaries_for_mergers_with_asymmetric_shares.py} +84 -90
  7. mergeron/examples/{safeharbor_boundaries_for_symmetric_firm_mergers.py → enforcement_boundaries_for_symmetric_firm_mergers.py} +3 -3
  8. mergeron/examples/guidelines_enforcement_patterns.py +18 -16
  9. mergeron/examples/investigations_stats_obs_tables.py +15 -14
  10. mergeron/examples/investigations_stats_sim_tables.py +49 -54
  11. mergeron/examples/plotSafeHarbs_symbolically.py +1 -1
  12. mergeron/examples/sound_guppi_safeharbor.py +59 -54
  13. mergeron/examples/summarize_ftc_investigations_data.py +4 -4
  14. mergeron/examples/visualize_empirical_margin_distribution.py +2 -2
  15. mergeron/examples/visualize_guidelines_tests.py +67 -65
  16. mergeron/gen/__init__.py +104 -42
  17. mergeron/gen/_data_generation_functions_nonpublic.py +6 -6
  18. mergeron/gen/data_generation.py +1 -4
  19. mergeron/gen/investigations_stats.py +21 -27
  20. mergeron/gen/{guidelines_tests.py → upp_tests.py} +98 -102
  21. {mergeron-2024.738940.0.dist-info → mergeron-2024.738949.0.dist-info}/METADATA +2 -5
  22. mergeron-2024.738949.0.dist-info/RECORD +42 -0
  23. {mergeron-2024.738940.0.dist-info → mergeron-2024.738949.0.dist-info}/WHEEL +1 -1
  24. mergeron-2024.738940.0.dist-info/RECORD +0 -42
@@ -24,7 +24,7 @@ from scipy.interpolate import interp1d # type: ignore
24
24
 
25
25
  from ..core import ftc_merger_investigations_data as fid # noqa: TID252
26
26
  from ..core.proportions_tests import propn_ci # noqa: TID252
27
- from . import TF, TI
27
+ from . import TF, TI, INVResolution
28
28
 
29
29
 
30
30
  @enum.unique
@@ -47,16 +47,10 @@ class EVIDENConstants(enum.StrEnum):
47
47
  CC = "Strong Customer Complaints"
48
48
  NE = "No Entry Evidence"
49
49
  ED = "Entry Difficult"
50
+ EE = "Entry Easy"
50
51
  UR = "Unrestricted on additional evidence"
51
52
 
52
53
 
53
- @enum.unique
54
- class PolicySelector(enum.StrEnum):
55
- CLRN = "clearance"
56
- ENFT = "enforcement"
57
- BOTH = "both"
58
-
59
-
60
54
  @enum.unique
61
55
  class StatsGrpSelector(enum.StrEnum):
62
56
  FC = "ByFirmCount"
@@ -219,7 +213,7 @@ def invres_stats_output(
219
213
  _table_ind_group: INDGRPConstants = INDGRPConstants.ALL,
220
214
  _table_evid_cond: EVIDENConstants = EVIDENConstants.UR,
221
215
  _stats_group: StatsGrpSelector = StatsGrpSelector.FC,
222
- _test_regime: PolicySelector = PolicySelector.CLRN,
216
+ _invres_spec: INVResolution = INVResolution.CLRN,
223
217
  /,
224
218
  *,
225
219
  return_type_sel: StatsReturnSelector = StatsReturnSelector.RPT,
@@ -250,7 +244,7 @@ def invres_stats_output(
250
244
  _table_ind_group,
251
245
  _table_evid_cond,
252
246
  _stats_group,
253
- _test_regime,
247
+ _invres_spec,
254
248
  )
255
249
 
256
250
  _invres_stats_hdr_list, _invres_stats_dat_list = _latex_tbl_invres_stats_func(
@@ -259,7 +253,7 @@ def invres_stats_output(
259
253
 
260
254
  if print_to_screen:
261
255
  print(
262
- f"{_test_regime.capitalize()} stats ({return_type_sel})",
256
+ f"{_invres_spec.capitalize()} stats ({return_type_sel})",
263
257
  f"for Period: {_data_period}",
264
258
  "\u2014",
265
259
  f"{_table_ind_group};",
@@ -271,12 +265,12 @@ def invres_stats_output(
271
265
 
272
266
 
273
267
  def invres_stats_cnts_by_group(
274
- _invdata_array_dict: Mapping[str, Mapping[str, Mapping[str, fid.TableData]]],
268
+ _invdata_array_dict: Mapping[str, Mapping[str, Mapping[str, fid.INVTableData]]],
275
269
  _study_period: str,
276
270
  _table_ind_grp: INDGRPConstants,
277
271
  _table_evid_cond: EVIDENConstants,
278
272
  _stats_group: StatsGrpSelector,
279
- _test_regime: PolicySelector,
273
+ _invres_spec: INVResolution,
280
274
  /,
281
275
  ) -> NDArray[np.int64]:
282
276
  if _stats_group == StatsGrpSelector.HD:
@@ -301,17 +295,17 @@ def invres_stats_cnts_by_group(
301
295
  _study_period,
302
296
  _table_ind_grp,
303
297
  _table_evid_cond,
304
- _test_regime,
298
+ _invres_spec,
305
299
  )
306
300
  )
307
301
 
308
302
 
309
303
  def invres_cnts_listing_byfirmcount(
310
- _data_array_dict: Mapping[str, Mapping[str, Mapping[str, fid.TableData]]],
304
+ _data_array_dict: Mapping[str, Mapping[str, Mapping[str, fid.INVTableData]]],
311
305
  _data_period: str = "1996-2003",
312
306
  _table_ind_group: INDGRPConstants = INDGRPConstants.ALL,
313
307
  _table_evid_cond: EVIDENConstants = EVIDENConstants.UR,
314
- _test_regime: PolicySelector = PolicySelector.CLRN,
308
+ _invres_spec: INVResolution = INVResolution.CLRN,
315
309
  /,
316
310
  ) -> NDArray[np.int64]:
317
311
  if _data_period not in _data_array_dict:
@@ -328,12 +322,12 @@ def invres_cnts_listing_byfirmcount(
328
322
 
329
323
  _ndim_in = 1
330
324
  _stats_kept_indxs = []
331
- match _test_regime:
332
- case PolicySelector.CLRN:
325
+ match _invres_spec:
326
+ case INVResolution.CLRN:
333
327
  _stats_kept_indxs = [-1, -2]
334
- case PolicySelector.ENFT:
328
+ case INVResolution.ENFT:
335
329
  _stats_kept_indxs = [-1, -3]
336
- case PolicySelector.BOTH:
330
+ case INVResolution.BOTH:
337
331
  _stats_kept_indxs = [-1, -3, -2]
338
332
 
339
333
  return np.column_stack([
@@ -343,11 +337,11 @@ def invres_cnts_listing_byfirmcount(
343
337
 
344
338
 
345
339
  def invres_cnts_listing_byhhianddelta(
346
- _data_array_dict: Mapping[str, Mapping[str, Mapping[str, fid.TableData]]],
340
+ _data_array_dict: Mapping[str, Mapping[str, Mapping[str, fid.INVTableData]]],
347
341
  _data_period: str = "1996-2003",
348
342
  _table_ind_group: INDGRPConstants = INDGRPConstants.ALL,
349
343
  _table_evid_cond: EVIDENConstants = EVIDENConstants.UR,
350
- _test_regime: PolicySelector = PolicySelector.CLRN,
344
+ _invres_spec: INVResolution = INVResolution.CLRN,
351
345
  /,
352
346
  ) -> NDArray[np.int64]:
353
347
  if _data_period not in _data_array_dict:
@@ -364,12 +358,12 @@ def invres_cnts_listing_byhhianddelta(
364
358
 
365
359
  _ndim_in = 2
366
360
  _stats_kept_indxs = []
367
- match _test_regime:
368
- case PolicySelector.CLRN:
361
+ match _invres_spec:
362
+ case INVResolution.CLRN:
369
363
  _stats_kept_indxs = [-1, -2]
370
- case PolicySelector.ENFT:
364
+ case INVResolution.ENFT:
371
365
  _stats_kept_indxs = [-1, -3]
372
- case PolicySelector.BOTH:
366
+ case INVResolution.BOTH:
373
367
  _stats_kept_indxs = [-1, -3, -2]
374
368
 
375
369
  return np.column_stack([
@@ -379,7 +373,7 @@ def invres_cnts_listing_byhhianddelta(
379
373
 
380
374
 
381
375
  def table_no_lku(
382
- _data_array_dict_sub: Mapping[str, fid.TableData],
376
+ _data_array_dict_sub: Mapping[str, fid.INVTableData],
383
377
  _table_ind_group: INDGRPConstants = INDGRPConstants.ALL,
384
378
  _table_evid_cond: EVIDENConstants = EVIDENConstants.UR,
385
379
  /,
@@ -5,31 +5,35 @@ from generated market data.
5
5
  """
6
6
 
7
7
  from importlib.metadata import version
8
+ from pathlib import Path
8
9
 
9
10
  from .. import _PKG_NAME # noqa: TID252
10
11
 
11
12
  __version__ = version(_PKG_NAME)
12
13
 
13
- import enum
14
- from collections.abc import Mapping, Sequence
14
+ from collections.abc import Sequence
15
+ from contextlib import suppress
15
16
  from dataclasses import fields
16
- from typing import Any, Literal, TypeAlias
17
+ from typing import Literal, TypeAlias, TypedDict
17
18
 
18
19
  import numpy as np
19
20
  import tables as ptb # type: ignore
20
- from attr import define, evolve, field, validators
21
+ from attrs import evolve
22
+ from attrs import fields as attrs_fields
21
23
  from joblib import Parallel, cpu_count, delayed # type: ignore
22
24
  from numpy.random import SeedSequence
23
25
  from numpy.typing import NDArray
24
26
 
25
- from ..core import guidelines_standards as gsl # noqa: TID252
27
+ from ..core import guidelines_boundaries as gbl # noqa: TID252
26
28
  from . import (
27
29
  EMPTY_ARRAY_DEFAULT,
28
- FCOUNT_WTS_DEFAULT,
29
30
  DataclassInstance,
31
+ INVResolution,
30
32
  MarketDataSample,
31
33
  MarketSampleSpec,
32
34
  RECConstants,
35
+ UPPAggrSelector,
36
+ UPPTestRegime,
33
37
  UPPTestsCounts,
34
38
  UPPTestsRaw,
35
39
  )
@@ -39,46 +43,21 @@ from . import investigations_stats as isl
39
43
  ptb.parameters.MAX_NUMEXPR_THREADS = 8
40
44
  ptb.parameters.MAX_BLOSC_THREADS = 4
41
45
 
42
- SaveData: TypeAlias = Literal[False] | tuple[Literal[True], ptb.File, str]
46
+ SaveData: TypeAlias = Literal[False] | tuple[Literal[True], ptb.File, ptb.Group]
43
47
 
44
48
 
45
- @enum.unique
46
- class UPPAggrSelector(enum.StrEnum):
47
- """
48
- Aggregator selection for GUPPI and diversion ratio
49
-
50
- """
51
-
52
- AVG = "average"
53
- CPA = "cross-product-share-weighted average"
54
- CPD = "cross-product-share-weighted distance"
55
- DIS = "symmetrically-weighted distance"
56
- MAX = "max"
57
- MIN = "min"
58
- OSA = "own-share-weighted average"
59
- OSD = "own-share-weighted distance"
60
-
61
-
62
- @define(slots=True, frozen=True)
63
- class UPPTestRegime:
64
- resolution: isl.PolicySelector = field( # type: ignore
65
- default=isl.PolicySelector.ENFT,
66
- validator=validators.instance_of(isl.PolicySelector), # type: ignore
67
- )
68
- primary_aggregator: UPPAggrSelector = field( # type: ignore
69
- default=UPPAggrSelector.MAX,
70
- validator=validators.instance_of(UPPAggrSelector | None), # type: ignore
71
- )
72
- secondary_aggregator: UPPAggrSelector | None = field( # type: ignore
73
- default=primary_aggregator,
74
- validator=validators.instance_of(UPPAggrSelector | None), # type: ignore
75
- )
49
+ class IVNRESCntsArgs(TypedDict, total=False):
50
+ sim_test_regime: UPPTestRegime
51
+ saved_array_name_suffix: str
52
+ save_data_to_file: SaveData
53
+ seed_seq_list: SeedSequence
54
+ num_threads: int
76
55
 
77
56
 
78
57
  def sim_invres_cnts_ll(
79
- _invres_parm_vec: gsl.GuidelinesSTD,
58
+ _invres_parm_vec: gbl.HMGThresholds,
80
59
  _mkt_sample_spec: MarketSampleSpec,
81
- _sim_invres_cnts_kwargs: Mapping[str, Any],
60
+ _sim_invres_cnts_kwargs: IVNRESCntsArgs,
82
61
  /,
83
62
  ) -> UPPTestsCounts:
84
63
  """
@@ -125,23 +104,23 @@ def sim_invres_cnts_ll(
125
104
  zip(*[g.spawn(_iter_count) for g in _sseql], strict=True) # type: ignore
126
105
  )
127
106
 
128
- _sim_invres_cnts_ll_kwargs = {
107
+ _sim_invres_cnts_ll_kwargs: IVNRESCntsArgs = { # type: ignore
129
108
  _k: _v
130
109
  for _k, _v in _sim_invres_cnts_kwargs.items()
131
110
  if _k != "seed_seq_list"
132
111
  }
133
112
  else:
134
- _sim_invres_cnts_ll_kwargs = {}
113
+ _sim_invres_cnts_ll_kwargs: IVNRESCntsArgs = {}
135
114
 
136
115
  _res_list = Parallel(n_jobs=_thread_count, prefer="threads")(
137
116
  delayed(sim_invres_cnts)(
138
117
  _invres_parm_vec,
139
118
  _mkt_sample_spec_here,
140
119
  **_sim_invres_cnts_ll_kwargs,
141
- saved_array_name_suffix=f"{_thread_id:0{int(np.ceil(np.log10(_thread_count)))}d}",
120
+ saved_array_name_suffix=f"{_iter_id:0{2 + int(np.ceil(np.log10(_iter_count)))}d}",
142
121
  seed_seq_list=_rng_seed_seq_list_ch,
143
122
  )
144
- for _thread_id, _rng_seed_seq_list_ch in enumerate(_rng_seed_seq_list)
123
+ for _iter_id, _rng_seed_seq_list_ch in enumerate(_rng_seed_seq_list)
145
124
  )
146
125
 
147
126
  _res_list_stacks = UPPTestsCounts(*[
@@ -161,7 +140,7 @@ def sim_invres_cnts_ll(
161
140
 
162
141
 
163
142
  def sim_invres_cnts(
164
- _upp_test_parms: gsl.GuidelinesSTD,
143
+ _upp_test_parms: gbl.HMGThresholds,
165
144
  _mkt_sample_spec: MarketSampleSpec,
166
145
  /,
167
146
  *,
@@ -202,34 +181,36 @@ def sim_invres_cnts(
202
181
  )
203
182
  del _market_data
204
183
 
205
- # Clearance/enforcement counts --- by firm count
206
184
  _stats_rowlen = 6
207
- _firm_counts_weights: NDArray[np.float64 | np.int64] = (
208
- FCOUNT_WTS_DEFAULT
209
- if _mkt_sample_spec.share_spec.firm_counts_weights is None
210
- else _mkt_sample_spec.share_spec.firm_counts_weights
211
- )
212
- _max_firm_count = len(_firm_counts_weights)
185
+ # Clearance/enforcement counts --- by firm count
186
+ _firm_counts_weights = _mkt_sample_spec.share_spec.firm_counts_weights
187
+ if _firm_counts_weights is not None and np.all(_firm_counts_weights >= 0):
188
+ _max_firm_count = len(_firm_counts_weights)
213
189
 
214
- _invres_cnts_sim_byfirmcount_array = -1 * np.ones(_stats_rowlen, np.int64)
215
- for _firm_cnt in 2 + np.arange(_max_firm_count):
216
- _firm_count_test = _fcounts == _firm_cnt
190
+ _invres_cnts_sim_byfirmcount_array = -1 * np.ones(_stats_rowlen, np.int64)
191
+ for _firm_cnt in 2 + np.arange(_max_firm_count):
192
+ _firm_count_test = _fcounts == _firm_cnt
217
193
 
218
- _invres_cnts_sim_byfirmcount_array = np.row_stack((
219
- _invres_cnts_sim_byfirmcount_array,
220
- np.array([
221
- _firm_cnt,
222
- np.einsum("ij->", 1 * _firm_count_test),
223
- *[
224
- np.einsum(
225
- "ij->",
226
- 1 * (_firm_count_test & getattr(_upp_tests_data, _f.name)),
227
- )
228
- for _f in fields(_upp_tests_data)
229
- ],
230
- ]),
231
- ))
232
- _invres_cnts_sim_byfirmcount_array = _invres_cnts_sim_byfirmcount_array[1:]
194
+ _invres_cnts_sim_byfirmcount_array = np.row_stack((
195
+ _invres_cnts_sim_byfirmcount_array,
196
+ np.array([
197
+ _firm_cnt,
198
+ np.einsum("ij->", 1 * _firm_count_test),
199
+ *[
200
+ np.einsum(
201
+ "ij->",
202
+ 1 * (_firm_count_test & getattr(_upp_tests_data, _f.name)),
203
+ )
204
+ for _f in fields(_upp_tests_data)
205
+ ],
206
+ ]),
207
+ ))
208
+ _invres_cnts_sim_byfirmcount_array = _invres_cnts_sim_byfirmcount_array[1:]
209
+ else:
210
+ _invres_cnts_sim_byfirmcount_array = np.array(
211
+ np.nan * np.empty((1, _stats_rowlen)), np.int64
212
+ )
213
+ _invres_cnts_sim_byfirmcount_array[0] = 2
233
214
 
234
215
  # Clearance/enfrocement counts --- by delta
235
216
  _hhi_delta_ranged = isl.hhi_delta_ranger(_hhi_delta)
@@ -303,7 +284,7 @@ def sim_invres_cnts(
303
284
 
304
285
 
305
286
  def gen_upp_arrays(
306
- _upp_test_parms: gsl.GuidelinesSTD,
287
+ _upp_test_parms: gbl.HMGThresholds,
307
288
  _market_data: MarketDataSample,
308
289
  _sim_test_regime: UPPTestRegime,
309
290
  /,
@@ -317,7 +298,7 @@ def gen_upp_arrays(
317
298
 
318
299
  _invres_resolution, _guppi_aggregator, _divr_aggregator = (
319
300
  getattr(_sim_test_regime, _f)
320
- for _f in ("resolution", "primary_aggregator", "secondary_aggregator")
301
+ for _f in ("resolution", "guppi_aggregator", "divr_aggregator")
321
302
  )
322
303
 
323
304
  _guppi_array = np.empty_like(_market_data.divr_array)
@@ -410,7 +391,7 @@ def gen_upp_arrays(
410
391
  if _divr_aggregator == UPPAggrSelector.MAX:
411
392
  _divr_test_vector = _market_data.divr_array.max(axis=1, keepdims=True)
412
393
 
413
- if _invres_resolution == isl.PolicySelector.ENFT:
394
+ if _invres_resolution == INVResolution.ENFT:
414
395
  _upp_tests_data = UPPTestsRaw(
415
396
  _guppi_test_vector >= _g_bar,
416
397
  (_guppi_test_vector >= _g_bar) | (_divr_test_vector >= _divr_bar),
@@ -436,52 +417,67 @@ def gen_upp_arrays(
436
417
  return _upp_tests_data
437
418
 
438
419
 
420
+ def initialize_hd5(
421
+ _h5_path: Path, _hmg_pub_year: gbl.HMGPubYear, _test_regime: UPPTestRegime, /
422
+ ) -> tuple[SaveData, str]:
423
+ _h5_title = f"HMG version: {_hmg_pub_year}; Test regime: {_test_regime}"
424
+ if _h5_path.is_file():
425
+ _h5_path.unlink()
426
+ _h5_file = ptb.open_file(_h5_path, mode="w", title=_h5_title)
427
+ _save_data_to_file: tuple[Literal[True], ptb.File, str] = (True, _h5_file, "/")
428
+ _next_subgroup_name = "invres_{}_{}_{}_{}".format(
429
+ _hmg_pub_year,
430
+ *(
431
+ getattr(_test_regime, _f.name).name
432
+ for _f in attrs_fields(type(_test_regime))
433
+ ),
434
+ )
435
+ return _save_data_to_file, _next_subgroup_name
436
+
437
+
439
438
  def save_data_to_hdf5(
440
439
  _dclass: DataclassInstance,
441
- _saved_array_name_suffix: str,
440
+ _saved_array_name_suffix: str = "",
442
441
  _excl_attrs: Sequence[str] = (),
443
442
  /,
444
443
  *,
445
444
  save_data_to_file: SaveData = False,
446
445
  ) -> None:
447
446
  if save_data_to_file:
448
- _, _h5_datafile, _h5_hier = save_data_to_file
447
+ _, _h5_file, _h5_group = save_data_to_file
449
448
  # Save market data arrays
450
- for _array_name in fields(_dclass):
451
- if _excl_attrs and _array_name in _excl_attrs:
452
- pass
453
- save_to_hdf(
454
- _dclass,
455
- _array_name.name,
456
- _h5_datafile,
457
- _h5_hier,
449
+ for _array_field in fields(_dclass):
450
+ _array_name = _array_field.name
451
+ if _array_name in _excl_attrs:
452
+ continue
453
+ save_array_to_hdf5(
454
+ getattr(_dclass, _array_name),
455
+ _array_name,
456
+ _h5_group,
457
+ _h5_file,
458
458
  saved_array_name_suffix=_saved_array_name_suffix,
459
459
  )
460
460
 
461
461
 
462
- def save_to_hdf(
463
- _dclass: DataclassInstance,
462
+ def save_array_to_hdf5(
463
+ _array_obj: NDArray[np.floating | np.integer | np.bool_],
464
464
  _array_name: str,
465
- _h5_datafile: ptb.File,
466
- _h5_hier: str,
465
+ _h5_group: ptb.Group,
466
+ _h5_file: ptb.File,
467
467
  /,
468
468
  *,
469
469
  saved_array_name_suffix: str | None = None,
470
470
  ) -> None:
471
- _data_array = getattr(_dclass, _array_name)
472
- _h5_array_name = (
473
- f"{_array_name}_{saved_array_name_suffix}"
474
- if saved_array_name_suffix
475
- else _array_name
476
- )
477
- print(
478
- f"PyTables: Now saving array, {_h5_array_name!r}, at node, {f'"{_h5_hier}"'}."
479
- )
480
- _h5_array = _h5_datafile.create_carray(
481
- _h5_hier,
471
+ _h5_array_name = f"{_array_name}_{saved_array_name_suffix or ""}".rstrip("_")
472
+
473
+ with suppress(ptb.NoSuchNodeError):
474
+ _h5_file.remove_node(_h5_group, name=_array_name)
475
+
476
+ _h5_array = ptb.CArray(
477
+ _h5_group,
482
478
  _h5_array_name,
483
- obj=_data_array,
484
- createparents=True,
485
- title=f"{_array_name})",
479
+ atom=ptb.Atom.from_dtype(_array_obj.dtype),
480
+ shape=_array_obj.shape,
481
+ filters=ptb.Filters(complevel=3, complib="blosc:lz4hc", fletcher32=True),
486
482
  )
487
- _h5_array[:] = _data_array
483
+ _h5_array[:] = _array_obj
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mergeron
3
- Version: 2024.738940.0
3
+ Version: 2024.738949.0
4
4
  Summary: Analysis of standards defined in Horizontal Merger Guidelines
5
5
  License: MIT
6
6
  Keywords: merger policy analysis,merger guidelines,merger screening,policy presumptions,concentration standards,upward pricing pressure,GUPPI
@@ -18,7 +18,6 @@ Classifier: Programming Language :: Python :: 3
18
18
  Classifier: Programming Language :: Python :: 3.12
19
19
  Classifier: Programming Language :: Python :: 3 :: Only
20
20
  Classifier: Programming Language :: Python :: Implementation :: CPython
21
- Requires-Dist: aenum (>=3.1)
22
21
  Requires-Dist: attrs (>=23.2)
23
22
  Requires-Dist: bs4 (>=0.0.1)
24
23
  Requires-Dist: certifi (>=2023.11.17)
@@ -28,13 +27,11 @@ Requires-Dist: jinja2 (>=3.1)
28
27
  Requires-Dist: joblib (>=1.3)
29
28
  Requires-Dist: lxml (>=5.0)
30
29
  Requires-Dist: matplotlib (>=3.8)
31
- Requires-Dist: mkl (==2023.2)
32
30
  Requires-Dist: mpmath (>=1.3)
33
31
  Requires-Dist: msgpack (>=1.0)
34
32
  Requires-Dist: msgpack-numpy (>=0.4)
35
33
  Requires-Dist: numpy (>=1.26)
36
34
  Requires-Dist: openpyxl (>=3.1.2)
37
- Requires-Dist: pyarrow (>=15.0)
38
35
  Requires-Dist: pymupdf (>=1.23)
39
36
  Requires-Dist: requests (>=2.31)
40
37
  Requires-Dist: requests-toolbelt (>=1.0.0)
@@ -61,7 +58,7 @@ Routines for downloading and organizing FTC merger investigtions data published
61
58
 
62
59
  Routines for plotting boundaries of (sets of mergers falling within) specified concentration and diversion ratio boundaries and for calibrating GUPPI thresholds to concentration (ΔHHI) thresholds, and vice-versa.
63
60
 
64
- mergeron.core.guidelines_standards
61
+ mergeron.core.guidelines_boundaries
65
62
 
66
63
  Routines for generating industry data under various distributions of shares, prices, and margins. The user can specify whether rates are specified as, "proportional", "inside-out" (i.e., consistent with merging-firms' in-market shares and a default recapture rate), or "outside-in", (i.e., purchase probabilities are 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). Price-cost-margins may be specified as symmetric, i.i.d, or consistent with equilibrium conditions for (profit-mazimization in) Bertrand-Nash oligopoly with MNL demand. 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. Two alternative approaches for modeling statutory filing requirements (HSR filing thresholds) are implemented.
67
64
 
@@ -0,0 +1,42 @@
1
+ mergeron/License.txt,sha256=csSkn4lgUmJ0VEw1KAFZ3a8q0L4XccUdJ6Jj6xSNNRY,1246
2
+ mergeron/__init__.py,sha256=gk_2mS6jdui5fVmVHHfZVaEG9LyO3vfRATnES29ajRA,398
3
+ mergeron/core/InCommon RSA Server CA cert chain.pem,sha256=W8TqydgY8jphQ4fr6WMdT6jLwqFjHLpx8fFr3LXub4s,4292
4
+ mergeron/core/__init__.py,sha256=iyfxkX3-SoMS4ZQZKHKPn8JEMN536vpty9oSZf0LHv8,115
5
+ mergeron/core/damodaran_margin_data.py,sha256=N1SU_PDjFMoCzCqone-If-gR4PpcG-MK5TfayusOJLs,8166
6
+ mergeron/core/excel_helper.py,sha256=_TkoWMPB4MZSVcP6qzqwqWWHcxHFrJu7prMbIArC98w,8079
7
+ mergeron/core/ftc_merger_investigations_data.py,sha256=8Zn-kbEg6J6R-qkpkkq-8kBHJt7QbGcRPn9hpjgFfP4,26761
8
+ mergeron/core/guidelines_boundaries.py,sha256=uWQUoVn2SCL-4cCTUkEPfeMTmFpIHLfMXFMTPNV0mqA,44733
9
+ mergeron/core/proportions_tests.py,sha256=YER1RTLSTSyNbP4ZUkvUWTViUv4lxlnRCCKuC6HbWXI,15320
10
+ mergeron/core/pseudorandom_numbers.py,sha256=ZnIE1ixp3JcgJjlulgMsIcWFVAxeyjC9lsiMIk7OHlM,9430
11
+ mergeron/examples/__init__.py,sha256=iyfxkX3-SoMS4ZQZKHKPn8JEMN536vpty9oSZf0LHv8,115
12
+ mergeron/examples/concentration_as_diversion.py,sha256=p9-VzqC8Tb3fMJD1mLnqmMnvOCrCTULjIPCEG0RhASQ,20645
13
+ mergeron/examples/enforcement_boundaries_for_mergers_with_asymmetric_shares.py,sha256=-jOHETKp788pqKTv7U25t28UzVtJNMmUn1FVH7jCiCU,16020
14
+ mergeron/examples/enforcement_boundaries_for_symmetric_firm_mergers.py,sha256=DAljm5NJquE56f-x4pLXzKCdhYQyVpWaM8uGlD6rIEs,5779
15
+ mergeron/examples/example_parameterizations.py,sha256=VP-hi7L0j30ffcEzmJ3P8mOj1VjwEWKCTZSx_CaVQxA,4197
16
+ mergeron/examples/guidelines_enforcement_patterns.py,sha256=iHGUaWCidVwIywI60ZNB4AnvzpTe60az1H7AzB3ddl0,2255
17
+ mergeron/examples/investigations_stats_obs_tables.py,sha256=WP38WWjLEn1JHKutaGLa-f5pmoePYgGfzc6vrYZ9of4,17827
18
+ mergeron/examples/investigations_stats_sim_tables.py,sha256=ND3eKEm7h9L9B4MRUMk98CBBuZ5gd6CE-S2iHxeErIQ,14917
19
+ mergeron/examples/plotSafeHarbs_symbolically.py,sha256=S-F1q0OouQCWE0t5XS-jmJaZcAHq7E0q2rsn-ewSTQI,1528
20
+ mergeron/examples/sound_guppi_safeharbor.py,sha256=mclCHLgBJOSPIxyWaxdfh3RdRVhmBhDhVwuKWNVn-XE,6085
21
+ mergeron/examples/summarize_ftc_investigations_data.py,sha256=447vtwlAsfc3Po8wFcKRHC4Ur-zvKc5dwBjtu4M49ig,1360
22
+ mergeron/examples/testIntrinsicClearanceRates.py,sha256=T0-6m-SEPVy-mY8gZY2HlJO4ncBa47r87bERhhANLFs,5378
23
+ mergeron/examples/visualize_empirical_margin_distribution.py,sha256=eMTWgNJ1eSTZBgwojZXAYMfuzgMGM2UU999axNjBip4,2918
24
+ mergeron/examples/visualize_guidelines_tests.py,sha256=VE3aotuFOsU-CSt4SymRG8_iVfIHPgrxVFRB7B1hCyI,9365
25
+ mergeron/ext/__init__.py,sha256=iyfxkX3-SoMS4ZQZKHKPn8JEMN536vpty9oSZf0LHv8,115
26
+ mergeron/ext/tol_colors.py,sha256=wFOHZXWZonbp9mhmSGu9mVujBYhdTsvx9_WikMpoCmo,22229
27
+ mergeron/gen/__init__.py,sha256=MxjGj4bHklt6R-Xc-iT46pgK4XZNlcMDErnlF3jA7LU,16787
28
+ mergeron/gen/_data_generation_functions_nonpublic.py,sha256=fQu-CEfjdHeCod-6nrejpXAvV1dTG6H4bZBTXVd5j9s,21370
29
+ mergeron/gen/data_generation.py,sha256=52youq5pmg-cuJo9tefy8Kab4_fyWgmQrFrazIqHnGg,8868
30
+ mergeron/gen/investigations_stats.py,sha256=ByLTr3rkvGjKxoOkBvB74WTugvilE1lLEP67OYhDWMs,22815
31
+ mergeron/gen/upp_tests.py,sha256=0qytw39LIDfSR_aS-wpu7NikNfcnlos9EYQaLgkCQZg,16188
32
+ mergeron/jinja_LaTex_templates/clrrate_cis_summary_table_template.tex.jinja2,sha256=ae4JiciU-pt8YAM8mRbsmt4W6ePuN1y1NPCWD95oXIo,4833
33
+ mergeron/jinja_LaTex_templates/ftcinvdata_byhhianddelta_table_template.tex.jinja2,sha256=ODEurkC0UHuWpjRUiQpeW85njSeUEUJYRdYg8gqoEq0,3642
34
+ mergeron/jinja_LaTex_templates/ftcinvdata_summary_table_template.tex.jinja2,sha256=h8_DEE0iskT9tnga5lZtxcoevN7pY4iKF-maErt4UU4,2906
35
+ mergeron/jinja_LaTex_templates/ftcinvdata_summarypaired_table_template.tex.jinja2,sha256=Ox0ctiyW_hoOPzoWskOpuygomuV6XWhLeLo40KGRy2U,5224
36
+ mergeron/jinja_LaTex_templates/mergeron.cls,sha256=AV2mk4-uERvAuMkE95Ka7el6LZsb0JZKP4ieiNCnfMU,4562
37
+ mergeron/jinja_LaTex_templates/mergeron_table_collection_template.tex.jinja2,sha256=nr6xUI0_2KHG4Sz9k1JFVQjs2h9qS9BGt1MeE6Tygs8,2429
38
+ mergeron/jinja_LaTex_templates/setup_tikz_tables.tex.jinja2,sha256=WKVxtp3eoMchfGliQAJMj4w2FtBkWG5z2V3-hBYUYUQ,3292
39
+ mergeron/py.typed,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
40
+ mergeron-2024.738949.0.dist-info/METADATA,sha256=frwPeN3n7LB93DCX30amODqFJyAfwNbX5ErHWbU9rY4,6362
41
+ mergeron-2024.738949.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
42
+ mergeron-2024.738949.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.8.1
2
+ Generator: poetry-core 1.9.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,42 +0,0 @@
1
- mergeron/License.txt,sha256=csSkn4lgUmJ0VEw1KAFZ3a8q0L4XccUdJ6Jj6xSNNRY,1246
2
- mergeron/__init__.py,sha256=gk_2mS6jdui5fVmVHHfZVaEG9LyO3vfRATnES29ajRA,398
3
- mergeron/core/InCommon RSA Server CA cert chain.pem,sha256=W8TqydgY8jphQ4fr6WMdT6jLwqFjHLpx8fFr3LXub4s,4292
4
- mergeron/core/__init__.py,sha256=iyfxkX3-SoMS4ZQZKHKPn8JEMN536vpty9oSZf0LHv8,115
5
- mergeron/core/damodaran_margin_data.py,sha256=N1SU_PDjFMoCzCqone-If-gR4PpcG-MK5TfayusOJLs,8166
6
- mergeron/core/excel_helper.py,sha256=Sf0EPQ18UNG_sxa4c2iqcJyP0aNc5sYedn8oetQ1S5o,7539
7
- mergeron/core/ftc_merger_investigations_data.py,sha256=C37gFwSSgUFu98FW8ZDlUTgEaz4qYa1aKPC3SPtXChU,26553
8
- mergeron/core/guidelines_standards.py,sha256=EgwUjutfegZGg_P42hk1dmHJwfE0D0TxLySKgPUXZ7Y,44576
9
- mergeron/core/proportions_tests.py,sha256=zALaWNrGOltsCp2ZSP4pcUfrOCaOoR5YDavqxQHADKA,15275
10
- mergeron/core/pseudorandom_numbers.py,sha256=ZnIE1ixp3JcgJjlulgMsIcWFVAxeyjC9lsiMIk7OHlM,9430
11
- mergeron/examples/__init__.py,sha256=iyfxkX3-SoMS4ZQZKHKPn8JEMN536vpty9oSZf0LHv8,115
12
- mergeron/examples/concentration_as_diversion.py,sha256=RqUkF5N-uBKb3VdiuOeSAqStdPScint1BPruj5uD84c,20575
13
- mergeron/examples/example_parameterizations.py,sha256=VP-hi7L0j30ffcEzmJ3P8mOj1VjwEWKCTZSx_CaVQxA,4197
14
- mergeron/examples/guidelines_enforcement_patterns.py,sha256=gpAW9jLLg3bbf4ueCu71QUKIca_eb3tTtAuTwY14m3c,2235
15
- mergeron/examples/investigations_stats_obs_tables.py,sha256=IDUZqZHiNvyO05d-yaYUJ_3-G_tchA4Z4MTaEICV9g0,17801
16
- mergeron/examples/investigations_stats_sim_tables.py,sha256=Qb7SiFZuDQVt1aBzl8lS5XnzDkOaUtPgWcgSZm6xXh8,15537
17
- mergeron/examples/plotSafeHarbs_symbolically.py,sha256=PgBQ6MMapE5LYHpvR_0iuMCuRPpK-dSea493mT2kU-o,1527
18
- mergeron/examples/safeharbor_boundaries_for_mergers_with_asymmetric_shares.py,sha256=HWVb-B3R4e0E2Ozt7LGYPzUGjAOsYV_doFPsmTeCqL0,15594
19
- mergeron/examples/safeharbor_boundaries_for_symmetric_firm_mergers.py,sha256=1hnG-MaE7e8wI2-R21oBcBZT8iKwYlr8ljqU4bbQmHg,5778
20
- mergeron/examples/sound_guppi_safeharbor.py,sha256=E66B7kp-CT9aS7uSaTsFo3zeGOWNAXo-XECoRLOqwsg,5818
21
- mergeron/examples/summarize_ftc_investigations_data.py,sha256=gdArFnmiX08RHPu1uns3tUI4HlRORzaP4a3QfJd4n8o,1356
22
- mergeron/examples/testIntrinsicClearanceRates.py,sha256=T0-6m-SEPVy-mY8gZY2HlJO4ncBa47r87bERhhANLFs,5378
23
- mergeron/examples/visualize_empirical_margin_distribution.py,sha256=lBA38XVqiI7NsEtO--C37azrMRjzOVi1Fm5-_QV4DAk,2901
24
- mergeron/examples/visualize_guidelines_tests.py,sha256=AiTZq-eBmbfszaYiAInZLSoO6FCM4M0YEjuxIFwqZ6s,9216
25
- mergeron/ext/__init__.py,sha256=iyfxkX3-SoMS4ZQZKHKPn8JEMN536vpty9oSZf0LHv8,115
26
- mergeron/ext/tol_colors.py,sha256=wFOHZXWZonbp9mhmSGu9mVujBYhdTsvx9_WikMpoCmo,22229
27
- mergeron/gen/__init__.py,sha256=ClrPKh2Bhe4_zGcBYGJkMff-XDZo1VNkq3oVQPLB334,15119
28
- mergeron/gen/_data_generation_functions_nonpublic.py,sha256=V-PC75Ye_tujPaXaCqXWvgffDh94DMoR2ShhlSQWJtw,21365
29
- mergeron/gen/data_generation.py,sha256=dGEwt_GGToOIY4jhsRzva_1OS2Zff4nmkldn9UxLEHM,8917
30
- mergeron/gen/guidelines_tests.py,sha256=jJ1YAWcBhnGzR7pC0vjzGEsxqAsb2WTix8g6KGkd130,15971
31
- mergeron/gen/investigations_stats.py,sha256=5eKFzLAzjtGL76MOEtnGcZI_d0fiKi66qLBxPUp8WWs,22896
32
- mergeron/jinja_LaTex_templates/clrrate_cis_summary_table_template.tex.jinja2,sha256=ae4JiciU-pt8YAM8mRbsmt4W6ePuN1y1NPCWD95oXIo,4833
33
- mergeron/jinja_LaTex_templates/ftcinvdata_byhhianddelta_table_template.tex.jinja2,sha256=ODEurkC0UHuWpjRUiQpeW85njSeUEUJYRdYg8gqoEq0,3642
34
- mergeron/jinja_LaTex_templates/ftcinvdata_summary_table_template.tex.jinja2,sha256=h8_DEE0iskT9tnga5lZtxcoevN7pY4iKF-maErt4UU4,2906
35
- mergeron/jinja_LaTex_templates/ftcinvdata_summarypaired_table_template.tex.jinja2,sha256=Ox0ctiyW_hoOPzoWskOpuygomuV6XWhLeLo40KGRy2U,5224
36
- mergeron/jinja_LaTex_templates/mergeron.cls,sha256=AV2mk4-uERvAuMkE95Ka7el6LZsb0JZKP4ieiNCnfMU,4562
37
- mergeron/jinja_LaTex_templates/mergeron_table_collection_template.tex.jinja2,sha256=nr6xUI0_2KHG4Sz9k1JFVQjs2h9qS9BGt1MeE6Tygs8,2429
38
- mergeron/jinja_LaTex_templates/setup_tikz_tables.tex.jinja2,sha256=WKVxtp3eoMchfGliQAJMj4w2FtBkWG5z2V3-hBYUYUQ,3292
39
- mergeron/py.typed,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
40
- mergeron-2024.738940.0.dist-info/METADATA,sha256=snMq9DvwPjDmZgQlLDhksCUUbhIqxYwq4J_hPJEaUkQ,6452
41
- mergeron-2024.738940.0.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
42
- mergeron-2024.738940.0.dist-info/RECORD,,