fuzzytool 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. fuzzytool-0.1.0/.github/workflows/ci.yml +24 -0
  2. fuzzytool-0.1.0/.github/workflows/docs.yml +40 -0
  3. fuzzytool-0.1.0/.github/workflows/release-pypi.yml +23 -0
  4. fuzzytool-0.1.0/.gitignore +27 -0
  5. fuzzytool-0.1.0/.zenodo.json +24 -0
  6. fuzzytool-0.1.0/CHANGELOG.md +52 -0
  7. fuzzytool-0.1.0/CITATION.cff +18 -0
  8. fuzzytool-0.1.0/CLAUDE.md +82 -0
  9. fuzzytool-0.1.0/CONTRIBUTING.md +36 -0
  10. fuzzytool-0.1.0/LICENSE +21 -0
  11. fuzzytool-0.1.0/PKG-INFO +126 -0
  12. fuzzytool-0.1.0/README.md +89 -0
  13. fuzzytool-0.1.0/ROADMAP.md +52 -0
  14. fuzzytool-0.1.0/docs/api/python.md +63 -0
  15. fuzzytool-0.1.0/docs/citing.md +30 -0
  16. fuzzytool-0.1.0/docs/comparison.md +72 -0
  17. fuzzytool-0.1.0/docs/extending.md +54 -0
  18. fuzzytool-0.1.0/docs/getting-started.md +57 -0
  19. fuzzytool-0.1.0/docs/guide/anfis.md +29 -0
  20. fuzzytool-0.1.0/docs/guide/clustering.md +50 -0
  21. fuzzytool-0.1.0/docs/guide/defuzzification.md +28 -0
  22. fuzzytool-0.1.0/docs/guide/ftransform.md +29 -0
  23. fuzzytool-0.1.0/docs/guide/mamdani.md +32 -0
  24. fuzzytool-0.1.0/docs/guide/membership.md +36 -0
  25. fuzzytool-0.1.0/docs/guide/rules.md +47 -0
  26. fuzzytool-0.1.0/docs/guide/tsk.md +27 -0
  27. fuzzytool-0.1.0/docs/guide/type2.md +73 -0
  28. fuzzytool-0.1.0/docs/guide/visualization.md +27 -0
  29. fuzzytool-0.1.0/docs/index.md +36 -0
  30. fuzzytool-0.1.0/docs/installation.md +18 -0
  31. fuzzytool-0.1.0/examples/anfis.py +24 -0
  32. fuzzytool-0.1.0/examples/clustering.py +28 -0
  33. fuzzytool-0.1.0/examples/credit_risk.py +39 -0
  34. fuzzytool-0.1.0/examples/credit_risk_it2.py +40 -0
  35. fuzzytool-0.1.0/examples/ftransform.py +30 -0
  36. fuzzytool-0.1.0/fuzzytool/__init__.py +55 -0
  37. fuzzytool-0.1.0/fuzzytool/anfis.py +141 -0
  38. fuzzytool-0.1.0/fuzzytool/cluster.py +231 -0
  39. fuzzytool-0.1.0/fuzzytool/datasets.py +104 -0
  40. fuzzytool-0.1.0/fuzzytool/defuzz.py +84 -0
  41. fuzzytool-0.1.0/fuzzytool/ftransform.py +79 -0
  42. fuzzytool-0.1.0/fuzzytool/inference/__init__.py +6 -0
  43. fuzzytool-0.1.0/fuzzytool/inference/mamdani.py +93 -0
  44. fuzzytool-0.1.0/fuzzytool/inference/tsk.py +77 -0
  45. fuzzytool-0.1.0/fuzzytool/membership.py +149 -0
  46. fuzzytool-0.1.0/fuzzytool/norms.py +105 -0
  47. fuzzytool-0.1.0/fuzzytool/rules.py +34 -0
  48. fuzzytool-0.1.0/fuzzytool/sets.py +210 -0
  49. fuzzytool-0.1.0/fuzzytool/type2/__init__.py +27 -0
  50. fuzzytool-0.1.0/fuzzytool/type2/inference.py +122 -0
  51. fuzzytool-0.1.0/fuzzytool/type2/reduction.py +83 -0
  52. fuzzytool-0.1.0/fuzzytool/type2/sets.py +96 -0
  53. fuzzytool-0.1.0/fuzzytool/viz.py +118 -0
  54. fuzzytool-0.1.0/mkdocs.yml +79 -0
  55. fuzzytool-0.1.0/notebooks/01_quickstart.ipynb +210 -0
  56. fuzzytool-0.1.0/notebooks/02_type2.ipynb +141 -0
  57. fuzzytool-0.1.0/notebooks/03_clustering.ipynb +130 -0
  58. fuzzytool-0.1.0/notebooks/04_learning.ipynb +147 -0
  59. fuzzytool-0.1.0/notebooks/README.md +18 -0
  60. fuzzytool-0.1.0/paper.bib +32 -0
  61. fuzzytool-0.1.0/paper.md +66 -0
  62. fuzzytool-0.1.0/pyproject.toml +52 -0
  63. fuzzytool-0.1.0/tests/test_cluster.py +73 -0
  64. fuzzytool-0.1.0/tests/test_inference.py +49 -0
  65. fuzzytool-0.1.0/tests/test_learning.py +84 -0
  66. fuzzytool-0.1.0/tests/test_membership.py +40 -0
  67. fuzzytool-0.1.0/tests/test_type2.py +77 -0
@@ -0,0 +1,24 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.9", "3.11", "3.13"]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-python@v5
17
+ with:
18
+ python-version: ${{ matrix.python-version }}
19
+ - name: Install
20
+ run: pip install -e ".[dev,viz]"
21
+ - name: Lint
22
+ run: ruff check fuzzytool tests
23
+ - name: Test
24
+ run: pytest -q
@@ -0,0 +1,40 @@
1
+ name: Docs
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ permissions:
8
+ contents: read
9
+ pages: write
10
+ id-token: write
11
+
12
+ concurrency:
13
+ group: pages
14
+ cancel-in-progress: true
15
+
16
+ jobs:
17
+ build:
18
+ runs-on: ubuntu-latest
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.12"
24
+ - name: Install (package + docs deps so mkdocstrings can import it)
25
+ run: pip install -e ".[docs]"
26
+ - name: Build
27
+ run: mkdocs build --strict
28
+ - uses: actions/upload-pages-artifact@v3
29
+ with:
30
+ path: site
31
+
32
+ deploy:
33
+ needs: build
34
+ runs-on: ubuntu-latest
35
+ environment:
36
+ name: github-pages
37
+ url: ${{ steps.deployment.outputs.page_url }}
38
+ steps:
39
+ - id: deployment
40
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,23 @@
1
+ name: Release (PyPI)
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ environment: pypi
11
+ permissions:
12
+ id-token: write # PyPI Trusted Publishing (OIDC) — no API token needed
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: actions/setup-python@v5
16
+ with:
17
+ python-version: "3.12"
18
+ - name: Build sdist + wheel
19
+ run: |
20
+ pip install build
21
+ python -m build
22
+ - name: Publish to PyPI
23
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,27 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+ .venv/
9
+ venv/
10
+
11
+ # Tooling
12
+ .pytest_cache/
13
+ .ruff_cache/
14
+ .coverage
15
+ htmlcov/
16
+ .mypy_cache/
17
+
18
+ # MkDocs build output
19
+ site/
20
+
21
+ # Jupyter
22
+ .ipynb_checkpoints/
23
+
24
+ # OS / editor
25
+ .DS_Store
26
+ .vscode/
27
+ .idea/
@@ -0,0 +1,24 @@
1
+ {
2
+ "title": "fuzzytool: a clean, extensible fuzzy-logic toolkit in pure Python",
3
+ "description": "A composable, extensible fuzzy-logic toolkit in pure Python + NumPy: membership functions, t-/s-norms, Mamdani and Takagi-Sugeno inference, interval type-2 sets with Karnik-Mendel type reduction, fuzzy clustering (FCM, Gustafson-Kessel, possibilistic), ANFIS, and the F-transform.",
4
+ "license": "MIT",
5
+ "upload_type": "software",
6
+ "access_right": "open",
7
+ "creators": [
8
+ {
9
+ "name": "Salmeron, Jose L.",
10
+ "affiliation": "CUNEF Universidad"
11
+ }
12
+ ],
13
+ "keywords": [
14
+ "fuzzy logic",
15
+ "fuzzy inference",
16
+ "Mamdani",
17
+ "Takagi-Sugeno",
18
+ "interval type-2",
19
+ "fuzzy clustering",
20
+ "ANFIS",
21
+ "F-transform",
22
+ "Python"
23
+ ]
24
+ }
@@ -0,0 +1,52 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format is based on
4
+ [Keep a Changelog](https://keepachangelog.com/) and the project adheres to
5
+ [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [Unreleased]
8
+
9
+ ### Added
10
+
11
+ - Example notebooks (`notebooks/`): quickstart, interval type-2, clustering, and
12
+ ANFIS/F-transform — committed executed.
13
+ - Documentation: a comparison page vs scikit-fuzzy and a citing/releasing page;
14
+ `.zenodo.json` for DOI archival; `notebooks` optional dependency group.
15
+ - **ANFIS** (`fuzzytool.anfis.ANFIS`): a trainable first-order Sugeno system over
16
+ a grid partition, fit with Jang's hybrid scheme (least-squares consequents +
17
+ gradient-descent premises). `fit` / `predict` / `history_`.
18
+ - **F-transform** (`fuzzytool.ftransform.FTransform`): direct and inverse fuzzy
19
+ transform over a triangular partition of unity, with `fit` / `smooth` for
20
+ denoising and compression.
21
+ - **Fuzzy clustering** (`fuzzytool.cluster`):
22
+ - `fuzzy_cmeans` (Bezdek FCM), `gustafson_kessel` (adaptive Mahalanobis norm),
23
+ `possibilistic_cmeans` (typicalities); all seeded for reproducibility.
24
+ - Validity metrics: `partition_coefficient`, `partition_entropy`, `xie_beni`.
25
+ - `viz.plot_clusters` and `datasets.make_blobs`.
26
+ - **Interval type-2 (IT2)** support (`fuzzytool.type2`):
27
+ - IT2 membership functions with a footprint of uncertainty: `it2` (explicit
28
+ LMF/UMF), `it2_scale` (height), `it2_gauss_uncertain_mean`,
29
+ `it2_gauss_uncertain_std`.
30
+ - Interval-valued antecedent evaluation (`Antecedent.eval_interval`); type-1
31
+ and IT2 terms can be mixed in one rule.
32
+ - `IT2Mamdani` (center-of-sets type reduction) and `IT2TSK` engines.
33
+ - Karnik-Mendel type reduction: `km_endpoint`, `karnik_mendel`, `centroid_it2`.
34
+ - `viz.plot_it2_variable` (shaded FOU); `datasets.credit_risk_it2`.
35
+
36
+ ## [0.1.0] - 2026-06-24
37
+
38
+ ### Added
39
+
40
+ - Core membership functions: triangular, trapezoidal, gaussian, generalized
41
+ bell, sigmoid (`fuzzytool.membership`).
42
+ - T-norms and s-norms (min/prod/Łukasiewicz, max/probor/Łukasiewicz), resolved
43
+ by name (`fuzzytool.norms`).
44
+ - `Variable` (linguistic variable) with auto-generated or explicit terms, and an
45
+ operator-based rule-antecedent expression tree (`&`, `|`, `~`).
46
+ - **Mamdani** inference with configurable implication/aggregation and
47
+ defuzzification (centroid, bisector, MOM/SOM/LOM).
48
+ - **Takagi-Sugeno (TSK)** inference (zero- and first-order, plus callable
49
+ consequents).
50
+ - `fuzzytool.viz`: membership-function plots and 2-input control surfaces.
51
+ - `fuzzytool.datasets.tipper`: the classic example system.
52
+ - Test suite, MkDocs Material documentation, and CI.
@@ -0,0 +1,18 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use fuzzytool, please cite it as below."
3
+ title: "fuzzytool: a clean, extensible fuzzy-logic toolkit in pure Python"
4
+ type: software
5
+ authors:
6
+ - family-names: Salmeron
7
+ given-names: Jose L.
8
+ version: 0.1.0
9
+ date-released: 2026-06-24
10
+ license: MIT
11
+ repository-code: "https://github.com/fuzzytool/fuzzytool.github.io"
12
+ url: "https://fuzzytool.github.io"
13
+ keywords:
14
+ - fuzzy logic
15
+ - fuzzy inference
16
+ - Mamdani
17
+ - Takagi-Sugeno
18
+ - Python
@@ -0,0 +1,82 @@
1
+ # CLAUDE.md
2
+
3
+ Guide for working in this repository with Claude Code.
4
+
5
+ ## What this project is
6
+
7
+ **fuzzytool** — a clean, extensible **fuzzy-logic toolkit** in **pure Python +
8
+ NumPy**, published on PyPI with docs on GitHub Pages. Priorities, in order:
9
+ 1) a composable API, 2) algorithm comparison, 3) visualization, 4) code clarity.
10
+ It is the fuzzy-logic sibling of the *turboswarm* PSO library and follows the
11
+ same packaging and extensibility philosophy.
12
+
13
+ ## Architecture
14
+
15
+ ```
16
+ fuzzytool/
17
+ membership.py MF Protocol + tri/trap/gauss/gbell/sigmoid
18
+ norms.py t-norms (AND) / s-norms (OR), resolved by name
19
+ sets.py FuzzySet, Variable, antecedent tree (& | ~)
20
+ rules.py Rule dataclass (shared by the engines)
21
+ defuzz.py centroid / bisector / mom / som / lom
22
+ inference/ mamdani.py, tsk.py
23
+ viz.py matplotlib: membership plots, control surface
24
+ datasets.py example systems (credit_risk)
25
+ tests/ examples/ docs/
26
+ ```
27
+
28
+ ### The central design (read before touching the engines)
29
+
30
+ The inference loop knows **nothing** about concrete variants. Everything that
31
+ changes lives behind small Protocols:
32
+
33
+ - **`MembershipFunction`** (`membership.py`) — a callable `x -> degree`. A new
34
+ shape is a new callable; nothing else changes.
35
+ - **`Norm`** (`norms.py`) — t-/s-norms, resolved by name via `get_tnorm` /
36
+ `get_snorm`. You may also pass a callable directly to an engine.
37
+ - **defuzzifiers** (`defuzz.py`) — resolved by name via `get_defuzzifier`.
38
+
39
+ Rules compose with operators on `Proposition` objects: `&` → t-norm (AND),
40
+ `|` → s-norm (OR), `~` → complement (NOT). The antecedent tree is evaluated by
41
+ `Antecedent.eval(inputs, tnorm, snorm)`; both engines reuse it.
42
+
43
+ `Mamdani` consequents are propositions (`output[term]`); `TSK` consequents are
44
+ numbers, coefficient mappings, or callables.
45
+
46
+ ## Commands (verified)
47
+
48
+ ```bash
49
+ python -m venv .venv && source .venv/bin/activate
50
+ pip install -e ".[dev,viz,docs]"
51
+ pytest -q # tests + doctests (--doctest-modules)
52
+ ruff check fuzzytool tests
53
+ python examples/credit_risk.py
54
+ mkdocs serve # docs at http://127.0.0.1:8000
55
+ mkdocs build --strict
56
+ ```
57
+
58
+ ## Conventions
59
+
60
+ - **Language:** all code, comments, identifiers and prose in **English**
61
+ (published internationally on GitHub and PyPI).
62
+ - **Vectorize:** membership functions accept scalars *and* NumPy arrays.
63
+ - **NumPy 2 compat:** `np.trapz` was renamed `np.trapezoid`; `defuzz.py` shims
64
+ both — do not call `np.trapz` directly elsewhere.
65
+ - **Tests:** every new MF / connective / defuzzifier / engine needs a test;
66
+ engines need a behavioral check (monotonicity or known output).
67
+ - **Docstrings:** Google style (rendered by `mkdocstrings`).
68
+
69
+ ## How to extend (typical tasks)
70
+
71
+ - **New membership function:** any callable `x -> degree`; add a factory in
72
+ `membership.py` if it is a standard shape, plus a test.
73
+ - **New connective:** register a `(a, b) -> result` in `norms._TNORMS` /
74
+ `_SNORMS`, or pass it directly to the engine.
75
+ - **New defuzzifier:** add a `(x, y) -> float` to `defuzz._METHODS`.
76
+ - **New engine:** implement `__call__(**inputs)`, reuse `Antecedent.eval` and the
77
+ shared `Rule`. Templates: `inference/mamdani.py`, `inference/tsk.py`.
78
+
79
+ ## Status
80
+
81
+ See `ROADMAP.md`. Phase 1 (core + Mamdani) and Phase 2 (TSK + viz) are done;
82
+ type-2, clustering, ANFIS and F-transform are planned.
@@ -0,0 +1,36 @@
1
+ # Contributing
2
+
3
+ Thanks for your interest in fuzzytool!
4
+
5
+ ## Setup
6
+
7
+ ```bash
8
+ python -m venv .venv && source .venv/bin/activate
9
+ pip install -e ".[dev,viz,docs]"
10
+ ```
11
+
12
+ ## Checks (run before opening a PR)
13
+
14
+ ```bash
15
+ ruff check fuzzytool tests # lint
16
+ pytest -q # tests + doctests
17
+ mkdocs build --strict # docs build cleanly
18
+ ```
19
+
20
+ ## Conventions
21
+
22
+ - **Language:** all code, comments, identifiers, and prose are in **English**
23
+ (the project is published internationally on GitHub and PyPI).
24
+ - **Tests:** every new membership function, connective, defuzzifier, or engine
25
+ needs a test. Inference engines need at least one behavioral test (e.g. a
26
+ monotonicity or known-output check).
27
+ - **Docstrings:** Google style (rendered by `mkdocstrings`).
28
+ - **Extensibility first:** prefer adding a callable behind an existing Protocol
29
+ over special-casing the inference loop. See [`docs/extending.md`](docs/extending.md).
30
+
31
+ ## Adding a feature
32
+
33
+ 1. Implement it in the relevant module.
34
+ 2. Export it where appropriate (`__init__.py` for public API).
35
+ 3. Add tests and a docs entry.
36
+ 4. Update `CHANGELOG.md` and, if it completes a milestone, `ROADMAP.md`.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jose L. Salmeron
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,126 @@
1
+ Metadata-Version: 2.4
2
+ Name: fuzzytool
3
+ Version: 0.1.0
4
+ Summary: A clean, extensible fuzzy-logic toolkit in pure Python + NumPy
5
+ Project-URL: Homepage, https://fuzzytool.github.io
6
+ Project-URL: Documentation, https://fuzzytool.github.io
7
+ Project-URL: Repository, https://github.com/fuzzytool/fuzzytool.github.io
8
+ Project-URL: Issues, https://github.com/fuzzytool/fuzzytool.github.io/issues
9
+ Author: Jose L. Salmeron
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: anfis,fuzzy inference,fuzzy logic,mamdani,takagi-sugeno,type-2
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
18
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
19
+ Requires-Python: >=3.9
20
+ Requires-Dist: numpy>=1.21
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest-cov; extra == 'dev'
23
+ Requires-Dist: pytest>=7; extra == 'dev'
24
+ Requires-Dist: ruff; extra == 'dev'
25
+ Provides-Extra: docs
26
+ Requires-Dist: mkdocs-material; extra == 'docs'
27
+ Requires-Dist: mkdocstrings[python]; extra == 'docs'
28
+ Provides-Extra: notebooks
29
+ Requires-Dist: ipykernel; extra == 'notebooks'
30
+ Requires-Dist: jupyter; extra == 'notebooks'
31
+ Requires-Dist: matplotlib>=3.4; extra == 'notebooks'
32
+ Requires-Dist: nbconvert; extra == 'notebooks'
33
+ Requires-Dist: nbformat; extra == 'notebooks'
34
+ Provides-Extra: viz
35
+ Requires-Dist: matplotlib>=3.4; extra == 'viz'
36
+ Description-Content-Type: text/markdown
37
+
38
+ <p align="center">
39
+ <a href="https://pypi.org/project/fuzzytool/"><img src="https://img.shields.io/pypi/v/fuzzytool?logo=pypi&logoColor=white" alt="PyPI"></a>
40
+ <a href="https://github.com/fuzzytool/fuzzytool.github.io/actions/workflows/ci.yml"><img src="https://github.com/fuzzytool/fuzzytool.github.io/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
41
+ <a href="https://fuzzytool.github.io/"><img src="https://img.shields.io/badge/docs-fuzzytool.github.io-3f51b5" alt="Docs"></a>
42
+ <img src="https://img.shields.io/pypi/pyversions/fuzzytool?logo=python&logoColor=white" alt="Python versions">
43
+ <img src="https://img.shields.io/badge/license-MIT-blue" alt="License: MIT">
44
+ </p>
45
+
46
+ # fuzzytool
47
+
48
+ A clean, **extensible fuzzy-logic toolkit** in **pure Python + NumPy**. Its
49
+ design priorities are a composable API, algorithm comparison, visualization and
50
+ code clarity — a modern alternative to the verbose control API of scikit-fuzzy.
51
+
52
+ ```python
53
+ import fuzzytool as fz
54
+
55
+ # Credit-risk premium: a lender turns a credit score + debt-to-income ratio
56
+ # into the risk points it adds on top of its base interest rate.
57
+ score = fz.Variable("score", (300, 850), terms=["poor", "fair", "good", "excellent"])
58
+ dti = fz.Variable("dti", (0, 50), terms=["low", "moderate", "high"])
59
+ premium = fz.Variable("premium", (0, 12), terms=["low", "medium", "high"])
60
+
61
+ sys = fz.Mamdani(defuzz="centroid")
62
+ sys.rule(score["poor"] | dti["high"], premium["high"]) # |=OR &=AND ~=NOT
63
+ sys.rule(score["fair"] & dti["moderate"], premium["medium"])
64
+ sys.rule(score["good"] | score["excellent"], premium["low"])
65
+
66
+ print(sys(score=800, dti=10)) # the system is just callable -> a low premium
67
+ ```
68
+
69
+ ## The design idea (extensibility)
70
+
71
+ The inference loop knows **nothing** about any concrete variant. Everything that
72
+ changes lives behind small Python **Protocols**:
73
+
74
+ - **`MembershipFunction`** (`fuzzytool/membership.py`) — a callable `x -> degree`.
75
+ A new shape = a new callable.
76
+ - **`Norm`** (`fuzzytool/norms.py`) — t-norms (AND) and s-norms (OR), resolved by
77
+ name. A new connective = one registered function.
78
+ - **defuzzifiers** (`fuzzytool/defuzz.py`) — centroid, bisector, MOM/SOM/LOM,
79
+ resolved by name.
80
+
81
+ Rules read like logic thanks to operator overloading: `&` is the t-norm, `|` the
82
+ s-norm, `~` the complement.
83
+
84
+ ## What it includes / roadmap
85
+
86
+ | Phase | Content | Status |
87
+ |------|-----------|--------|
88
+ | 1 | Core: membership functions, t-/s-norms, `Variable`, operator rules, **Mamdani** + defuzzification, tipper example, tests | ✅ |
89
+ | 2 | **Takagi-Sugeno (TSK)** inference + `viz` (membership plots, control surface) | ✅ (TSK + viz) |
90
+ | 3 | **Type-2 / interval type-2** sets (footprint of uncertainty) + Karnik-Mendel type reduction | ✅ |
91
+ | 4 | **Fuzzy clustering**: fuzzy c-means, Gustafson-Kessel, possibilistic | ✅ |
92
+ | 5 | **ANFIS** (trainable TSK) + **F-transform** (direct/inverse) | ✅ |
93
+ | 6 | Notebooks, JOSS `paper.md`, Zenodo DOI, PyPI release | ⏳ |
94
+
95
+ See [`ROADMAP.md`](ROADMAP.md).
96
+
97
+ ## Install
98
+
99
+ ```bash
100
+ pip install fuzzytool # core (NumPy only)
101
+ pip install fuzzytool[viz] # + matplotlib visualization
102
+ ```
103
+
104
+ From source, for development:
105
+
106
+ ```bash
107
+ python -m venv .venv && source .venv/bin/activate
108
+ pip install -e ".[dev,viz,docs]"
109
+ pytest -q
110
+ python examples/tipper.py
111
+ ```
112
+
113
+ ## Documentation
114
+
115
+ A documentation portal (narrative guide + API reference from docstrings) is built
116
+ with **MkDocs Material** and published to **GitHub Pages**:
117
+ <https://fuzzytool.github.io/>.
118
+
119
+ ```bash
120
+ pip install -e ".[docs]"
121
+ mkdocs serve # live portal at http://127.0.0.1:8000
122
+ ```
123
+
124
+ ## License
125
+
126
+ MIT. See [`LICENSE`](LICENSE).
@@ -0,0 +1,89 @@
1
+ <p align="center">
2
+ <a href="https://pypi.org/project/fuzzytool/"><img src="https://img.shields.io/pypi/v/fuzzytool?logo=pypi&logoColor=white" alt="PyPI"></a>
3
+ <a href="https://github.com/fuzzytool/fuzzytool.github.io/actions/workflows/ci.yml"><img src="https://github.com/fuzzytool/fuzzytool.github.io/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
4
+ <a href="https://fuzzytool.github.io/"><img src="https://img.shields.io/badge/docs-fuzzytool.github.io-3f51b5" alt="Docs"></a>
5
+ <img src="https://img.shields.io/pypi/pyversions/fuzzytool?logo=python&logoColor=white" alt="Python versions">
6
+ <img src="https://img.shields.io/badge/license-MIT-blue" alt="License: MIT">
7
+ </p>
8
+
9
+ # fuzzytool
10
+
11
+ A clean, **extensible fuzzy-logic toolkit** in **pure Python + NumPy**. Its
12
+ design priorities are a composable API, algorithm comparison, visualization and
13
+ code clarity — a modern alternative to the verbose control API of scikit-fuzzy.
14
+
15
+ ```python
16
+ import fuzzytool as fz
17
+
18
+ # Credit-risk premium: a lender turns a credit score + debt-to-income ratio
19
+ # into the risk points it adds on top of its base interest rate.
20
+ score = fz.Variable("score", (300, 850), terms=["poor", "fair", "good", "excellent"])
21
+ dti = fz.Variable("dti", (0, 50), terms=["low", "moderate", "high"])
22
+ premium = fz.Variable("premium", (0, 12), terms=["low", "medium", "high"])
23
+
24
+ sys = fz.Mamdani(defuzz="centroid")
25
+ sys.rule(score["poor"] | dti["high"], premium["high"]) # |=OR &=AND ~=NOT
26
+ sys.rule(score["fair"] & dti["moderate"], premium["medium"])
27
+ sys.rule(score["good"] | score["excellent"], premium["low"])
28
+
29
+ print(sys(score=800, dti=10)) # the system is just callable -> a low premium
30
+ ```
31
+
32
+ ## The design idea (extensibility)
33
+
34
+ The inference loop knows **nothing** about any concrete variant. Everything that
35
+ changes lives behind small Python **Protocols**:
36
+
37
+ - **`MembershipFunction`** (`fuzzytool/membership.py`) — a callable `x -> degree`.
38
+ A new shape = a new callable.
39
+ - **`Norm`** (`fuzzytool/norms.py`) — t-norms (AND) and s-norms (OR), resolved by
40
+ name. A new connective = one registered function.
41
+ - **defuzzifiers** (`fuzzytool/defuzz.py`) — centroid, bisector, MOM/SOM/LOM,
42
+ resolved by name.
43
+
44
+ Rules read like logic thanks to operator overloading: `&` is the t-norm, `|` the
45
+ s-norm, `~` the complement.
46
+
47
+ ## What it includes / roadmap
48
+
49
+ | Phase | Content | Status |
50
+ |------|-----------|--------|
51
+ | 1 | Core: membership functions, t-/s-norms, `Variable`, operator rules, **Mamdani** + defuzzification, tipper example, tests | ✅ |
52
+ | 2 | **Takagi-Sugeno (TSK)** inference + `viz` (membership plots, control surface) | ✅ (TSK + viz) |
53
+ | 3 | **Type-2 / interval type-2** sets (footprint of uncertainty) + Karnik-Mendel type reduction | ✅ |
54
+ | 4 | **Fuzzy clustering**: fuzzy c-means, Gustafson-Kessel, possibilistic | ✅ |
55
+ | 5 | **ANFIS** (trainable TSK) + **F-transform** (direct/inverse) | ✅ |
56
+ | 6 | Notebooks, JOSS `paper.md`, Zenodo DOI, PyPI release | ⏳ |
57
+
58
+ See [`ROADMAP.md`](ROADMAP.md).
59
+
60
+ ## Install
61
+
62
+ ```bash
63
+ pip install fuzzytool # core (NumPy only)
64
+ pip install fuzzytool[viz] # + matplotlib visualization
65
+ ```
66
+
67
+ From source, for development:
68
+
69
+ ```bash
70
+ python -m venv .venv && source .venv/bin/activate
71
+ pip install -e ".[dev,viz,docs]"
72
+ pytest -q
73
+ python examples/tipper.py
74
+ ```
75
+
76
+ ## Documentation
77
+
78
+ A documentation portal (narrative guide + API reference from docstrings) is built
79
+ with **MkDocs Material** and published to **GitHub Pages**:
80
+ <https://fuzzytool.github.io/>.
81
+
82
+ ```bash
83
+ pip install -e ".[docs]"
84
+ mkdocs serve # live portal at http://127.0.0.1:8000
85
+ ```
86
+
87
+ ## License
88
+
89
+ MIT. See [`LICENSE`](LICENSE).
@@ -0,0 +1,52 @@
1
+ # Roadmap
2
+
3
+ Phases mirror the structure of the sibling project *turboswarm*: each phase is a
4
+ self-contained, testable increment.
5
+
6
+ ## ✅ Phase 1 — Core + Mamdani
7
+
8
+ - [x] Membership functions (tri, trap, gauss, gbell, sigmoid) behind the
9
+ `MembershipFunction` Protocol.
10
+ - [x] T-norms / s-norms resolved by name; standard complement.
11
+ - [x] `Variable` + operator-based antecedent tree (`&`, `|`, `~`).
12
+ - [x] Mamdani inference + defuzzification (centroid, bisector, MOM/SOM/LOM).
13
+ - [x] Tipper example, test suite, packaging, docs, CI.
14
+
15
+ ## ✅ Phase 2 — TSK + visualization
16
+
17
+ - [x] Takagi-Sugeno inference (zero/first-order + callable consequents).
18
+ - [x] `viz`: membership plots, 2-input control surface.
19
+ - [ ] Example notebooks (tipper, TSK, comparison).
20
+
21
+ ## ✅ Phase 3 — Type-2 / interval type-2
22
+
23
+ - [x] IT2 membership functions (footprint of uncertainty): explicit LMF/UMF,
24
+ height scaling, uncertain Gaussian mean, uncertain Gaussian spread.
25
+ - [x] Interval antecedent evaluation (type-1 and IT2 terms mix freely).
26
+ - [x] IT2 inference: `IT2Mamdani` (center-of-sets) and `IT2TSK`.
27
+ - [x] Karnik-Mendel type reduction (`km_endpoint`, `karnik_mendel`,
28
+ `centroid_it2`) + FOU visualization.
29
+
30
+ ## ✅ Phase 4 — Fuzzy clustering
31
+
32
+ - [x] Fuzzy c-means (FCM).
33
+ - [x] Gustafson-Kessel.
34
+ - [x] Possibilistic c-means.
35
+ - [x] Cluster-quality metrics (partition coefficient, partition entropy,
36
+ Xie-Beni) + 2-D cluster visualization and a synthetic-blob generator.
37
+
38
+ ## ✅ Phase 5 — ANFIS + F-transform
39
+
40
+ - [x] ANFIS: trainable first-order TSK with Jang's hybrid learning (least
41
+ squares for consequents + gradient descent for premises).
42
+ - [x] F-transform: direct and inverse over a triangular fuzzy partition
43
+ (partition of unity), with smoothing/denoising.
44
+
45
+ ## ⏳ Phase 6 — Release
46
+
47
+ - [x] Example notebooks (`notebooks/`) and a comparison page vs scikit-fuzzy.
48
+ - [x] JOSS `paper.md`; Zenodo metadata (`.zenodo.json`) and a citing/releasing page.
49
+ - [x] GitHub Pages live (`https://fuzzytool.github.io`).
50
+ - [ ] Register the PyPI trusted publisher, then tag `v0.1.0` to publish (the
51
+ `release-pypi.yml` workflow is ready).
52
+ - [ ] Enable the Zenodo GitHub integration and cut a release to mint a DOI.