frsutils public API¶
frsutils exposes its stable user-facing API from the package root:
from frsutils import compute_approximations
The grouped frsutils.api namespace exposes the same facade objects. User code,
notebooks, examples, and downstream research packages should prefer one of these
public import paths instead of importing from frsutils.core or frsutils.utils.
The shared interpretation rules for relation orientation, self-comparisons, VQRS defaults, boundary values, and backend equivalence are collected in Core computation contracts.
Purpose¶
FRsutils is a fuzzy-rough computation library for research workflows. Its public API provides task-oriented helpers for:
- pairwise similarity construction,
- lower and upper fuzzy-rough approximations,
- signed-boundary and positive-region values,
- dense and exact blockwise execution,
- dense fuzzy-rough model construction,
- reusable positive-region scoring.
The supported fuzzy-rough model aliases are:
"itfrs"— implicator/T-norm fuzzy-rough sets,"owafrs"— ordered weighted averaging fuzzy-rough sets,"vqrs"— vaguely quantified rough sets.
Main public entry points¶
| Task | Public API |
|---|---|
| Compute all approximation outputs | compute_approximations |
| Compute one output | compute_lower_approximation, compute_upper_approximation, compute_signed_boundary, compute_boundary_region, compute_positive_region |
| Build a pairwise similarity matrix | build_similarity_matrix |
| Build a dense or blockwise similarity engine | build_similarity_engine |
| Build a dense fuzzy-rough model object | build_fuzzy_rough_model |
| Compute and cache positive-region scores | FuzzyRoughPositiveRegionScorer |
Preferred imports:
from frsutils import (
FuzzyRoughApproximationResult,
FuzzyRoughPositiveRegionScorer,
build_fuzzy_rough_model,
build_similarity_engine,
build_similarity_matrix,
compute_approximations,
compute_boundary_region,
compute_lower_approximation,
compute_positive_region,
compute_signed_boundary,
compute_upper_approximation,
)
Quick start¶
import numpy as np
from frsutils import compute_approximations
X = np.array(
[
[0.00, 0.10],
[0.08, 0.18],
[0.15, 0.12],
[0.80, 0.82],
[0.88, 0.90],
[0.95, 0.86],
],
dtype=float,
)
y = np.array([0, 0, 0, 1, 1, 1], dtype=int)
result = compute_approximations(
X,
y,
model="itfrs",
similarity="linear",
)
print(result.positive_region)
A runnable version is available in examples/public_api_quickstart.py.
Computing approximations¶
compute_approximations is the main functional entry point:
from frsutils import compute_approximations
result = compute_approximations(
X,
y,
model="vqrs",
similarity="linear",
engine="dense",
)
It returns a FuzzyRoughApproximationResult, so downstream code accesses named
fields rather than positional tuple entries:
result.lower
result.upper
result.boundary
result.signed_boundary
result.positive_region
The public result contract is:
np.allclose(result.boundary, result.upper - result.lower)
np.allclose(result.signed_boundary, result.boundary)
np.allclose(result.positive_region, result.lower)
signed_boundary is the explicit name for the un-clipped difference
upper - lower. The result field boundary, the model method
boundary_region(), and the helper compute_boundary_region() remain
available for backward compatibility. Signed boundary values can be negative
when a custom model configuration does not guarantee lower <= upper.
Public result arrays are NumPy arrays, including results produced by optional CuPy-backed blockwise internals.
Input validation and minimum dataset size¶
All public approximation entry points use the same minimum-size contract:
X and y, or a precomputed similarity matrix and y, must describe at least
two aligned samples. Empty and single-sample inputs raise ValueError for all
three models and for both dense and blockwise execution. The approximation
wrapper functions and FuzzyRoughPositiveRegionScorer follow the same rule.
Feature data supplied to the public similarity and approximation builders must
be a finite two-dimensional numeric array. Values such as NaN, positive
infinity, and negative infinity are rejected. A precomputed similarity matrix
must be finite, square, aligned with the one-dimensional label array, and at
least 2 x 2.
This validation is performed at the public boundary so mathematically undefined or model-dependent edge behavior does not leak into research workflows.
Dense execution¶
Dense execution materializes or consumes a full pairwise similarity matrix and uses the dense reference model implementations:
result = compute_approximations(
X,
y,
model="owafrs",
similarity="linear",
engine="dense",
)
Dense approximation execution is NumPy-only. backend="numpy" and
backend="auto" are accepted; backend="cupy" raises a clear error rather
than being silently ignored. Use blockwise execution for optional CuPy-backed
computation.
A precomputed similarity matrix can be supplied in dense mode:
from frsutils import build_similarity_matrix, compute_approximations
S = build_similarity_matrix(X, similarity="linear")
result = compute_approximations(
None,
y,
model="itfrs",
similarity_matrix=S,
engine="dense",
)
For precomputed relations, FRsutils uses the explicit
rows_are_queries orientation:
similarity_matrix[i, j] = R(x_i, x_j)
Row i is aggregated to produce the approximation value returned for sample
x_i; column j provides evidence from sample x_j. Symmetric similarity
matrices are unaffected by this distinction, but transposing an asymmetric
relation can change the result.
When a precomputed matrix is supplied, do not also pass similarity or
similarity_* settings. FRsutils did not construct that matrix and therefore
reports result.similarity is None rather than claiming an unknown provenance.
Blockwise execution¶
Blockwise execution computes exact approximations without materializing the full similarity matrix by default:
result = compute_approximations(
X,
y,
model="itfrs",
similarity="linear",
engine="blockwise",
block_size=256,
backend="numpy",
)
Blockwise mode requires X and does not accept a precomputed
similarity_matrix. To materialize the matrix for inspection, set
return_similarity_matrix=True:
result = compute_approximations(
X,
y,
model="vqrs",
similarity="linear",
engine="blockwise",
block_size=256,
return_similarity_matrix=True,
)
S = result.similarity_matrix
Model examples¶
The three public model aliases use the same flat configuration contract. These examples intentionally configure model-specific components so the routing rules are visible.
ITFRS¶
result = compute_approximations(
X,
y,
model="itfrs",
similarity="gaussian",
similarity_sigma=0.4,
similarity_tnorm="yager",
similarity_tnorm_p=2.0,
ub_tnorm_name="yager",
ub_tnorm_p=1.7,
lb_implicator_name="goguen",
)
OWAFRS¶
result = compute_approximations(
X,
y,
model="owafrs",
similarity="linear",
ub_tnorm_name="minimum",
lb_implicator_name="lukasiewicz",
ub_owa_method_name="exponential",
ub_owa_method_base=2.5,
lb_owa_method_name="harmonic",
)
VQRS¶
result = compute_approximations(
X,
y,
model="vqrs",
similarity="linear",
lb_fuzzy_quantifier_name="linear",
lb_fuzzy_quantifier_alpha=0.0,
lb_fuzzy_quantifier_beta=0.5,
ub_fuzzy_quantifier_name="quadratic",
ub_fuzzy_quantifier_alpha=0.1,
ub_fuzzy_quantifier_beta=0.8,
)
The public defaults are ITFRS with a minimum upper T-norm and Lukasiewicz lower
implicator; linear similarity aggregated by the minimum T-norm is used when
similarity settings are omitted. OWAFRS defaults to linear upper and lower OWA
weights. VQRS defaults to a stricter quadratic lower quantifier
Q(0.2, 1.0) and a more permissive quadratic upper quantifier
Q(0.0, 0.6).
See Public configuration contract for the complete selector, prefix, alias, parameter, default, validation, and backward-compatibility rules.
Approximation wrapper functions¶
Wrapper functions are available when only one output is needed:
from frsutils import compute_positive_region
positive = compute_positive_region(
X,
y,
model="itfrs",
similarity="linear",
)
The wrappers delegate to compute_approximations and return NumPy arrays.
Result object and execution metadata¶
FuzzyRoughApproximationResult is a frozen public result container:
data = result.as_dict()
as_dict() omits similarity_matrix by default because the matrix can be large.
Include it explicitly when needed:
data = result.as_dict(include_similarity_matrix=True)
frozen prevents reassigning result attributes; contained NumPy arrays and the
configuration dictionary are not deep-immutable objects.
Important metadata fields are:
| Field | Meaning |
|---|---|
model |
Canonical fuzzy-rough model alias. |
similarity |
Similarity alias used by FRsutils to build the matrix, or None for externally supplied matrices. |
engine |
Canonical approximation engine: "dense" or "blockwise". |
backend |
Canonical resolved backend. Dense execution reports "numpy". |
block_size |
Positive integer for blockwise execution; None for dense execution. |
used_blockwise |
Whether blockwise approximation execution was used. |
used_gpu_similarity_blocks |
Whether similarity blocks used the optional CuPy backend. |
used_gpu_approximation_accumulators |
Whether model-specific approximation accumulators stayed CuPy-resident before final NumPy conversion. |
For OWAFRS, CuPy-backed blockwise execution currently accelerates similarity blocks; the OWA approximation accumulators are not claimed to be GPU-resident.
Similarity API¶
Use build_similarity_matrix for an ordinary dense pairwise matrix:
from frsutils import build_similarity_matrix
S = build_similarity_matrix(
X,
similarity="gaussian",
similarity_sigma=0.5,
)
Use build_similarity_engine when block iteration is needed:
from frsutils import build_similarity_engine
engine = build_similarity_engine(
X,
engine="blockwise",
block_size=256,
similarity="linear",
)
for block in engine.iter_blocks():
print(block.row_slice, block.col_slice, block.values.shape)
Similarity builders accept only similarity-related flat configuration. Model
parameters such as ub_tnorm_name are rejected instead of being ignored.
Building dense model objects¶
build_fuzzy_rough_model constructs a dense model object from a precomputed
similarity matrix and labels:
from frsutils import build_fuzzy_rough_model, build_similarity_matrix
S = build_similarity_matrix(X, similarity="linear")
model = build_fuzzy_rough_model(
model_type="itfrs",
similarity_matrix=S,
labels=y,
)
lower = model.lower_approximation()
The builder applies the same authoritative model defaults as
compute_approximations. It accepts model-related flat configuration only;
similarity settings are rejected because the matrix has already been built.
Positive-region scorer¶
FuzzyRoughPositiveRegionScorer provides an estimator-like API for fitted-sample
positive-region scores:
from frsutils import FuzzyRoughPositiveRegionScorer
scorer = FuzzyRoughPositiveRegionScorer(
model="itfrs",
similarity="linear",
engine="blockwise",
backend="numpy",
block_size=512,
)
scores = scorer.fit_score(X, y)
result = scorer.as_result()
After a successful fit, the scorer exposes result_, positive_region_,
lower_, upper_, signed_boundary_, and n_samples_in_. The legacy
boundary_ attribute remains available as an alias of signed_boundary_; both
refer to the same unclipped upper_ - lower_ array.
The scorer follows scikit-learn conventions for parameter handling, cloning,
get_params, and set_params. It computes fuzzy-rough scores for the fitted
training relation; unseen-sample scoring is not currently defined. After fit,
request the cached fitted scores with no argument:
scores = scorer.score_samples()
Passing X to score_samples(X) raises ValueError instead of silently
returning training scores for unrelated samples.
extra_params may hold contract-defined flat keys not represented by an
explicit scorer constructor parameter. It cannot duplicate or alias an explicit
constructor parameter, because hidden overrides would break reproducibility.
Flat public configuration¶
The stable public configuration boundary is flat only. A selector chooses a registered component, and component parameters use the same component prefix:
<component>_name = <registered alias>
<component>_<constructor parameter> = <value>
For example:
result = compute_approximations(
X,
y,
model="itfrs",
similarity="gaussian",
similarity_sigma=0.5,
ub_tnorm_name="yager",
ub_tnorm_p=2.0,
lb_implicator_name="lukasiewicz",
)
Similarity selectors use the shorter public names similarity and
similarity_tnorm; their parameters still use similarity_ and
similarity_tnorm_ prefixes.
| Component role | Selector | Parameter prefix |
|---|---|---|
| Similarity | similarity |
similarity_ |
| Similarity aggregation T-norm | similarity_tnorm |
similarity_tnorm_ |
| Upper T-norm | ub_tnorm_name |
ub_tnorm_ |
| Lower implicator | lb_implicator_name |
lb_implicator_ |
| Upper OWA weighting | ub_owa_method_name |
ub_owa_method_ |
| Lower OWA weighting | lb_owa_method_name |
lb_owa_method_ |
| Lower fuzzy quantifier | lb_fuzzy_quantifier_name |
lb_fuzzy_quantifier_ |
| Upper fuzzy quantifier | ub_fuzzy_quantifier_name |
ub_fuzzy_quantifier_ |
A flat configuration dictionary can be passed through config:
config = {
"type": "itfrs",
"similarity": "gaussian",
"similarity_sigma": 0.5,
"ub_tnorm_name": "minimum",
"lb_implicator_name": "lukasiewicz",
}
result = compute_approximations(X, y, config=config)
Additional flat keyword arguments override ordinary values from config.
Explicit model sources are stricter: model="vqrs" and config={"type":
"itfrs"} are a conflict and raise ValueError rather than silently choosing one.
If no model source is supplied, the public default is "itfrs".
Nested component dictionaries are an internal normalized representation and are rejected at public API boundaries. This is intentional: one flat configuration contract keeps parameter names searchable, typo-checkable, reproducible, and compatible with estimator-style parameter workflows.
The detailed source of truth is Public configuration contract.
Advanced public exports¶
The facade also exposes registry discovery and concrete model/similarity types for advanced inspection and downstream research code:
from frsutils import (
FuzzyRoughModel,
ITFRS,
OWAFRS,
Similarity,
VQRS,
get_fuzzy_rough_model_class,
list_fuzzy_rough_models,
list_similarities,
)
Similarity engine classes, SimilarityBlock, and
calculate_similarity_matrix are also exported for advanced workflows. They are
not the preferred starting point for tutorials; use the task-level builders and
computation functions when possible.
Internal flat-to-nested construction helpers such as
normalize_flat_config_to_nested, apply_config_aliases, and
extract_prefixed_params are deliberately not exported by frsutils or
frsutils.api.
Downstream-package rule¶
Downstream packages should depend on the public facade:
from frsutils import build_similarity_matrix, compute_positive_region
Avoid deep internal imports in downstream user-facing code:
# Avoid this in user-facing examples and downstream packages.
from frsutils.core.models.itfrs import ITFRS
from frsutils.core.similarities import build_similarity_matrix
from frsutils.utils.init_helpers import normalize_flat_config_to_nested
The frsutils namespace is the compatibility boundary. Internal modules may
change between releases.
Backend behavior¶
NumPy is the stable backend. CuPy support is optional and used only through explicit supported blockwise paths:
result = compute_approximations(
X,
y,
model="itfrs",
similarity="linear",
engine="blockwise",
backend="cupy",
)
Public outputs remain NumPy arrays regardless of the internal backend. See Backends for the model-specific backend contract.