Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
bc5ba3e
Merge branch 'release/v0.6.0' into develop
AP6YC Jun 6, 2024
e70bd79
Merge branch 'hotfix/docs-links' into develop
AP6YC Jun 6, 2024
a858036
fix doc builds
NiklasMelton Jun 4, 2026
1272dc9
make docs conf and workflow agree on branches to build on
NiklasMelton Jun 4, 2026
acdfbc5
remove tests for 3.7 and x86. 3.7 is deprecated. Extend tests through…
NiklasMelton Jun 4, 2026
ee6fe57
remove tests for 3.15, not stable yet
NiklasMelton Jun 4, 2026
c45d40b
add conn index
NiklasMelton Jun 4, 2026
48e72c3
artlib only supports python >=3.9, add support for newer pythons
NiklasMelton Jun 4, 2026
e775593
conn references
NiklasMelton Jun 4, 2026
aa5940c
test only python 3.9 and up
NiklasMelton Jun 4, 2026
6bf1d64
Merge pull request #86 from AP6YC/build-bugs
AP6YC Sep 3, 2026
518206e
Merge branch 'develop' into conn-kmeans
AP6YC Sep 3, 2026
28c2e09
Drop python 3.8 in tests because of artlib 0.1.7 dep conflict
AP6YC Sep 3, 2026
c5ece72
Merge pull request #87 from AP6YC/conn-kmeans
AP6YC Sep 3, 2026
bc618ab
add CVI Info
NiklasMelton Jun 4, 2026
ba97c62
Merge pull request #85 from AP6YC/cvi-info
AP6YC Sep 3, 2026
bf7da6a
Bump pypa/gh-action-pypi-publish in /.github/workflows
dependabot[bot] Sep 3, 2026
6fa02a8
Merge pull request #89 from AP6YC/dependabot/github_actions/dot-githu…
AP6YC Sep 3, 2026
bad9718
Update readme to add conn index
NiklasMelton Sep 8, 2026
ea9d5f8
kmeans conn support
NiklasMelton Sep 8, 2026
c71bb91
add merge and remove opps to CVIs
NiklasMelton Sep 9, 2026
4661977
support incremental ops when batch initialized
NiklasMelton Sep 9, 2026
065c3c4
Merge pull request #90 from AP6YC/add-conn-to-readme
AP6YC Sep 9, 2026
a155732
remove redundant _mode property
NiklasMelton Sep 9, 2026
72cedf1
Merge branch 'develop' into kmeans-conn
AP6YC Sep 9, 2026
e2ded43
refactor to reduce redundancy
NiklasMelton Sep 9, 2026
0071061
Merge pull request #91 from AP6YC/kmeans-conn
AP6YC Sep 10, 2026
b3a21e8
Merge branch 'develop' into merge-remove-ops
AP6YC Sep 10, 2026
de15b4b
Added a patch in testing for CONN's unique incremental api
AP6YC Sep 10, 2026
7639959
Merge pull request #92 from AP6YC/merge-remove-ops
AP6YC Sep 10, 2026
cb0cbb8
Bump to v0.7.0
AP6YC Sep 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 20 additions & 27 deletions .github/workflows/Documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,51 +8,44 @@ on:
tags: '*'
pull_request:

# sphinx-build doc _build
permissions:
contents: write
contents: write

jobs:
docs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
with:
lfs: 'true'
lfs: true
fetch-depth: 0
- uses: actions/setup-python@v3

- name: Install dependencies
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip"

- name: Fetch all branches and tags
run: |
# pip install -r docs/requirements.txt
pip install -e .[docs]
git fetch origin '+refs/heads/*:refs/remotes/origin/*' --tags --force

- name: Sphinx Build Develop
- name: Install dependencies
run: |
git checkout develop
git fetch --all
git pull --all
cd ${{ github.workspace }}/docs
# make html
sphinx-multiversion source build/html
python -m pip install --upgrade pip
python -m pip install -e ".[docs]"
python --version
python -m pip show sphinx sphinx-multiversion

- name: Sphinx Build Main
- name: Build docs
run: |
git checkout main
cd ${{ github.workspace }}/docs
cd docs
sphinx-multiversion source build/html

# - name: Make symlinks
# run: |
# ln -sf ${{ github.workspace }}/build/html/main ${{ github.workspace }}/build/html/stable
# ln -sf ${{ github.workspace }}/build/html/develop ${{ github.workspace }}/build/html/dev

- name: Deploy
uses: peaceiris/actions-gh-pages@v3
if: ${{ github.event_name == 'push' && ((github.ref == 'refs/heads/main') || (github.ref == 'refs/heads/develop'))}}
if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') }}
with:
publish_branch: gh-pages
github_token: ${{ secrets.GITHUB_TOKEN }}
# publish_dir: docs/build/
publish_dir: docs/build/html/
# publish_dir: _build/
# force_orphan: true
publish_dir: docs/build/html/
2 changes: 1 addition & 1 deletion .github/workflows/Publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
run: python -m build
- name: Publish package
# uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
uses: pypa/gh-action-pypi-publish@v1.5.1
uses: pypa/gh-action-pypi-publish@v1.13.0
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
3 changes: 1 addition & 2 deletions .github/workflows/Test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@ jobs:
strategy:
matrix:
# Test on current Python LTS versions
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
os:
- ubuntu-latest
# - macOS-latest
# - windows-latest
arch:
- x64
- x86

steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

# IDE ignores
.vscode/
.idea/

# Project ignores
_dev/
Expand Down Expand Up @@ -142,3 +143,4 @@ dmypy.json

# Pyre type checker
.pyre/
.idea/
38 changes: 32 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ A Python package implementing both batch and incremental cluster validity indice
- [Usage](#usage)
- [Quickstart](#quickstart)
- [Detailed Usage](#detailed-usage)
- [Remove and Merge](#remove-and-merge)
- [Implemented CVIs](#implemented-cvis)
- [History](#history)
- [Acknowledgements](#acknowledgements)
Expand Down Expand Up @@ -79,7 +80,7 @@ pip install cvi
You can also specify a version to install in the usual way with

```python
pip install cvi==v0.6.0
pip install cvi==v0.7.0
```

Alternatively, you can manually install a release from the [releases page](https://github.com/AP6YC/cvi/releases) on GitHub.
Expand Down Expand Up @@ -114,6 +115,14 @@ for ix in range(n_samples):
criterion_values = my_cvi.get_cvi(samples[ix, :], labels[ix])
```

Users can also query the `.info` property of the CVI objects to obtain relevant
scaling and naming information.

```
>>> print(my_cvi.info)
CVIInfo(name='Calinski-Harabasz', name_short='CH', index_min=0.0, index_max=inf, optimality='max')
```

### Detailed Usage

The `cvi` package contains a set of implemented CVIs with batch and incremental update methods.
Expand Down Expand Up @@ -169,21 +178,38 @@ for ix in range(n_samples):

> **NOTE**:
>
> Currently only using _either_ batch _or_ incremental methods is supported; switching from batch to incremental updates with the same is not yet implemented.
> After batch initialization, additional samples may be added incrementally by passing a single sample and label to `get_cvi`.

### Remove and Merge

An initialized CVI can remove a previously added sample or merge two existing clusters without retaining and replaying the full dataset:

```python
# Remove a sample from its current cluster.
criterion_value = my_cvi.remove(sample, label)

# Merge every member of source_label into target_label.
criterion_value = my_cvi.merge(target_label, source_label)
```

Both methods update the object in place and return its new criterion value. Removing the final sample of a cluster deletes that cluster, while `merge` retains `target_label` and deletes `source_label`. The caller is responsible for ensuring that a removed sample belongs to the supplied label.

Add, remove, and merge are supported after either incremental or batch initialization.

## Implemented CVIs

The following CVIs have been implemented as of the latest version of `cvi`:

- **CH**: Calinski-Harabasz
- **cSIL**: Centroid-based Silhouette
- **DB**: Davies-Bouldin
- **CH**: Calinski-Harabasz.
- **CONN**: Prototype-based intra- and inter-cluster connectivity index.
- **cSIL**: Centroid-based Silhouette index.
- **DB**: Davies-Bouldin index.
- **GD43**: Generalized Dunn's Index 43.
- **GD53**: Generalized Dunn's Index 53.
- **PS**: Partition Separation.
- **rCIP**: (Renyi's) representative Cross Information Potential.
- **WB**: WB-index.
- **XB**: Xie-Beni.
- **XB**: Xie-Beni index.

## History

Expand Down
56 changes: 16 additions & 40 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
project = 'cvi'
copyright = '2024, Sasha Petrenko'
author = 'Sasha Petrenko'
release = '0.6.0'
version = '0.6.0'
release = '0.7.0'
version = '0.7.0'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand All @@ -31,8 +31,6 @@
'sphinx.ext.intersphinx',
'sphinx.ext.napoleon',
"sphinx_multiversion",
# 'sphinx.ext.autosectionlabel',
# 'sphinx_autopackagesummary',
]

autosummary_generate_overwrite = True
Expand All @@ -54,8 +52,6 @@
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

# html_theme = 'alabaster'
# html_theme = 'sphinx_rtd_theme'
html_theme = 'furo'

html_static_path = ['_static']
Expand All @@ -72,47 +68,27 @@
],
}

# html_css_files = [
# 'css/rtd.css',
# ]

# -- Options for EPUB output
epub_show_urls = 'footnote'


# Whitelist pattern for tags (set to None to ignore all tags)
# smv_tag_whitelist = r'^.*$'
# smv_tag_whitelist = r'v*'
# Ignore tags for now
smv_tag_whitelist = None
# smv_tag_pattern = r'^v\d*\.\d*\.\d*$'
# smv_tag_pattern = r'^.*(?!alpha)$'

# Whitelist pattern for branches (set to None to ignore all branches)
# smv_branch_whitelist = r'^.*$
# smv_branch_whitelist = None
# smv_branch_whitelist = r'^(main|develop)$'
# smv_branch_whitelist = r'^self-host-docs$'
smv_branch_whitelist = r'^(main|develop)$'

# Whitelist pattern for remotes (set to None to use local branches only)
smv_remote_whitelist = None

# Pattern for released versions
# smv_released_pattern = r'^v.*$'
# smv_released_pattern = r'v\d*\.\d*\.\d*'

# Build docs for main and develop, whether sphinx-multiversion sees them
# as local branches or as remote branches.
smv_branch_whitelist = r'^(origin/)?(main|develop)$'

# Allow origin/main and origin/develop.
smv_remote_whitelist = r'^origin$'

# No tags are being built, so this does not matter much right now.
smv_released_pattern = r'^tags/.*$'

# Format for versioned output directories inside the build directory
# Use simple output directories: main, develop.
smv_outputdir_format = '{ref.name}'

# Determines whether remote or local git branches/tags are preferred if their output dirs conflict
smv_prefer_remote_refs = False

# # Skip param objects because of their weird rendering in docs
# def maybe_skip_member(app, what, name, obj, skip, options):
# # print app, what, name, obj, skip, options
# # if name == ""
# return True
# Prefer remote refs in CI, since GitHub Actions reliably has origin/main
# and origin/develop after fetching.
smv_prefer_remote_refs = True

# def setup(app):
# app.connect('autodoc-skip-member', maybe_skip_member)
19 changes: 18 additions & 1 deletion docs/source/guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,24 @@ The incremental methods are used automatically based upon the dimensions of the
criterion_values[ix] = my_cvi.get_cvi(sample, label)

.. note::
Currently only using *either* batch *or* incremental methods is supported; switching from batch to incremental updates with the same is not yet implemented.
After batch initialization, additional samples may be added incrementally by passing a single sample and label to ``get_cvi``.

Remove and Merge
----------------

An initialized CVI can remove a previously added sample or merge two existing clusters without retaining and replaying the full dataset:

.. code-block:: python

# Remove a sample from its current cluster.
criterion_value = my_cvi.remove(sample, label)

# Merge every member of source_label into target_label.
criterion_value = my_cvi.merge(target_label, source_label)

Both methods update the object in place and return its new criterion value. Removing the final sample of a cluster deletes that cluster, while ``merge`` retains ``target_label`` and deletes ``source_label``. The caller is responsible for ensuring that a removed sample belongs to the supplied label.

Add, remove, and merge are supported after either incremental or batch initialization.

Implemented CVIs
----------------
Expand Down
14 changes: 7 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ authors = [
#
# For a discussion on single-sourcing the version, see
# https://packaging.python.org/guides/single-sourcing-package-version/
version = "0.6.0"
version = "0.7.0"

# This is a one-line description or tagline of what your project does. This
# corresponds to the "Summary" metadata field:
Expand All @@ -34,7 +34,7 @@ readme = "README.md" # Optional
# 'Programming Language' classifiers above, 'pip install' will check this
# and refuse to install the project if the version does not match. See
# https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires
requires-python = ">=3.6"
requires-python = ">=3.9"

# This is either text indicating the license for the distribution, or a file
# that contains the license
Expand Down Expand Up @@ -86,13 +86,12 @@ classifiers = [ # Optional
# that you indicate you support Python 3. These classifiers are *not*
# checked by "pip install". See instead "python_requires" below.
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: 3 :: Only",
]

Expand All @@ -104,6 +103,8 @@ classifiers = [ # Optional
# https://packaging.python.org/discussions/install-requires-vs-requirements/
dependencies = [ # Optional
"numpy",
"artlib>=0.1.7",
"scikit-learn",
]

# List additional groups of dependencies here (e.g. development
Expand All @@ -127,11 +128,10 @@ test = [
"pytest-cov",
"coverage",
"pandas",
"scikit-learn",
"flake8",
]
docs = [
"sphinx",
"sphinx<9",
"furo",
"sphinx-multiversion",
]
Expand Down
5 changes: 4 additions & 1 deletion src/cvi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
"""

# Set the version variable of the package
__version__ = "0.6.0"
__version__ = "0.7.0"

# Import CVI modules to the top level
from .modules import (
CVI,
CH,
CONN,
cSIL,
DB,
GD43,
Expand All @@ -26,6 +27,7 @@
__all__ = [
"CVI",
"CH",
"CONN",
"cSIL",
"DB",
"GD43",
Expand All @@ -40,6 +42,7 @@
# Convenience variable containing all implemented modules
MODULES = [
CH,
CONN,
cSIL,
DB,
GD43,
Expand Down
Loading
Loading