CharlesCNorton commited on
Commit
8676f26
·
0 Parent(s):

4-bit Gray to binary converter, magnitude 33

Browse files
Files changed (5) hide show
  1. README.md +75 -0
  2. config.json +9 -0
  3. create_safetensors.py +98 -0
  4. model.py +47 -0
  5. model.safetensors +0 -0
README.md ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ tags:
4
+ - pytorch
5
+ - safetensors
6
+ - threshold-logic
7
+ - neuromorphic
8
+ ---
9
+
10
+ # threshold-gray2binary
11
+
12
+ 4-bit Gray code to binary converter.
13
+
14
+ ## Function
15
+
16
+ gray2binary(G3, G2, G1, G0) -> (B3, B2, B1, B0)
17
+
18
+ Conversion formulas:
19
+ - B3 = G3
20
+ - B2 = G3 XOR G2
21
+ - B1 = G3 XOR G2 XOR G1
22
+ - B0 = G3 XOR G2 XOR G1 XOR G0
23
+
24
+ ## Example Conversions
25
+
26
+ | Gray | Binary |
27
+ |------|--------|
28
+ | 0000 | 0000 (0) |
29
+ | 0001 | 0001 (1) |
30
+ | 0011 | 0010 (2) |
31
+ | 0010 | 0011 (3) |
32
+ | 0110 | 0100 (4) |
33
+ | 0111 | 0101 (5) |
34
+ | 0101 | 0110 (6) |
35
+ | 0100 | 0111 (7) |
36
+
37
+ ## Architecture
38
+
39
+ Cascade XOR structure with shared intermediate results:
40
+
41
+ ```
42
+ G3 ──────────────────────────────────────────► B3
43
+ G3,G2 ─► [XOR] ─► X1 ────────────────────────► B2
44
+ X1,G1 ─► [XOR] ─► X2 ──────────► B1
45
+ X2,G0 ─► [XOR] ──► B0
46
+ ```
47
+
48
+ Each XOR uses 3 neurons (OR, NAND, AND) with mag-7 weights.
49
+
50
+ ## Parameters
51
+
52
+ | | |
53
+ |---|---|
54
+ | Inputs | 4 |
55
+ | Outputs | 4 |
56
+ | Neurons | 10 |
57
+ | Layers | 6 |
58
+ | Parameters | 46 |
59
+ | Magnitude | 33 |
60
+
61
+ ## Usage
62
+
63
+ ```python
64
+ from safetensors.torch import load_file
65
+ import torch
66
+
67
+ w = load_file('model.safetensors')
68
+
69
+ # Convert gray code 0110 (which is binary 4)
70
+ # Full implementation in model.py
71
+ ```
72
+
73
+ ## License
74
+
75
+ MIT
config.json ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "threshold-gray2binary",
3
+ "description": "4-bit Gray code to binary converter",
4
+ "inputs": 4,
5
+ "outputs": 4,
6
+ "neurons": 10,
7
+ "layers": 6,
8
+ "parameters": 46
9
+ }
create_safetensors.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from safetensors.torch import save_file
3
+
4
+ # Gray to Binary: B[i] = XOR(G[n-1], G[n-2], ..., G[i])
5
+ # B3 = G3
6
+ # B2 = G3 XOR G2
7
+ # B1 = G3 XOR G2 XOR G1
8
+ # B0 = G3 XOR G2 XOR G1 XOR G0
9
+ #
10
+ # Using cascade XOR: XOR(a,b) = AND(OR(a,b), NAND(a,b))
11
+ # With sharing: X1 = XOR(G3,G2), X2 = XOR(X1,G1), X3 = XOR(X2,G0)
12
+ # B3=G3, B2=X1, B1=X2, B0=X3
13
+
14
+ weights = {}
15
+
16
+ # Inputs: G3, G2, G1, G0
17
+
18
+ # === B3 = G3 (identity) ===
19
+ weights['b3.weight'] = torch.tensor([[2.0, 0.0, 0.0, 0.0]], dtype=torch.float32)
20
+ weights['b3.bias'] = torch.tensor([-1.0], dtype=torch.float32)
21
+
22
+ # === X1 = XOR(G3, G2) → B2 ===
23
+ # Layer 1: OR and NAND from inputs
24
+ weights['x1_or.weight'] = torch.tensor([[1.0, 1.0, 0.0, 0.0]], dtype=torch.float32)
25
+ weights['x1_or.bias'] = torch.tensor([-1.0], dtype=torch.float32)
26
+ weights['x1_nand.weight'] = torch.tensor([[-1.0, -1.0, 0.0, 0.0]], dtype=torch.float32)
27
+ weights['x1_nand.bias'] = torch.tensor([1.0], dtype=torch.float32)
28
+ # Layer 2: AND(or, nand) → X1 = B2
29
+ weights['b2.weight'] = torch.tensor([[1.0, 1.0]], dtype=torch.float32)
30
+ weights['b2.bias'] = torch.tensor([-2.0], dtype=torch.float32)
31
+
32
+ # === X2 = XOR(X1, G1) → B1 ===
33
+ # Need to feed X1 (from layer 2) and G1 (from input)
34
+ # Layer 3: OR(X1, G1), NAND(X1, G1)
35
+ # X1 is neuron output, G1 is input[2]
36
+ weights['x2_or.weight'] = torch.tensor([[1.0, 1.0]], dtype=torch.float32) # [X1, G1]
37
+ weights['x2_or.bias'] = torch.tensor([-1.0], dtype=torch.float32)
38
+ weights['x2_nand.weight'] = torch.tensor([[-1.0, -1.0]], dtype=torch.float32)
39
+ weights['x2_nand.bias'] = torch.tensor([1.0], dtype=torch.float32)
40
+ # Layer 4: AND → X2 = B1
41
+ weights['b1.weight'] = torch.tensor([[1.0, 1.0]], dtype=torch.float32)
42
+ weights['b1.bias'] = torch.tensor([-2.0], dtype=torch.float32)
43
+
44
+ # === X3 = XOR(X2, G0) → B0 ===
45
+ # Layer 5: OR(X2, G0), NAND(X2, G0)
46
+ weights['x3_or.weight'] = torch.tensor([[1.0, 1.0]], dtype=torch.float32)
47
+ weights['x3_or.bias'] = torch.tensor([-1.0], dtype=torch.float32)
48
+ weights['x3_nand.weight'] = torch.tensor([[-1.0, -1.0]], dtype=torch.float32)
49
+ weights['x3_nand.bias'] = torch.tensor([1.0], dtype=torch.float32)
50
+ # Layer 6: AND → X3 = B0
51
+ weights['b0.weight'] = torch.tensor([[1.0, 1.0]], dtype=torch.float32)
52
+ weights['b0.bias'] = torch.tensor([-2.0], dtype=torch.float32)
53
+
54
+ save_file(weights, 'model.safetensors')
55
+
56
+ def gray2binary(g3, g2, g1, g0):
57
+ # B3 = G3
58
+ b3 = int(g3 * 2 - 1 >= 0)
59
+
60
+ # X1 = XOR(G3, G2)
61
+ x1_or = int(g3 + g2 - 1 >= 0)
62
+ x1_nand = int(-g3 - g2 + 1 >= 0)
63
+ x1 = int(x1_or + x1_nand - 2 >= 0)
64
+ b2 = x1
65
+
66
+ # X2 = XOR(X1, G1)
67
+ x2_or = int(x1 + g1 - 1 >= 0)
68
+ x2_nand = int(-x1 - g1 + 1 >= 0)
69
+ x2 = int(x2_or + x2_nand - 2 >= 0)
70
+ b1 = x2
71
+
72
+ # X3 = XOR(X2, G0)
73
+ x3_or = int(x2 + g0 - 1 >= 0)
74
+ x3_nand = int(-x2 - g0 + 1 >= 0)
75
+ x3 = int(x3_or + x3_nand - 2 >= 0)
76
+ b0 = x3
77
+
78
+ return b3, b2, b1, b0
79
+
80
+ print("Verifying gray2binary...")
81
+ errors = 0
82
+ for i in range(16):
83
+ # Convert i to gray code
84
+ gray = i ^ (i >> 1)
85
+ g3, g2, g1, g0 = (gray >> 3) & 1, (gray >> 2) & 1, (gray >> 1) & 1, gray & 1
86
+
87
+ b3, b2, b1, b0 = gray2binary(g3, g2, g1, g0)
88
+ result = b3 * 8 + b2 * 4 + b1 * 2 + b0
89
+
90
+ if result != i:
91
+ errors += 1
92
+ print(f"ERROR: gray {g3}{g2}{g1}{g0} (={gray}) -> {b3}{b2}{b1}{b0} (={result}), expected {i}")
93
+
94
+ if errors == 0:
95
+ print("All 16 test cases passed!")
96
+
97
+ mag = sum(t.abs().sum().item() for t in weights.values())
98
+ print(f"Magnitude: {mag:.0f}")
model.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from safetensors.torch import load_file
3
+
4
+ def load_model(path='model.safetensors'):
5
+ return load_file(path)
6
+
7
+ def gray2binary(g3, g2, g1, g0, weights):
8
+ """Convert 4-bit Gray code to binary."""
9
+ inp = torch.tensor([float(g3), float(g2), float(g1), float(g0)])
10
+
11
+ # B3 = G3
12
+ b3 = int((inp @ weights['b3.weight'].T + weights['b3.bias'] >= 0).item())
13
+
14
+ # X1 = XOR(G3, G2)
15
+ x1_or = int((inp @ weights['x1_or.weight'].T + weights['x1_or.bias'] >= 0).item())
16
+ x1_nand = int((inp @ weights['x1_nand.weight'].T + weights['x1_nand.bias'] >= 0).item())
17
+ x1_vec = torch.tensor([float(x1_or), float(x1_nand)])
18
+ b2 = int((x1_vec @ weights['b2.weight'].T + weights['b2.bias'] >= 0).item())
19
+ x1 = b2
20
+
21
+ # X2 = XOR(X1, G1)
22
+ x2_inp = torch.tensor([float(x1), float(g1)])
23
+ x2_or = int((x2_inp @ weights['x2_or.weight'].T + weights['x2_or.bias'] >= 0).item())
24
+ x2_nand = int((x2_inp @ weights['x2_nand.weight'].T + weights['x2_nand.bias'] >= 0).item())
25
+ x2_vec = torch.tensor([float(x2_or), float(x2_nand)])
26
+ b1 = int((x2_vec @ weights['b1.weight'].T + weights['b1.bias'] >= 0).item())
27
+ x2 = b1
28
+
29
+ # X3 = XOR(X2, G0)
30
+ x3_inp = torch.tensor([float(x2), float(g0)])
31
+ x3_or = int((x3_inp @ weights['x3_or.weight'].T + weights['x3_or.bias'] >= 0).item())
32
+ x3_nand = int((x3_inp @ weights['x3_nand.weight'].T + weights['x3_nand.bias'] >= 0).item())
33
+ x3_vec = torch.tensor([float(x3_or), float(x3_nand)])
34
+ b0 = int((x3_vec @ weights['b0.weight'].T + weights['b0.bias'] >= 0).item())
35
+
36
+ return b3, b2, b1, b0
37
+
38
+ if __name__ == '__main__':
39
+ w = load_model()
40
+ print('Gray to Binary conversion:')
41
+ print('Binary -> Gray -> Binary')
42
+ for i in range(16):
43
+ gray = i ^ (i >> 1)
44
+ g3, g2, g1, g0 = (gray >> 3) & 1, (gray >> 2) & 1, (gray >> 1) & 1, gray & 1
45
+ b3, b2, b1, b0 = gray2binary(g3, g2, g1, g0, w)
46
+ result = b3 * 8 + b2 * 4 + b1 * 2 + b0
47
+ print(f' {i:2d} -> {g3}{g2}{g1}{g0} -> {b3}{b2}{b1}{b0} = {result:2d}')
model.safetensors ADDED
Binary file (1.48 kB). View file