diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70e0082..c1d5528 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,7 +47,7 @@ jobs: run: | FMT=xml pixi run test-coverage - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v5.0.2 + uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} - name: Build SDist diff --git a/doc/index.rst b/doc/index.rst index 090401b..75bd283 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -22,6 +22,13 @@ API Reference extend ssc ols + make_poly_ids + make_poly_features + make_time_shift_features + make_time_shift_ids + make_narx + print_narx + Narx Useful Links ------------ diff --git a/fastcan/__init__.py b/fastcan/__init__.py index dee6cfc..e89cf40 100644 --- a/fastcan/__init__.py +++ b/fastcan/__init__.py @@ -4,6 +4,15 @@ from ._extend import extend from ._fastcan import FastCan +from ._narx import ( + Narx, + make_narx, + make_poly_features, + make_poly_ids, + make_time_shift_features, + make_time_shift_ids, + print_narx, +) from ._refine import refine from ._utils import ols, ssc @@ -13,4 +22,11 @@ "ols", "refine", "extend", + "make_narx", + "print_narx", + "Narx", + "make_poly_features", + "make_poly_ids", + "make_time_shift_features", + "make_time_shift_ids", ] diff --git a/fastcan/_narx.py b/fastcan/_narx.py new file mode 100644 index 0000000..4f9d29a --- /dev/null +++ b/fastcan/_narx.py @@ -0,0 +1,856 @@ +""" +This file contains Narx model class. +""" + +import math +from itertools import combinations_with_replacement +from numbers import Integral, Real + +import numpy as np +from scipy.optimize import least_squares +from scipy.stats import rankdata +from sklearn.base import BaseEstimator, RegressorMixin +from sklearn.linear_model import LinearRegression +from sklearn.utils import check_array, check_X_y +from sklearn.utils._param_validation import Interval, StrOptions, validate_params +from sklearn.utils.validation import check_is_fitted + +from ._fastcan import FastCan +from ._refine import refine + + +@validate_params( + {"X": ["array-like"], "ids": ["array-like"]}, + prefer_skip_nested_validation=True, +) +def make_time_shift_features(X, ids): + """Make time shift features. + + Parameters + ---------- + X : array-likeof shape (n_samples, n_features) + The data to transform, column by column. + + ids : array-like of shape (n_outputs, 2) + The unique id numbers of output features, which are + (feature_idx, delay). + + Returns + ------- + out : ndarray of shape (n_samples, n_outputs) + The matrix of features, where `n_outputs` is the number of time shift + features generated from the combination of inputs. + + Examples + -------- + >>> from fastcan import make_time_shift_features + >>> X = [[1, 2], [3, 4], [5, 6], [7, 8]] + >>> ids = [[0, 0], [0, 1], [1, 1]] + >>> make_time_shift_features(X, ids) + array([[1., 1., 2.], + [3., 1., 2.], + [5., 3., 4.], + [7., 5., 6.]]) + """ + X = check_array(X, ensure_2d=True, dtype=float) + ids = check_array(ids, ensure_2d=True, dtype=int) + n_samples = X.shape[0] + n_outputs = ids.shape[0] + out = np.zeros([n_samples, n_outputs]) + for i, id_temp in enumerate(ids): + out[:, i] = np.r_[ + np.full(id_temp[1], X[0, id_temp[0]]), + X[: -id_temp[1] or None, id_temp[0]], + ] + + return out + + +@validate_params( + { + "n_features": [ + Interval(Integral, 1, None, closed="left"), + ], + "max_delay": [ + Interval(Integral, 0, None, closed="left"), + ], + "include_zero_delay": ["boolean", "array-like"], + }, + prefer_skip_nested_validation=True, +) +def make_time_shift_ids( + n_features=1, + max_delay=1, + include_zero_delay=False, +): + """Generate ids for time shift features. + (variable_index, delay_number) + + Parameters + ---------- + n_features: int, default=1 + The number of input features. + + max_delay : int, default=1 + The maximum delay of time shift features. + + include_zero_delay : {bool, array-like} of shape (n_features,) default=False + Whether to include the original (zero-delay) features. + + Returns + ------- + ids : array-like of shape (`n_output_features_`, 2) + The unique id numbers of output features. + + Examples + -------- + >>> from fastcan import make_time_shift_ids + >>> make_time_shift_ids(2, max_delay=3, include_zero_delay=[True, False]) + array([[0, 0], + [0, 1], + [0, 2], + [0, 3], + [1, 1], + [1, 2], + [1, 3]]) + """ + if isinstance(include_zero_delay, bool): + return np.stack( + np.meshgrid( + range(n_features), + range(not include_zero_delay, max_delay + 1), + indexing="ij", + ), + -1, + ).reshape(-1, 2) + + include_zero_delay = check_array(include_zero_delay, ensure_2d=False, dtype=bool) + if include_zero_delay.shape[0] != n_features: + raise ValueError( + f"The length of `include_zero_delay`={include_zero_delay} " + f"should be equal to `n_features`={n_features}." + ) + + ids = np.stack( + np.meshgrid( + range(n_features), + range(max_delay + 1), + indexing="ij", + ), + -1, + ).reshape(-1, 2) + exclude_zero_delay_idx = np.where(~include_zero_delay)[0] + mask = np.isin(ids[:, 0], exclude_zero_delay_idx) & (ids[:, 1] == 0) + return ids[~mask] + + +@validate_params( + {"X": ["array-like"], "ids": ["array-like"]}, + prefer_skip_nested_validation=True, +) +def make_poly_features(X, ids): + """Make polynomial features. + + Parameters + ---------- + X : array-like of shape (n_samples, n_features) + The data to transform, column by column. + + ids : array-like of shape (n_outputs, degree) + The unique id numbers of output features, which are formed + of non-negative int values. + + Returns + ------- + out.T : ndarray of shape (n_samples, n_outputs) + The matrix of features, where n_outputs is the number of polynomial + features generated from the combination of inputs. + + Examples + -------- + >>> from fastcan import make_poly_features + >>> X = [[1, 2], [3, 4], [5, 6], [7, 8]] + >>> ids = [[0, 0], [0, 1], [1, 1], [0, 2]] + >>> make_poly_features(X, ids) + array([[ 1., 1., 1., 2.], + [ 1., 3., 9., 4.], + [ 1., 5., 25., 6.], + [ 1., 7., 49., 8.]]) + """ + X = check_array(X, ensure_2d=True, dtype=float) + ids = check_array(ids, ensure_2d=True, dtype=int) + n_samples = X.shape[0] + n_outputs, degree = ids.shape + + # Generate polynomial features + out = np.ones([n_outputs, n_samples]) + unique_features = np.unique(ids) + unique_features = unique_features[unique_features != 0] + for i in range(degree): + for j in unique_features: + mask = ids[:, i] == j + out[mask, :] *= X[:, j - 1] + + return out.T + + +@validate_params( + { + "n_features": [ + Interval(Integral, 1, None, closed="left"), + ], + "degree": [ + None, + Interval(Integral, 1, None, closed="left"), + ], + }, + prefer_skip_nested_validation=True, +) +def make_poly_ids( + n_features=1, + degree=1, +): + """Generate ids for polynomial features. + (variable_index, variable_index, ...) + variable_index starts from 1, and 0 represents constant. + + Parameters + ---------- + n_features: int, default=1 + The number of input features. + + degree : int, default=1 + The maximum degree of polynomial features. + + Returns + ------- + ids : array-like of shape (n_outputs, degree) + The unique id numbers of output features. + + Examples + -------- + >>> from fastcan import make_poly_ids + >>> make_poly_ids(2, degree=3) + array([[0, 0, 1], + [0, 0, 2], + [0, 1, 1], + [0, 1, 2], + [0, 2, 2], + [1, 1, 1], + [1, 1, 2], + [1, 2, 2], + [2, 2, 2]]) + """ + n_outputs = math.comb(n_features + degree, degree) - 1 + if n_outputs > np.iinfo(np.intp).max: + msg = ( + "The output that would result from the current configuration would" + f" have {n_outputs} features which is too large to be" + f" indexed by {np.intp().dtype.name}." + ) + raise ValueError(msg) + + ids = np.array( + list( + combinations_with_replacement( + range(n_features + 1), + degree, + ) + ) + ) + + const_id = np.where((ids == 0).all(axis=1)) + return np.delete(ids, const_id, 0) # remove the constant featrue + + +class Narx(BaseEstimator, RegressorMixin): + """Nonlinear Autoregressive eXogenous model. + For example, a (polynomial) Narx model is like + y(t) = y(t-1)*u(t-1) + u(t-1)^2 + u(t-2) + 1.5 + where y(t) is the system output at time t, + u(t) is the system input at time t, + u(t-1) is called a (time shift) variable, and + u(t-1)^2 is called a (polynomial) term. + + Parameters + ---------- + time_shift_ids : array-like of shape (n_variables, 2), default=None + The unique id numbers of time shift variables, which are + (feature_idx, delay). The ids are used to generate time + shift variables, such as u(k-1), and y(k-2). + + poly_ids : array-like of shape (n_polys, degree), default=None + The unique id numbers of polynomial terms, excluding the intercept. + Here n_terms = n_polys + 1 (intercept). + The ids are used to generate polynomial terms, such as u(k-1)^2, + and u(k-1)*y(k-2). + + Attributes + ---------- + coef_ : array of shape (`n_features_in_`,) + Estimated coefficients for the linear regression problem. + + intercept_ : float + Independent term in the linear model. + + n_features_in_ : int + Number of features seen during :term:`fit`. + + feature_names_in_ : ndarray of shape (`n_features_in_`,) + Names of features seen during :term:`fit`. Defined only when `X` + has feature names that are all strings. + + expression_ : str + The lambda exprssion of the model in the string form. + + max_delay_ : int + The maximum time delay of the time shift variables. + + time_shift_ids_ : array-like of shape (n_variables, 2) + The unique id numbers of time shift variables, which are + (feature_idx, delay). + + poly_ids_ : array-like of shape (n_polys, degree) + The unique id numbers of polynomial terms, excluding the intercept. + + References + ---------- + * Billings, Stephen A. (2013). + Nonlinear System Identification: Narmax Methods in the Time, Frequency, + and Spatio-Temporal Domains. + + Examples + -------- + >>> import numpy as np + >>> from fastcan import Narx, print_narx + >>> rng = np.random.default_rng(12345) + >>> n_samples = 1000 + >>> max_delay = 3 + >>> e = rng.normal(0, 0.1, n_samples) + >>> u = rng.uniform(0, 1, n_samples+max_delay) # input + >>> y = np.zeros(n_samples+max_delay) # output + >>> for i in range(max_delay, n_samples+max_delay): + ... y[i] = 0.5*y[i-1] + 0.7*u[i-2] + 1.5*u[i-1]*u[i-3] + 1 + >>> y = y[max_delay:]+e + >>> X = u[max_delay:].reshape(-1, 1) + >>> time_shift_ids = [[0, 1], # u(k-1) + ... [0, 2], # u(k-2) + ... [0, 3], # u(k-3) + ... [1, 1]] # y(k-1) + >>> poly_ids = [[0, 2], # 1*u(k-1) + ... [0, 4], # 1*y(k-1) + ... [1, 3]] # u(k-1)*u(k-3) + >>> narx = Narx(time_shift_ids=time_shift_ids, + ... poly_ids=poly_ids).fit(X, y, coef_init="one_step_ahead") + >>> print_narx(narx) + | Term | Coef | + ================================= + | Intercept | 1.008 | + | X[k-2,0] | 0.701 | + | y_hat[k-1] | 0.498 | + | X[k-1,0]*X[k-3,0] | 1.496 | + """ + + _parameter_constraints: dict = { + "time_shift_ids": [None, "array-like"], + "poly_ids": [None, "array-like"], + } + + def __init__( + self, + *, # keyword call only + time_shift_ids=None, + poly_ids=None, + ): + self.time_shift_ids = time_shift_ids + self.poly_ids = poly_ids + + @validate_params( + { + "coef_init": [None, StrOptions({"one_step_ahead"}), "array-like"], + }, + prefer_skip_nested_validation=True, + ) + def fit(self, X, y, coef_init=None, **params): + """ + Fit narx model. + + Parameters + ---------- + X : {array-like, sparse matrix} of shape (n_samples, `n_features_in_`) + Training data. + + y : array-like of shape (n_samples,) + Target values. Will be cast to X's dtype if necessary. + + coef_init : array-like of shape (n_terms,), default=None + The initial values of coefficients and intercept for optimization. + When `coef_init` is None, the model will be a One-Step-Ahead Narx. + When `coef_init` is `one_step_ahead`, the model will be a Multi-Step-Ahead + Narx whose coefficients and intercept are initialized by the a + One-Step-Ahead Narx. + When `coef_init` is an array, the model will be a Multi-Step-Ahead + Narx whose coefficients and intercept are initialized by the array. + + **params : dict + Keyword arguments passed to + `scipy.optimize.least_squares`. + + Returns + ------- + self : object + Fitted Estimator. + """ + X, y = self._validate_data(X, y, y_numeric=True, multi_output=False) + + if self.time_shift_ids is None: + self.time_shift_ids_ = make_time_shift_ids( + n_features=X.shape[1], + max_delay=0, + include_zero_delay=True, + ) + else: + self.time_shift_ids_ = check_array( + self.time_shift_ids, + ensure_2d=True, + dtype=Integral, + ) + if (self.time_shift_ids_[:, 0].min() < 0) or ( + self.time_shift_ids_[:, 0].max() >= X.shape[1] + 1 + ): + raise ValueError( + "The element x of the first column of time_shift_ids should " + f"satisfy 0 <= x < {X.shape[1]+1}." + ) + if (self.time_shift_ids_[:, 1].min() < 0) or ( + self.time_shift_ids_[:, 1].max() >= X.shape[0] + ): + raise ValueError( + "The element x of the second column of time_shift_ids should " + f"satisfy 0 <= x < {X.shape[0]}." + ) + + if self.poly_ids is None: + self.poly_ids_ = make_poly_ids(X.shape[1], 1) + else: + self.poly_ids_ = check_array( + self.poly_ids, + ensure_2d=True, + dtype=Integral, + ) + if (self.poly_ids_.min() < 0) or ( + self.poly_ids_.max() > self.time_shift_ids_.shape[0] + ): + raise ValueError( + "The element x of poly_ids should " + f"satisfy 0 <= x <= {self.time_shift_ids_.shape[0]}." + ) + + self.max_delay_ = self.time_shift_ids_[:, 1].max() + n_terms = self.poly_ids_.shape[0] + 1 + + if isinstance(coef_init, (type(None), str)): + # fit a one-step-ahead Narx model + xy_hstack = np.c_[X, y] + osa_narx = LinearRegression() + time_shift_terms = make_time_shift_features(xy_hstack, self.time_shift_ids_) + poly_terms = make_poly_features(time_shift_terms, self.poly_ids_) + + osa_narx.fit(poly_terms, y) + if coef_init is None: + self.coef_ = osa_narx.coef_ + self.intercept_ = osa_narx.intercept_ + return self + + coef_init = np.r_[osa_narx.coef_, osa_narx.intercept_] + else: + coef_init = check_array( + coef_init, + ensure_2d=False, + dtype=np.float64, + ) + if coef_init.shape[0] != n_terms: + raise ValueError( + "`coef_init` should have the shape of " + f"(`n_terms`,), i.e., ({n_terms,}), " + f"but got {coef_init.shape}." + ) + + lsq = least_squares( + Narx._residual, + x0=coef_init, + args=( + self._expression, + X, + y, + self.max_delay_, + ), + **params, + ) + self.coef_ = lsq.x[:-1] + self.intercept_ = lsq.x[-1] + return self + + def _get_variable(self, time_shift_id, X, y_hat, k): + if time_shift_id[0] < self.n_features_in_: + variable = X[k - time_shift_id[1], time_shift_id[0]] + else: + variable = y_hat[k - time_shift_id[1]] + return variable + + def _get_term(self, term_id, X, y_hat, k): + term = 1 + for _, variable_id in enumerate(term_id): + if variable_id != 0: + time_shift_id = self.time_shift_ids_[variable_id - 1] + term *= self._get_variable(time_shift_id, X, y_hat, k) + return term + + def _expression(self, X, y_hat, coef, intercept, k): + y_pred = intercept + for i, term_id in enumerate(self.poly_ids_): + y_pred += coef[i] * self._get_term(term_id, X, y_hat, k) + return y_pred + + @staticmethod + def _predict(expression, X, y_init, coef, intercept, max_delay): + n_samples = X.shape[0] + y_hat = np.zeros(n_samples) + y_hat[:max_delay] = y_init + for k in range(max_delay, n_samples): + y_hat[k] = expression(X, y_hat, coef, intercept, k) + if np.any(y_hat[k] > 1e20): + y_hat[k:] = np.inf + return y_hat + return y_hat + + @staticmethod + def _residual( + coef_intercept, + expression, + X, + y, + max_delay, + ): + coef = coef_intercept[:-1] + intercept = coef_intercept[-1] + + return ( + y - Narx._predict(expression, X, y[:max_delay], coef, intercept, max_delay) + ).flatten() + + @validate_params( + { + "y_init": [None, "array-like"], + }, + prefer_skip_nested_validation=True, + ) + def predict(self, X, y_init=None): + """ + Predict using the linear model. + + Parameters + ---------- + X : array-like of shape (n_samples, `n_features_in_`) + Samples. + + y_init : array-like of shape (`max_delay`,), default=None + The initial values for the prediction of y. + + Returns + ------- + y_hat : array-like of shape (n_samples,) + Returns predicted values. + """ + check_is_fitted(self) + + X = self._validate_data(X, reset=False) + if y_init is None: + y_init = np.zeros(self.max_delay_) + else: + y_init = check_array(y_init, ensure_2d=False, dtype=np.float64) + if y_init.shape[0] != self.max_delay_: + raise ValueError( + "`y_init` should have the shape of " + "(`max_delay`,), i.e., " + f"({self.max_delay_},), " + f"but got {y_init.shape}." + ) + + return Narx._predict( + self._expression, + X, + y_init, + self.coef_, + self.intercept_, + self.max_delay_, + ) + + +@validate_params( + { + "narx": [Narx], + "term_space": [Interval(Integral, 1, None, closed="left")], + "coef_space": [Interval(Integral, 1, None, closed="left")], + "float_precision": [Interval(Integral, 0, None, closed="left")], + }, + prefer_skip_nested_validation=True, +) +def print_narx( + narx, + term_space=20, + coef_space=10, + float_precision=3, +): + """Print a Narx model as a Table which contains Term and Coef. + + Parameters + ---------- + narx : Narx model + The Narx model to be printed. + + term_space: int, default=20 + The space for the column of Term. + + coef_space: int, default=10 + The space for the column of Coef. + + float_precision: int, default=3 + The number of places after the decimal for Coef. + + Returns + ------- + table : str + The table of terms and coefficients of the Narx model. + + Examples + -------- + >>> from sklearn.datasets import load_diabetes + >>> from fastcan import print_narx, Narx + >>> X, y = load_diabetes(return_X_y=True) + >>> print_narx(Narx().fit(X, y), term_space=10, coef_space=5, float_precision=0) + | Term |Coef | + ================== + |Intercept | 152 | + | X[k-0,0] | -10 | + | X[k-0,1] |-240 | + | X[k-0,2] | 520 | + | X[k-0,3] | 324 | + | X[k-0,4] |-792 | + | X[k-0,5] | 477 | + | X[k-0,6] | 101 | + | X[k-0,7] | 177 | + | X[k-0,8] | 751 | + | X[k-0,9] | 68 | + """ + check_is_fitted(narx) + def _get_variable_str(time_shift_id): + if time_shift_id[0] < narx.n_features_in_: + variable_str = f"X[k-{time_shift_id[1]},{time_shift_id[0]}]" + else: + variable_str = f"y_hat[k-{time_shift_id[1]}]" + return variable_str + + def _get_term_str(term_id): + term_str = "" + for _, variable_id in enumerate(term_id): + if variable_id != 0: + time_shift_id = narx.time_shift_ids_[variable_id - 1] + term_str += "*" + _get_variable_str(time_shift_id) + return term_str[1:] + + print(f"|{'Term':^{term_space}}" + f"|{'Coef':^{coef_space}}|") + print("=" * (term_space + coef_space + 3)) + print( + f"|{'Intercept':^{term_space}}|" + + f"{narx.intercept_:^{coef_space}.{float_precision}f}|" + ) + for i, term_id in enumerate(narx.poly_ids_): + print( + f"|{_get_term_str(term_id):^{term_space}}|" + + f"{narx.coef_[i]:^{coef_space}.{float_precision}f}|" + ) + + +@validate_params( + { + "X": ["array-like"], + "y": ["array-like"], + "n_features_to_select": [ + Interval(Integral, 1, None, closed="left"), + ], + "max_delay": [ + Interval(Integral, 1, None, closed="left"), + ], + "poly_degree": [ + Interval(Integral, 1, None, closed="left"), + ], + "include_zero_delay": [None, "array-like"], + "static_indices": [None, "array-like"], + "eta": ["boolean"], + "verbose": ["verbose"], + "drop": [ + None, + Interval(Integral, 1, None, closed="left"), + StrOptions({"all"}), + ], + "max_iter": [ + None, + Interval(Integral, 1, None, closed="left"), + ], + }, + prefer_skip_nested_validation=True, +) +def make_narx( + X, + y, + n_features_to_select, + max_delay=1, + poly_degree=1, + *, + include_zero_delay=None, + static_indices=None, + eta=False, + verbose=1, + drop=None, + max_iter=None, +): + """Find `time_shift_ids` and `poly_ids` for a Narx model. + + Parameters + ---------- + X : array-like of shape (n_samples, n_features) + Feature matrix. + + y : array-like of shape (n_samples,) + Target matrix. + + n_features_to_select : int + The parameter is the absolute number of features to select. + + max_delay : int, default=1 + The maximum delay of time shift features. + + poly_degree : int, default=1 + The maximum degree of polynomial features. + + include_zero_delay : {None, array-like} of shape (n_features,) default=None + Whether to include the original (zero-delay) features. + + static_indices : {None, array-like} of shape (n_static_features,) default=None + The indices of static features without time delay. + + .. note:: + If the corresponding include_zero_delay of the static features is False, the + static feature will be excluded from candidate features. + + eta : bool, default=False + Whether to use eta-cosine method. + + verbose : int, default=1 + The verbosity level. + + drop : int or "all", default=None + The number of the selected features dropped for the consequencing + reselection. If `drop` is None, no refining will be performed. + + max_iter : int, default=None + The maximum number of valid iterations in the refining process. + + Returns + ------- + narx : Narx + Narx instance. + + Examples + -------- + >>> import numpy as np + >>> from sklearn.metrics import mean_squared_error + >>> from fastcan import make_narx, print_narx + >>> rng = np.random.default_rng(12345) + >>> n_samples = 1000 + >>> max_delay = 3 + >>> e = rng.normal(0, 0.1, n_samples) + >>> u0 = rng.uniform(0, 1, n_samples+max_delay) # input + >>> u1 = rng.normal(0, 0.1, n_samples) # static input (i.e. no time shift) + >>> y = np.zeros(n_samples+max_delay) # output + >>> for i in range(max_delay, n_samples+max_delay): + ... y[i] = (0.5*y[i-1] + 0.3*u0[i]**2 + 2*u0[i-1]*u0[i-3] + + ... 1.5*u0[i-2]*u1[i-max_delay] + 1) + >>> y = y[max_delay:]+e + >>> X = np.c_[u0[max_delay:], u1] + >>> narx = make_narx(X=X, + ... y=y, + ... n_features_to_select=4, + ... max_delay=3, + ... poly_degree=2, + ... static_indices=[1], + ... eta=True, + ... verbose=0, + ... drop=1) + >>> print(f"{mean_squared_error(y, narx.fit(X, y).predict(X)):.4f}") + 0.0289 + >>> print_narx(narx) + | Term | Coef | + ================================= + | Intercept | 1.054 | + | y_hat[k-1] | 0.483 | + | X[k-0,0]*X[k-0,0] | 0.307 | + | X[k-1,0]*X[k-3,0] | 1.999 | + | X[k-2,0]*X[k-0,1] | 1.527 | + """ + X, y = check_X_y(X, y, dtype=Real, multi_output=False) + + xy_hstack = np.c_[X, y] + n_features = X.shape[1] + n_outputs = xy_hstack.shape[1] - n_features + + if include_zero_delay is None: + include_zero_delay = [True] * n_features + [False] * n_outputs + + time_shift_ids_all = make_time_shift_ids( + n_features=xy_hstack.shape[1], + max_delay=max_delay, + include_zero_delay=include_zero_delay, + ) + + time_shift_ids_all = np.delete( + time_shift_ids_all, + ( + np.isin(time_shift_ids_all[:, 0], static_indices) + & (time_shift_ids_all[:, 1] > 0) + ), + 0, + ) + time_shift_terms = make_time_shift_features(xy_hstack, time_shift_ids_all) + + poly_ids_all = make_poly_ids( + time_shift_ids_all.shape[0], + poly_degree, + ) + poly_terms = make_poly_features(time_shift_terms, poly_ids_all) + + csf = FastCan( + n_features_to_select, + eta=eta, + verbose=0, + ).fit(poly_terms, y) + if drop is not None: + indices, _ = refine(csf, drop=drop, max_iter=max_iter, verbose=verbose) + support = np.zeros(shape=csf.n_features_in_, dtype=bool) + support[indices] = True + else: + support = csf.get_support() + selected_poly_ids = poly_ids_all[support] + time_shift_ids = time_shift_ids_all[ + np.unique(selected_poly_ids[selected_poly_ids.nonzero()]) - 1, : + ] + poly_ids = ( + rankdata( + np.r_[[[0] * poly_degree], selected_poly_ids], + method="dense", + ).reshape(-1, poly_degree)[1:] + - 1 + ) + + return Narx(time_shift_ids=time_shift_ids, poly_ids=poly_ids) diff --git a/pixi.lock b/pixi.lock index 8d06b2d..8531b61 100644 --- a/pixi.lock +++ b/pixi.lock @@ -14,7 +14,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.8.30-hbcca054_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.6.4-py312h178313f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.6.8-py312h178313f_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cython-3.0.11-py312h8fd2918_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cython-lint-0.16.6-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_0.conda @@ -48,7 +48,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.12.1-h297d8ca_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.1.3-py312h58c1407_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.4.0-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.2-pyhff2d567_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py312hf9745cd_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_0.conda @@ -60,12 +61,16 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.12.7-hc5c86c4_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-build-1.2.2.post1-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.12-5_cp312.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.7.3-py312h2156523_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.8.0-py312h2156523_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.5.2-py312h7a48858_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.14.1-py312h62794b6_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.3.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tokenize-rt-6.1.0-pyhd8ed1ab_0.conda @@ -73,31 +78,29 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.1.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.5.1-h0f3a69f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/uv-0.5.4-h0f3a69f_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.21.0-pyhd8ed1ab_0.conda - pypi: https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/25/c2/fc7193cc5383637ff390a712e88e4ded0452c9fbcf84abe3de5ea3df1866/contourpy-1.3.1.tar.gz + - pypi: https://files.pythonhosted.org/packages/16/92/92a76dc2ff3a12e69ba94e7e05168d37d0345fa08c87e1fe24d0c2a42223/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/ba/99/6794142b90b853a9155316c8f470d2e4821fe6f086b03e372aca848227dd/contourpy-1.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/57/5e/de2e6e51cb6894f2f2bc2641f6c845561361b622e96df3cca04df77222c9/fonttools-4.54.1-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/fc/0b/dbe13f2c8d745ffdf5c2bc25391263927d4ec2b927e44d5d5f70cd372873/fonttools-4.55.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl - pypi: https://files.pythonhosted.org/packages/27/48/e791a7ed487dbb9729ef32bb5d1af16693d8925f4366befef54119b2e576/furo-2024.8.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/85/4d/2255e1c76304cbd60b48cee302b66d1dde4468dc5b1160e4b7cb43778f2a/kiwisolver-1.4.7.tar.gz - - pypi: https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz - - pypi: https://files.pythonhosted.org/packages/9e/d8/3d7f706c69e024d4287c1110d74f7dabac91d9843b99eadc90de9efc8869/matplotlib-3.9.2.tar.gz - - pypi: https://files.pythonhosted.org/packages/a5/26/0d95c04c868f6bdb0c447e3ee2de5564411845e36a858cfd63766bc7b563/pillow-11.0.0.tar.gz + - pypi: https://files.pythonhosted.org/packages/21/e4/c0b6746fd2eb62fe702118b3ca0cb384ce95e1261cfada58ff693aeec08a/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/27/75/de5b9cd67648051cae40039da0c8cbc497a0d99acb1a1f3d087cd66d27b7/matplotlib-3.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/7f/42/6e0f2c2d5c60f499aa29be14f860dd4539de322cd8fb84ee01553493fb4d/pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/be/ec/2eb3cd785efd67806c46c13a17339708ddc346cbb684eade7a6e6f79536a/pyparsing-3.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/26/60/1ddff83a56d33aaf6f10ec8ce84b4c007d9368b21008876fceda7e7381ef/sphinx-8.1.3-py3-none-any.whl @@ -121,17 +124,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/cctools_osx-64-1010.6-h98e843e_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/clang-17-17.0.6-default_hb173f14_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/clang-17.0.6-default_he371ed4_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/clang_impl_osx-64-17.0.6-h1af8efd_21.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/clang_osx-64-17.0.6-hb91bd55_21.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clang_impl_osx-64-17.0.6-h1af8efd_23.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clang_osx-64-17.0.6-h7e5c614_23.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx-17.0.6-default_he371ed4_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_impl_osx-64-17.0.6-hc3430b7_21.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_osx-64-17.0.6-hb91bd55_21.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_impl_osx-64-17.0.6-hc3430b7_23.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_osx-64-17.0.6-h7e5c614_23.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/compiler-rt-17.0.6-h1020d70_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-64-17.0.6-hf2b8a54_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/compilers-1.8.0-h694c41f_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.6.4-py313h25ec13a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.6.8-py313h717bdf5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cxx-compiler-1.8.0-h385f146_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cython-3.0.11-py313h496bac6_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cython-lint-0.16.6-pyhff2d567_0.conda @@ -151,7 +154,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.9.0-25_osx64_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.9.0-25_osx64_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libclang-cpp17-17.0.6-default_hb173f14_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-19.1.3-hf95d169_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-19.1.4-hf95d169_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-devel-17.0.6-h8f8a49f_6.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.6.4-h240833e_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.2-h0d85af4_5.tar.bz2 @@ -166,7 +169,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.47.0-h2f8c449_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.13.5-h495214b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-19.1.3-hf78d878_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-19.1.4-ha54dae1_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-tools-17.0.6-hbedff68_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/meson-1.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_0.conda @@ -178,7 +181,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/ninja-1.12.1-h3c5361c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.1.3-py313h7ca3f3b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.4.0-hd471939_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.2-pyhff2d567_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pandas-2.2.3-py313h38cdd20_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_0.conda @@ -190,13 +194,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.0-h0608dab_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-build-1.2.2.post1-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python_abi-3.13-5_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.7.3-py313h2493e73_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.8.0-py313h2493e73_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/scikit-learn-1.5.2-py313h3d59ad1_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/scipy-1.14.1-py313hbd2dc07_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.3.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/sigtool-0.1.3-h88f4db0_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/tapi-1300.6.5-h390ca13_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h1abcd95_1.conda @@ -205,7 +213,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.1.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/uv-0.5.1-h8de1528_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/uv-0.5.4-h8de1528_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xz-5.2.6-h775f41a_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.21.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.3.1-hd23fc13_2.conda @@ -218,7 +226,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/9a/e7/de62050dce687c5e96f946a93546910bc67e483fe05324439e329ff36105/contourpy-1.3.1-cp313-cp313-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/05/3d/cc515cae84a11d696f2cb7c139a90997b15f02e2e97ec09a5d79302cbcd7/fonttools-4.54.1-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/0c/e9/4822ad238fe215133c7df20f1cdb1a58cfb634a31523e77ff0fb2033970a/fonttools-4.55.0-cp313-cp313-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/27/48/e791a7ed487dbb9729ef32bb5d1af16693d8925f4366befef54119b2e576/furo-2024.8.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl @@ -229,9 +237,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/63/24/e2e15e392d00fcf4215907465d8ec2a2f23bcec1481a8ebe4ae760459995/pillow-11.0.0-cp313-cp313-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/be/ec/2eb3cd785efd67806c46c13a17339708ddc346cbb684eade7a6e6f79536a/pyparsing-3.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/26/60/1ddff83a56d33aaf6f10ec8ce84b4c007d9368b21008876fceda7e7381ef/sphinx-8.1.3-py3-none-any.whl @@ -255,17 +261,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1010.6-h4208deb_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-17-17.0.6-default_h146c034_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-17.0.6-default_h360f5da_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-17.0.6-he47c785_21.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-17.0.6-h54d7cd3_21.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-17.0.6-he47c785_23.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-17.0.6-h07b0088_23.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-17.0.6-default_h360f5da_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-17.0.6-h50f59cd_21.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-17.0.6-h54d7cd3_21.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-17.0.6-h50f59cd_23.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-17.0.6-h07b0088_23.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-17.0.6-h856b3c1_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-17.0.6-h832e737_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/compilers-1.8.0-hce30654_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.6.4-py313heb2b014_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.6.8-py313ha9b7d5b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.8.0-h18dbf2f_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cython-3.0.11-py313h80254e6_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cython-lint-0.16.6-pyhff2d567_0.conda @@ -284,7 +290,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.9.0-25_osxarm64_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-25_osxarm64_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp17-17.0.6-default_h146c034_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-19.1.3-ha82da77_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-19.1.4-ha82da77_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-17.0.6-h86353a2_6.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.6.4-h286801f_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2 @@ -299,7 +305,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.47.0-hbaaea75_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.13.5-h376fa9f_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-19.1.3-hb52a8e5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-19.1.4-hdb05f8b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-17.0.6-h5090b49_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/meson-1.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/meson-python-0.17.1-pyh70fd9c4_0.conda @@ -311,7 +317,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.12.1-h420ef59_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.1.3-py313hca4752e_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.4.0-h39f12f2_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.2-pyhff2d567_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.2.3-py313h47b39a6_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_0.conda @@ -323,13 +330,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.0-h75c3a9f_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-build-1.2.2.post1-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python_abi-3.13-5_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.7.3-py313heab95af_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.8.0-py313heab95af_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.5.2-py313h14e4f8e_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.14.1-py313hb3ee861_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.3.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-0.1.3-h44b9a77_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1300.6.5-h03f4b80_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda @@ -338,7 +349,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.1.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/uv-0.5.1-h668ec48_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/uv-0.5.4-h668ec48_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-5.2.6-h57fd34a_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.21.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.1-h8359307_2.conda @@ -351,7 +362,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/78/4d/c2a09ae014ae984c6bdd29c11e74d3121b25eaa117eca0bb76340efd7e1c/contourpy-1.3.1-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/03/03/05d4b22d1a674d066380657f60bbc0eda2d206446912e676d1a33a206878/fonttools-4.54.1-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/c3/87/a669ac26c6077e37ffb06abf29c5571789eefe518d06c52df392181ee694/fonttools-4.55.0-cp313-cp313-macosx_10_13_universal2.whl - pypi: https://files.pythonhosted.org/packages/27/48/e791a7ed487dbb9729ef32bb5d1af16693d8925f4366befef54119b2e576/furo-2024.8.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl @@ -362,9 +373,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/43/72/92ad4afaa2afc233dc44184adff289c2e77e8cd916b3ddb72ac69495bda3/pillow-11.0.0-cp313-cp313-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/be/ec/2eb3cd785efd67806c46c13a17339708ddc346cbb684eade7a6e6f79536a/pyparsing-3.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/26/60/1ddff83a56d33aaf6f10ec8ce84b4c007d9368b21008876fceda7e7381ef/sphinx-8.1.3-py3-none-any.whl @@ -385,7 +394,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.8.30-h56e8100_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-win_pyh7428d3b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/coverage-7.6.4-py313hb4c8b1a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/coverage-7.6.8-py313hb4c8b1a_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cython-3.0.11-py313h7176d0d_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cython-lint-0.16.6-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.2-pyhd8ed1ab_0.conda @@ -412,7 +421,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.12.1-hc790b64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.1.3-py313hee8cc43_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.4.0-h2466b09_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.2-pyhff2d567_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.2.3-py313hf91d08e_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.3.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_0.conda @@ -425,11 +435,15 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-6.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.0-hf5aa216_100_cp313.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-build-1.2.2.post1-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python_abi-3.13-5_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.7.3-py313h331c231_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.8.0-py313h331c231_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/scikit-learn-1.5.2-py313h4f67946_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.14.1-py313h16bbbb2_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.3.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.13.0-hc790b64_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda @@ -439,10 +453,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024b-hc8b5060_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.5.1-ha08ef0e_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_22.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.40.33810-hcc2c482_22.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.40.33810-h3bf8584_22.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/uv-0.5.4-ha08ef0e_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_23.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.42.34433-he29a5d6_23.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.42.34433-hdffcdeb_23.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xz-5.2.6-h8d14728_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.21.0-pyhd8ed1ab_0.conda - pypi: https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl @@ -453,7 +467,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/e3/d5/28bca491f65312b438fbf076589dcde7f6f966b196d900777f5811b9c4e2/contourpy-1.3.1-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/63/da/f7a1d837de419e3d4cccbd0dbf53c7399f610f65ceb9bcbf2480f3ae7950/fonttools-4.54.1-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/35/ca/b4638aa3e446184892e2f9cc8ef44bb506f47fea04580df7fb84f5a4363d/fonttools-4.55.0-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/27/48/e791a7ed487dbb9729ef32bb5d1af16693d8925f4366befef54119b2e576/furo-2024.8.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl @@ -464,9 +478,7 @@ environments: - pypi: https://files.pythonhosted.org/packages/fb/01/3755ba287dac715e6afdb333cb1f6d69740a7475220b4637b5ce3d78cec2/pillow-11.0.0-cp313-cp313-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/be/ec/2eb3cd785efd67806c46c13a17339708ddc346cbb684eade7a6e6f79536a/pyparsing-3.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/26/60/1ddff83a56d33aaf6f10ec8ce84b4c007d9368b21008876fceda7e7381ef/sphinx-8.1.3-py3-none-any.whl @@ -879,6 +891,12 @@ packages: url: https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl sha256: 922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8 requires_python: '>=3.6' +- kind: pypi + name: charset-normalizer + version: 3.4.0 + url: https://files.pythonhosted.org/packages/16/92/92a76dc2ff3a12e69ba94e7e05168d37d0345fa08c87e1fe24d0c2a42223/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + sha256: 8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15 + requires_python: '>=3.7.0' - kind: pypi name: charset-normalizer version: 3.4.0 @@ -897,12 +915,6 @@ packages: url: https://files.pythonhosted.org/packages/65/97/fc9bbc54ee13d33dc54a7fcf17b26368b18505500fc01e228c27b5222d80/charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl sha256: 707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b requires_python: '>=3.7.0' -- kind: pypi - name: charset-normalizer - version: 3.4.0 - url: https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl - sha256: fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079 - requires_python: '>=3.7.0' - kind: conda name: clang version: 17.0.6 @@ -986,12 +998,12 @@ packages: - kind: conda name: clang_impl_osx-64 version: 17.0.6 - build: h1af8efd_21 - build_number: 21 + build: h1af8efd_23 + build_number: 23 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/clang_impl_osx-64-17.0.6-h1af8efd_21.conda - sha256: 739050856565443f5568370f9a0a28f803579eb5dbee635c65b83056e52e42c9 - md5: 6ef491cbc462aae64eaa0213e7ae6222 + url: https://conda.anaconda.org/conda-forge/osx-64/clang_impl_osx-64-17.0.6-h1af8efd_23.conda + sha256: 2b8df6446dc59a8f6be800891f29fe3b5ec404a98dcd47b6a78e3f379b9079f7 + md5: 90132dd643d402883e4fbd8f0527e152 depends: - cctools_osx-64 - clang 17.0.6.* @@ -1001,17 +1013,17 @@ packages: license: BSD-3-Clause license_family: BSD purls: [] - size: 17526 - timestamp: 1728550487882 + size: 17880 + timestamp: 1731984936767 - kind: conda name: clang_impl_osx-arm64 version: 17.0.6 - build: he47c785_21 - build_number: 21 + build: he47c785_23 + build_number: 23 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-17.0.6-he47c785_21.conda - sha256: e3e2038b22b425f4fd4bae6d50c15be1a6da2075c3ff5072c7f98bff14072b4a - md5: 2417a85d8d37df3df2bd37b6ae0514aa + url: https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-17.0.6-he47c785_23.conda + sha256: 7a5999645f66f12f8ff9f07ead73d3552f79fff09675487ec1f4f087569587e1 + md5: 519e4d9eb59dd0a1484e509dcc789217 depends: - cctools_osx-arm64 - clang 17.0.6.* @@ -1021,40 +1033,40 @@ packages: license: BSD-3-Clause license_family: BSD purls: [] - size: 17585 - timestamp: 1728550578755 + size: 17965 + timestamp: 1731984992637 - kind: conda name: clang_osx-64 version: 17.0.6 - build: hb91bd55_21 - build_number: 21 + build: h7e5c614_23 + build_number: 23 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/clang_osx-64-17.0.6-hb91bd55_21.conda - sha256: 446ff91c60c6266e4e5bcaab20377116ef59e1e3b712da7aa37faad644ae8065 - md5: d94a0f2c03e7a50203d2b78d7dd9fa25 + url: https://conda.anaconda.org/conda-forge/osx-64/clang_osx-64-17.0.6-h7e5c614_23.conda + sha256: 3d17b28357a97780ed6bb32caac7fb2df170540e07e1a233f0f8b18b7c1fc641 + md5: 615b86de1eb0162b7fa77bb8cbf57f1d depends: - - clang_impl_osx-64 17.0.6 h1af8efd_21 + - clang_impl_osx-64 17.0.6 h1af8efd_23 license: BSD-3-Clause license_family: BSD purls: [] - size: 20624 - timestamp: 1728550493227 + size: 21169 + timestamp: 1731984940250 - kind: conda name: clang_osx-arm64 version: 17.0.6 - build: h54d7cd3_21 - build_number: 21 + build: h07b0088_23 + build_number: 23 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-17.0.6-h54d7cd3_21.conda - sha256: f71a0285bba6695a3d1693563d43b4b3f31f611dccf2b8c3be2a480cf1da2b7a - md5: 83a80f491ac81d81f28cb9a46d3f5439 + url: https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-17.0.6-h07b0088_23.conda + sha256: ccafb62b45d71f646f0ca925fc7342d093fe5ea17ceeb15b84f1c277fc716295 + md5: cf5bbfc8b558c41d2a4ba17f5cabb48c depends: - - clang_impl_osx-arm64 17.0.6 he47c785_21 + - clang_impl_osx-arm64 17.0.6 he47c785_23 license: BSD-3-Clause license_family: BSD purls: [] - size: 20608 - timestamp: 1728550586726 + size: 21177 + timestamp: 1731984996665 - kind: conda name: clangxx version: 17.0.6 @@ -1092,75 +1104,75 @@ packages: - kind: conda name: clangxx_impl_osx-64 version: 17.0.6 - build: hc3430b7_21 - build_number: 21 + build: hc3430b7_23 + build_number: 23 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/clangxx_impl_osx-64-17.0.6-hc3430b7_21.conda - sha256: 68bfcd5f17945497582cb91a44737a94a2600a0dab7f0ef6c9118e1d5fb089de - md5: 9dbdec57445cac0f0c39aefe3d3900bc + url: https://conda.anaconda.org/conda-forge/osx-64/clangxx_impl_osx-64-17.0.6-hc3430b7_23.conda + sha256: 32d450b4aa7c74758b6a0f51f7e7037638e8b5b871f85879f1a74227564ddf69 + md5: b724718bfe53f93e782fe944ec58029e depends: - - clang_osx-64 17.0.6 hb91bd55_21 + - clang_osx-64 17.0.6 h7e5c614_23 - clangxx 17.0.6.* - libcxx >=17 - libllvm17 >=17.0.6,<17.1.0a0 license: BSD-3-Clause license_family: BSD purls: [] - size: 17588 - timestamp: 1728550507978 + size: 17925 + timestamp: 1731984956864 - kind: conda name: clangxx_impl_osx-arm64 version: 17.0.6 - build: h50f59cd_21 - build_number: 21 + build: h50f59cd_23 + build_number: 23 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-17.0.6-h50f59cd_21.conda - sha256: bfdf0b768b36694707fab931ccbe9971bd1b9a258c0806c62596d5c93167e972 - md5: a78eb1ab3aad5251ff9c6da5a99d59be + url: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-17.0.6-h50f59cd_23.conda + sha256: 7b975e2a1e141769ba4bc45792d145c68a72923465355d3f83ad60450529e01f + md5: d086b99e198e21b3b29d2847cade1fce depends: - - clang_osx-arm64 17.0.6 h54d7cd3_21 + - clang_osx-arm64 17.0.6 h07b0088_23 - clangxx 17.0.6.* - libcxx >=17 - libllvm17 >=17.0.6,<17.1.0a0 license: BSD-3-Clause license_family: BSD purls: [] - size: 17648 - timestamp: 1728550606508 + size: 18005 + timestamp: 1731985015782 - kind: conda name: clangxx_osx-64 version: 17.0.6 - build: hb91bd55_21 - build_number: 21 + build: h7e5c614_23 + build_number: 23 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/clangxx_osx-64-17.0.6-hb91bd55_21.conda - sha256: 780cd56526c835bb5ca867939b3a8613af4ea67c9c37cc952bfaad438974b098 - md5: cfcbb6790123280b5be7992d392e8194 + url: https://conda.anaconda.org/conda-forge/osx-64/clangxx_osx-64-17.0.6-h7e5c614_23.conda + sha256: 08e758458bc99394b108ed051636149f9bc8fafcf059758ac3d406194273d1c0 + md5: 78039b25bfcffb920407522839555289 depends: - - clang_osx-64 17.0.6 hb91bd55_21 - - clangxx_impl_osx-64 17.0.6 hc3430b7_21 + - clang_osx-64 17.0.6 h7e5c614_23 + - clangxx_impl_osx-64 17.0.6 hc3430b7_23 license: BSD-3-Clause license_family: BSD purls: [] - size: 19261 - timestamp: 1728550514642 + size: 19559 + timestamp: 1731984961996 - kind: conda name: clangxx_osx-arm64 version: 17.0.6 - build: h54d7cd3_21 - build_number: 21 + build: h07b0088_23 + build_number: 23 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-17.0.6-h54d7cd3_21.conda - sha256: 02bc5ed5f37a6e3d4e244d09e4e5db7bfc9ad2b7342f14a68f2b971511b7afc7 - md5: 594c1db6262e284e928c9d4f28dc8846 + url: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-17.0.6-h07b0088_23.conda + sha256: 58c65adb2e03209ec1dcd926c3256a3a188d6cfa23a89b7fcaa6c9ff56a0f364 + md5: 743758f55670a6a9a0c93010cd497801 depends: - - clang_osx-arm64 17.0.6 h54d7cd3_21 - - clangxx_impl_osx-arm64 17.0.6 h50f59cd_21 + - clang_osx-arm64 17.0.6 h07b0088_23 + - clangxx_impl_osx-arm64 17.0.6 h50f59cd_23 license: BSD-3-Clause license_family: BSD purls: [] - size: 19257 - timestamp: 1728550613321 + size: 19581 + timestamp: 1731985020343 - kind: conda name: click version: 8.1.7 @@ -1332,8 +1344,8 @@ packages: - kind: pypi name: contourpy version: 1.3.1 - url: https://files.pythonhosted.org/packages/25/c2/fc7193cc5383637ff390a712e88e4ded0452c9fbcf84abe3de5ea3df1866/contourpy-1.3.1.tar.gz - sha256: dfd97abd83335045a913e3bcc4a09c0ceadbe66580cf573fe961f4a825efa699 + url: https://files.pythonhosted.org/packages/78/4d/c2a09ae014ae984c6bdd29c11e74d3121b25eaa117eca0bb76340efd7e1c/contourpy-1.3.1-cp313-cp313-macosx_11_0_arm64.whl + sha256: 523a8ee12edfa36f6d2a49407f705a6ef4c5098de4f498619787e272de93f2d5 requires_dist: - numpy>=1.23 - furo ; extra == 'docs' @@ -1357,8 +1369,8 @@ packages: - kind: pypi name: contourpy version: 1.3.1 - url: https://files.pythonhosted.org/packages/78/4d/c2a09ae014ae984c6bdd29c11e74d3121b25eaa117eca0bb76340efd7e1c/contourpy-1.3.1-cp313-cp313-macosx_11_0_arm64.whl - sha256: 523a8ee12edfa36f6d2a49407f705a6ef4c5098de4f498619787e272de93f2d5 + url: https://files.pythonhosted.org/packages/9a/e7/de62050dce687c5e96f946a93546910bc67e483fe05324439e329ff36105/contourpy-1.3.1-cp313-cp313-macosx_10_13_x86_64.whl + sha256: a761d9ccfc5e2ecd1bf05534eda382aa14c3e4f9205ba5b1684ecfe400716ef2 requires_dist: - numpy>=1.23 - furo ; extra == 'docs' @@ -1382,8 +1394,8 @@ packages: - kind: pypi name: contourpy version: 1.3.1 - url: https://files.pythonhosted.org/packages/9a/e7/de62050dce687c5e96f946a93546910bc67e483fe05324439e329ff36105/contourpy-1.3.1-cp313-cp313-macosx_10_13_x86_64.whl - sha256: a761d9ccfc5e2ecd1bf05534eda382aa14c3e4f9205ba5b1684ecfe400716ef2 + url: https://files.pythonhosted.org/packages/ba/99/6794142b90b853a9155316c8f470d2e4821fe6f086b03e372aca848227dd/contourpy-1.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + sha256: efa874e87e4a647fd2e4f514d5e91c7d493697127beb95e77d2f7561f6905bd9 requires_dist: - numpy>=1.23 - furo ; extra == 'docs' @@ -1431,12 +1443,12 @@ packages: requires_python: '>=3.10' - kind: conda name: coverage - version: 7.6.4 + version: 7.6.8 build: py312h178313f_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.6.4-py312h178313f_0.conda - sha256: 62ef1654898b67a1aae353c8910323c803db0dcf0c117d5796eb1cfb03a2d777 - md5: a32fbd2322865ac80c7db74c553f5306 + url: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.6.8-py312h178313f_0.conda + sha256: f81fb017d0312a392d6454f374e69379650108bb5d709c635edf9dcbb9a39eef + md5: fe8c93f4c75908fe2a1cc45ed0c47edf depends: - __glibc >=2.17,<3.0.a0 - libgcc >=13 @@ -1444,71 +1456,67 @@ packages: - python_abi 3.12.* *_cp312 - tomli license: Apache-2.0 - license_family: APACHE purls: - pkg:pypi/coverage?source=hash-mapping - size: 363969 - timestamp: 1729610283175 + size: 364534 + timestamp: 1732426278362 - kind: conda name: coverage - version: 7.6.4 - build: py313h25ec13a_0 + version: 7.6.8 + build: py313h717bdf5_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.6.4-py313h25ec13a_0.conda - sha256: 42bb1b0b84dcca5cb91f1d46c47e81a5d2e3841ae5afa7b0371a0b12678fa861 - md5: 3b51dc2570f11e20bb75fa3bd7d88c46 + url: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.6.8-py313h717bdf5_0.conda + sha256: d32fae25cce0ba4cc24a0fd55606fa9d4fa6e78b5b3513c0ba47eae21e65ac7c + md5: 1f858c8c3b1dee85e64ce68fdaa0b6e7 depends: - __osx >=10.13 - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 - tomli license: Apache-2.0 - license_family: APACHE purls: - pkg:pypi/coverage?source=hash-mapping - size: 368189 - timestamp: 1729610234183 + size: 368990 + timestamp: 1732426436029 - kind: conda name: coverage - version: 7.6.4 - build: py313hb4c8b1a_0 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/coverage-7.6.4-py313hb4c8b1a_0.conda - sha256: b50527a1817204027501a4bdde679c827c2641642bd02981b7b9a4a005a1d61c - md5: 44f5384dd440c681cd21a74f60cd4416 + version: 7.6.8 + build: py313ha9b7d5b_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.6.8-py313ha9b7d5b_0.conda + sha256: 1747141f16821adced20f12966831ff444f06942dbecb36d443db43fa8b0dfe0 + md5: 2a72ba6a651f184a6515acfa48687d11 depends: + - __osx >=11.0 - python >=3.13,<3.14.0a0 + - python >=3.13,<3.14.0a0 *_cp313 - python_abi 3.13.* *_cp313 - tomli - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 license: Apache-2.0 - license_family: APACHE purls: - pkg:pypi/coverage?source=hash-mapping - size: 395778 - timestamp: 1729610578496 + size: 370706 + timestamp: 1732426401447 - kind: conda name: coverage - version: 7.6.4 - build: py313heb2b014_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.6.4-py313heb2b014_0.conda - sha256: 6287585f00497951d1c21db0ab06c5e654b73a667854061545e35719a98d124f - md5: f8c2dc680b0eccff1a401c4e54948a31 + version: 7.6.8 + build: py313hb4c8b1a_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/coverage-7.6.8-py313hb4c8b1a_0.conda + sha256: 01b3d6d287dd34363efaa47baf93148f404af7b4f7b52f3117a3575dc6edb86a + md5: 258641c09a12218156e1706d6bea5bf6 depends: - - __osx >=11.0 - python >=3.13,<3.14.0a0 - - python >=3.13,<3.14.0a0 *_cp313 - python_abi 3.13.* *_cp313 - tomli + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Apache-2.0 - license_family: APACHE purls: - pkg:pypi/coverage?source=hash-mapping - size: 371141 - timestamp: 1729610332414 + size: 396450 + timestamp: 1732426714288 - kind: conda name: cxx-compiler version: 1.8.0 @@ -1687,7 +1695,7 @@ packages: name: fastcan version: 0.2.7 path: . - sha256: 624e3741a374c38866d0fc7637a384cffd3379575e043e7b6f7f49403faf4271 + sha256: d984857746012fb9f781a6c713718bb6094bb0e2c2577a4dea5ce7e894d36f71 requires_dist: - scikit-learn>=1.5.0 - furo ; extra == 'docs' @@ -1698,9 +1706,9 @@ packages: editable: true - kind: pypi name: fonttools - version: 4.54.1 - url: https://files.pythonhosted.org/packages/03/03/05d4b22d1a674d066380657f60bbc0eda2d206446912e676d1a33a206878/fonttools-4.54.1-cp313-cp313-macosx_11_0_arm64.whl - sha256: 357cacb988a18aace66e5e55fe1247f2ee706e01debc4b1a20d77400354cddeb + version: 4.55.0 + url: https://files.pythonhosted.org/packages/0c/e9/4822ad238fe215133c7df20f1cdb1a58cfb634a31523e77ff0fb2033970a/fonttools-4.55.0-cp313-cp313-macosx_10_13_x86_64.whl + sha256: 01124f2ca6c29fad4132d930da69158d3f49b2350e4a779e1efbe0e82bd63f6c requires_dist: - fs>=2.2.0,<3 ; extra == 'all' - lxml>=4.0 ; extra == 'all' @@ -1735,9 +1743,9 @@ packages: requires_python: '>=3.8' - kind: pypi name: fonttools - version: 4.54.1 - url: https://files.pythonhosted.org/packages/05/3d/cc515cae84a11d696f2cb7c139a90997b15f02e2e97ec09a5d79302cbcd7/fonttools-4.54.1-cp313-cp313-macosx_10_13_universal2.whl - sha256: 6e37561751b017cf5c40fce0d90fd9e8274716de327ec4ffb0df957160be3bff + version: 4.55.0 + url: https://files.pythonhosted.org/packages/35/ca/b4638aa3e446184892e2f9cc8ef44bb506f47fea04580df7fb84f5a4363d/fonttools-4.55.0-cp313-cp313-win_amd64.whl + sha256: 2863555ba90b573e4201feaf87a7e71ca3b97c05aa4d63548a4b69ea16c9e998 requires_dist: - fs>=2.2.0,<3 ; extra == 'all' - lxml>=4.0 ; extra == 'all' @@ -1772,9 +1780,9 @@ packages: requires_python: '>=3.8' - kind: pypi name: fonttools - version: 4.54.1 - url: https://files.pythonhosted.org/packages/57/5e/de2e6e51cb6894f2f2bc2641f6c845561361b622e96df3cca04df77222c9/fonttools-4.54.1-py3-none-any.whl - sha256: 37cddd62d83dc4f72f7c3f3c2bcf2697e89a30efb152079896544a93907733bd + version: 4.55.0 + url: https://files.pythonhosted.org/packages/c3/87/a669ac26c6077e37ffb06abf29c5571789eefe518d06c52df392181ee694/fonttools-4.55.0-cp313-cp313-macosx_10_13_universal2.whl + sha256: 8118dc571921dc9e4b288d9cb423ceaf886d195a2e5329cc427df82bba872cd9 requires_dist: - fs>=2.2.0,<3 ; extra == 'all' - lxml>=4.0 ; extra == 'all' @@ -1809,9 +1817,9 @@ packages: requires_python: '>=3.8' - kind: pypi name: fonttools - version: 4.54.1 - url: https://files.pythonhosted.org/packages/63/da/f7a1d837de419e3d4cccbd0dbf53c7399f610f65ceb9bcbf2480f3ae7950/fonttools-4.54.1-cp313-cp313-win_amd64.whl - sha256: 262705b1663f18c04250bd1242b0515d3bbae177bee7752be67c979b7d47f43d + version: 4.55.0 + url: https://files.pythonhosted.org/packages/fc/0b/dbe13f2c8d745ffdf5c2bc25391263927d4ec2b927e44d5d5f70cd372873/fonttools-4.55.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl + sha256: 732a9a63d6ea4a81b1b25a1f2e5e143761b40c2e1b79bb2b68e4893f45139a40 requires_dist: - fs>=2.2.0,<3 ; extra == 'all' - lxml>=4.0 ; extra == 'all' @@ -2212,14 +2220,14 @@ packages: - kind: pypi name: kiwisolver version: 1.4.7 - url: https://files.pythonhosted.org/packages/2a/fc/6c0374f7503522539e2d4d1b497f5ebad3f8ed07ab51aed2af988dd0fb65/kiwisolver-1.4.7-cp313-cp313-macosx_11_0_arm64.whl - sha256: 7ab9ccab2b5bd5702ab0803676a580fffa2aa178c2badc5557a84cc943fcf750 + url: https://files.pythonhosted.org/packages/21/e4/c0b6746fd2eb62fe702118b3ca0cb384ce95e1261cfada58ff693aeec08a/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + sha256: 693902d433cf585133699972b6d7c42a8b9f8f826ebcaf0132ff55200afc599e requires_python: '>=3.8' - kind: pypi name: kiwisolver version: 1.4.7 - url: https://files.pythonhosted.org/packages/85/4d/2255e1c76304cbd60b48cee302b66d1dde4468dc5b1160e4b7cb43778f2a/kiwisolver-1.4.7.tar.gz - sha256: 9893ff81bd7107f7b685d3017cc6583daadb4fc26e4a888350df530e41980a60 + url: https://files.pythonhosted.org/packages/2a/fc/6c0374f7503522539e2d4d1b497f5ebad3f8ed07ab51aed2af988dd0fb65/kiwisolver-1.4.7-cp313-cp313-macosx_11_0_arm64.whl + sha256: 7ab9ccab2b5bd5702ab0803676a580fffa2aa178c2badc5557a84cc943fcf750 requires_python: '>=3.8' - kind: pypi name: kiwisolver @@ -2540,34 +2548,34 @@ packages: timestamp: 1725505540477 - kind: conda name: libcxx - version: 19.1.3 + version: 19.1.4 build: ha82da77_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-19.1.3-ha82da77_0.conda - sha256: 6d062760c6439e75b9a44d800d89aff60fe3441998d87506c62dc94c50412ef4 - md5: bf691071fba4734984231617783225bc + url: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-19.1.4-ha82da77_0.conda + sha256: 342896ebc1d6acbf022ca6df006a936b9a472579e91e3c502cb1f52f218b78e9 + md5: a2d3d484d95889fccdd09498d8f6bf9a depends: - __osx >=11.0 license: Apache-2.0 WITH LLVM-exception license_family: Apache purls: [] - size: 520771 - timestamp: 1730314603920 + size: 520678 + timestamp: 1732060258949 - kind: conda name: libcxx - version: 19.1.3 + version: 19.1.4 build: hf95d169_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libcxx-19.1.3-hf95d169_0.conda - sha256: 466f259bb13a8058fef28843977c090d21ad337b71a842ccc0407bccf8d27011 - md5: 86801fc56d4641e3ef7a63f5d996b960 + url: https://conda.anaconda.org/conda-forge/osx-64/libcxx-19.1.4-hf95d169_0.conda + sha256: 48c6d0ab9dd0c66693f79f4a032cd9ebb64fb88329dfa747aeac5299f9b3f33b + md5: 5f23923c08151687ff2fc3002b0a7234 depends: - __osx >=10.13 license: Apache-2.0 WITH LLVM-exception license_family: Apache purls: [] - size: 528991 - timestamp: 1730314340106 + size: 529010 + timestamp: 1732060320836 - kind: conda name: libcxx-devel version: 17.0.6 @@ -3488,38 +3496,38 @@ packages: timestamp: 1727963183990 - kind: conda name: llvm-openmp - version: 19.1.3 - build: hb52a8e5_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-19.1.3-hb52a8e5_0.conda - sha256: 49a8940e727aa82ee034fa9a60b3fcababec41b3192d955772aab635a5374b82 - md5: dd695d23e78d1ca4fecce969b1e1db61 + version: 19.1.4 + build: ha54dae1_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-19.1.4-ha54dae1_0.conda + sha256: 69fca4a9318d7367ec3e0e7d6e6023a46ae1113dbd67da6d0f93fffa0ef54497 + md5: 193715d512f648fe0865f6f13b1957e3 depends: - - __osx >=11.0 + - __osx >=10.13 constrains: - - openmp 19.1.3|19.1.3.* + - openmp 19.1.4|19.1.4.* license: Apache-2.0 WITH LLVM-exception license_family: APACHE purls: [] - size: 280488 - timestamp: 1730364082380 + size: 305132 + timestamp: 1732102427054 - kind: conda name: llvm-openmp - version: 19.1.3 - build: hf78d878_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-19.1.3-hf78d878_0.conda - sha256: 3d28e9938ab1400322ba76968cdbee035009d611bbee94ec6b38a154551954b4 - md5: 18a8498d57d871da066beaa09263a638 + version: 19.1.4 + build: hdb05f8b_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-19.1.4-hdb05f8b_0.conda + sha256: dfdcd8de37899d984326f9734b28f46f80b88c068e44c562933a8b3117f2401a + md5: 76ca179ec970bea6e275e2fa477c2d3c depends: - - __osx >=10.13 + - __osx >=11.0 constrains: - - openmp 19.1.3|19.1.3.* + - openmp 19.1.4|19.1.4.* license: Apache-2.0 WITH LLVM-exception license_family: APACHE purls: [] - size: 305524 - timestamp: 1730364180247 + size: 281554 + timestamp: 1732102484807 - kind: conda name: llvm-tools version: 17.0.6 @@ -3590,14 +3598,14 @@ packages: - kind: pypi name: markupsafe version: 3.0.2 - url: https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz - sha256: ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0 + url: https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + sha256: e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8 requires_python: '>=3.9' - kind: pypi name: matplotlib version: 3.9.2 - url: https://files.pythonhosted.org/packages/5c/7f/8932eac316b32f464b8f9069f151294dcd892c8fbde61fe8bcd7ba7f7f7e/matplotlib-3.9.2-cp313-cp313-macosx_10_13_x86_64.whl - sha256: 18128cc08f0d3cfff10b76baa2f296fc28c4607368a8402de61bb3f2eb33c7d9 + url: https://files.pythonhosted.org/packages/27/75/de5b9cd67648051cae40039da0c8cbc497a0d99acb1a1f3d087cd66d27b7/matplotlib-3.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + sha256: f6ee45bc4245533111ced13f1f2cace1e7f89d1c793390392a80c139d6cf0e6c requires_dist: - contourpy>=1.0.1 - cycler>=0.10 @@ -3618,8 +3626,8 @@ packages: - kind: pypi name: matplotlib version: 3.9.2 - url: https://files.pythonhosted.org/packages/90/89/9db9db3dd0ff3e2c49e452236dfe29e60b5586a88f8928ca1d153d0da8b5/matplotlib-3.9.2-cp313-cp313-macosx_11_0_arm64.whl - sha256: 4876d7d40219e8ae8bb70f9263bcbe5714415acfdf781086601211335e24f8aa + url: https://files.pythonhosted.org/packages/5c/7f/8932eac316b32f464b8f9069f151294dcd892c8fbde61fe8bcd7ba7f7f7e/matplotlib-3.9.2-cp313-cp313-macosx_10_13_x86_64.whl + sha256: 18128cc08f0d3cfff10b76baa2f296fc28c4607368a8402de61bb3f2eb33c7d9 requires_dist: - contourpy>=1.0.1 - cycler>=0.10 @@ -3640,8 +3648,8 @@ packages: - kind: pypi name: matplotlib version: 3.9.2 - url: https://files.pythonhosted.org/packages/9e/d8/3d7f706c69e024d4287c1110d74f7dabac91d9843b99eadc90de9efc8869/matplotlib-3.9.2.tar.gz - sha256: 96ab43906269ca64a6366934106fa01534454a69e471b7bf3d79083981aaab92 + url: https://files.pythonhosted.org/packages/90/89/9db9db3dd0ff3e2c49e452236dfe29e60b5586a88f8928ca1d153d0da8b5/matplotlib-3.9.2-cp313-cp313-macosx_11_0_arm64.whl + sha256: 4876d7d40219e8ae8bb70f9263bcbe5714415acfdf781086601211335e24f8aa requires_dist: - contourpy>=1.0.1 - cycler>=0.10 @@ -4194,20 +4202,124 @@ packages: - kind: conda name: packaging version: '24.2' - build: pyhd8ed1ab_0 + build: pyhff2d567_1 + build_number: 1 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/packaging-24.2-pyhd8ed1ab_0.conda - sha256: 0f8273bf66c2a5c1de72312a509deae07f163bb0ae8de8273c52e6fe945a0850 - md5: c16469afe1ec91aaafcf4bea966c0465 + url: https://conda.anaconda.org/conda-forge/noarch/packaging-24.2-pyhff2d567_1.conda + sha256: 74843f871e5cd8a1baf5ed8c406c571139c287141efe532f8ffbdafa3664d244 + md5: 8508b703977f4c4ada34d657d051972c depends: - python >=3.8 license: Apache-2.0 license_family: APACHE purls: - pkg:pypi/packaging?source=hash-mapping - size: 60345 - timestamp: 1731457074006 + size: 60380 + timestamp: 1731802602808 +- kind: conda + name: pandas + version: 2.2.3 + build: py312hf9745cd_1 + build_number: 1 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.3-py312hf9745cd_1.conda + sha256: ad275a83bfebfa8a8fee9b0569aaf6f513ada6a246b2f5d5b85903d8ca61887e + md5: 8bce4f6caaf8c5448c7ac86d87e26b4b + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + - numpy >=1.19,<3 + - numpy >=1.22.4 + - python >=3.12,<3.13.0a0 + - python-dateutil >=2.8.1 + - python-tzdata >=2022a + - python_abi 3.12.* *_cp312 + - pytz >=2020.1,<2024.2 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pandas?source=hash-mapping + size: 15436913 + timestamp: 1726879054912 +- kind: conda + name: pandas + version: 2.2.3 + build: py313h38cdd20_1 + build_number: 1 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/pandas-2.2.3-py313h38cdd20_1.conda + sha256: baf98a0c2a15a3169b7c0443c04b37b489575477f5cf443146f283e1259de01f + md5: ab61fb255c951a0514616e92dd2e18b2 + depends: + - __osx >=10.13 + - libcxx >=17 + - numpy >=1.21,<3 + - numpy >=1.22.4 + - python >=3.13.0rc2,<3.14.0a0 + - python-dateutil >=2.8.1 + - python-tzdata >=2022a + - python_abi 3.13.* *_cp313 + - pytz >=2020.1,<2024.2 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pandas?source=hash-mapping + size: 14632093 + timestamp: 1726878912764 +- kind: conda + name: pandas + version: 2.2.3 + build: py313h47b39a6_1 + build_number: 1 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.2.3-py313h47b39a6_1.conda + sha256: b3ca1ad2ba2d43b964e804feeec9f6b737a2ecbe17b932ea6a954ff26a567b5c + md5: 59f9c74ce982d17b4534f10b6c1b3b1e + depends: + - __osx >=11.0 + - libcxx >=17 + - numpy >=1.21,<3 + - numpy >=1.22.4 + - python >=3.13.0rc2,<3.14.0a0 + - python >=3.13.0rc2,<3.14.0a0 *_cp313 + - python-dateutil >=2.8.1 + - python-tzdata >=2022a + - python_abi 3.13.* *_cp313 + - pytz >=2020.1,<2024.2 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pandas?source=hash-mapping + size: 14464446 + timestamp: 1726878986761 +- kind: conda + name: pandas + version: 2.2.3 + build: py313hf91d08e_1 + build_number: 1 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/pandas-2.2.3-py313hf91d08e_1.conda + sha256: 8fb218382be188497cbf549eb9de2825195cb076946e1f9929f3758b3f3b4e88 + md5: 9c6dab4d9b20463121faf04283b4d1a1 + depends: + - numpy >=1.21,<3 + - numpy >=1.22.4 + - python >=3.13.0rc2,<3.14.0a0 + - python-dateutil >=2.8.1 + - python-tzdata >=2022a + - python_abi 3.13.* *_cp313 + - pytz >=2020.1,<2024.2 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/pandas?source=hash-mapping + size: 14215159 + timestamp: 1726879653675 - kind: conda name: pathspec version: 0.12.1 @@ -4282,8 +4394,8 @@ packages: - kind: pypi name: pillow version: 11.0.0 - url: https://files.pythonhosted.org/packages/a5/26/0d95c04c868f6bdb0c447e3ee2de5564411845e36a858cfd63766bc7b563/pillow-11.0.0.tar.gz - sha256: 72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739 + url: https://files.pythonhosted.org/packages/7f/42/6e0f2c2d5c60f499aa29be14f860dd4539de322cd8fb84ee01553493fb4d/pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl + sha256: 00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7 requires_dist: - furo ; extra == 'docs' - olefile ; extra == 'docs' @@ -4715,14 +4827,41 @@ packages: - pkg:pypi/build?source=hash-mapping size: 25208 timestamp: 1728263490046 -- kind: pypi +- kind: conda name: python-dateutil version: 2.9.0.post0 - url: https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl - sha256: a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427 - requires_dist: - - six>=1.5 - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*' + build: pyhff2d567_0 + subdir: noarch + noarch: python + url: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhff2d567_0.conda + sha256: 3888012c5916efaef45d503e3e544bbcc571b84426c1bb9577799ada9efefb54 + md5: b6dfd90a2141e573e4b6a81630b56df5 + depends: + - python >=3.9 + - six >=1.5 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/python-dateutil?source=hash-mapping + size: 221925 + timestamp: 1731919374686 +- kind: conda + name: python-tzdata + version: '2024.2' + build: pyhd8ed1ab_0 + subdir: noarch + noarch: python + url: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.2-pyhd8ed1ab_0.conda + sha256: fe3f62ce2bc714bdaa222ab3f0344a2815ad9e853c6df38d15c9f25de8a3a6d4 + md5: 986287f89929b2d629bd6ef6497dc307 + depends: + - python >=3.6 + license: Apache-2.0 + license_family: APACHE + purls: + - pkg:pypi/tzdata?source=hash-mapping + size: 142527 + timestamp: 1727140688093 - kind: conda name: python_abi version: '3.12' @@ -4787,6 +4926,23 @@ packages: purls: [] size: 6716 timestamp: 1723823166911 +- kind: conda + name: pytz + version: '2024.1' + build: pyhd8ed1ab_0 + subdir: noarch + noarch: python + url: https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda + sha256: 1a7d6b233f7e6e3bbcbad054c8fd51e690a67b129a899a056a5e45dd9f00cb41 + md5: 3eeeeb9e4827ace8c0c1419c85d590ad + depends: + - python >=3.7 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pytz?source=hash-mapping + size: 188538 + timestamp: 1706886944988 - kind: conda name: readline version: '8.2' @@ -4851,12 +5007,12 @@ packages: requires_python: '>=3.8' - kind: conda name: ruff - version: 0.7.3 + version: 0.8.0 build: py312h2156523_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.7.3-py312h2156523_0.conda - sha256: 313110b1c431fe61cb3fe5e1cc4f1ffce905e95aab559055d1a86039c8ea7e35 - md5: ed126dd09a1f2081996c5b71423a2b80 + url: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.8.0-py312h2156523_0.conda + sha256: 4612ed5e995f4735ac8193c1319690b62440598fad9ebf24198b7ba49396cb2c + md5: 8c1d1a4d606a6d822643a44f124af736 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=13 @@ -4869,16 +5025,16 @@ packages: license_family: MIT purls: - pkg:pypi/ruff?source=hash-mapping - size: 7767902 - timestamp: 1731084470644 + size: 7886786 + timestamp: 1732285636885 - kind: conda name: ruff - version: 0.7.3 + version: 0.8.0 build: py313h2493e73_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.7.3-py313h2493e73_0.conda - sha256: da697673f5b0a262e23bd06c2c7da981a8030bb71fea65211461cb2a074559e2 - md5: 7839d705328bbd8bbea6d0640883ef22 + url: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.8.0-py313h2493e73_0.conda + sha256: cf612c148a46d4d56143f25a081662ff0b0e254110a56be7f51c492de94d9a61 + md5: c4f55071260737af0613c25c7e0e8297 depends: - __osx >=10.13 - libcxx >=18 @@ -4890,16 +5046,16 @@ packages: license_family: MIT purls: - pkg:pypi/ruff?source=hash-mapping - size: 7150721 - timestamp: 1731084661752 + size: 7284256 + timestamp: 1732286157815 - kind: conda name: ruff - version: 0.7.3 + version: 0.8.0 build: py313h331c231_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/ruff-0.7.3-py313h331c231_0.conda - sha256: 4c301d063b1bb5ef793c4e28a34836cd0cb8656680b067646f3b2be909cf30f8 - md5: 1c3729796124b0fcb53a017ca9a348ce + url: https://conda.anaconda.org/conda-forge/win-64/ruff-0.8.0-py313h331c231_0.conda + sha256: c3b6938349a1c97a54a1f921ea324284ad2eafe774ab33902028c39f8eb5fc92 + md5: 4c755a91f686eb21da6fbb8f7cb158bd depends: - python >=3.13,<3.14.0a0 - python_abi 3.13.* *_cp313 @@ -4910,16 +5066,16 @@ packages: license_family: MIT purls: - pkg:pypi/ruff?source=hash-mapping - size: 6778389 - timestamp: 1731085064447 + size: 6873151 + timestamp: 1732286500899 - kind: conda name: ruff - version: 0.7.3 + version: 0.8.0 build: py313heab95af_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.7.3-py313heab95af_0.conda - sha256: 45ece98aeb19cfda0e6cb6726e3a7afaccd50ccb70f6f1dbe9c8342bf6f6662c - md5: 56268c148f06f7d4bbd3b3940a2b873e + url: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.8.0-py313heab95af_0.conda + sha256: 8fa95df70654b8f7124924b023c7b5bd3548385b0c539fe7fd00c2850be4a811 + md5: 51a01bd7e637556f33e14695983fcd02 depends: - __osx >=11.0 - libcxx >=18 @@ -4932,8 +5088,8 @@ packages: license_family: MIT purls: - pkg:pypi/ruff?source=hash-mapping - size: 6858893 - timestamp: 1731084445790 + size: 6960999 + timestamp: 1732286297576 - kind: conda name: scikit-learn version: 1.5.2 @@ -5151,21 +5307,21 @@ packages: timestamp: 1729481595130 - kind: conda name: setuptools - version: 75.3.0 - build: pyhd8ed1ab_0 + version: 75.6.0 + build: pyhff2d567_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.3.0-pyhd8ed1ab_0.conda - sha256: a36d020b9f32fc3f1a6488a1c4a9c13988c6468faf6895bf30ca69521a61230e - md5: 2ce9825396daf72baabaade36cee16da + url: https://conda.anaconda.org/conda-forge/noarch/setuptools-75.6.0-pyhff2d567_0.conda + sha256: eeec4645f70ce0ed03348397dced9d218a650a42df98592419af61d2689163ed + md5: 68d7d406366926b09a6a023e3d0f71d7 depends: - - python >=3.8 + - python >=3.9 license: MIT license_family: MIT purls: - pkg:pypi/setuptools?source=hash-mapping - size: 779561 - timestamp: 1730382173961 + size: 774304 + timestamp: 1732216189406 - kind: conda name: sigtool version: 0.1.3 @@ -5196,12 +5352,23 @@ packages: purls: [] size: 213817 timestamp: 1643442169866 -- kind: pypi +- kind: conda name: six version: 1.16.0 - url: https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl - sha256: 8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 - requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*' + build: pyh6c4a22f_0 + subdir: noarch + noarch: python + url: https://conda.anaconda.org/conda-forge/noarch/six-1.16.0-pyh6c4a22f_0.tar.bz2 + sha256: a85c38227b446f42c5b90d9b642f2c0567880c15d72492d8da074a59c8f91dd6 + md5: e5f25f8dbc060e9a8d912e432202afc2 + depends: + - python + license: MIT + license_family: MIT + purls: + - pkg:pypi/six?source=hash-mapping + size: 14259 + timestamp: 1620240338595 - kind: pypi name: snowballstemmer version: 2.2.0 @@ -5644,12 +5811,12 @@ packages: requires_python: '>=3.8' - kind: conda name: uv - version: 0.5.1 + version: 0.5.4 build: h0f3a69f_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/uv-0.5.1-h0f3a69f_0.conda - sha256: 9bda0a65af5d2865cfe887dd90dbf04ed97bf6920a1c223396036e1c1f831f58 - md5: 2f0601933384868b7c34193247a1b167 + url: https://conda.anaconda.org/conda-forge/linux-64/uv-0.5.4-h0f3a69f_0.conda + sha256: 826c427524d1930d66bdbbe9f2a380d46abc02e06b4b9870e4c5eb661a292156 + md5: ecce7c2d83da66eaabf8ba4961a4c828 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=13 @@ -5658,16 +5825,16 @@ packages: - __glibc >=2.17 license: Apache-2.0 OR MIT purls: [] - size: 9804886 - timestamp: 1731134694659 + size: 10061197 + timestamp: 1732159190433 - kind: conda name: uv - version: 0.5.1 + version: 0.5.4 build: h668ec48_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/uv-0.5.1-h668ec48_0.conda - sha256: a9275898733ebbe40ad0b3a3f2ca7b7c8861309d48396e188f6ba433a7206de1 - md5: 96791a25fa69cd8db922861f257adccd + url: https://conda.anaconda.org/conda-forge/osx-arm64/uv-0.5.4-h668ec48_0.conda + sha256: 85b61a53c0f39339c67a4f11b708fa1f59ad5f0a85d907f3c5ff001c88914b31 + md5: baad04fb088c4c66acf74a870bdb4536 depends: - __osx >=11.0 - libcxx >=18 @@ -5675,16 +5842,16 @@ packages: - __osx >=11.0 license: Apache-2.0 OR MIT purls: [] - size: 8674748 - timestamp: 1731135650399 + size: 8942315 + timestamp: 1732160450871 - kind: conda name: uv - version: 0.5.1 + version: 0.5.4 build: h8de1528_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/uv-0.5.1-h8de1528_0.conda - sha256: ef5af89267bfadec1fc8b1b7183a8f1af686147e6f6fc5b19b87c56fa9136228 - md5: b09d0da73064bde62006e802df19f44e + url: https://conda.anaconda.org/conda-forge/osx-64/uv-0.5.4-h8de1528_0.conda + sha256: 7ee578a9944f39c7d249c18fcde7f8a6d3131c3788c9dc6b8b3c36c0784b3340 + md5: 0cf1dbd494c85fd0730a27b9c335b2ea depends: - __osx >=10.13 - libcxx >=18 @@ -5692,33 +5859,33 @@ packages: - __osx >=10.13 license: Apache-2.0 OR MIT purls: [] - size: 9344837 - timestamp: 1731135239423 + size: 9694051 + timestamp: 1732159860536 - kind: conda name: uv - version: 0.5.1 + version: 0.5.4 build: ha08ef0e_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/uv-0.5.1-ha08ef0e_0.conda - sha256: 14c1a23e7ef6694d1bd7eef5edb9a5819d19ddf1006a5deda012d017932292f3 - md5: 442819ddf83c287ddd3078477cafd57d + url: https://conda.anaconda.org/conda-forge/win-64/uv-0.5.4-ha08ef0e_0.conda + sha256: 493bece8c71254c2f9002fe5f53dd71265ce38d9dee2842286120e86acc2e523 + md5: 9fc38b02b5c4fa1be9a42c1b951d98e1 depends: - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: Apache-2.0 OR MIT purls: [] - size: 10691540 - timestamp: 1731135656601 + size: 10797785 + timestamp: 1732160258909 - kind: conda name: vc version: '14.3' - build: ha32ba9b_22 - build_number: 22 + build: ha32ba9b_23 + build_number: 23 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_22.conda - sha256: 2a47c5bd8bec045959afada7063feacd074ad66b170c1ea92dd139b389fcf8fd - md5: 311c9ba1dfdd2895a8cb08346ff26259 + url: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_23.conda + sha256: 986ddaf8feec2904eac9535a7ddb7acda1a1dfb9482088fdb8129f1595181663 + md5: 7c10ec3158d1eb4ddff7007c9101adb0 depends: - vc14_runtime >=14.38.33135 track_features: @@ -5726,42 +5893,42 @@ packages: license: BSD-3-Clause license_family: BSD purls: [] - size: 17447 - timestamp: 1728400826998 + size: 17479 + timestamp: 1731710827215 - kind: conda name: vc14_runtime - version: 14.40.33810 - build: hcc2c482_22 - build_number: 22 + version: 14.42.34433 + build: he29a5d6_23 + build_number: 23 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.40.33810-hcc2c482_22.conda - sha256: 4c669c65007f88a7cdd560192f7e6d5679d191ac71610db724e18b2410964d64 - md5: ce23a4b980ee0556a118ed96550ff3f3 + url: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.42.34433-he29a5d6_23.conda + sha256: c483b090c4251a260aba6ff3e83a307bcfb5fb24ad7ced872ab5d02971bd3a49 + md5: 32b37d0cfa80da34548501cdc913a832 depends: - ucrt >=10.0.20348.0 constrains: - - vs2015_runtime 14.40.33810.* *_22 + - vs2015_runtime 14.42.34433.* *_23 license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime license_family: Proprietary purls: [] - size: 750719 - timestamp: 1728401055788 + size: 754247 + timestamp: 1731710681163 - kind: conda name: vs2015_runtime - version: 14.40.33810 - build: h3bf8584_22 - build_number: 22 + version: 14.42.34433 + build: hdffcdeb_23 + build_number: 23 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.40.33810-h3bf8584_22.conda - sha256: 80aa9932203d65a96f817b8be4fafc176fb2b3fe6cf6899ede678b8f0317fbff - md5: 8c6b061d44cafdfc8e8c6eb5f100caf0 + url: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.42.34433-hdffcdeb_23.conda + sha256: 568ce8151eaae256f1cef752fc78651ad7a86ff05153cc7a4740b52ae6536118 + md5: 5c176975ca2b8366abad3c97b3cd1e83 depends: - - vc14_runtime >=14.40.33810 + - vc14_runtime >=14.42.34433 license: BSD-3-Clause license_family: BSD purls: [] - size: 17453 - timestamp: 1728400827536 + size: 17572 + timestamp: 1731710685291 - kind: conda name: xz version: 5.2.6 diff --git a/pyproject.toml b/pyproject.toml index 54025e6..c8ce34a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,7 @@ docs = ["furo", "matplotlib", "sphinx_gallery", "sphinx-design"] [tool.pixi.feature.test.dependencies] pytest = "*" pytest-cov = "*" +pandas = "*" [tool.pixi.feature.fmt.dependencies] black = "*" diff --git a/tests/test_extend.py b/tests/test_extend.py index 49d24f9..b37e990 100644 --- a/tests/test_extend.py +++ b/tests/test_extend.py @@ -1,9 +1,7 @@ """Test feature selection extend""" import numpy as np import pytest -from numpy.testing import ( - assert_array_equal, -) +from numpy.testing import assert_array_equal from sklearn.datasets import make_classification from fastcan import FastCan, extend diff --git a/tests/test_narx.py b/tests/test_narx.py new file mode 100644 index 0000000..bb4544a --- /dev/null +++ b/tests/test_narx.py @@ -0,0 +1,114 @@ +"""Test Narx""" + +import numpy as np +import pytest +from numpy.testing import assert_array_equal +from sklearn.utils.estimator_checks import check_estimator + +from fastcan import Narx, make_narx, make_poly_ids, make_time_shift_ids, print_narx + + +def test_narx_is_sklearn_estimator(): + check_estimator(Narx()) + +def test_poly_ids(): + with pytest.raises(ValueError, match=r"The output that would result from the .*"): + make_poly_ids(10, 1000) + +def test_time_ids(): + with pytest.raises(ValueError, match=r"The length of `include_zero_delay`.*"): + make_time_shift_ids(3, 2, [False, True, False, True]) + +def test_narx(): + rng = np.random.default_rng(12345) + n_samples = 1000 + max_delay = 3 + e = rng.normal(0, 0.1, n_samples) + u0 = rng.uniform(0, 1, n_samples+max_delay) + u1 = rng.normal(0, 0.1, n_samples) + y = np.zeros(n_samples+max_delay) + for i in range(max_delay, n_samples+max_delay): + y[i] = 0.5*y[i-1]+0.3*u0[i]**2+2*u0[i-1]*u0[i-3]+1.5*u0[i-2]*u1[i-max_delay]+1 + y = y[max_delay:]+e + X = np.c_[u0[max_delay:], u1] + + params = { + "n_features_to_select": rng.integers(low=1, high=4), + "max_delay": rng.integers(low=0, high=10), + "poly_degree": rng.integers(low=2, high=5), + } + + narx_default = make_narx(X=X, y=y, **params) + + assert narx_default.poly_ids.shape[0] ==\ + params["n_features_to_select"] + + params["include_zero_delay"] = [False, True, False] + narx_0_delay = make_narx(X=X, y=y, **params) + time_shift_ids = narx_0_delay.time_shift_ids + assert ~np.isin(0, time_shift_ids[time_shift_ids[:, 0] == 0][:, 1]) + assert np.isin(0, time_shift_ids[time_shift_ids[:, 0] == 1][:, 1]) + assert ~np.isin(0, time_shift_ids[time_shift_ids[:, 0] == 2][:, 1]) + + params["static_indices"] = [1] + narx_static = make_narx(X=X, y=y, **params) + time_shift_ids = narx_static.time_shift_ids + assert time_shift_ids[time_shift_ids[:, 0] == 1][0, 1] == 0 + + params["drop"] = 1 + params["max_iter"] = 10 + narx_drop = make_narx(X=X, y=y, **params) + assert np.any( + narx_drop.poly_ids !=\ + narx_static.poly_ids + ) + narx_drop_coef = narx_drop.fit(X, y).coef_ + + time_shift_ids = make_time_shift_ids(X.shape[1]+1, 5, include_zero_delay=False) + poly_ids = make_poly_ids(time_shift_ids.shape[0], 2) + narx_osa = Narx(time_shift_ids=time_shift_ids, poly_ids=poly_ids).fit(X, y) + assert narx_osa.coef_.size == poly_ids.shape[0] + narx_osa_msa = narx_drop.fit( + X, y, coef_init="one_step_ahead" + ) + narx_osa_msa_coef = narx_osa_msa.coef_ + assert np.any(narx_osa_msa_coef != narx_drop_coef) + narx_array_init_msa = narx_osa_msa.fit( + X, y, coef_init=np.zeros(narx_osa_msa_coef.size+1) + ) + assert np.any(narx_array_init_msa.coef_ != narx_osa_msa_coef) + + y_init = [1]*narx_array_init_msa.max_delay_ + y_hat = narx_array_init_msa.predict(X, y_init=y_init) + assert_array_equal(y_hat[:3], y_init) + + print_narx(narx_array_init_msa) + + with pytest.raises(ValueError, match=r"`y_init` should have the shape of .*"): + narx_array_init_msa.predict(X, y_init=[1]*(narx_array_init_msa.max_delay_-1)) + + with pytest.raises(ValueError, match=r"`coef_init` should have the shape of .*"): + narx_array_init_msa.fit(X, y, coef_init=np.zeros(narx_osa_msa_coef.size)) + + time_shift_ids = make_time_shift_ids(X.shape[1]+2, 3, include_zero_delay=False) + poly_ids = make_poly_ids(time_shift_ids.shape[0], 2) + with pytest.raises(ValueError, match=r"The element x of the first column of tim.*"): + narx_osa = Narx(time_shift_ids=time_shift_ids, poly_ids=poly_ids).fit(X, y) + + time_shift_ids = np.array( + [ + [0, 0], + [0, -1], + [1, 1], + [1, 2], + ] + ) + poly_ids = make_poly_ids(time_shift_ids.shape[0], 2) + with pytest.raises(ValueError, match=r"The element x of the second column of ti.*"): + narx_osa = Narx(time_shift_ids=time_shift_ids, poly_ids=poly_ids).fit(X, y) + + + time_shift_ids = make_time_shift_ids(X.shape[1]+1, 3, include_zero_delay=False) + poly_ids = make_poly_ids(time_shift_ids.shape[0]+1, 2) + with pytest.raises(ValueError, match=r"The element x of poly_ids should .*"): + narx_osa = Narx(time_shift_ids=time_shift_ids, poly_ids=poly_ids).fit(X, y)