cos-comparison 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.
- cos_comparison-0.1.0/LICENSE.txt +21 -0
- cos_comparison-0.1.0/PKG-INFO +46 -0
- cos_comparison-0.1.0/README.md +26 -0
- cos_comparison-0.1.0/cos_comparison/__init__.py +146 -0
- cos_comparison-0.1.0/cos_comparison/cos_comparison.py +1892 -0
- cos_comparison-0.1.0/cos_comparison/cos_comparison_c/__init__.py +1 -0
- cos_comparison-0.1.0/cos_comparison/cos_comparison_c/cos_comparison_c.py +558 -0
- cos_comparison-0.1.0/cos_comparison/cos_comparison_numpy.py +498 -0
- cos_comparison-0.1.0/cos_comparison/cos_comparison_old.py +89 -0
- cos_comparison-0.1.0/cos_comparison.egg-info/PKG-INFO +46 -0
- cos_comparison-0.1.0/cos_comparison.egg-info/SOURCES.txt +15 -0
- cos_comparison-0.1.0/cos_comparison.egg-info/dependency_links.txt +1 -0
- cos_comparison-0.1.0/cos_comparison.egg-info/requires.txt +3 -0
- cos_comparison-0.1.0/cos_comparison.egg-info/top_level.txt +1 -0
- cos_comparison-0.1.0/pyproject.toml +30 -0
- cos_comparison-0.1.0/setup.cfg +4 -0
- cos_comparison-0.1.0/tests/test_core.py +38 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Li Jinxin
|
|
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,46 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cos-comparison
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local similarity comparison for feature extraction – biologically inspired, zero‑training edge / pattern detection.
|
|
5
|
+
Author: Li Jinxin
|
|
6
|
+
License: MIT
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Intended Audience :: Science/Research
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
|
+
Requires-Python: >=3.8
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE.txt
|
|
17
|
+
Provides-Extra: numpy
|
|
18
|
+
Requires-Dist: numpy>=1.20; extra == "numpy"
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# Cos Comparison
|
|
22
|
+
|
|
23
|
+
[](https://www.python.org/downloads/)
|
|
24
|
+
[](https://opensource.org/licenses/MIT)
|
|
25
|
+
|
|
26
|
+
**Local similarity comparison for feature extraction – biologically inspired, zero‑training edge / pattern detection.**
|
|
27
|
+
|
|
28
|
+
## Core Idea
|
|
29
|
+
|
|
30
|
+
Information is produced by **local comparison** in raw data.
|
|
31
|
+
This module implements the **center‑surround antagonism** mechanism from neuroscience, extracting edges, textures, and keypoints using only sliding window similarity.
|
|
32
|
+
|
|
33
|
+
The main formula (cosine‑modulated similarity):
|
|
34
|
+
|
|
35
|
+
$$ \text{cosmod} = \frac{2\,(A\cdot B)}{\|A\|^2 + \|B\|^2} $$
|
|
36
|
+
|
|
37
|
+
- Spurt for real AGI
|
|
38
|
+
- No training, no labels, no backpropagation
|
|
39
|
+
- Works on 1D, 2D, 3D, 4D data (audio, images, video, volumes)
|
|
40
|
+
- Supports passive (reflex) and active (template matching) modes
|
|
41
|
+
- Pure Python core + optional NumPy / C acceleration
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pip install cos-comparison
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Cos Comparison
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/downloads/)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
**Local similarity comparison for feature extraction – biologically inspired, zero‑training edge / pattern detection.**
|
|
7
|
+
|
|
8
|
+
## Core Idea
|
|
9
|
+
|
|
10
|
+
Information is produced by **local comparison** in raw data.
|
|
11
|
+
This module implements the **center‑surround antagonism** mechanism from neuroscience, extracting edges, textures, and keypoints using only sliding window similarity.
|
|
12
|
+
|
|
13
|
+
The main formula (cosine‑modulated similarity):
|
|
14
|
+
|
|
15
|
+
$$ \text{cosmod} = \frac{2\,(A\cdot B)}{\|A\|^2 + \|B\|^2} $$
|
|
16
|
+
|
|
17
|
+
- Spurt for real AGI
|
|
18
|
+
- No training, no labels, no backpropagation
|
|
19
|
+
- Works on 1D, 2D, 3D, 4D data (audio, images, video, volumes)
|
|
20
|
+
- Supports passive (reflex) and active (template matching) modes
|
|
21
|
+
- Pure Python core + optional NumPy / C acceleration
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pip install cos-comparison
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# cos_comparison package initializer
|
|
2
|
+
#
|
|
3
|
+
# Dynamic fallback through configured backends. Any attribute that is not
|
|
4
|
+
# already defined in this module is lazily resolved at call time by
|
|
5
|
+
# searching the backends listed in config.json in order. Once a backend
|
|
6
|
+
# returns a result (or raises an unexpected error), the process stops.
|
|
7
|
+
|
|
8
|
+
import importlib
|
|
9
|
+
import json
|
|
10
|
+
import os
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
# ----------------------------------------------------------------------
|
|
14
|
+
# File context manager (kept from original codebase)
|
|
15
|
+
# ----------------------------------------------------------------------
|
|
16
|
+
class file_context:
|
|
17
|
+
__slots__ = ("file",)
|
|
18
|
+
def __init__(self, *arg, **kwarg):
|
|
19
|
+
self.file = open(*arg, **kwarg)
|
|
20
|
+
def __enter__(self):
|
|
21
|
+
self.file = self.file.__enter__()
|
|
22
|
+
return self
|
|
23
|
+
def __exit__(self, *arg):
|
|
24
|
+
self.file.__exit__(*arg)
|
|
25
|
+
def __del__(self):
|
|
26
|
+
self.close()
|
|
27
|
+
def __getattr__(self, name):
|
|
28
|
+
return getattr(self.file, name)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# ----------------------------------------------------------------------
|
|
32
|
+
# Backend discovery from config.json
|
|
33
|
+
# ----------------------------------------------------------------------
|
|
34
|
+
def _load_backend_names() -> list:
|
|
35
|
+
"""Return the ordered list of backend module names."""
|
|
36
|
+
conf_path = os.path.join(os.path.dirname(__file__), "config.json")
|
|
37
|
+
if not os.path.exists(conf_path):
|
|
38
|
+
return ["backend_python"] # sensible default
|
|
39
|
+
|
|
40
|
+
with file_context(conf_path, "r", encoding="utf-8") as f:
|
|
41
|
+
try:
|
|
42
|
+
meta, _ = json.load(f) # [backends, plugin_dir]
|
|
43
|
+
except Exception:
|
|
44
|
+
return ["backend_python"]
|
|
45
|
+
|
|
46
|
+
if isinstance(meta, list) and meta:
|
|
47
|
+
return meta
|
|
48
|
+
return ["backend_python"]
|
|
49
|
+
|
|
50
|
+
import os
|
|
51
|
+
|
|
52
|
+
def _get_backend_order():
|
|
53
|
+
try:
|
|
54
|
+
return _load_backend_names()
|
|
55
|
+
except:
|
|
56
|
+
pass
|
|
57
|
+
env_order = os.environ.get("COS_BACKEND", "").strip()
|
|
58
|
+
if env_order:
|
|
59
|
+
return [name.strip() for name in env_order.split(",")]
|
|
60
|
+
|
|
61
|
+
return [
|
|
62
|
+
"cos_comparison_c",
|
|
63
|
+
"cos_comparison_numpy",
|
|
64
|
+
"cos_comparison",
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
_BACKEND_NAMES = _get_backend_order()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# ----------------------------------------------------------------------
|
|
72
|
+
# Module cache (avoid repeated imports)
|
|
73
|
+
# ----------------------------------------------------------------------
|
|
74
|
+
_module_cache: dict = {} # name -> module | None
|
|
75
|
+
|
|
76
|
+
def _import_backend(name: str) -> Any:
|
|
77
|
+
"""Import a backend module and cache it. Returns module or None."""
|
|
78
|
+
if name in _module_cache:
|
|
79
|
+
return _module_cache[name]
|
|
80
|
+
try:
|
|
81
|
+
mod = importlib.import_module(f".{name}", package="cos_comparison")
|
|
82
|
+
_module_cache[name] = mod
|
|
83
|
+
return mod
|
|
84
|
+
except ImportError:
|
|
85
|
+
_module_cache[name] = None
|
|
86
|
+
return None
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# ----------------------------------------------------------------------
|
|
90
|
+
# Callable object that searches backends on every invocation
|
|
91
|
+
# ----------------------------------------------------------------------
|
|
92
|
+
class _FallbackWrapper:
|
|
93
|
+
__slots__ = ("func_name",)
|
|
94
|
+
|
|
95
|
+
def __init__(self, func_name: str):
|
|
96
|
+
self.func_name = func_name
|
|
97
|
+
|
|
98
|
+
def __call__(self, *args, **kwargs):
|
|
99
|
+
last_exception = None
|
|
100
|
+
for bname in _BACKENDS:
|
|
101
|
+
mod = _import_backend(bname)
|
|
102
|
+
if mod is None:
|
|
103
|
+
continue # module not available
|
|
104
|
+
func = getattr(mod, self.func_name, None)
|
|
105
|
+
if func is None:
|
|
106
|
+
continue # function not provided
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
return func(*args, **kwargs)
|
|
110
|
+
except NotImplementedError:
|
|
111
|
+
# Backend explicitly refuses this call -- normal fallback
|
|
112
|
+
continue
|
|
113
|
+
except Exception as exc:
|
|
114
|
+
# Unexpected error – remember it but try next backend
|
|
115
|
+
last_exception = exc
|
|
116
|
+
continue
|
|
117
|
+
|
|
118
|
+
if last_exception is not None:
|
|
119
|
+
raise last_exception
|
|
120
|
+
raise RuntimeError(
|
|
121
|
+
f"No backend among {_BACKENDS} provides a working "
|
|
122
|
+
f"implementation for '{self.func_name}'."
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# ----------------------------------------------------------------------
|
|
127
|
+
# Intercept missing attributes (Python 3.7+)
|
|
128
|
+
# ----------------------------------------------------------------------
|
|
129
|
+
def __getattr__(name: str):
|
|
130
|
+
"""Called only when `name` is not found in the module globals.
|
|
131
|
+
|
|
132
|
+
Returns a callable wrapper that searches backends on each call.
|
|
133
|
+
Once created, the wrapper is cached in the module's dictionary so
|
|
134
|
+
that subsequent lookups are fast.
|
|
135
|
+
"""
|
|
136
|
+
# No exclusion of private names – internal functions may be needed.
|
|
137
|
+
wrapper = _FallbackWrapper(name)
|
|
138
|
+
globals()[name] = wrapper
|
|
139
|
+
return wrapper
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
# ----------------------------------------------------------------------
|
|
143
|
+
# Provide a useful __dir__ for introspection
|
|
144
|
+
# ----------------------------------------------------------------------
|
|
145
|
+
def __dir__() -> list:
|
|
146
|
+
return sorted(set(globals().keys()))
|