mergeron 2024.738930.0__py3-none-any.whl → 2024.738936.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mergeron might be problematic. Click here for more details.

Files changed (30) hide show
  1. mergeron/core/__init__.py +1 -1
  2. mergeron/core/guidelines_standards.py +247 -57
  3. mergeron/core/proportions_tests.py +19 -19
  4. mergeron/core/pseudorandom_numbers.py +30 -29
  5. mergeron/examples/__init__.py +1 -1
  6. mergeron/examples/concentration_as_diversion.py +75 -88
  7. mergeron/examples/investigations_stats_obs_tables.py +119 -111
  8. mergeron/examples/investigations_stats_sim_tables.py +108 -87
  9. mergeron/examples/plotSafeHarbs_symbolically.py +2 -2
  10. mergeron/examples/safeharbor_boundaries_for_mergers_with_asymmetric_shares.py +35 -28
  11. mergeron/examples/safeharbor_boundaries_for_symmetric_firm_mergers.py +6 -13
  12. mergeron/examples/sound_guppi_safeharbor.py +23 -18
  13. mergeron/examples/testIntrinsicClearanceRates.py +5 -5
  14. mergeron/examples/visualize_empirical_margin_distribution.py +1 -1
  15. mergeron/examples/{visualize_guidelines_tests_scatterplots.py → visualize_guidelines_tests.py} +42 -48
  16. mergeron/ext/__init__.py +1 -1
  17. mergeron/gen/__init__.py +1 -1
  18. mergeron/gen/data_generation.py +25 -24
  19. mergeron/gen/guidelines_tests.py +47 -47
  20. mergeron/gen/investigations_stats.py +98 -46
  21. mergeron/jinja_LaTex_templates/clrrate_cis_summary_table_template.tex.jinja2 +2 -3
  22. mergeron/jinja_LaTex_templates/ftcinvdata_byhhianddelta_table_template.tex.jinja2 +2 -3
  23. mergeron/jinja_LaTex_templates/ftcinvdata_summary_table_template.tex.jinja2 +1 -2
  24. mergeron/jinja_LaTex_templates/ftcinvdata_summarypaired_table_template.tex.jinja2 +13 -14
  25. mergeron/jinja_LaTex_templates/mergeron.cls +161 -0
  26. mergeron/jinja_LaTex_templates/mergeron_table_collection_template.tex.jinja2 +90 -0
  27. {mergeron-2024.738930.0.dist-info → mergeron-2024.738936.2.dist-info}/METADATA +15 -18
  28. mergeron-2024.738936.2.dist-info/RECORD +41 -0
  29. mergeron-2024.738930.0.dist-info/RECORD +0 -39
  30. {mergeron-2024.738930.0.dist-info → mergeron-2024.738936.2.dist-info}/WHEEL +0 -0
@@ -6,17 +6,16 @@ This boundary is limited to share-margin space, given restrictions from symmetry
6
6
 
7
7
  from pathlib import Path
8
8
 
9
+ import matplotlib as mpl
9
10
  import numpy as np
10
11
  from matplotlib import cm as colormgr
11
12
  from matplotlib import colors as mcolors
12
13
  from matplotlib.ticker import AutoMinorLocator, MultipleLocator, StrMethodFormatter
13
14
 
14
15
  import mergeron.core.guidelines_standards as gsf
16
+ from mergeron import DATA_DIR
15
17
 
16
18
  PROG_PATH = Path(__file__)
17
- data_path = Path.home() / PROG_PATH.parents[1].stem
18
- if not data_path.is_dir():
19
- data_path.mkdir(parents=True)
20
19
 
21
20
 
22
21
  def _main() -> None:
@@ -43,14 +42,11 @@ def _main() -> None:
43
42
 
44
43
  print("Generate data for plots")
45
44
  # Mgn coords, and div-ratio coords
46
- dh_bar, g_bar, r_bar, dr_bar = 0.01, 0.06, 0.80, 0.20
45
+ g_bar, r_bar, dr_bar = 0.06, 0.80, 0.20
47
46
 
48
47
  step_size = 10**-5
49
48
  sym_shr_vec = np.arange(gsf.shr_from_gbd(g_bar), 0.5 + step_size, step_size)
50
49
  mst_vec = (g_bar / r_bar) * (1 - sym_shr_vec) / sym_shr_vec
51
- mst_vec_gsf = np.where(
52
- sym_shr_vec > gsf.shr_from_gbd(dr_bar, m_star=1.00), np.nan, mst_vec
53
- )
54
50
 
55
51
  print("Setup basic figure and axes for plots of safe harbor boundaries.")
56
52
 
@@ -120,7 +116,7 @@ def _main() -> None:
120
116
  linestyle="-",
121
117
  linewidth=0.75,
122
118
  alpha=1,
123
- color=colormgr.cividis(dr_bar_mgn[0]),
119
+ color=mpl.colormaps["cividis"](dr_bar_mgn[0]),
124
120
  zorder=5.5,
125
121
  )
126
122
 
@@ -173,10 +169,7 @@ def _main() -> None:
173
169
  _minorLocator = AutoMinorLocator(5)
174
170
  _majorLocator = MultipleLocator(0.05)
175
171
  for _axs in ax1.xaxis, ax1.yaxis:
176
- if _axs == ax1.xaxis:
177
- _majorticklabels_rot = 45
178
- elif _axs == ax1.yaxis:
179
- _majorticklabels_rot = 0
172
+ _majorticklabels_rot = 45 if _axs == ax1.xaxis else 0
180
173
  # x-axis
181
174
  _axs.set_major_locator(_majorLocator)
182
175
  _axs.set_minor_locator(_minorLocator)
@@ -206,7 +199,7 @@ def _main() -> None:
206
199
  cm_plot.ax.set_ylim(0, 1.0)
207
200
  cm_plot.outline.set_visible(False)
208
201
 
209
- plt.savefig(data_path.joinpath(f"{PROG_PATH.stem}.pdf"))
202
+ plt.savefig(DATA_DIR / PROG_PATH.with_suffix(".pdf").name)
210
203
 
211
204
 
212
205
  if __name__ == "__main__":
@@ -13,15 +13,15 @@ import mergeron.gen.guidelines_tests as gtl
13
13
  import mergeron.gen.investigations_stats as isl
14
14
  from mergeron import DATA_DIR
15
15
 
16
- tests_of_interest: tuple[gtl.UPPTestSpec, ...] = (
16
+ tests_of_interest: tuple[gtl.UPPTestRegime, ...] = (
17
17
  (isl.PolicySelector.CLRN, gtl.GUPPIWghtngSelector.MAX, gtl.GUPPIWghtngSelector.MAX),
18
18
  (isl.PolicySelector.ENFT, gtl.GUPPIWghtngSelector.MIN, gtl.GUPPIWghtngSelector.MIN),
19
19
  )
20
20
 
21
- mod_path = Path(__file__)
21
+ PROG_PATH = Path(__file__)
22
22
 
23
23
 
24
- def analyze_inv_data(
24
+ def analyze_invres_data(
25
25
  _sample_size: int = 10**6,
26
26
  _hmg_std_pub_year: Literal[1992, 2010, 2023] = 1992,
27
27
  _test_sel: tuple[
@@ -50,16 +50,16 @@ def analyze_inv_data(
50
50
  If True, simulated data are save to file (hdf5 format)
51
51
 
52
52
  """
53
- _inv_parm_vec = gsf.GuidelinesStandards(_hmg_std_pub_year).presumption[2:]
53
+ _invres_parm_vec = gsf.GuidelinesStandards(_hmg_std_pub_year).presumption
54
54
 
55
- _save_data_to_file: Literal[False] | tuple[Literal[True], ptb.File, str] = False
55
+ _save_data_to_file: gtl.SaveData = False
56
56
  if save_data_to_file_flag:
57
57
  _h5_hier_pat = re.compile(r"\W")
58
58
  _blosc_filters = ptb.Filters(
59
59
  complevel=3, complib="blosc:lz4hc", fletcher32=True
60
60
  )
61
61
  _h5_datafile = ptb.open_file(
62
- str(DATA_DIR / f"{mod_path.stem}_sound.h5"),
62
+ DATA_DIR / PROG_PATH.with_suffix(".h5").name,
63
63
  mode="w",
64
64
  title=f"GUPPI Safeharbor {_test_sel[0].capitalize()} Rate Module",
65
65
  filters=_blosc_filters,
@@ -115,27 +115,32 @@ def analyze_inv_data(
115
115
 
116
116
  _ind_sample_spec = dgl.MarketSampleSpec(
117
117
  _sample_size,
118
- _inv_parm_vec[0],
118
+ _invres_parm_vec.rec,
119
119
  dgl.PRIConstants.SYM,
120
120
  share_spec=dgl.ShareSpec(
121
- dgl.SHRConstants.UNI, _recapture_spec_test, dgl.EMPTY_ARRAY_DEFAULT
121
+ _recapture_spec_test,
122
+ dgl.SHRConstants.UNI,
123
+ dgl.EMPTY_ARRAY_DEFAULT,
124
+ dgl.FCOUNT_WTS_DEFAULT,
122
125
  ),
123
126
  pcm_spec=dgl.PCMSpec(
124
127
  _pcm_dist_type_test, _pcm_dist_firm2_test, _pcm_dist_parms_test
125
128
  ),
126
129
  )
127
130
 
128
- _inv_cnts_kwargs = {
129
- "sim_inv_sel": _test_sel,
131
+ _invres_cnts_kwargs = {
132
+ "sim_test_regime": _test_sel,
130
133
  "save_data_to_file": _save_data_to_file,
131
134
  }
132
135
 
133
136
  _start_time = datetime.now()
134
137
  (
135
- _inv_rate_sim_byfirmcount_array,
136
- _inv_rate_sim_bydelta_array,
137
- _inv_rate_sim_byconczone_array,
138
- ) = gtl.sim_inv_cnts_ll(_inv_parm_vec, _ind_sample_spec, _inv_cnts_kwargs)
138
+ _invres_rate_sim_byfirmcount_array,
139
+ _invres_rate_sim_bydelta_array,
140
+ _invres_rate_sim_byconczone_array,
141
+ ) = gtl.sim_invres_cnts_ll(
142
+ _invres_parm_vec, _ind_sample_spec, _invres_cnts_kwargs
143
+ )
139
144
  _run_duration = datetime.now() - _start_time
140
145
  print(
141
146
  f"Simulation completed in {_run_duration / timedelta(seconds=1):.6f} secs.",
@@ -143,8 +148,8 @@ def analyze_inv_data(
143
148
  sep=", ",
144
149
  )
145
150
 
146
- _stats_hdr_list, _stats_dat_list = isl.latex_tbl_inv_stats_1dim(
147
- _inv_rate_sim_bydelta_array,
151
+ _stats_hdr_list, _stats_dat_list = isl.latex_tbl_invres_stats_1dim(
152
+ _invres_rate_sim_bydelta_array,
148
153
  return_type_sel=isl.StatsReturnSelector.RPT,
149
154
  sort_order=isl.SortSelector.REV,
150
155
  )
@@ -162,8 +167,8 @@ def analyze_inv_data(
162
167
  del _pcm_dist_type_test, _pcm_dist_parms_test
163
168
 
164
169
  if save_data_to_file_flag:
165
- _h5_datafile.close()
170
+ _save_data_to_file[1].close() # type: ignore
166
171
 
167
172
 
168
173
  if __name__ == "__main__":
169
- analyze_inv_data(10**7, 2023, tests_of_interest[1], save_data_to_file_flag=False)
174
+ analyze_invres_data(10**7, 2023, tests_of_interest[1], save_data_to_file_flag=False)
@@ -1,11 +1,11 @@
1
1
  """
2
2
 
3
- Estimation of intrinsic clearance rates for ΔHHI safeharbor and GUPPI safeharbor
4
- Demonstrates MC integration with closed-form integrand and indicator-function
5
- integrand (Tested with Python 3.8 and 3.9; NumPy module is required.)
3
+ Estimation of intrinsic clearance rates for ΔHHI safeharbor and GUPPI safeharbor
4
+ Demonstrates MC integration with closed-form integrand and indicator-function
5
+ integrand (Tested with Python 3.8 and 3.9; NumPy module is required.)
6
6
 
7
- S. Murthy Kambhampaty, © 2019. This work is licensed under a CC BY-NC-SA 4.0 License
8
- https://creativecommons.org/licenses/by-nc-sa/4.0/
7
+ S. Murthy Kambhampaty, © 2019. This work is licensed under a CC BY-NC-SA 4.0 License
8
+ https://creativecommons.org/licenses/by-nc-sa/4.0/
9
9
 
10
10
  """
11
11
 
@@ -97,4 +97,4 @@ if __name__ == "__main__":
97
97
  mgn_ax.set_ylabel("Relative Frequency", fontsize=10)
98
98
 
99
99
  mgn_fig.tight_layout()
100
- plt.savefig(DATA_DIR / f"{PROG_PATH.stem}.pdf")
100
+ plt.savefig(PROG_PATH.with_suffix(".pdf"))
@@ -19,7 +19,6 @@ import numpy as np
19
19
  import tables as ptb # type: ignore
20
20
  from matplotlib import cm, colors
21
21
  from matplotlib.ticker import StrMethodFormatter
22
- from numpy import arange, argsort, column_stack, einsum, ones_like
23
22
  from numpy.typing import NDArray
24
23
 
25
24
  import mergeron.core.guidelines_standards as gsf
@@ -39,9 +38,9 @@ blosc_filters = ptb.Filters(
39
38
 
40
39
  def gen_plot_data(
41
40
  _market_data: dgl.MarketsSample,
42
- _g_bar: float,
41
+ _std_vec: gsf.GuidelinesSTD,
43
42
  _pcm_firm2_star: float = 0.30,
44
- _inv_sel: gtl.UPPTestSpec = (
43
+ _test_regime: gtl.UPPTestRegime = (
45
44
  isl.PolicySelector.CLRN,
46
45
  gtl.GUPPIWghtngSelector.MAX,
47
46
  None,
@@ -54,29 +53,20 @@ def gen_plot_data(
54
53
  f"{_pcm_firm2_star * 100:03.1f}".replace(".", "dot")
55
54
  )
56
55
 
57
- _pcm_array = column_stack((
56
+ _pcm_array = np.column_stack((
58
57
  _m1 := _market_data.pcm_array[:, [0]],
59
- _pcm_firm2_star * ones_like(_m1),
58
+ _pcm_firm2_star * np.ones_like(_m1),
60
59
  ))
61
60
  del _m1
62
61
 
63
- _guppi_array = einsum("ij,ij->ij", _pcm_array[:, ::-1], _market_data.divr_array)
64
-
65
- _guppi_est = (
66
- _guppi_array.max(axis=1, keepdims=True)
67
- if _inv_sel[1] == gtl.GUPPIWghtngSelector.MAX
68
- else _guppi_array.min(axis=1, keepdims=True)
69
- )
70
-
71
- _gbd_test = (
72
- (_guppi_est < _g_bar)
73
- if _inv_sel[0] == isl.PolicySelector.CLRN
74
- else (_guppi_est >= _g_bar)
62
+ _upp_tests = gtl.gen_upp_arrays(
63
+ _std_vec,
64
+ dgl.MarketsSample(_market_data.frmshr_array, _pcm_array, *_market_data[2:]),
65
+ _test_regime,
75
66
  )
76
67
 
77
- del _guppi_est
78
-
79
- _gbd_test_rows = np.where(_gbd_test)[0]
68
+ _gbd_test_rows = np.where(_upp_tests.guppi_test_simple)[0]
69
+ del _upp_tests
80
70
 
81
71
  _qtyshr_firm1_inv, _qtyshr_firm2_inv = (
82
72
  _market_data.frmshr_array[_gbd_test_rows][:, [0]],
@@ -86,7 +76,7 @@ def gen_plot_data(
86
76
  _pcm_array[_gbd_test_rows][:, [0]],
87
77
  _pcm_array[_gbd_test_rows][:, [1]],
88
78
  )
89
- del _gbd_test, _gbd_test_rows
79
+ del _gbd_test_rows
90
80
 
91
81
  _pcm_plotter = _pcm_firm1_inv
92
82
 
@@ -108,8 +98,8 @@ def gen_plot_data(
108
98
  title=f"{_array_name}",
109
99
  )
110
100
 
111
- _pcm_sorter = argsort(_pcm_plotter, axis=0)
112
- if _inv_sel[0] != isl.PolicySelector.CLRN:
101
+ _pcm_sorter = np.argsort(_pcm_plotter, axis=0)
102
+ if _test_regime[0] != isl.PolicySelector.CLRN:
113
103
  _pcm_sorter = _pcm_sorter[::-1, :]
114
104
  _qtyshr_firm1_plotter = _qtyshr_firm1_inv[_pcm_sorter]
115
105
  _qtyshr_firm2_plotter = _qtyshr_firm2_inv[_pcm_sorter]
@@ -130,13 +120,16 @@ def gen_plot_data(
130
120
  def _main(
131
121
  _hmg_pub_year: gsf.HMGPubYear,
132
122
  _market_sample_spec: dgl.MarketSampleSpec,
133
- _inv_sel: gtl.UPPTestSpec,
123
+ _test_regime: gtl.UPPTestRegime,
134
124
  _save_data_to_file: gtl.SaveData,
135
125
  ) -> None:
136
- _r_bar, _g_bar, _divr_bar, *_ = getattr(
126
+ guidelins_std_vec = getattr(
137
127
  gsf.GuidelinesStandards(_hmg_pub_year),
138
- "safeharbor" if _inv_sel[0] == isl.PolicySelector.ENFT else "presumption",
139
- )[2:]
128
+ "safeharbor" if _test_regime[0] == isl.PolicySelector.ENFT else "presumption",
129
+ )
130
+
131
+ _, _r_bar, _g_bar, _divr_bar, *_ = guidelins_std_vec
132
+
140
133
  market_data = dgl.gen_market_sample(_market_sample_spec, seed_seq_list=None)
141
134
 
142
135
  # Set up a plot grid to fill in the various scatterplots
@@ -173,12 +166,12 @@ def _main(
173
166
  _ax_now.text(
174
167
  0.81,
175
168
  0.72,
176
- "\n".join([
177
- r"$m_2 = m^* = {0:.{1}f}\%$".format(
169
+ "\n".join((
170
+ R"$m_2 = m^* = {0:.{1}f}\%$".format(
178
171
  (_pcmv := _pcm_firm2_star * 100), 1 * (_pcmv % 1 > 0)
179
172
  ),
180
- r"$m_1 \neq m_2$",
181
- ]),
173
+ R"$m_1 \neq m_2$",
174
+ )),
182
175
  rotation=0,
183
176
  ha="right",
184
177
  va="top",
@@ -203,9 +196,9 @@ def _main(
203
196
 
204
197
  _qtyshr_firm1_plotter, _qtyshr_firm2_plotter, _pcm_plotter = gen_plot_data(
205
198
  market_data,
206
- _g_bar,
199
+ guidelins_std_vec,
207
200
  _pcm_firm2_star,
208
- _inv_sel,
201
+ _test_regime,
209
202
  h5handle=_save_data_to_file[1] if _save_data_to_file else None,
210
203
  )
211
204
 
@@ -231,7 +224,7 @@ def _main(
231
224
  ax=_ax_cm,
232
225
  orientation="vertical",
233
226
  fraction=3.0,
234
- ticks=arange(0, 1.2, 0.2),
227
+ ticks=np.arange(0, 1.2, 0.2),
235
228
  format=StrMethodFormatter("{x:>3.0%}"),
236
229
  )
237
230
  _cm_plot.set_label(label="Firm 1 Price-Cost Margin, $m_1$", fontsize=10)
@@ -242,26 +235,30 @@ def _main(
242
235
 
243
236
  _cm_plot.outline.set_visible(False)
244
237
 
245
- _base_name = DATA_DIR.joinpath(
246
- f"{PROG_PATH.stem}_{_hmg_pub_year}gbar{f"{_g_bar * 100:02.0f}"}PCT_{market_sample_spec.share_spec[0]}Recapture_{_inv_sel}"
238
+ _base_name = DATA_DIR / "{}_{}Rate_{}gbar{}PCT_{}Recapture".format(
239
+ PROG_PATH.stem,
240
+ f"{_test_regime[0]}".capitalize(),
241
+ _hmg_pub_year,
242
+ f"{_g_bar * 100:02.0f}",
243
+ market_sample_spec.share_spec[0],
247
244
  )
248
245
  _my_fig_2dsg_savepath = DATA_DIR / f"{_base_name}_2DScatterGrid.pdf"
249
- print(f"Save 2D plot to, {_my_fig_2dsg_savepath!r}")
246
+ print(f"Save 2D plot to, {f'"{_my_fig_2dsg_savepath}"'}")
250
247
  _fig_2dsg.savefig(_my_fig_2dsg_savepath, dpi=600)
251
248
 
252
249
 
253
250
  if __name__ == "__main__":
254
251
  # Get Guidelines parameter values
255
252
  hmg_pub_year: Final = 2023
256
- inv_sel: gtl.UPPTestSpec = (
253
+ test_regime: gtl.UPPTestRegime = (
257
254
  isl.PolicySelector.ENFT,
258
255
  gtl.GUPPIWghtngSelector.MIN,
259
256
  gtl.GUPPIWghtngSelector.MIN,
260
257
  )
261
- r_bar, g_bar, divr_bar, *_ = getattr(
258
+ r_bar = getattr(
262
259
  gsf.GuidelinesStandards(hmg_pub_year),
263
- "safeharbor" if inv_sel[0] == isl.PolicySelector.ENFT else "presumption",
264
- )[2:]
260
+ "presumption" if test_regime[0] == isl.PolicySelector.ENFT else "safeharbor",
261
+ ).rec
265
262
 
266
263
  sample_sz = 10**7
267
264
 
@@ -269,16 +266,13 @@ if __name__ == "__main__":
269
266
  sample_sz,
270
267
  r_bar,
271
268
  share_spec=dgl.ShareSpec(
272
- dgl.RECConstants.INOUT,
273
- dgl.SHRConstants.UNI,
274
- DIST_PARMS_DEFAULT,
275
- dgl.FCOUNT_WTS_DEFAULT,
269
+ dgl.RECConstants.INOUT, dgl.SHRConstants.UNI, DIST_PARMS_DEFAULT, None
276
270
  ),
277
271
  )
278
272
 
279
273
  save_data_to_file_flag = False
280
274
  if save_data_to_file_flag:
281
- h5path = DATA_DIR / f"{PROG_PATH.stem}.h5"
275
+ h5path = DATA_DIR / PROG_PATH.with_suffix(".h5").name
282
276
  h5datafile = ptb.open_file(
283
277
  h5path,
284
278
  mode="w",
@@ -293,7 +287,7 @@ if __name__ == "__main__":
293
287
  else:
294
288
  save_data_to_file = False
295
289
 
296
- _main(hmg_pub_year, market_sample_spec, inv_sel, save_data_to_file)
290
+ _main(hmg_pub_year, market_sample_spec, test_regime, save_data_to_file)
297
291
 
298
292
  if save_data_to_file_flag:
299
- h5datafile.close()
293
+ save_data_to_file[1].close() # type: ignore
mergeron/ext/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from importlib.metadata import version
2
2
 
3
- from .. import _PKG_NAME
3
+ from .. import _PKG_NAME # noqa: TID252
4
4
 
5
5
  __version__ = version(_PKG_NAME)
mergeron/gen/__init__.py CHANGED
@@ -1,5 +1,5 @@
1
1
  from importlib.metadata import version
2
2
 
3
- from .. import _PKG_NAME
3
+ from .. import _PKG_NAME # noqa: TID252
4
4
 
5
5
  __version__ = version(_PKG_NAME)
@@ -12,12 +12,12 @@ from .. import _PKG_NAME # noqa: TID252
12
12
  __version__ = version(_PKG_NAME)
13
13
 
14
14
  import enum
15
- from typing import Literal, NamedTuple
15
+ from typing import Literal, NamedTuple, TypeVar
16
16
 
17
17
  import attrs
18
18
  import numpy as np
19
19
  from numpy.random import SeedSequence
20
- from numpy.typing import NDArray
20
+ from numpy.typing import NBitBase, NDArray
21
21
 
22
22
  from ..core.damodaran_margin_data import resample_mgn_data # noqa: TID252
23
23
  from ..core.pseudorandom_numbers import ( # noqa: TID252
@@ -29,6 +29,8 @@ from ..core.pseudorandom_numbers import ( # noqa: TID252
29
29
  EMPTY_ARRAY_DEFAULT = np.zeros(2)
30
30
  FCOUNT_WTS_DEFAULT = ((_nr := np.arange(1, 6)[::-1]) / _nr.sum()).astype(np.float64)
31
31
 
32
+ TF = TypeVar("TF", bound=NBitBase)
33
+
32
34
 
33
35
  @enum.unique
34
36
  class PRIConstants(tuple[bool, str | None], enum.ReprEnum):
@@ -378,7 +380,7 @@ class ShareDataSample(NamedTuple):
378
380
  class PriceDataSample(NamedTuple):
379
381
  """Container for generated price array, and related."""
380
382
 
381
- price_array: NDArray[np.float64]
383
+ price_array: NDArray[np.floating]
382
384
  """Merging-firms' prices"""
383
385
 
384
386
  hsr_filing_test: NDArray[np.bool_]
@@ -660,7 +662,7 @@ def _gen_share_data(
660
662
 
661
663
  def _gen_market_shares_uniform(
662
664
  _s_size: int = 10**6,
663
- _dist_parms_mktshr: NDArray[np.floating] | None = DIST_PARMS_DEFAULT,
665
+ _dist_parms_mktshr: NDArray[np.floating[TF]] | None = DIST_PARMS_DEFAULT,
664
666
  _mktshr_rng_seed_seq: SeedSequence | None = None,
665
667
  _nthreads: int = 16,
666
668
  /,
@@ -685,7 +687,9 @@ def _gen_market_shares_uniform(
685
687
  """
686
688
 
687
689
  _frmshr_array = np.empty((_s_size, 2), dtype=np.float64)
688
- _dist_parms_mktshr = _dist_parms_mktshr or DIST_PARMS_DEFAULT
690
+ _dist_parms_mktshr = (
691
+ DIST_PARMS_DEFAULT if _dist_parms_mktshr is None else _dist_parms_mktshr # type: ignore
692
+ )
689
693
  _mrng = MultithreadedRNG(
690
694
  _frmshr_array,
691
695
  dist_type="Uniform",
@@ -723,8 +727,8 @@ def _gen_market_shares_dirichlet_multisample(
723
727
  _s_size: int = 10**6,
724
728
  _recapture_spec: RECConstants = RECConstants.INOUT,
725
729
  _dist_type_dir: SHRConstants = SHRConstants.DIR_FLAT,
726
- _dist_parms_dir: NDArray[np.floating] | None = None,
727
- _firm_count_wts: NDArray[np.floating] | None = None, # type: ignore
730
+ _dist_parms_dir: NDArray[np.floating[TF]] | None = None,
731
+ _firm_count_wts: NDArray[np.floating[TF]] | None = None, # type: ignore
728
732
  _fcount_rng_seed_seq: SeedSequence | None = None,
729
733
  _mktshr_rng_seed_seq: SeedSequence | None = None,
730
734
  _nthreads: int = 16,
@@ -858,7 +862,7 @@ def _gen_market_shares_dirichlet_multisample(
858
862
 
859
863
 
860
864
  def _gen_market_shares_dirichlet(
861
- _dir_alphas: NDArray[np.floating],
865
+ _dir_alphas: NDArray[np.floating[TF]],
862
866
  _s_size: int = 10**6,
863
867
  _recapture_spec: RECConstants = RECConstants.INOUT,
864
868
  _mktshr_rng_seed_seq: SeedSequence | None = None,
@@ -940,8 +944,8 @@ def _gen_market_shares_dirichlet(
940
944
 
941
945
 
942
946
  def _gen_pr_ratio(
943
- _frmshr_array: NDArray[np.floating],
944
- _nth_firm_share: NDArray[np.floating],
947
+ _frmshr_array: NDArray[np.floating[TF]],
948
+ _nth_firm_share: NDArray[np.floating[TF]],
945
949
  _mkt_sample_spec: MarketSampleSpec,
946
950
  _seed_seq: SeedSequence | None = None,
947
951
  /,
@@ -1030,10 +1034,10 @@ def _gen_pr_ratio(
1030
1034
 
1031
1035
 
1032
1036
  def gen_divr_array(
1033
- _frmshr_array: NDArray[np.floating],
1037
+ _frmshr_array: NDArray[np.floating[TF]],
1034
1038
  _r_bar: float,
1035
1039
  _recapture_spec: RECConstants = RECConstants.INOUT,
1036
- _aggregate_purchase_prob: NDArray[np.floating] = EMPTY_ARRAY_DEFAULT,
1040
+ _aggregate_purchase_prob: NDArray[np.floating[TF]] = EMPTY_ARRAY_DEFAULT,
1037
1041
  /,
1038
1042
  ) -> NDArray[np.float64]:
1039
1043
  """
@@ -1090,10 +1094,10 @@ def gen_divr_array(
1090
1094
 
1091
1095
 
1092
1096
  def _gen_pcm_data(
1093
- _frmshr_array: NDArray[np.floating],
1097
+ _frmshr_array: NDArray[np.floating[TF]],
1094
1098
  _mkt_sample_spec: MarketSampleSpec,
1095
- _price_array: NDArray[np.floating],
1096
- _aggregate_purchase_prob: NDArray[np.floating],
1099
+ _price_array: NDArray[np.floating[TF]],
1100
+ _aggregate_purchase_prob: NDArray[np.floating[TF]],
1097
1101
  _pcm_rng_seed_seq: SeedSequence,
1098
1102
  _nthreads: int = 16,
1099
1103
  /,
@@ -1174,7 +1178,7 @@ def _beta_located(
1174
1178
  """
1175
1179
  Given mean and stddev, return shape parameters for corresponding Beta distribution
1176
1180
 
1177
- Solve the first two moments of the standard Beta to get the shape parameters. [1]_
1181
+ Solve the first two moments of the standard Beta to get the shape parameters.
1178
1182
 
1179
1183
  Parameters
1180
1184
  ----------
@@ -1187,16 +1191,13 @@ def _beta_located(
1187
1191
  -------
1188
1192
  shape parameters for Beta distribution
1189
1193
 
1190
- References
1191
- ----------
1192
- .. [1] NIST. https://www.itl.nist.gov/div898/handbook/eda/section3/eda366h.htm
1193
-
1194
1194
  """
1195
- _mul = (_mu - _mu**2 - _sigma**2) / _sigma**2
1195
+
1196
+ _mul = -1 + _mu * (1 - _mu) / _sigma**2
1196
1197
  return np.array([_mu * _mul, (1 - _mu) * _mul], dtype=np.float64)
1197
1198
 
1198
1199
 
1199
- def beta_located_bound(_dist_parms: NDArray[np.floating], /) -> NDArray[np.float64]:
1200
+ def beta_located_bound(_dist_parms: NDArray[np.floating[TF]], /) -> NDArray[np.float64]:
1200
1201
  R"""
1201
1202
  Return shape parameters for a non-standard beta, given the mean, stddev, range
1202
1203
 
@@ -1204,7 +1205,7 @@ def beta_located_bound(_dist_parms: NDArray[np.floating], /) -> NDArray[np.float
1204
1205
  Recover the r.v.s as
1205
1206
  :math:`\min + (\max - \min) \cdot \symup{Β}(a, b)`,
1206
1207
  with `a` and `b` calculated from the specified mean (:math:`\mu`) and
1207
- variance (:math:`\sigma`). [7]_
1208
+ variance (:math:`\sigma`). [8]_
1208
1209
 
1209
1210
  Parameters
1210
1211
  ----------
@@ -1221,7 +1222,7 @@ def beta_located_bound(_dist_parms: NDArray[np.floating], /) -> NDArray[np.float
1221
1222
 
1222
1223
  References
1223
1224
  ----------
1224
- .. [7] NIST. https://www.itl.nist.gov/div898/handbook/eda/section3/eda366h.htm
1225
+ .. [8] NIST, Beta Distribution. https://www.itl.nist.gov/div898/handbook/eda/section3/eda366h.htm
1225
1226
  """ # noqa: RUF002
1226
1227
 
1227
1228
  _bmu, _bsigma, _bmin, _bmax = _dist_parms