bs-python-utils 0.8.0__tar.gz → 0.8.1__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.
- bs_python_utils-0.8.1/LICENSE +21 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/PKG-INFO +9 -2
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/README.md +3 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/__init__.py +14 -6
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bivariate_quantiles.py +12 -5
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_altair.py +36 -18
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_logging.py +10 -5
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_mem.py +6 -3
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_opt.py +25 -12
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_seaborn.py +3 -1
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_sparse_gaussian.py +12 -6
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bsmplutils.py +2 -1
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bsnputils.py +1 -1
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/chebyshev.py +1 -1
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/distance_covariances.py +1 -1
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils.egg-info/PKG-INFO +9 -2
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils.egg-info/SOURCES.txt +1 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils.egg-info/requires.txt +2 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/pyproject.toml +7 -2
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/Timer.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_mathstr.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bs_plots.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bssputils.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bsstats.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/bsutils.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_altair.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_distance_covariances.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_mem.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_mpl.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_opt.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_seaborn.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_sklearn.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/pandas_utils.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/sklearn_utils.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/streamlit_utils.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils.egg-info/dependency_links.txt +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils.egg-info/top_level.txt +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/setup.cfg +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_bivariate_quantiles.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_bs_opt.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_bs_sparse_gaussian.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_bsnputils.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_bssputils.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_bsstats.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_bsutils.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_chebyshev.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_nptri.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_random_draws.py +0 -0
- {bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/tests/test_sklearn_utils.py +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023, Bernard Salanie
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bs-python-utils
|
|
3
|
-
Version: 0.8.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.8.1
|
|
4
|
+
Summary: Utilities programs for my Python code
|
|
5
5
|
Requires-Python: >=3.12
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
7
8
|
Requires-Dist: altair>=5.5.0
|
|
8
9
|
Requires-Dist: altair-saver>=0.5.0
|
|
9
10
|
Requires-Dist: emcee>=3.1.6
|
|
@@ -15,12 +16,15 @@ Requires-Dist: numpy>=2.3.3
|
|
|
15
16
|
Requires-Dist: pandas>=2.3.2
|
|
16
17
|
Requires-Dist: pre-commit>=4.3.0
|
|
17
18
|
Requires-Dist: pytest>=8.4.2
|
|
19
|
+
Requires-Dist: mypy
|
|
20
|
+
Requires-Dist: ruff>=0.14.0
|
|
18
21
|
Requires-Dist: scikit-learn>=1.7.2
|
|
19
22
|
Requires-Dist: scipy>=1.16.2
|
|
20
23
|
Requires-Dist: seaborn>=0.13.2
|
|
21
24
|
Requires-Dist: statsmodels>=0.14.5
|
|
22
25
|
Requires-Dist: streamlit>=1.49.1
|
|
23
26
|
Requires-Dist: vega-datasets>=0.9.0
|
|
27
|
+
Dynamic: license-file
|
|
24
28
|
|
|
25
29
|
# bs-python-utils
|
|
26
30
|
|
|
@@ -37,6 +41,9 @@ Requires-Dist: vega-datasets>=0.9.0
|
|
|
37
41
|
|
|
38
42
|
### Release notes
|
|
39
43
|
|
|
44
|
+
#### 0.8.1 (October 18, 2025)
|
|
45
|
+
Deleted extra examples scripts.
|
|
46
|
+
|
|
40
47
|
#### 0.8 (October 14, 2025)
|
|
41
48
|
Switched to `uv` for project management. Used Codex to clean up the code and generate more tests. Added the `examples` subdirectory.
|
|
42
49
|
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
|
|
14
14
|
### Release notes
|
|
15
15
|
|
|
16
|
+
#### 0.8.1 (October 18, 2025)
|
|
17
|
+
Deleted extra examples scripts.
|
|
18
|
+
|
|
16
19
|
#### 0.8 (October 14, 2025)
|
|
17
20
|
Switched to `uv` for project management. Used Codex to clean up the code and generate more tests. Added the `examples` subdirectory.
|
|
18
21
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
"""This package contains a number of functions that I have found useful in my
|
|
1
|
+
"""This package contains a number of functions that I have found useful in my
|
|
2
|
+
programming.
|
|
2
3
|
|
|
3
|
-
* `bsutils` has (inter alia) some I/O functions, error reporting, and $C^2$
|
|
4
|
+
* `bsutils` has (inter alia) some I/O functions, error reporting, and $C^2$
|
|
5
|
+
extensions of log and exp
|
|
4
6
|
* `bs_logging` has customized logging
|
|
5
7
|
* `bs_mathstr` has Unicode for math strings
|
|
6
8
|
* `bs_mem` reports memory usage
|
|
@@ -9,12 +11,18 @@
|
|
|
9
11
|
* `bssputils` has Scipy functions
|
|
10
12
|
* `sklearn_utils` has Sklearn functions
|
|
11
13
|
* `pandas_utils` has Pandas functions
|
|
12
|
-
* `bsstats` has TSLS code; nonparametric and flexible estimation; and code to
|
|
14
|
+
* `bsstats` has TSLS code; nonparametric and flexible estimation; and code to
|
|
15
|
+
draw random samples
|
|
13
16
|
* `bs_opt` interfaces with `scipy.optimize`
|
|
14
|
-
* `bs_sparse_gaussian` uses sparse integration to evaluate $E f(X)$ for
|
|
17
|
+
* `bs_sparse_gaussian` uses sparse integration to evaluate $E f(X)$ for
|
|
18
|
+
$X \\simeq N(0,1)$
|
|
15
19
|
* `chebyshev` has Chebyshev interpolation and integration in dimensions 1 and 2
|
|
16
20
|
* `distance_covariances` has measures of nonlinear dependence between random variables
|
|
17
|
-
* `bivariate_quantiles` computes quantiles and ranks for 2-dimensional random
|
|
21
|
+
* `bivariate_quantiles` computes quantiles and ranks for 2-dimensional random
|
|
22
|
+
variables à la [Chernozhukov-Galichon-Hallin-Henry (*Ann. Stats.* 2017)](
|
|
23
|
+
https://projecteuclid.org/journals/annals-of-statistics/volume-45/issue-1/
|
|
24
|
+
MongeKantorovich-depth-quantiles-ranks-and-signs/10.1214/16-AOS1450.full).
|
|
18
25
|
|
|
19
|
-
* `bs_plots` gathers plotting routines in Matplotlib, Seaborn and Altair from
|
|
26
|
+
* `bs_plots` gathers plotting routines in Matplotlib, Seaborn and Altair from
|
|
27
|
+
`bsmplutils`, `bs_seaborn`, and `bs_altair`.
|
|
20
28
|
"""
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"""This takes in observations of a bivariate random variable `y`
|
|
2
|
-
and computes vector quantiles and vector ranks à la
|
|
2
|
+
and computes vector quantiles and vector ranks à la
|
|
3
|
+
[Chernozhukov-Galichon-Hallin-Henry (*Ann. Stats.* 2017)](
|
|
4
|
+
https://projecteuclid.org/journals/annals-of-statistics/volume-45/
|
|
5
|
+
issue-1/MongeKantorovich-depth-quantiles-ranks-and-signs/10.1214/16-AOS1450.full).
|
|
3
6
|
|
|
4
7
|
|
|
5
8
|
Note:
|
|
@@ -7,10 +10,12 @@ Note:
|
|
|
7
10
|
|
|
8
11
|
The sequence of steps is as follows:
|
|
9
12
|
|
|
10
|
-
* choose a number of Chebyshev nodes for numerical integration and optimize
|
|
13
|
+
* choose a number of Chebyshev nodes for numerical integration and optimize
|
|
14
|
+
the weights: `v = solve_for_v(y, n_nodes)`
|
|
11
15
|
* to obtain the $(u_1,u_2)$ quantiles for $(u_1, u_2)\\in [0,1]$, run
|
|
12
16
|
`qtiles_y = bivariate_quantiles_v(y, v, u1, u2)`
|
|
13
|
-
* to compute the vector ranks for all points in the sample (the barycenters
|
|
17
|
+
* to compute the vector ranks for all points in the sample (the barycenters
|
|
18
|
+
of the cells in the power diagram):
|
|
14
19
|
`ranks_y = bivariate_ranks_v(y, v, n_nodes)`
|
|
15
20
|
|
|
16
21
|
Steps 1 and 2 can be combined: `qtiles_y = bivariate_quantiles(y, v, u1, u2, n_nodes)`
|
|
@@ -122,7 +127,8 @@ def bivariate_ranks_v(
|
|
|
122
127
|
y: Observations with shape ``(n, 2)``.
|
|
123
128
|
v: Dual weights returned by ``solve_for_v_``.
|
|
124
129
|
n_nodes: Number of Chebyshev nodes used in the quadrature.
|
|
125
|
-
presorted: Set to ``True`` when ``y``/``v`` are pre-sorted by the
|
|
130
|
+
presorted: Set to ``True`` when ``y``/``v`` are pre-sorted by the
|
|
131
|
+
second coordinate.
|
|
126
132
|
|
|
127
133
|
Returns:
|
|
128
134
|
Array of average ranks (shape ``(n, 2)``) with ``nan`` for zero-mass cells.
|
|
@@ -228,7 +234,8 @@ def solve_for_v_(y: np.ndarray, n_nodes: int = 32, verbose: bool = False) -> np.
|
|
|
228
234
|
verbose: Print optimisation diagnostics when ``True``.
|
|
229
235
|
|
|
230
236
|
Returns:
|
|
231
|
-
Array of length ``n`` containing the optimal weights (including the
|
|
237
|
+
Array of length ``n`` containing the optimal weights (including the
|
|
238
|
+
residual term).
|
|
232
239
|
"""
|
|
233
240
|
n, d = y.shape
|
|
234
241
|
|
|
@@ -2,13 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
* `alt_lineplot`, `alt_superposed_lineplot`, `alt_superposed_faceted_lineplot`
|
|
4
4
|
* `alt_plot_fun`: plots a function
|
|
5
|
-
* `alt_density`, `alt_faceted_densities`: plots the density of `x`, or of `x`
|
|
6
|
-
|
|
7
|
-
* `
|
|
8
|
-
|
|
5
|
+
* `alt_density`, `alt_faceted_densities`: plots the density of `x`, or of `x`
|
|
6
|
+
conditional on a category
|
|
7
|
+
* `alt_superposed_faceted_densities`: plots the density of `x` superposed by
|
|
8
|
+
`f` and faceted by `g`
|
|
9
|
+
* `alt_scatterplot`, `alt_scatterplot_with_histo`, `alt-linked_scatterplots`:
|
|
10
|
+
variants of scatter plots
|
|
11
|
+
* `alt_histogram_by`, `alt_histogram_continuous`: histograms of `x` by `y`,
|
|
12
|
+
and of a continuous `x`
|
|
9
13
|
* `alt_stacked_area`,`alt_stacked_area_facets`: stacked area plots
|
|
10
|
-
* `plot_parameterized_estimates`: plots densities of estimates of
|
|
11
|
-
|
|
14
|
+
* `plot_parameterized_estimates`: plots densities of estimates of
|
|
15
|
+
coefficients, with the true values, as a function of a parameter
|
|
16
|
+
* `plot_true_sim_facets, plot_true_sim2_facets`: plot two simulated values
|
|
17
|
+
and the true values of statistics as a function of a parameter
|
|
12
18
|
* `alt_tick_plots`: vertically arranged tick plots of variables
|
|
13
19
|
* `alt_matrix_heatmap`: plots a heatmap of a matrix.
|
|
14
20
|
"""
|
|
@@ -66,7 +72,8 @@ def alt_scatterplot(
|
|
|
66
72
|
title: Optional chart title.
|
|
67
73
|
color: Column used for color encoding.
|
|
68
74
|
aggreg: Optional aggregation function for ``str_y`` (e.g. ``"mean"``).
|
|
69
|
-
selection: When ``True`` and a ``color`` is supplied, enable
|
|
75
|
+
selection: When ``True`` and a ``color`` is supplied, enable
|
|
76
|
+
legend-based multi-selection.
|
|
70
77
|
|
|
71
78
|
Returns:
|
|
72
79
|
The Altair ``Chart`` for further composition or rendering.
|
|
@@ -134,7 +141,8 @@ def alt_boxes(
|
|
|
134
141
|
title: str | None = None,
|
|
135
142
|
save: str | None = None,
|
|
136
143
|
) -> alt.Chart:
|
|
137
|
-
"""horizontal boxplots of `df[continuous_var]` by `df[discrete_var]` and
|
|
144
|
+
"""horizontal boxplots of `df[continuous_var]` by `df[discrete_var]` and
|
|
145
|
+
`df[group_var]`
|
|
138
146
|
|
|
139
147
|
Args:
|
|
140
148
|
df: datframe with the three variables
|
|
@@ -143,7 +151,8 @@ def alt_boxes(
|
|
|
143
151
|
group_var: name of the grouping variable
|
|
144
152
|
max_cols: maximum number of columns. Defaults to 3.
|
|
145
153
|
title: a plot title. Defaults to None.
|
|
146
|
-
save: the name of a file to save to (HTML extension will be added).
|
|
154
|
+
save: the name of a file to save to (HTML extension will be added).
|
|
155
|
+
Defaults to None.
|
|
147
156
|
|
|
148
157
|
Returns:
|
|
149
158
|
the chart.
|
|
@@ -372,8 +381,10 @@ def alt_linked_scatterplots(
|
|
|
372
381
|
save: str | None = None,
|
|
373
382
|
) -> alt.Chart:
|
|
374
383
|
"""
|
|
375
|
-
Creates two scatterplots: of `df[str_x1]` vs `df[str_y]` and of
|
|
376
|
-
|
|
384
|
+
Creates two scatterplots: of `df[str_x1]` vs `df[str_y]` and of
|
|
385
|
+
`df[str_x2]` vs `df[str_y]`,
|
|
386
|
+
both with color as per `df[str_f]`. Selecting an interval in one shows up
|
|
387
|
+
in the other.
|
|
377
388
|
|
|
378
389
|
Args:
|
|
379
390
|
df:
|
|
@@ -408,7 +419,8 @@ def alt_scatterplot_with_histo(
|
|
|
408
419
|
) -> alt.Chart:
|
|
409
420
|
"""
|
|
410
421
|
Scatterplot of `df[str_x]` vs `df[str_y]` with colors as per `df[str_f]`
|
|
411
|
-
allows to select an interval and histograns the counts of `df[str_f]` in
|
|
422
|
+
allows to select an interval and histograns the counts of `df[str_f]` in
|
|
423
|
+
the interval.
|
|
412
424
|
|
|
413
425
|
Args:
|
|
414
426
|
df: the data with the `str_x` and `str_f` variables
|
|
@@ -544,7 +556,8 @@ def alt_superposed_faceted_lineplot(
|
|
|
544
556
|
save: str | None = None,
|
|
545
557
|
) -> alt.Chart:
|
|
546
558
|
"""
|
|
547
|
-
Plots `df[str_x]` vs `df[str_y]` superposed by `df[str_f]` and faceted by
|
|
559
|
+
Plots `df[str_x]` vs `df[str_y]` superposed by `df[str_f]` and faceted by
|
|
560
|
+
`df[str_g]`
|
|
548
561
|
|
|
549
562
|
Args:
|
|
550
563
|
df: the data with the `str_x`, `str_y`, and `str_f` variables
|
|
@@ -683,7 +696,8 @@ def alt_stacked_area_facets(
|
|
|
683
696
|
save: str | None = None,
|
|
684
697
|
) -> alt.Chart:
|
|
685
698
|
"""
|
|
686
|
-
Normalized stacked lineplots of `df[str_x]` vs `df[str_y]` by `df[str_f]`,
|
|
699
|
+
Normalized stacked lineplots of `df[str_x]` vs `df[str_y]` by `df[str_f]`,
|
|
700
|
+
faceted by `df[str_g]`
|
|
687
701
|
|
|
688
702
|
Args:
|
|
689
703
|
df: the data with columns for `str_x`, `str_y`, and `str_f`
|
|
@@ -721,7 +735,8 @@ def _stack_estimates(
|
|
|
721
735
|
estimate_names: str | list[str], estimates: np.ndarray, df: pd.DataFrame
|
|
722
736
|
) -> tuple[pd.DataFrame, list[str]]:
|
|
723
737
|
"""
|
|
724
|
-
adds to a dataframe `df` columns with names `estimate_names` for various
|
|
738
|
+
adds to a dataframe `df` columns with names `estimate_names` for various
|
|
739
|
+
`estimates of one coefficient
|
|
725
740
|
|
|
726
741
|
Args:
|
|
727
742
|
estimate_names: names of the n estimate columns to be added
|
|
@@ -767,7 +782,8 @@ def plot_parameterized_estimates(
|
|
|
767
782
|
save: str | None = None,
|
|
768
783
|
) -> alt.Chart:
|
|
769
784
|
"""
|
|
770
|
-
Plots estimates of coefficients, with the true values,
|
|
785
|
+
Plots estimates of coefficients, with the true values, as a function of a
|
|
786
|
+
parameter; one facet per coefficient
|
|
771
787
|
|
|
772
788
|
Args:
|
|
773
789
|
parameter_name: the name of the parameter
|
|
@@ -871,7 +887,8 @@ def plot_true_sim_facets(
|
|
|
871
887
|
save: str | None = None,
|
|
872
888
|
) -> alt.Chart:
|
|
873
889
|
"""
|
|
874
|
-
Plots simulated and true values of statistics as a function of a parameter;
|
|
890
|
+
Plots simulated and true values of statistics as a function of a parameter;
|
|
891
|
+
one facet per coefficient
|
|
875
892
|
|
|
876
893
|
Args:
|
|
877
894
|
parameter_name: the name of the parameter
|
|
@@ -972,7 +989,8 @@ def plot_true_sim2_facets(
|
|
|
972
989
|
save: str | None = None,
|
|
973
990
|
) -> alt.Chart:
|
|
974
991
|
"""
|
|
975
|
-
Plots simulated values for two methods and true values of statistics as a
|
|
992
|
+
Plots simulated values for two methods and true values of statistics as a
|
|
993
|
+
function of a parameter;
|
|
976
994
|
one facet per coefficient
|
|
977
995
|
|
|
978
996
|
Args:
|
|
@@ -21,7 +21,8 @@ def init_logger(
|
|
|
21
21
|
|
|
22
22
|
Args:
|
|
23
23
|
logger_name: name for the logger
|
|
24
|
-
log_level_for_console: minimum level of messages logged to the
|
|
24
|
+
log_level_for_console: minimum level of messages logged to the
|
|
25
|
+
console logging
|
|
25
26
|
log_level_for_file:
|
|
26
27
|
save_dir:
|
|
27
28
|
|
|
@@ -35,10 +36,13 @@ def init_logger(
|
|
|
35
36
|
|
|
36
37
|
This will create two logs:
|
|
37
38
|
|
|
38
|
-
* one
|
|
39
|
-
|
|
39
|
+
* one printed to console where we run the code (the
|
|
40
|
+
`StreamHandler`),
|
|
41
|
+
* and one that will be saved to file `save_dir/logger_name.txt`
|
|
42
|
+
(the `FileHandler`).
|
|
40
43
|
|
|
41
|
-
`'logger.propagate = False'`
|
|
44
|
+
`'logger.propagate = False'` makes sure that the logs sent to file
|
|
45
|
+
will not be printed to console.
|
|
42
46
|
|
|
43
47
|
We use the `Formatter` class to define the format of the logs.
|
|
44
48
|
Here:
|
|
@@ -49,7 +53,8 @@ def init_logger(
|
|
|
49
53
|
and the line number, `lineno`.
|
|
50
54
|
* Lastly, the message itself — `message`.
|
|
51
55
|
|
|
52
|
-
The default has only `INFO` logs and above (i.e., also
|
|
56
|
+
The default has only `INFO` logs and above (i.e., also
|
|
57
|
+
`WARNING, ERROR` and `CRITICAL`)
|
|
53
58
|
displayed in the console; the file will also include `DEBUG` logs.
|
|
54
59
|
"""
|
|
55
60
|
logger = logging.getLogger()
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"""Reports on memory usage:
|
|
2
2
|
|
|
3
3
|
* `mem_usage`: prints the top `n` largest global items in memory
|
|
4
|
-
* `memory_display_top`: prints the top `n` largest memory allocations
|
|
5
|
-
|
|
4
|
+
* `memory_display_top`: prints the top `n` largest memory allocations
|
|
5
|
+
since tracing started
|
|
6
|
+
* `memory_display_top_diffs`: prints the top `n` largest memory
|
|
7
|
+
allocations since the last snapshot.
|
|
6
8
|
"""
|
|
7
9
|
|
|
8
10
|
import linecache
|
|
@@ -67,7 +69,8 @@ def memory_display_top(
|
|
|
67
69
|
snapshot: tracemalloc.Snapshot, key_type: str = "lineno", limit: int | None = 5
|
|
68
70
|
) -> None:
|
|
69
71
|
"""
|
|
70
|
-
prints out the lines with the top `limit` allocations of memory since
|
|
72
|
+
prints out the lines with the top `limit` allocations of memory since
|
|
73
|
+
`tracemalloc.start()`
|
|
71
74
|
|
|
72
75
|
Args:
|
|
73
76
|
snapshot: obtained from tracemalloc.take_snapshot()
|
|
@@ -3,12 +3,17 @@
|
|
|
3
3
|
* `ScalarFunctionAndGradient`, `ProximalFunction` type aliases
|
|
4
4
|
* an `OptimizeParams` class
|
|
5
5
|
* `check_gradient_scalar_function` checks whether an analytical gradient is correct
|
|
6
|
-
* `acc_grad_descent`: accelerated gradient descent for convex, possibly
|
|
7
|
-
|
|
8
|
-
* `
|
|
9
|
-
|
|
10
|
-
* `
|
|
11
|
-
|
|
6
|
+
* `acc_grad_descent`: accelerated gradient descent for convex, possibly
|
|
7
|
+
non-smooth functions
|
|
8
|
+
* `minimize_some_fixed`: minimizes a function with some parameter values
|
|
9
|
+
possibly fixed and some possibly within bounds, using L-BFGS-B
|
|
10
|
+
* `minimize_free`: minimizes a function with some parameter values possibly
|
|
11
|
+
within bounds
|
|
12
|
+
* `dfp_update, bfgs_update`: compute updates to the inverse Hessian
|
|
13
|
+
* `armijo_alpha, barzilai_borwein_alpha`: two ways of computing the step
|
|
14
|
+
length
|
|
15
|
+
* `print_optimization_results`, `print_constrained_optimization_results`
|
|
16
|
+
format the results.
|
|
12
17
|
"""
|
|
13
18
|
|
|
14
19
|
from dataclasses import dataclass
|
|
@@ -27,7 +32,9 @@ from bs_python_utils.Timer import timeit
|
|
|
27
32
|
ScalarFunctionAndGradient = Callable[
|
|
28
33
|
[np.ndarray, Iterable, Optional[bool]], Union[float, tuple[float, np.ndarray]]
|
|
29
34
|
]
|
|
30
|
-
"""Type of `f(v, args, gr)` that returns a scalar value and also a gradient if
|
|
35
|
+
"""Type of `f(v, args, gr)` that returns a scalar value and also a gradient if
|
|
36
|
+
`gr` is `True`.
|
|
37
|
+
"""
|
|
31
38
|
|
|
32
39
|
|
|
33
40
|
ProximalFunction = Callable[[np.ndarray, float, Iterable], np.ndarray]
|
|
@@ -36,7 +43,9 @@ ProximalFunction = Callable[[np.ndarray, float, Iterable], np.ndarray]
|
|
|
36
43
|
|
|
37
44
|
@dataclass
|
|
38
45
|
class OptimizeParams:
|
|
39
|
-
"""used for optimization; combines values, bounds and initial values for a
|
|
46
|
+
"""used for optimization; combines values, bounds and initial values for a
|
|
47
|
+
parameter vector
|
|
48
|
+
"""
|
|
40
49
|
|
|
41
50
|
params_values: np.ndarray | None
|
|
42
51
|
params_bounds: list[tuple] | None
|
|
@@ -137,7 +146,8 @@ def armijo_alpha(
|
|
|
137
146
|
c1: Armijo sufficient-decrease constant.
|
|
138
147
|
|
|
139
148
|
Returns:
|
|
140
|
-
Step size satisfying the Armijo condition; returns ``0.0`` when the
|
|
149
|
+
Step size satisfying the Armijo condition; returns ``0.0`` when the
|
|
150
|
+
supplied direction
|
|
141
151
|
is numerically orthogonal to the gradient.
|
|
142
152
|
"""
|
|
143
153
|
f0 = f(x, args)
|
|
@@ -177,7 +187,8 @@ def barzilai_borwein_alpha(
|
|
|
177
187
|
args: Extra arguments passed to the gradient.
|
|
178
188
|
|
|
179
189
|
Returns:
|
|
180
|
-
A tuple ``(alpha, gradient)`` where ``alpha`` is the safeguarded BB
|
|
190
|
+
A tuple ``(alpha, gradient)`` where ``alpha`` is the safeguarded BB
|
|
191
|
+
step size.
|
|
181
192
|
"""
|
|
182
193
|
eps = 1e-12
|
|
183
194
|
g = grad_f(x, args)
|
|
@@ -391,10 +402,12 @@ def minimize_some_fixed(
|
|
|
391
402
|
grad_obj: its gradient function
|
|
392
403
|
fixed_vars: a list if the indices of variables whose values are fixed
|
|
393
404
|
fixed_vals: their fixed values
|
|
394
|
-
x_init: the initial values of all variables (those on fixed variables
|
|
405
|
+
x_init: the initial values of all variables (those on fixed variables
|
|
406
|
+
are not used)
|
|
395
407
|
args: other parameters
|
|
396
408
|
options: any options passed on to `scipy.optimize.minimize`
|
|
397
|
-
bounds: the bounds on all variables (those on fixed variables are
|
|
409
|
+
bounds: the bounds on all variables (those on fixed variables are
|
|
410
|
+
not used)
|
|
398
411
|
time_execution: if `True`, time the execution and print the result
|
|
399
412
|
|
|
400
413
|
Returns:
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
* `bs_sns_bar_x_byf`: make a bar plot of `x` by `f`
|
|
5
5
|
* `bs_sns_bar_x_byfg`: make a bar plot of `x` by `f` and `g`
|
|
6
6
|
* `bs_sns_plot_density`: basic density plot
|
|
7
|
-
* `bs_sns_density_estimates`: plots the densities of estimates of several
|
|
7
|
+
* `bs_sns_density_estimates`: plots the densities of estimates of several
|
|
8
|
+
coefficients with several methods, superposed by methods and faceted by
|
|
9
|
+
coefficients.
|
|
8
10
|
"""
|
|
9
11
|
|
|
10
12
|
from collections.abc import Callable
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Sets up sparse integration over a Gaussian, given text files that contain
|
|
2
|
+
Sets up sparse integration over a Gaussian, given text files that contain
|
|
3
|
+
rescaled Gauss-Hermite nodes and weights.
|
|
3
4
|
|
|
4
|
-
These files must be named `GHsparseGrid{ndims}prec{iprec}.txt`, where
|
|
5
|
-
|
|
5
|
+
These files must be named `GHsparseGrid{ndims}prec{iprec}.txt`, where
|
|
6
|
+
`ndims` is the number of dimensions of integration
|
|
7
|
+
and `iprec` is a precision level that must be 9, 13, or (most precise) 17.
|
|
8
|
+
The file must have `(ndims+1)` columns,
|
|
6
9
|
with the weights in the first column.
|
|
7
10
|
|
|
8
|
-
The nodes and weights are rescaled so that `f(nodes) @ weights` approximates
|
|
11
|
+
The nodes and weights are rescaled so that `f(nodes) @ weights` approximates
|
|
12
|
+
`Ef(X)` for `X` an `N(0,I)` variable.
|
|
9
13
|
"""
|
|
10
14
|
|
|
11
15
|
from pathlib import Path
|
|
@@ -20,7 +24,8 @@ def setup_sparse_gaussian(
|
|
|
20
24
|
ndims: int, iprec: int, GHsparsedir: str | None = None
|
|
21
25
|
) -> TwoArrays:
|
|
22
26
|
"""
|
|
23
|
-
Get nodes and weights for sparse integration Ef(X) with X = N(0,1) in
|
|
27
|
+
Get nodes and weights for sparse integration Ef(X) with X = N(0,1) in
|
|
28
|
+
`ndims` dimensions.
|
|
24
29
|
|
|
25
30
|
Examples:
|
|
26
31
|
>>> nodes, weights = setup_sparse_gaussian(mdims, iprec)
|
|
@@ -33,7 +38,8 @@ def setup_sparse_gaussian(
|
|
|
33
38
|
|
|
34
39
|
Returns:
|
|
35
40
|
a pair of arrays `nodes` and `weights`;
|
|
36
|
-
`nodes` has `ndims-1` columns and `weights` is a vector with the same
|
|
41
|
+
`nodes` has `ndims-1` columns and `weights` is a vector with the same
|
|
42
|
+
number of rows.
|
|
37
43
|
"""
|
|
38
44
|
GHdir = (
|
|
39
45
|
Path.home() / "Dropbox" / "GHsparseGrids"
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
A Matplotlib utility program:
|
|
3
3
|
|
|
4
4
|
* `ax_text`: annotate an `ax` with text.
|
|
5
|
-
* `bs_mpl_plot_dcm_fit`: generates a boxplot of the predicted probas for a
|
|
5
|
+
* `bs_mpl_plot_dcm_fit`: generates a boxplot of the predicted probas for a
|
|
6
|
+
discrete choice model
|
|
6
7
|
"""
|
|
7
8
|
|
|
8
9
|
import matplotlib.axes as axes
|
|
@@ -781,7 +781,7 @@ def outer_bivar(pol1: Polynomial, pol2: Polynomial) -> BivariatePolynomial:
|
|
|
781
781
|
"""
|
|
782
782
|
p1 = pol1.coef
|
|
783
783
|
p2 = pol2.coef
|
|
784
|
-
prod_coef = np.outer(p1, p2)
|
|
784
|
+
prod_coef = np.outer(p1, p2) # type: ignore
|
|
785
785
|
return BivariatePolynomial(prod_coef)
|
|
786
786
|
|
|
787
787
|
|
|
@@ -240,7 +240,7 @@ def _pdcovs_bootstrap(
|
|
|
240
240
|
C_YZ = _dcov_prod(Y_ddi, Z_ddi, unbiased)
|
|
241
241
|
C_ZZ = _dcov_prod(Z_ddi, Z_ddi, unbiased)
|
|
242
242
|
pdcov_stats_boot[idraw] = C_XY - (C_XZ * C_YZ) / C_ZZ
|
|
243
|
-
return n * pdcov_stats_boot
|
|
243
|
+
return cast(np.ndarray, n * pdcov_stats_boot)
|
|
244
244
|
|
|
245
245
|
|
|
246
246
|
def pvalue_pdcov(pdcov_results: PdcovResults, ndraws: int = 199) -> float:
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bs-python-utils
|
|
3
|
-
Version: 0.8.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.8.1
|
|
4
|
+
Summary: Utilities programs for my Python code
|
|
5
5
|
Requires-Python: >=3.12
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
7
8
|
Requires-Dist: altair>=5.5.0
|
|
8
9
|
Requires-Dist: altair-saver>=0.5.0
|
|
9
10
|
Requires-Dist: emcee>=3.1.6
|
|
@@ -15,12 +16,15 @@ Requires-Dist: numpy>=2.3.3
|
|
|
15
16
|
Requires-Dist: pandas>=2.3.2
|
|
16
17
|
Requires-Dist: pre-commit>=4.3.0
|
|
17
18
|
Requires-Dist: pytest>=8.4.2
|
|
19
|
+
Requires-Dist: mypy
|
|
20
|
+
Requires-Dist: ruff>=0.14.0
|
|
18
21
|
Requires-Dist: scikit-learn>=1.7.2
|
|
19
22
|
Requires-Dist: scipy>=1.16.2
|
|
20
23
|
Requires-Dist: seaborn>=0.13.2
|
|
21
24
|
Requires-Dist: statsmodels>=0.14.5
|
|
22
25
|
Requires-Dist: streamlit>=1.49.1
|
|
23
26
|
Requires-Dist: vega-datasets>=0.9.0
|
|
27
|
+
Dynamic: license-file
|
|
24
28
|
|
|
25
29
|
# bs-python-utils
|
|
26
30
|
|
|
@@ -37,6 +41,9 @@ Requires-Dist: vega-datasets>=0.9.0
|
|
|
37
41
|
|
|
38
42
|
### Release notes
|
|
39
43
|
|
|
44
|
+
#### 0.8.1 (October 18, 2025)
|
|
45
|
+
Deleted extra examples scripts.
|
|
46
|
+
|
|
40
47
|
#### 0.8 (October 14, 2025)
|
|
41
48
|
Switched to `uv` for project management. Used Codex to clean up the code and generate more tests. Added the `examples` subdirectory.
|
|
42
49
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "bs-python-utils"
|
|
3
|
-
version = "0.8.
|
|
4
|
-
description = "
|
|
3
|
+
version = "0.8.1"
|
|
4
|
+
description = "Utilities programs for my Python code"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12"
|
|
7
7
|
dependencies = [
|
|
@@ -16,6 +16,8 @@ dependencies = [
|
|
|
16
16
|
"pandas>=2.3.2",
|
|
17
17
|
"pre-commit>=4.3.0",
|
|
18
18
|
"pytest>=8.4.2",
|
|
19
|
+
"mypy",
|
|
20
|
+
"ruff>=0.14.0",
|
|
19
21
|
"scikit-learn>=1.7.2",
|
|
20
22
|
"scipy>=1.16.2",
|
|
21
23
|
"seaborn>=0.13.2",
|
|
@@ -29,3 +31,6 @@ packages = ["bs_python_utils"]
|
|
|
29
31
|
|
|
30
32
|
[tool.setuptools.package-data]
|
|
31
33
|
"bs_python_utils" = ["examples/*", "examples/**/*"]
|
|
34
|
+
|
|
35
|
+
[tool.ruff]
|
|
36
|
+
line-length = 88
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_seaborn.py
RENAMED
|
File without changes
|
{bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils/examples/examples_sklearn.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bs_python_utils-0.8.0 → bs_python_utils-0.8.1}/bs_python_utils.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|