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
@@ -11,45 +11,53 @@ with the larger GUPPI estimate.
11
11
  from __future__ import annotations
12
12
 
13
13
  import gc
14
- from contextlib import suppress
15
14
  from dataclasses import fields
16
15
  from pathlib import Path
17
16
  from typing import Final
18
17
 
19
18
  import numpy as np
20
- import tables as ptb # type: ignore
21
19
  from matplotlib import cm, colors
22
20
  from matplotlib.ticker import StrMethodFormatter
23
21
  from numpy.typing import NDArray
24
22
 
25
- import mergeron.core.guidelines_standards as gsl
23
+ import mergeron.core.guidelines_boundaries as gbl
26
24
  import mergeron.gen.data_generation as dgl
27
- import mergeron.gen.guidelines_tests as gtl
28
- import mergeron.gen.investigations_stats as isl
25
+ import mergeron.gen.upp_tests as utl
29
26
  from mergeron import DATA_DIR
30
27
  from mergeron.core.pseudorandom_numbers import DIST_PARMS_DEFAULT
31
- from mergeron.gen import ShareSpec
28
+ from mergeron.gen import (
29
+ INVResolution,
30
+ MarketDataSample,
31
+ MarketSampleSpec,
32
+ RECConstants,
33
+ ShareSpec,
34
+ SHRConstants,
35
+ UPPAggrSelector,
36
+ UPPTestRegime,
37
+ )
32
38
 
33
39
  PROG_PATH = Path(__file__)
34
40
 
35
41
 
36
- blosc_filters = ptb.Filters(
37
- complevel=3, complib="blosc:lz4", bitshuffle=True, fletcher32=True
38
- )
39
-
40
-
41
42
  def gen_plot_data(
42
- _market_data: dgl.MarketDataSample,
43
- _std_vec: gsl.GuidelinesSTD,
43
+ _market_data: MarketDataSample,
44
+ _std_vec: gbl.HMGThresholds,
44
45
  _pcm_firm2_star: float,
45
- _test_regime: gtl.UPPTestRegime,
46
+ _test_regime: UPPTestRegime,
46
47
  /,
47
48
  *,
48
- h5handle: ptb.File | None = None,
49
+ save_data_to_file: utl.SaveData = False,
49
50
  ) -> tuple[NDArray[np.float64], NDArray[np.float64], NDArray[np.float64]]:
50
- _h5hier = "/plotData_mstar{}PCT".format(
51
- f"{_pcm_firm2_star * 100:03.1f}".replace(".", "dot")
52
- )
51
+ if save_data_to_file:
52
+ _, _h5_file, _h5_hier = save_data_to_file
53
+ _h5_hier = _h5_file.create_group(
54
+ _h5_hier,
55
+ "plotData_mstar{}PCT".format(
56
+ f"{_pcm_firm2_star * 100:03.1f}".replace(".", "dot")
57
+ ),
58
+ title=f"Firm 2 margin = {_pcm_firm2_star * 100:03.1f}%",
59
+ )
60
+ save_data_to_file = (True, _h5_file, _h5_hier)
53
61
 
54
62
  _pcm_array = np.column_stack((
55
63
  _m1 := _market_data.pcm_array[:, [0]],
@@ -57,12 +65,10 @@ def gen_plot_data(
57
65
  ))
58
66
  del _m1
59
67
 
60
- _upp_test_raw = gtl.gen_upp_arrays(
68
+ _upp_test_raw = utl.gen_upp_arrays(
61
69
  _std_vec,
62
- dgl.MarketDataSample(*[
63
- _pcm_array.astype(_f.type)
64
- if _f.name == "pcm_array"
65
- else getattr(_market_data, _f.name)
70
+ MarketDataSample(*[ # type: ignore
71
+ _pcm_array if _f.name == "pcm_array" else getattr(_market_data, _f.name)
66
72
  for _f in fields(_market_data)
67
73
  ]),
68
74
  _test_regime,
@@ -83,7 +89,7 @@ def gen_plot_data(
83
89
 
84
90
  _pcm_plotter = _pcm_firm1_inv
85
91
 
86
- if h5handle:
92
+ if save_data_to_file:
87
93
  print("Save data to tables")
88
94
  for _array_name in (
89
95
  "qtyshr_firm1_inv",
@@ -91,18 +97,14 @@ def gen_plot_data(
91
97
  "pcm_firm1_inv",
92
98
  "pcm_firm2_inv",
93
99
  ):
94
- with suppress(ptb.NoSuchNodeError):
95
- h5handle.remove_node(_h5hier, name=_array_name)
96
- _array_h5 = h5handle.create_carray(
97
- _h5hier,
98
- _array_name,
99
- obj=locals().get(f"_{_array_name}"),
100
- createparents=True,
101
- title=f"{_array_name}",
102
- )
100
+ _array_obj: NDArray[any] = locals().get(f"_{_array_name}") # type: ignore
101
+ if np.any(_array_obj):
102
+ utl.save_array_to_hdf5(
103
+ _array_obj, _array_name, save_data_to_file[-1], save_data_to_file[1]
104
+ )
103
105
 
104
106
  _pcm_sorter = np.argsort(_pcm_plotter, axis=0)
105
- if test_regime.resolution != isl.PolicySelector.CLRN:
107
+ if test_regime.resolution != INVResolution.CLRN:
106
108
  _pcm_sorter = _pcm_sorter[::-1, :]
107
109
  _qtyshr_firm1_plotter = _qtyshr_firm1_inv[_pcm_sorter]
108
110
  _qtyshr_firm2_plotter = _qtyshr_firm2_inv[_pcm_sorter]
@@ -121,19 +123,19 @@ def gen_plot_data(
121
123
 
122
124
  # Generate market data
123
125
  def _main(
124
- _hmg_pub_year: gsl.HMGPubYear,
125
- _market_sample_spec: dgl.MarketSampleSpec,
126
- _test_regime: gtl.UPPTestRegime,
127
- _save_data_to_file: gtl.SaveData,
126
+ _hmg_pub_year: gbl.HMGPubYear,
127
+ _market_sample_spec: MarketSampleSpec,
128
+ _test_regime: UPPTestRegime,
129
+ save_data_to_file: utl.SaveData,
128
130
  ) -> None:
129
131
  guidelins_std_vec = getattr(
130
- gsl.GuidelinesStandards(_hmg_pub_year),
131
- "safeharbor"
132
- if test_regime.resolution == isl.PolicySelector.ENFT
133
- else "presumption",
132
+ gbl.GuidelinesThresholds(_hmg_pub_year),
133
+ "safeharbor" if test_regime.resolution == INVResolution.ENFT else "presumption",
134
134
  )
135
135
 
136
- _, _r_bar, _g_bar, _divr_bar, *_ = guidelins_std_vec
136
+ _r_bar, _g_bar, _divr_bar = (
137
+ getattr(guidelins_std_vec, _f) for _f in ("rec", "guppi", "divr")
138
+ )
137
139
 
138
140
  market_data = dgl.gen_market_sample(_market_sample_spec, seed_seq_list=None)
139
141
 
@@ -145,7 +147,7 @@ def _main(
145
147
  )
146
148
  _fig_norm = colors.Normalize(0.0, 1.0)
147
149
  _cmap_kwargs = {"cmap": "cividis", "norm": _fig_norm}
148
- _plt, _, _, _set_axis_def = gsl.boundary_plot()
150
+ _plt, _, _, _set_axis_def = gbl.boundary_plot()
149
151
 
150
152
  _fig_2dsg = _plt.figure(figsize=(8.5, 9.5), dpi=600)
151
153
 
@@ -204,7 +206,7 @@ def _main(
204
206
  guidelins_std_vec,
205
207
  _pcm_firm2_star,
206
208
  _test_regime,
207
- h5handle=_save_data_to_file[1] if _save_data_to_file else None,
209
+ save_data_to_file=save_data_to_file,
208
210
  )
209
211
 
210
212
  _ax_now.scatter(
@@ -255,44 +257,44 @@ def _main(
255
257
  if __name__ == "__main__":
256
258
  # Get Guidelines parameter values
257
259
  hmg_pub_year: Final = 2023
258
- test_regime: gtl.UPPTestRegime = gtl.UPPTestRegime(
259
- isl.PolicySelector.ENFT, gtl.UPPAggrSelector.MIN, gtl.UPPAggrSelector.MIN
260
+
261
+ test_regime: UPPTestRegime = UPPTestRegime(
262
+ INVResolution.ENFT, UPPAggrSelector.MIN, UPPAggrSelector.MIN
260
263
  )
264
+
261
265
  r_bar = getattr(
262
- gsl.GuidelinesStandards(hmg_pub_year),
263
- "presumption"
264
- if test_regime.resolution == isl.PolicySelector.ENFT
265
- else "safeharbor",
266
+ gbl.GuidelinesThresholds(hmg_pub_year),
267
+ "presumption" if test_regime.resolution == INVResolution.ENFT else "safeharbor",
266
268
  ).rec
267
269
 
268
270
  sample_sz = 10**7
269
271
 
270
- market_sample_spec = dgl.MarketSampleSpec(
272
+ market_sample_spec = MarketSampleSpec(
271
273
  sample_sz,
272
274
  r_bar,
273
275
  share_spec=ShareSpec(
274
- dgl.RECConstants.INOUT, dgl.SHRConstants.UNI, DIST_PARMS_DEFAULT, None
276
+ RECConstants.INOUT, SHRConstants.UNI, DIST_PARMS_DEFAULT, None
275
277
  ),
276
278
  )
277
279
 
278
- save_data_to_file_flag = False
280
+ save_data_to_file_flag = True
279
281
  if save_data_to_file_flag:
280
- h5path = DATA_DIR / PROG_PATH.with_suffix(".h5").name
281
- h5datafile = ptb.open_file(
282
- h5path,
283
- mode="w",
284
- title="Datasets, Sound GUPPI Safeharbor, Envelopes of GUPPI Boundaries",
285
- filters=blosc_filters,
286
- )
287
- save_data_to_file: gtl.SaveData = (
288
- True,
289
- h5datafile,
290
- "Intrinsic clearance stats",
282
+ h5_path = DATA_DIR / PROG_PATH.with_suffix(".h5").name
283
+ (_, h5_file, h5_group), h5_subgroup_name = utl.initialize_hd5(
284
+ h5_path, hmg_pub_year, test_regime
285
+ ) # type: ignore
286
+
287
+ h5_subgroup = h5_file.create_group(
288
+ h5_group,
289
+ h5_subgroup_name,
290
+ title=f"Market sample specifications: {market_sample_spec}",
291
291
  )
292
+ save_data_to_file: utl.SaveData = (True, h5_file, h5_subgroup)
292
293
  else:
293
294
  save_data_to_file = False
294
295
 
295
296
  _main(hmg_pub_year, market_sample_spec, test_regime, save_data_to_file)
296
297
 
297
298
  if save_data_to_file_flag:
299
+ save_data_to_file[1].flush() # type: ignore
298
300
  save_data_to_file[1].close() # type: ignore
mergeron/gen/__init__.py CHANGED
@@ -16,8 +16,8 @@ import enum
16
16
  from dataclasses import dataclass
17
17
  from typing import ClassVar, Protocol, TypeVar
18
18
 
19
- import attrs
20
19
  import numpy as np
20
+ from attrs import Attribute, define, field, validators
21
21
  from numpy.typing import NBitBase, NDArray
22
22
 
23
23
  from ..core.pseudorandom_numbers import DIST_PARMS_DEFAULT # noqa: TID252
@@ -29,14 +29,6 @@ TF = TypeVar("TF", bound=NBitBase)
29
29
  TI = TypeVar("TI", bound=NBitBase)
30
30
 
31
31
 
32
- # https://stackoverflow.com/questions/54668000
33
- class DataclassInstance(Protocol):
34
- """For type-hinting dataclass objects"""
35
-
36
- __dataclass_asdict__: ClassVar
37
- __dataclass_fields__: ClassVar
38
-
39
-
40
32
  @enum.unique
41
33
  class PRIConstants(tuple[bool, str | None], enum.ReprEnum):
42
34
  """Price specification.
@@ -91,7 +83,7 @@ class RECConstants(enum.StrEnum):
91
83
  FIXED = "proportional"
92
84
 
93
85
 
94
- @attrs.define(slots=True, frozen=True)
86
+ @define(slots=True, frozen=True)
95
87
  class ShareSpec:
96
88
  """Market share specification
97
89
 
@@ -150,7 +142,7 @@ class FM2Constants(enum.StrEnum):
150
142
  SYM = "symmetric"
151
143
 
152
144
 
153
- @attrs.define(slots=True, frozen=True)
145
+ @define(slots=True, frozen=True)
154
146
  class PCMSpec:
155
147
  """Price-cost margin (PCM) specification
156
148
 
@@ -224,18 +216,17 @@ class SSZConstants(float, enum.ReprEnum):
224
216
 
225
217
  # Validators for selected attributes of MarketSampleSpec
226
218
  def _sample_size_validator(
227
- _object: MarketSampleSpec, _attribute: attrs.Attribute, _value: int, /
219
+ _object: MarketSampleSpec, _attribute: Attribute, _value: int, /
228
220
  ) -> None:
229
- if _value < 10**6 or (_value % 10**5 != 0):
221
+ if _value < 10**6:
230
222
  raise ValueError(
231
- f"Sample size must be a multiple of {10** 4:,d} and not less than {10** 6:,d}."
223
+ f"Sample size must be not less than {10**6:,d}. Got, {_value:,d}."
232
224
  )
233
225
 
234
226
 
235
227
  def _recapture_rate_validator(
236
- _object: MarketSampleSpec, _attribute: attrs.Attribute, _value: float | None, /
228
+ _object: MarketSampleSpec, _attribute: Attribute, _value: float | None, /
237
229
  ) -> None:
238
- # if _value < 10**6 or (np.log10(_value) % 1 != 0):
239
230
  if _value and not (0 < _value <= 1):
240
231
  raise ValueError("Recapture rate must lie in the interval, [0, 1).")
241
232
 
@@ -247,7 +238,7 @@ def _recapture_rate_validator(
247
238
 
248
239
 
249
240
  def _share_spec_validator(
250
- _instance: MarketSampleSpec, _attribute: attrs.Attribute, _value: ShareSpec, /
241
+ _instance: MarketSampleSpec, _attribute: Attribute, _value: ShareSpec, /
251
242
  ) -> None:
252
243
  _r_bar = _instance.recapture_rate
253
244
  if _value.dist_type == SHRConstants.UNI:
@@ -278,7 +269,7 @@ def _share_spec_validator(
278
269
 
279
270
 
280
271
  def _pcm_spec_validator(
281
- _instance: MarketSampleSpec, _attribute: attrs.Attribute, _value: PCMSpec, /
272
+ _instance: MarketSampleSpec, _attribute: Attribute, _value: PCMSpec, /
282
273
  ) -> None:
283
274
  if (
284
275
  _instance.share_spec.recapture_spec == RECConstants.FIXED
@@ -312,18 +303,18 @@ def _pcm_spec_validator(
312
303
  )
313
304
 
314
305
 
315
- @attrs.define(slots=True, frozen=True)
306
+ @define(slots=True, frozen=True)
316
307
  class MarketSampleSpec:
317
308
  """Parameter specification for market data generation."""
318
309
 
319
- sample_size: int = attrs.field(
320
- default=10**6,
321
- validator=(attrs.validators.instance_of(int), _sample_size_validator),
310
+ sample_size: int = field(
311
+ default=10**6, validator=(validators.instance_of(int), _sample_size_validator)
322
312
  )
323
313
  """sample size generated"""
324
314
 
325
- recapture_rate: float | None = attrs.field(
326
- default=None, validator=attrs.validators.instance_of(float | None)
315
+ recapture_rate: float | None = field(
316
+ default=None,
317
+ validator=(validators.instance_of(float | None), _recapture_rate_validator),
327
318
  )
328
319
  """market recapture rate
329
320
 
@@ -331,72 +322,119 @@ class MarketSampleSpec:
331
322
  outside good choice probabilities (RECConstants.OUTIN).
332
323
  """
333
324
 
334
- pr_sym_spec: PRIConstants = attrs.field( # type: ignore
325
+ pr_sym_spec: PRIConstants = field( # type: ignore
335
326
  kw_only=True,
336
327
  default=PRIConstants.SYM,
337
- validator=attrs.validators.instance_of(PRIConstants), # type: ignore
328
+ validator=validators.instance_of(PRIConstants), # type: ignore
338
329
  )
339
330
  """Price specification, see PRIConstants"""
340
331
 
341
- share_spec: ShareSpec = attrs.field(
332
+ share_spec: ShareSpec = field(
342
333
  kw_only=True,
343
334
  default=ShareSpec(RECConstants.INOUT, SHRConstants.UNI, None, None),
344
- validator=[attrs.validators.instance_of(ShareSpec), _share_spec_validator],
335
+ validator=[validators.instance_of(ShareSpec), _share_spec_validator],
345
336
  )
346
337
  """See definition of ShareSpec"""
347
338
 
348
- pcm_spec: PCMSpec = attrs.field(
339
+ pcm_spec: PCMSpec = field(
349
340
  kw_only=True,
350
341
  default=PCMSpec(PCMConstants.UNI, FM2Constants.IID, None),
351
- validator=[attrs.validators.instance_of(PCMSpec), _pcm_spec_validator],
342
+ validator=[validators.instance_of(PCMSpec), _pcm_spec_validator],
352
343
  )
353
344
  """See definition of PCMSpec"""
354
345
 
355
- hsr_filing_test_type: SSZConstants = attrs.field( # type: ignore
346
+ hsr_filing_test_type: SSZConstants = field( # type: ignore
356
347
  kw_only=True,
357
348
  default=SSZConstants.ONE,
358
- validator=attrs.validators.instance_of(SSZConstants), # type: ignore
349
+ validator=validators.instance_of(SSZConstants), # type: ignore
359
350
  )
360
351
  """Method for modeling HSR filing threholds, see SSZConstants"""
361
352
 
362
353
 
354
+ @enum.unique
355
+ class INVResolution(enum.StrEnum):
356
+ CLRN = "clearance"
357
+ ENFT = "enforcement"
358
+ BOTH = "both"
359
+
360
+
361
+ @enum.unique
362
+ class UPPAggrSelector(enum.StrEnum):
363
+ """
364
+ Aggregator selection for GUPPI and diversion ratio
365
+
366
+ """
367
+
368
+ AVG = "average"
369
+ CPA = "cross-product-share-weighted average"
370
+ CPD = "cross-product-share-weighted distance"
371
+ DIS = "symmetrically-weighted distance"
372
+ MAX = "max"
373
+ MIN = "min"
374
+ OSA = "own-share-weighted average"
375
+ OSD = "own-share-weighted distance"
376
+
377
+
378
+ @define(slots=True, frozen=True)
379
+ class UPPTestRegime:
380
+ resolution: INVResolution = field( # type: ignore
381
+ default=INVResolution.ENFT,
382
+ validator=validators.instance_of(INVResolution), # type: ignore
383
+ )
384
+ guppi_aggregator: UPPAggrSelector = field( # type: ignore
385
+ default=UPPAggrSelector.MAX,
386
+ validator=validators.instance_of(UPPAggrSelector), # type: ignore
387
+ )
388
+ divr_aggregator: UPPAggrSelector | None = field( # type: ignore
389
+ default=guppi_aggregator,
390
+ validator=validators.instance_of(UPPAggrSelector | None), # type: ignore
391
+ )
392
+
393
+
394
+ # https://stackoverflow.com/questions/54668000
395
+ class DataclassInstance(Protocol):
396
+ """Generic dataclass-instance"""
397
+
398
+ __dataclass_fields__: ClassVar
399
+
400
+
363
401
  @dataclass(slots=True, frozen=True)
364
402
  class MarketDataSample:
365
403
  """Container for generated markets data sample."""
366
404
 
367
- frmshr_array: NDArray[np.floating]
405
+ frmshr_array: NDArray[np.float64]
368
406
  """Merging-firm shares (with two merging firms)"""
369
407
 
370
- pcm_array: NDArray[np.floating]
408
+ pcm_array: NDArray[np.float64]
371
409
  """Merging-firms' prices (normalized to 1, in default specification)"""
372
410
 
373
- price_array: NDArray[np.floating]
411
+ price_array: NDArray[np.float64]
374
412
  """Merging-firms' price-cost margins (PCM)"""
375
413
 
376
- fcounts: NDArray[np.integer]
414
+ fcounts: NDArray[np.int64]
377
415
  """Number of firms in market"""
378
416
 
379
- ratio_choice_prob_to_mktshr: NDArray[np.floating]
417
+ aggregate_purchase_prob: NDArray[np.float64]
380
418
  """
381
419
  One (1) minus probability that the outside good is chosen
382
420
 
383
421
  Converts market shares to choice probabilities by multiplication.
384
422
  """
385
423
 
386
- nth_firm_share: NDArray[np.floating]
424
+ nth_firm_share: NDArray[np.float64]
387
425
  """Market-share of n-th firm
388
426
 
389
427
  Relevant for testing for draws the do or
390
428
  do not meet HSR filing thresholds.
391
429
  """
392
430
 
393
- divr_array: NDArray[np.floating]
431
+ divr_array: NDArray[np.float64]
394
432
  """Diversion ratio between the merging firms"""
395
433
 
396
- hhi_post: NDArray[np.floating]
434
+ hhi_post: NDArray[np.float64]
397
435
  """Post-merger change in Herfindahl-Hirschmann Index (HHI)"""
398
436
 
399
- hhi_delta: NDArray[np.floating]
437
+ hhi_delta: NDArray[np.float64]
400
438
  """Change in HHI from combination of merging firms"""
401
439
 
402
440
 
@@ -425,7 +463,7 @@ class ShareDataSample:
425
463
  class PriceDataSample:
426
464
  """Container for generated price array, and related."""
427
465
 
428
- price_array: NDArray[np.floating]
466
+ price_array: NDArray[np.float64]
429
467
  """Merging-firms' prices"""
430
468
 
431
469
  hsr_filing_test: NDArray[np.bool_]
@@ -455,14 +493,38 @@ class MarginDataSample:
455
493
 
456
494
  @dataclass(slots=True, frozen=True)
457
495
  class UPPTestsRaw:
496
+ """arrays marking test failures and successes
497
+
498
+ A test success is a draw ("market") that meeets the
499
+ specified test criterion, and a test failure is
500
+ one that does not; test criteria are defined and
501
+ evaluated in:code:`guidelines_stats.gen_upp_arrays`.
502
+ """
503
+
458
504
  guppi_test_simple: NDArray[np.bool_]
505
+ """True if GUPPI estimate meets criterion"""
506
+
459
507
  guppi_test_compound: NDArray[np.bool_]
508
+ """True if both GUPPI estimate and diversion ratio estimate
509
+ meet criterion
510
+ """
511
+
460
512
  cmcr_test: NDArray[np.bool_]
513
+ """True if CMCR estimate meets criterion"""
514
+
461
515
  ipr_test: NDArray[np.bool_]
516
+ """True if IPR (partial price-simulation) estimate meets criterion"""
462
517
 
463
518
 
464
519
  @dataclass(slots=True, frozen=True)
465
520
  class UPPTestsCounts:
521
+ """counts of markets resolved as specified
522
+
523
+ Resolution is specified in a UPPTestRegime object.
524
+ """
525
+
466
526
  by_firm_count: NDArray[np.int64]
467
527
  by_delta: NDArray[np.int64]
468
528
  by_conczone: NDArray[np.int64]
529
+ """Zones are "unoncentrated", "moderately concentrated", and "highly concentrated"
530
+ """
@@ -116,7 +116,7 @@ def _gen_share_data(
116
116
 
117
117
  def _gen_market_shares_uniform(
118
118
  _s_size: int = 10**6,
119
- _dist_parms_mktshr: NDArray[np.floating[TF]] | None = DIST_PARMS_DEFAULT,
119
+ _dist_parms_mktshr: NDArray[np.floating[TF]] | None = DIST_PARMS_DEFAULT, # type: ignore
120
120
  _mktshr_rng_seed_seq: SeedSequence | None = None,
121
121
  _nthreads: int = 16,
122
122
  /,
@@ -141,8 +141,8 @@ def _gen_market_shares_uniform(
141
141
  """
142
142
 
143
143
  _frmshr_array = np.empty((_s_size, 2), dtype=np.float64)
144
- _dist_parms_mktshr = (
145
- DIST_PARMS_DEFAULT if _dist_parms_mktshr is None else _dist_parms_mktshr # type: ignore
144
+ _dist_parms_mktshr: NDArray[np.floating] = (
145
+ DIST_PARMS_DEFAULT if _dist_parms_mktshr is None else _dist_parms_mktshr
146
146
  )
147
147
  _mrng = MultithreadedRNG(
148
148
  _frmshr_array,
@@ -220,9 +220,9 @@ def _gen_market_shares_dirichlet_multisample(
220
220
 
221
221
  """
222
222
 
223
- _firm_count_wts: np.float64 = (
223
+ _firm_count_wts: NDArray[np.floating] = (
224
224
  FCOUNT_WTS_DEFAULT if _firm_count_wts is None else _firm_count_wts
225
- ) # type: ignore
225
+ )
226
226
 
227
227
  _min_choice_wt = 0.03 if _dist_type_dir == SHRConstants.DIR_FLAT_CONSTR else 0.00
228
228
  _fcount_keys, _choice_wts = zip(
@@ -441,7 +441,7 @@ def _gen_pr_data(
441
441
  )
442
442
  # del _pr_max_ratio
443
443
 
444
- _price_ratio_array = _price_array / _price_array[:, ::-1]
444
+ _price_array = _price_array.astype(np.float64)
445
445
  _rev_array = _price_array * _frmshr_array
446
446
  _nth_firm_rev = _nth_firm_price * _nth_firm_share
447
447
 
@@ -118,10 +118,7 @@ def gen_market_sample(
118
118
 
119
119
  # Generate merging-firm price data
120
120
  _price_data = _gen_pr_data(
121
- _mktshr_data.mktshr_array[:, :2],
122
- _mktshr_data.nth_firm_share,
123
- _mkt_sample_spec_here,
124
- _pr_rng_seed_seq,
121
+ _mktshr_array[:, :2], _nth_firm_share, _mkt_sample_spec_here, _pr_rng_seed_seq
125
122
  )
126
123
 
127
124
  _price_array, _hsr_filing_test = (