hypercomplex-engine 0.0.4__tar.gz → 0.4.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 (37) hide show
  1. {hypercomplex_engine-0.0.4/hypercomplex_engine.egg-info → hypercomplex_engine-0.4.0}/PKG-INFO +2 -2
  2. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/README.md +1 -1
  3. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/fast/fast_split.py +2 -2
  4. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/facade.py +8 -8
  5. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0/hypercomplex_engine.egg-info}/PKG-INFO +2 -2
  6. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex_engine.egg-info/SOURCES.txt +2 -1
  7. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/pyproject.toml +1 -1
  8. hypercomplex_engine-0.4.0/tests/test_split_dim.py +33 -0
  9. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/LICENSE +0 -0
  10. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/__init__.py +0 -0
  11. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/__init__.py +0 -0
  12. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/basis_element.py +0 -0
  13. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/basis_notation.py +0 -0
  14. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/fast/__init__.py +0 -0
  15. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/fast/bit_utils.py +0 -0
  16. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/fast/fast_dual.py +0 -0
  17. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/fast/fast_standard.py +0 -0
  18. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/holographic/__init__.py +0 -0
  19. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/holographic/dual.py +0 -0
  20. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/holographic/split.py +0 -0
  21. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/holographic/standard.py +0 -0
  22. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/table_builder/__init__.py +0 -0
  23. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/table_builder/common.py +0 -0
  24. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/table_builder/dual.py +0 -0
  25. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/table_builder/split.py +0 -0
  26. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/table_builder/standard.py +0 -0
  27. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/core/validation.py +0 -0
  28. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/printer/__init__.py +0 -0
  29. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/printer/cd_format.py +0 -0
  30. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex/printer/cd_table_printer.py +0 -0
  31. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex_engine.egg-info/dependency_links.txt +0 -0
  32. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex_engine.egg-info/requires.txt +0 -0
  33. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/hypercomplex_engine.egg-info/top_level.txt +0 -0
  34. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/setup.cfg +0 -0
  35. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/tests/test_fast_mode.py +0 -0
  36. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/tests/test_fixes_0_4.py +0 -0
  37. {hypercomplex_engine-0.0.4 → hypercomplex_engine-0.4.0}/tests/test_mega_mother.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hypercomplex-engine
3
- Version: 0.0.4
3
+ Version: 0.4.0
4
4
  Summary: Fast O(1)/O(n) multiplication engine and table generator for ordinary, split, and dual Cayley-Dickson algebras.
5
5
  Author-email: Maher Ben Abdessalem <ba.maher94@gmail.com>
6
6
  License: MIT License
@@ -490,7 +490,7 @@ print(result)
490
490
  |---|---|
491
491
  | `"integer"` | `+e5` |
492
492
  | `"graded"` | `+o13` |
493
- | `"latex"` | `+e_{13}` |
493
+ | `"latex"` | `+e_{5}` |
494
494
  | `"latex_integer"` | `+e_{5}` |
495
495
  | `"latex_graded"` | `+o_{13}` |
496
496
 
@@ -442,7 +442,7 @@ print(result)
442
442
  |---|---|
443
443
  | `"integer"` | `+e5` |
444
444
  | `"graded"` | `+o13` |
445
- | `"latex"` | `+e_{13}` |
445
+ | `"latex"` | `+e_{5}` |
446
446
  | `"latex_integer"` | `+e_{5}` |
447
447
  | `"latex_graded"` | `+o_{13}` |
448
448
 
@@ -31,8 +31,8 @@ class FastSplit:
31
31
  t2 = (sign2, index2)
32
32
 
33
33
  dim:
34
- Algebra exponent.
35
- If None, it is inferred from the indices.
34
+ Algebra exponent (required; the result depends on it,
35
+ e.g. e2*e2 is +1 at dim=2 but -1 at dim>=3).
36
36
 
37
37
  Returns:
38
38
  (final_sign, index1 XOR index2)
@@ -89,7 +89,6 @@ def _normalize_engine(engine: str) -> str:
89
89
  aliases = {
90
90
  "fast": "fast",
91
91
  "constant": "fast",
92
- "fast": "fast",
93
92
  "bitwise": "fast",
94
93
  "o1":"fast",
95
94
 
@@ -254,12 +253,18 @@ def multiply(
254
253
  "holographic" O(n) descent, useful for verification
255
254
 
256
255
  dim:
257
- Required for dual and dual_split.
258
- Optional for split.
256
+ Required for split, dual and dual_split.
257
+ Not used for standard.
259
258
  """
260
259
  kind = _normalize_kind(kind)
261
260
  engine = _normalize_engine(engine)
262
261
 
262
+ # dim is part of the algebra's identity for split/dual kinds (e.g. e2*e2 is
263
+ # +e0 in split dim=2 but -e0 for every larger split algebra), so it is
264
+ # required, never inferred. Validate before anything else.
265
+ if kind in ("split", "dual", "dual_split") and dim is None:
266
+ raise ValueError(f"dim is required for {kind} multiplication")
267
+
263
268
  # Zero propagation
264
269
  if int(a[0]) == 0 or int(b[0]) == 0:
265
270
  if kind in ("dual", "dual_split"):
@@ -268,9 +273,6 @@ def multiply(
268
273
 
269
274
  # Dual inputs may be local 3-tuples: (sign, local_index, eps)
270
275
  if kind in ("dual", "dual_split"):
271
- if dim is None:
272
- raise ValueError("dim is required for dual multiplication")
273
-
274
276
  a = _as_dual_global(a, dim)
275
277
  b = _as_dual_global(b, dim)
276
278
 
@@ -298,8 +300,6 @@ def multiply(
298
300
  return _standard_holo.multiply(a, b)
299
301
 
300
302
  if kind == "split":
301
- if dim is None:
302
- dim = max(int(a[1]), int(b[1])).bit_length()
303
303
  return _split_holo.multiply(a, b, dim)
304
304
 
305
305
  if kind == "dual":
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hypercomplex-engine
3
- Version: 0.0.4
3
+ Version: 0.4.0
4
4
  Summary: Fast O(1)/O(n) multiplication engine and table generator for ordinary, split, and dual Cayley-Dickson algebras.
5
5
  Author-email: Maher Ben Abdessalem <ba.maher94@gmail.com>
6
6
  License: MIT License
@@ -490,7 +490,7 @@ print(result)
490
490
  |---|---|
491
491
  | `"integer"` | `+e5` |
492
492
  | `"graded"` | `+o13` |
493
- | `"latex"` | `+e_{13}` |
493
+ | `"latex"` | `+e_{5}` |
494
494
  | `"latex_integer"` | `+e_{5}` |
495
495
  | `"latex_graded"` | `+o_{13}` |
496
496
 
@@ -31,4 +31,5 @@ hypercomplex_engine.egg-info/requires.txt
31
31
  hypercomplex_engine.egg-info/top_level.txt
32
32
  tests/test_fast_mode.py
33
33
  tests/test_fixes_0_4.py
34
- tests/test_mega_mother.py
34
+ tests/test_mega_mother.py
35
+ tests/test_split_dim.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hypercomplex-engine"
7
- version = "0.0.4"
7
+ version = "0.4.0"
8
8
  authors = [
9
9
  { name="Maher Ben Abdessalem", email="ba.maher94@gmail.com" },
10
10
  ]
@@ -0,0 +1,33 @@
1
+ """split/dual require an explicit dim; split rejects epsilon 3-tuples."""
2
+ import pytest
3
+ from hypercomplex import multiply
4
+
5
+
6
+ @pytest.mark.parametrize("engine", ["fast", "holographic"])
7
+ @pytest.mark.parametrize("kind", ["split", "dual", "dual_split"])
8
+ def test_dim_is_required_and_message_names_the_kind(kind, engine):
9
+ with pytest.raises(ValueError, match=f"dim is required for {kind}"):
10
+ multiply(kind, (1, 1), (1, 1), engine=engine)
11
+
12
+
13
+ @pytest.mark.parametrize("kind", ["split", "dual", "dual_split"])
14
+ def test_missing_dim_is_reported_even_for_zero_elements(kind):
15
+ with pytest.raises(ValueError, match="dim is required"):
16
+ multiply(kind, (0, 1), (1, 2))
17
+
18
+
19
+ @pytest.mark.parametrize("engine", ["fast", "holographic"])
20
+ def test_split_result_depends_on_dim(engine):
21
+ assert multiply("split", (1, 2), (1, 2), dim=2, engine=engine) == (1, 0)
22
+ for dim in (3, 4, 8):
23
+ assert multiply("split", (1, 2), (1, 2), dim=dim, engine=engine) == (-1, 0)
24
+
25
+
26
+ @pytest.mark.parametrize("eps", [0, 1])
27
+ def test_split_rejects_epsilon_three_tuples_with_clear_message(eps):
28
+ with pytest.raises(ValueError, match="3-tuple"):
29
+ multiply("split", (1, 1, eps), (1, 2), dim=2)
30
+
31
+
32
+ def test_standard_needs_no_dim():
33
+ assert multiply("standard", (1, 1), (1, 2)) == (1, 3)