Spaces:
Sleeping
Sleeping
| import numpy as np | |
| from scipy.spatial import ConvexHull, QhullError | |
| from .h_categorizer import h_categorizer | |
| def dict_to_vector(A, d): | |
| """Converts a dictionary {arg: value} into a numpy vector following the order of A.""" | |
| return np.array([d[a] for a in A], dtype=float) | |
| def sample_and_compute_X( | |
| A, | |
| R, | |
| epsilon=1e-4, | |
| max_iter=1000, | |
| n_samples=10000, | |
| seed=42, | |
| controlled_args=None | |
| ): | |
| """Generates n_samples random weight vectors and computes corresponding h-Categorizer results.""" | |
| rng = np.random.default_rng(seed) | |
| X = np.zeros((n_samples, len(A)), dtype=float) | |
| for i in range(n_samples): | |
| w = dict(zip(A, rng.random(len(A)))) | |
| # Override controlled arguments if specified | |
| if controlled_args: | |
| for arg, value in controlled_args.items(): | |
| w[arg] = value | |
| HC = h_categorizer(A, R, w, max_iter, epsilon) | |
| X[i, :] = dict_to_vector(A, HC) | |
| return X | |
| def _safe_hull(points, qhull_opts="QJ", jitter=1e-8): | |
| """ | |
| Try to compute a convex hull robustly. | |
| Uses 'QJ' (joggle) and adds slight random jitter if needed. | |
| Returns None if still degenerate. | |
| """ | |
| try: | |
| return ConvexHull(points, qhull_options=qhull_opts) | |
| except QhullError: | |
| try: | |
| pts = points + jitter * np.random.randn(*points.shape) | |
| return ConvexHull(pts, qhull_options=qhull_opts) | |
| except QhullError: | |
| return None | |
| # def compute_gradual_semantics( | |
| # A, | |
| # R, | |
| # n_samples=1000, | |
| # val_axes=None, | |
| # controlled_args=None, | |
| # epsilon=1e-4, | |
| # max_iter=1000 | |
| # ): | |
| # """Compute samples and convex hull information for the given argumentation framework.""" | |
| # X_res = sample_and_compute_X( | |
| # A, R, epsilon, max_iter, n_samples, controlled_args=controlled_args | |
| # ) | |
| # # Case 1D | |
| # if len(A) == 1: | |
| # axes = [A[0]] | |
| # hull = _safe_hull(X_res) | |
| # dim = 1 | |
| # return dim, axes, X_res, hull | |
| # # Case 2D | |
| # if len(A) == 2: | |
| # axes = A[:2] | |
| # hull = _safe_hull(X_res) | |
| # dim = 2 | |
| # return dim, axes, X_res, hull | |
| # # Case ≥ 3D → project on chosen axes | |
| # axes = val_axes if val_axes else A[:3] | |
| # idx = [A.index(ax) for ax in axes] | |
| # Xp = X_res[:, idx] | |
| # hull = _safe_hull(Xp) | |
| # dim = 3 | |
| # return dim, axes, Xp, hull | |
| def compute_gradual_space(num_args, R, n_samples, axes=None, controlled_args=None, epsilon=1e-4, max_iter=1000): | |
| """ | |
| Compute the convex hull (acceptability degree space) for the weighted h-categorizer. | |
| Returns (num_args, hull_volume, hull_area, hull_points, samples, axes) | |
| """ | |
| # Generate argument labels A, B, C, ... | |
| A = [chr(ord("A") + i) for i in range(num_args)] | |
| # 1. Sample and compute semantics | |
| X_res = sample_and_compute_X( | |
| A, R, epsilon, max_iter, n_samples, controlled_args=controlled_args | |
| ) | |
| # 2. Handle projections depending on argument count | |
| if num_args == 1: | |
| dim = 1 | |
| axes_used = [A[0]] | |
| hull_points = np.array([[np.min(X_res)], [np.max(X_res)]]) | |
| hull_volume = float(np.max(X_res) - np.min(X_res)) | |
| hull_area = None | |
| return num_args, hull_volume, hull_area, hull_points.tolist(), X_res.tolist(), axes_used | |
| if num_args == 2: | |
| dim = 2 | |
| axes_used = A[:2] | |
| hull = _safe_hull(X_res) | |
| if hull is None: | |
| hull_volume = 0.0 | |
| hull_area = 0.0 | |
| hull_points = [] | |
| else: | |
| hull_volume = float(hull.volume) | |
| hull_area = float(hull.area) | |
| hull_points = hull.points[hull.vertices].tolist() | |
| return num_args, hull_volume, hull_area, hull_points, X_res.tolist(), axes_used | |
| # num_args >= 3 | |
| axes_used = axes if axes else A[:3] | |
| idx = [A.index(ax) for ax in axes_used] | |
| Xp = X_res[:, idx] | |
| hull = _safe_hull(Xp) | |
| if hull is None: | |
| hull_volume = 0.0 | |
| hull_area = 0.0 | |
| hull_points = [] | |
| else: | |
| hull_volume = float(hull.volume) | |
| hull_area = float(hull.area) | |
| hull_points = hull.points[hull.vertices].tolist() | |
| return num_args, hull_volume, hull_area, hull_points, Xp.tolist(), axes_used | |