bs-python-utils 1.0.1__tar.gz → 1.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-1.0.1 → bs_python_utils-1.1}/PKG-INFO +3 -2
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/opt/bs_opt.py +4 -4
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/stats/bivariate_quantiles.py +94 -28
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils.egg-info/PKG-INFO +3 -2
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils.egg-info/requires.txt +1 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/pyproject.toml +7 -2
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/tests/test_bivariate_quantiles.py +20 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/LICENSE +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/README.md +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid1prec13.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid1prec17.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid1prec9.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid2prec13.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid2prec17.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid2prec9.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid3prec13.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid3prec17.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid3prec9.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid4prec13.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid4prec17.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid4prec9.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid5prec13.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid5prec17.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/GaussHermiteSparseGrids/GHsparseGrid5prec9.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/Timer.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/__init__.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/bivariate_quantiles.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/bs_altair.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/bs_logging.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/bs_mathstr.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/bs_mem.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/bs_opt.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/bs_plots.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/bs_seaborn.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/bs_sparse_gaussian.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/bsmplutils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/bsnputils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/bssputils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/bsstats.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/bsutils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/chebyshev.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/core/Timer.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/core/__init__.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/core/bs_logging.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/core/bs_mathstr.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/core/bs_mem.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/core/bsutils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/data_anal/__init__.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/data_anal/pandas_utils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/data_anal/sklearn_utils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/distance_covariances.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/examples/examples_altair.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/examples/examples_distance_covariances.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/examples/examples_mem.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/examples/examples_mpl.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/examples/examples_opt.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/examples/examples_seaborn.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/examples/examples_sklearn.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/examples/examples_sparse_gaussian.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/numerical/__init__.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/numerical/bs_sparse_gaussian.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/numerical/bsnputils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/numerical/bssputils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/numerical/chebyshev.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/opt/__init__.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/pandas_utils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/sklearn_utils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/stats/__init__.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/stats/bsstats.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/stats/distance_covariances.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/streamlit_utils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/viz/__init__.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/viz/bs_altair.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/viz/bs_plots.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/viz/bs_seaborn.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/viz/bsmplutils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/viz/streamlit_utils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils.egg-info/SOURCES.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils.egg-info/dependency_links.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils.egg-info/top_level.txt +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/setup.cfg +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/tests/test_bs_opt.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/tests/test_bs_sparse_gaussian.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/tests/test_bsnputils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/tests/test_bssputils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/tests/test_bsstats.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/tests/test_bsutils.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/tests/test_chebyshev.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/tests/test_nptri.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/tests/test_random_draws.py +0 -0
- {bs_python_utils-1.0.1 → bs_python_utils-1.1}/tests/test_sklearn_utils.py +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bs-python-utils
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1
|
|
4
4
|
Summary: Utilities programs for my Python code
|
|
5
|
-
Requires-Python: >=3.
|
|
5
|
+
Requires-Python: >=3.13
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
7
|
License-File: LICENSE
|
|
8
8
|
Requires-Dist: altair>=5.5.0
|
|
@@ -26,6 +26,7 @@ Requires-Dist: streamlit>=1.49.1
|
|
|
26
26
|
Requires-Dist: vega-datasets>=0.9.0
|
|
27
27
|
Requires-Dist: colorama>=0.4.6
|
|
28
28
|
Requires-Dist: pyarrow>=23.0.0
|
|
29
|
+
Requires-Dist: scipy-stubs~=1.16.2
|
|
29
30
|
Dynamic: license-file
|
|
30
31
|
|
|
31
32
|
## bs-python-utils
|
|
@@ -25,6 +25,7 @@ import numpy as np
|
|
|
25
25
|
import scipy.linalg as spla
|
|
26
26
|
import scipy.optimize as spopt
|
|
27
27
|
|
|
28
|
+
|
|
28
29
|
from bs_python_utils.numerical.bsnputils import TwoArrays, check_vector, npmaxabs
|
|
29
30
|
from bs_python_utils.core.bsutils import bs_error_abort, print_stars
|
|
30
31
|
from bs_python_utils.core.Timer import timeit
|
|
@@ -221,11 +222,11 @@ def check_gradient_scalar_function(
|
|
|
221
222
|
fg: should return the scalar value, and the gradient if its `gr` argument is `True`
|
|
222
223
|
p: where we are checking the gradient
|
|
223
224
|
args: other arguments passed to `fg`
|
|
224
|
-
mode: "central" or "forward"
|
|
225
|
-
EPS: the step for forward or central
|
|
225
|
+
mode: ``"central"`` or ``"forward"``
|
|
226
|
+
EPS: the step for forward or central finite differences
|
|
226
227
|
|
|
227
228
|
Returns:
|
|
228
|
-
the analytic and numeric gradients.
|
|
229
|
+
the analytic and numeric (or AD) gradients.
|
|
229
230
|
"""
|
|
230
231
|
f0, f_grad = fg(p, args, gr=True) # type: ignore
|
|
231
232
|
f0 = cast(float, f0)
|
|
@@ -285,7 +286,6 @@ def acc_grad_descent(
|
|
|
285
286
|
Returns:
|
|
286
287
|
A pair ``(x_star, status)`` where ``status`` is ``0`` on convergence and ``1`` otherwise.
|
|
287
288
|
"""
|
|
288
|
-
|
|
289
289
|
# no proximal projection if no h
|
|
290
290
|
local_prox_h: ProximalFunction = prox_h if prox_h else lambda x, t, p: x
|
|
291
291
|
|
|
@@ -15,6 +15,8 @@ References:
|
|
|
15
15
|
Quantiles, Ranks and Signs." *Annals of Statistics* 45(1), 2017.
|
|
16
16
|
"""
|
|
17
17
|
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
18
20
|
from typing import cast
|
|
19
21
|
|
|
20
22
|
import numpy as np
|
|
@@ -23,6 +25,74 @@ from bs_python_utils.core.bsutils import bs_error_abort
|
|
|
23
25
|
from bs_python_utils.numerical.bsnputils import TwoArrays, npmaxabs
|
|
24
26
|
from bs_python_utils.numerical.chebyshev import Interval, cheb_get_nodes_1d
|
|
25
27
|
from bs_python_utils.opt.bs_opt import minimize_free, print_optimization_results
|
|
28
|
+
from bs_python_utils.numerical.bsnputils import check_matrix
|
|
29
|
+
from scipy.special import logsumexp
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def bivariate_ranks_simul(
|
|
33
|
+
x: np.ndarray,
|
|
34
|
+
rng: np.random.Generator,
|
|
35
|
+
n_draws: int = 10_000,
|
|
36
|
+
h_mult: float = 100.0,
|
|
37
|
+
) -> np.ndarray:
|
|
38
|
+
"""This computes bivariate ranks for a matrix ``x` using simulations
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
x: Input matrix of shape ``(n, 2)``.
|
|
42
|
+
rng: Random number generator for reproducibility.
|
|
43
|
+
n_draws: Number of random draws for the simulation.
|
|
44
|
+
h_mult: we set the bandwidth h as std(v_init)/h_mult, default is 100.0
|
|
45
|
+
"""
|
|
46
|
+
n, d = check_matrix(x)
|
|
47
|
+
if d != 2:
|
|
48
|
+
bs_error_abort("Input matrix x must have 2 columns for bivariate ranks.")
|
|
49
|
+
|
|
50
|
+
v_init = np.mean(x, axis=1)[:-1]
|
|
51
|
+
h = np.std(v_init) / 100.0
|
|
52
|
+
|
|
53
|
+
tau_draws = rng.uniform(low=0.0, high=1.0, size=2 * n_draws).reshape((n_draws, 2))
|
|
54
|
+
|
|
55
|
+
def objv_and_grad(
|
|
56
|
+
v: np.ndarray,
|
|
57
|
+
ret: int = 0,
|
|
58
|
+
) -> float | np.ndarray | None:
|
|
59
|
+
vn = np.zeros(n)
|
|
60
|
+
vn[:-1] = v.copy()
|
|
61
|
+
vn[-1] = -np.sum(v)
|
|
62
|
+
psi_vals = tau_draws @ x.T - vn
|
|
63
|
+
lse_vals = logsumexp(psi_vals / h, axis=1)
|
|
64
|
+
psi_maxs = h * lse_vals
|
|
65
|
+
obj_val = np.mean(psi_maxs)
|
|
66
|
+
probs = np.exp(psi_vals / h - lse_vals.reshape((-1, 1)))
|
|
67
|
+
mean_probs = np.mean(probs, axis=0)
|
|
68
|
+
if ret == 0:
|
|
69
|
+
return obj_val
|
|
70
|
+
elif ret == 1:
|
|
71
|
+
grad = -mean_probs[:-1] + mean_probs[-1]
|
|
72
|
+
return grad
|
|
73
|
+
elif ret == 2:
|
|
74
|
+
ranks = (probs.T @ tau_draws / n_draws) / mean_probs.reshape((-1, 1))
|
|
75
|
+
return ranks
|
|
76
|
+
else:
|
|
77
|
+
bs_error_abort("Invalid value for ret. Must be 0, 1, or 2.")
|
|
78
|
+
return None
|
|
79
|
+
|
|
80
|
+
def objv(v: np.ndarray, args: list) -> float:
|
|
81
|
+
return objv_and_grad(v, ret=0)
|
|
82
|
+
|
|
83
|
+
def grad_objv(v: np.ndarray, args: list) -> np.ndarray:
|
|
84
|
+
return objv_and_grad(v, ret=1)
|
|
85
|
+
|
|
86
|
+
def ranks(v: np.ndarray, args: list) -> np.ndarray:
|
|
87
|
+
return objv_and_grad(v, ret=2)
|
|
88
|
+
|
|
89
|
+
resv = minimize_free(objv, grad_objv, v_init, args=[])
|
|
90
|
+
if not resv.success:
|
|
91
|
+
bs_error_abort(f"Optimization failed, message: {resv.message}")
|
|
92
|
+
|
|
93
|
+
v_sol = resv.x
|
|
94
|
+
r_x = ranks(v_sol, args=[])
|
|
95
|
+
return r_x
|
|
26
96
|
|
|
27
97
|
|
|
28
98
|
def _compute_ad(y: np.ndarray) -> TwoArrays:
|
|
@@ -54,16 +124,11 @@ def _compute_m_M(
|
|
|
54
124
|
Args:
|
|
55
125
|
v: Dual weights of length ``n``.
|
|
56
126
|
a_mat: Pairwise slope matrix returned by :func:`_compute_ad`.
|
|
57
|
-
dy2: Pairwise differences in the second coordinate.
|
|
127
|
+
dy2: Pairwise differences in the second coordinate (1 on diagonal).
|
|
58
128
|
tau1_nodes: Quadrature nodes for the first coordinate.
|
|
59
129
|
|
|
60
130
|
Returns:
|
|
61
131
|
A tuple ``(m, M)`` with arrays of shape ``(n, len(tau1_nodes))``.
|
|
62
|
-
|
|
63
|
-
Warning:
|
|
64
|
-
The (rare) ``dy2 == 0`` case currently raises warnings in computing ``b_mat``.
|
|
65
|
-
That logic works for the present implementation but should be refactored into a cleaner, more explicit
|
|
66
|
-
branch.
|
|
67
132
|
"""
|
|
68
133
|
dv = np.subtract.outer(v, v)
|
|
69
134
|
b_mat = dv / dy2
|
|
@@ -71,17 +136,12 @@ def _compute_m_M(
|
|
|
71
136
|
EPS = 1e-12
|
|
72
137
|
maskp = dy2 < EPS
|
|
73
138
|
maskm = dy2 > -EPS
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
f_matm = f_mat.copy()
|
|
81
|
-
f_matp[maskp] = 1
|
|
82
|
-
f_matm[maskm] = 0
|
|
83
|
-
m_low[:, i] = np.max(f_matm, axis=1)
|
|
84
|
-
m_high[:, i] = np.min(f_matp, axis=1)
|
|
139
|
+
# Vectorised over all quadrature nodes at once: (n_nodes, n, n)
|
|
140
|
+
f_mats = tau1_nodes[:, None, None] * a_mat[None, :, :] - b_mat[None, :, :]
|
|
141
|
+
f_mats_p = np.where(maskp, 1.0, f_mats)
|
|
142
|
+
f_mats_m = np.where(maskm, 0.0, f_mats)
|
|
143
|
+
m_low = np.max(f_mats_m, axis=2).T # (n, n_nodes)
|
|
144
|
+
m_high = np.min(f_mats_p, axis=2).T
|
|
85
145
|
return np.clip(m_low, 0.0, 1.0), np.clip(m_high, 0.0, 1.0)
|
|
86
146
|
|
|
87
147
|
|
|
@@ -132,11 +192,6 @@ def _objgrad(
|
|
|
132
192
|
tau1_weights = args[4]
|
|
133
193
|
vs1 = np.append(v, -np.sum(v))
|
|
134
194
|
m, M = _compute_m_M(vs1, a_mat, dy2, tau1_nodes)
|
|
135
|
-
# print(f"m is {m}")
|
|
136
|
-
# print(f"M is {M}")
|
|
137
|
-
# import sys
|
|
138
|
-
|
|
139
|
-
# sys.exit(1)
|
|
140
195
|
|
|
141
196
|
EPS = 1e-12
|
|
142
197
|
bivrank = np.zeros((n, 2))
|
|
@@ -190,7 +245,11 @@ def _grad(v: np.ndarray, args: list):
|
|
|
190
245
|
return grad_val
|
|
191
246
|
|
|
192
247
|
|
|
193
|
-
def _solve_for_v(
|
|
248
|
+
def _solve_for_v(
|
|
249
|
+
y: np.ndarray,
|
|
250
|
+
n_nodes: int = 32,
|
|
251
|
+
verbose: bool = False,
|
|
252
|
+
) -> TwoArrays:
|
|
194
253
|
"""Solve the dual optimization problem for the sample.
|
|
195
254
|
|
|
196
255
|
Args:
|
|
@@ -221,16 +280,21 @@ def _solve_for_v(y: np.ndarray, n_nodes: int = 32, verbose: bool = False) -> Two
|
|
|
221
280
|
argsog = [y, a_mat, dy2, tau1_nodes, tau1_weights, verbose]
|
|
222
281
|
|
|
223
282
|
res = minimize_free(_obj, _grad, v0, args=argsog)
|
|
283
|
+
|
|
224
284
|
if verbose:
|
|
225
285
|
print_optimization_results(res, "Minimizing over v")
|
|
226
286
|
|
|
227
287
|
if not res.success:
|
|
228
288
|
bs_error_abort("Problem! the optimization failed.")
|
|
229
|
-
|
|
289
|
+
|
|
290
|
+
vstar_free = res.x
|
|
291
|
+
|
|
230
292
|
if verbose:
|
|
231
293
|
print(f"The final gradient over v is close to 0: error {npmaxabs(res.jac)}")
|
|
232
|
-
|
|
233
|
-
|
|
294
|
+
|
|
295
|
+
_, _, bivranks = cast(tuple, _objgrad(vstar_free, argsog, gr=True))
|
|
296
|
+
|
|
297
|
+
vstar = np.append(vstar_free, -np.sum(vstar_free))
|
|
234
298
|
return cast(np.ndarray, vstar), cast(np.ndarray, bivranks)
|
|
235
299
|
|
|
236
300
|
|
|
@@ -255,11 +319,13 @@ def bivariate_ranks(
|
|
|
255
319
|
bs_error_abort(f"only works for 2-dimensional y, not for {d}")
|
|
256
320
|
|
|
257
321
|
_, bivranks = _solve_for_v(y, n_nodes, verbose)
|
|
258
|
-
return cast(np.ndarray, bivranks)
|
|
259
322
|
|
|
260
323
|
|
|
261
324
|
def bivariate_quantiles(
|
|
262
|
-
y: np.ndarray,
|
|
325
|
+
y: np.ndarray,
|
|
326
|
+
tau: np.ndarray,
|
|
327
|
+
n_nodes: int = 32,
|
|
328
|
+
verbose: bool = False,
|
|
263
329
|
) -> np.ndarray:
|
|
264
330
|
"""Solve for the dual weights and evaluate bivariate quantiles.
|
|
265
331
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bs-python-utils
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1
|
|
4
4
|
Summary: Utilities programs for my Python code
|
|
5
|
-
Requires-Python: >=3.
|
|
5
|
+
Requires-Python: >=3.13
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
7
7
|
License-File: LICENSE
|
|
8
8
|
Requires-Dist: altair>=5.5.0
|
|
@@ -26,6 +26,7 @@ Requires-Dist: streamlit>=1.49.1
|
|
|
26
26
|
Requires-Dist: vega-datasets>=0.9.0
|
|
27
27
|
Requires-Dist: colorama>=0.4.6
|
|
28
28
|
Requires-Dist: pyarrow>=23.0.0
|
|
29
|
+
Requires-Dist: scipy-stubs~=1.16.2
|
|
29
30
|
Dynamic: license-file
|
|
30
31
|
|
|
31
32
|
## bs-python-utils
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "bs-python-utils"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.1"
|
|
4
4
|
description = "Utilities programs for my Python code"
|
|
5
5
|
readme = "README.md"
|
|
6
|
-
requires-python = ">=3.
|
|
6
|
+
requires-python = ">=3.13"
|
|
7
7
|
dependencies = [
|
|
8
8
|
"altair>=5.5.0",
|
|
9
9
|
"altair-saver>=0.5.0",
|
|
@@ -26,8 +26,13 @@ dependencies = [
|
|
|
26
26
|
"vega-datasets>=0.9.0",
|
|
27
27
|
"colorama>=0.4.6",
|
|
28
28
|
"pyarrow>=23.0.0",
|
|
29
|
+
"scipy-stubs~=1.16.2",
|
|
29
30
|
]
|
|
30
31
|
|
|
32
|
+
[build-system]
|
|
33
|
+
requires = ["setuptools>=61"]
|
|
34
|
+
build-backend = "setuptools.build_meta"
|
|
35
|
+
|
|
31
36
|
[tool.setuptools.packages.find]
|
|
32
37
|
where = ["."]
|
|
33
38
|
include = ["bs_python_utils*"]
|
|
@@ -4,6 +4,7 @@ from bs_python_utils.numerical.bsnputils import npmaxabs
|
|
|
4
4
|
from bs_python_utils.stats.bivariate_quantiles import (
|
|
5
5
|
_compute_ad,
|
|
6
6
|
_solve_for_v,
|
|
7
|
+
bivariate_ranks_simul,
|
|
7
8
|
)
|
|
8
9
|
|
|
9
10
|
|
|
@@ -27,6 +28,25 @@ def test_bivariate_ranks():
|
|
|
27
28
|
assert npmaxabs(bivranks - bivranks_th) < 0.1
|
|
28
29
|
|
|
29
30
|
|
|
31
|
+
def test_bivariate_ranks_simul():
|
|
32
|
+
rng = np.random.default_rng(123)
|
|
33
|
+
n = 500
|
|
34
|
+
y = rng.normal(size=(n, 2))
|
|
35
|
+
|
|
36
|
+
bivranks = bivariate_ranks_simul(y, rng)
|
|
37
|
+
|
|
38
|
+
bivranks_th = np.empty_like(bivranks)
|
|
39
|
+
for k in range(n):
|
|
40
|
+
bivranks_th[k, 0] = np.mean(y[:, 0] < y[k, 0]) + 0.5 * np.mean(
|
|
41
|
+
y[:, 0] == y[k, 0]
|
|
42
|
+
)
|
|
43
|
+
bivranks_th[k, 1] = np.mean(y[:, 1] < y[k, 1]) + 0.5 * np.mean(
|
|
44
|
+
y[:, 1] == y[k, 1]
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
assert npmaxabs(bivranks - bivranks_th) < 0.1
|
|
48
|
+
|
|
49
|
+
|
|
30
50
|
def test_compute_ad():
|
|
31
51
|
y = np.array([[0.0, 1.0], [1.0, 1.3], [-1.0, 3.0]])
|
|
32
52
|
a_mat, dy2 = _compute_ad(y)
|
|
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
|
|
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
|
|
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
|
|
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-1.0.1 → bs_python_utils-1.1}/bs_python_utils/examples/examples_sparse_gaussian.py
RENAMED
|
File without changes
|
|
File without changes
|
{bs_python_utils-1.0.1 → bs_python_utils-1.1}/bs_python_utils/numerical/bs_sparse_gaussian.py
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|