CharlesCNorton commited on
Commit
41bc964
·
1 Parent(s): 9c3e925

Add optimality index and adaptive model wrapper

Browse files

- OPTIMALITY_INDEX.md: catalog of all circuits tested with magnitude results
- prune.py: wrapper now tries multiple calling conventions (*args, list, tensor)

Files changed (2) hide show
  1. OPTIMALITY_INDEX.md +69 -0
  2. prune.py +7 -1
OPTIMALITY_INDEX.md ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Optimality Index
2
+
3
+ Results of exhaustive magnitude enumeration on threshold logic circuits.
4
+
5
+ ## Summary
6
+
7
+ All circuits listed below have been verified via exhaustive enumeration. "Optimal" means no valid configuration exists at lower magnitude.
8
+
9
+ ## Single-Layer Gates (Linearly Separable)
10
+
11
+ | Circuit | Inputs | Params | Optimal Mag | Solutions | Configs Tested |
12
+ |---------|--------|--------|-------------|-----------|----------------|
13
+ | threshold-not | 1 | 2 | 1 | 1 | 5 |
14
+ | threshold-nor | 2 | 3 | 2 | 1 | 7 |
15
+ | threshold-implies | 2 | 3 | 2 | 1 | 25 |
16
+ | threshold-or | 2 | 3 | 3 | 1 | 25 |
17
+ | threshold-nand | 2 | 3 | 3 | 1 | 25 |
18
+ | threshold-and | 2 | 3 | 4 | 1 | 129 |
19
+ | threshold-nor3 | 3 | 4 | 3 | 1 | 129 |
20
+ | threshold-or3 | 3 | 4 | 4 | 1 | 321 |
21
+ | threshold-nand3 | 3 | 4 | 5 | 1 | 681 |
22
+ | threshold-and3 | 3 | 4 | 6 | 1 | 1,289 |
23
+ | threshold-demux | 2 | 6 | 7 | 1 | 19,825 |
24
+ | threshold-majority | 8 | 9 | 13 | 1 | 27,298,155 |
25
+
26
+ ## Multi-Layer Gates (Not Linearly Separable)
27
+
28
+ | Circuit | Inputs | Params | Original Mag | Optimal Mag | Solutions | Reduction |
29
+ |---------|--------|--------|--------------|-------------|-----------|-----------|
30
+ | threshold-xor | 2 | 9 | 10 | 7 | 6 | 30% |
31
+ | threshold-xnor | 2 | 9 | 9 | 7 | 2 | 22% |
32
+ | threshold-mux | 3 | 11 | 10 | 7 | 4 | 30% |
33
+
34
+ ## Optimized Variants Created
35
+
36
+ These repos contain the magnitude-optimal weights:
37
+
38
+ - `threshold-xor-mag7` - 6 solutions at magnitude 7
39
+ - `threshold-xnor-mag7` - 2 solutions at magnitude 7
40
+ - `threshold-mux-mag7` - 4 solutions at magnitude 7
41
+
42
+ ## Pending / In Progress
43
+
44
+ | Circuit | Params | Status |
45
+ |---------|--------|--------|
46
+ | threshold-halfadder | 12 | Running (expected optimal: 11) |
47
+ | threshold-mod4 | 9 | Running |
48
+ | threshold-biimplies | 9 | Not yet tested (same as XNOR) |
49
+ | threshold-halfsubtractor | 12 | Not yet tested |
50
+
51
+ ## Methodology
52
+
53
+ Exhaustive search enumerates all integer weight configurations by magnitude level (0, 1, 2, ...) until valid solutions are found. This guarantees the minimum magnitude is found.
54
+
55
+ For circuits with >12 parameters, exhaustive search becomes impractical. Use evolutionary or simulated annealing instead.
56
+
57
+ ## Key Findings
58
+
59
+ 1. **Single-layer threshold gates have unique optimal representations.** All tested single-layer gates have exactly 1 solution at their optimal magnitude.
60
+
61
+ 2. **Multi-layer gates can have solution families.** XOR has 6 solutions at magnitude 7, organized into two structural families.
62
+
63
+ 3. **Non-linearly-separable functions benefit most from optimization.** XOR/XNOR/MUX achieved 22-30% magnitude reduction.
64
+
65
+ 4. **Optimal magnitude = sum of components for independent subnetworks.** Halfadder (XOR + AND) expected optimal is 7 + 4 = 11.
66
+
67
+ ## Last Updated
68
+
69
+ 2026-01-23
prune.py CHANGED
@@ -581,7 +581,13 @@ class AdaptiveCircuit:
581
  def wrapper(inputs, weights):
582
  model = klass(weights)
583
  args = [int(inputs[i]) for i in range(n)]
584
- result = model(*args)
 
 
 
 
 
 
585
  return list(result) if isinstance(result, (list, tuple)) else [result]
586
  return wrapper
587
  return make_wrapper(attr, n_in)
 
581
  def wrapper(inputs, weights):
582
  model = klass(weights)
583
  args = [int(inputs[i]) for i in range(n)]
584
+ try:
585
+ result = model(*args)
586
+ except TypeError:
587
+ try:
588
+ result = model(args)
589
+ except TypeError:
590
+ result = model(torch.tensor(args, dtype=torch.float32))
591
  return list(result) if isinstance(result, (list, tuple)) else [result]
592
  return wrapper
593
  return make_wrapper(attr, n_in)