phanerozoic commited on
Commit
f85d9ac
Β·
verified Β·
1 Parent(s): b522ba1

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. README.md +89 -89
  2. config.json +9 -9
  3. create_safetensors.py +105 -105
  4. model.py +43 -43
README.md CHANGED
@@ -1,89 +1,89 @@
1
- ---
2
- license: mit
3
- tags:
4
- - pytorch
5
- - safetensors
6
- - threshold-logic
7
- - neuromorphic
8
- ---
9
-
10
- # threshold-7segment
11
-
12
- BCD to 7-segment display decoder.
13
-
14
- ## Function
15
-
16
- segment_decode(B3, B2, B1, B0) -> {a, b, c, d, e, f, g}
17
-
18
- Converts 4-bit BCD input (0-9) to 7 segment control signals.
19
-
20
- ## Segment Layout
21
-
22
- ```
23
- aaa
24
- f b
25
- ggg
26
- e c
27
- ddd
28
- ```
29
-
30
- ## Digit Patterns
31
-
32
- | Digit | a | b | c | d | e | f | g | Display |
33
- |-------|---|---|---|---|---|---|---|---------|
34
- | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | `0` |
35
- | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | `1` |
36
- | 2 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | `2` |
37
- | 3 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | `3` |
38
- | 4 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | `4` |
39
- | 5 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | `5` |
40
- | 6 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | `6` |
41
- | 7 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | `7` |
42
- | 8 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | `8` |
43
- | 9 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | `9` |
44
-
45
- ## Architecture
46
-
47
- Two-layer design:
48
-
49
- ```
50
- B3,B2,B1,B0 ─► [d0] ─┐
51
- [d1] ──
52
- [d2] ── [OR] ─► a
53
- [d3] ─┼─────► [OR] ─► b
54
- [d4] ── [OR] ─► c
55
- [d5] ── [OR] ─► d
56
- [d6] ── [OR] ─► e
57
- [d7] ── [OR] ─► f
58
- [d8] ── [OR] ─► g
59
- [d9] β”€β”˜
60
- ```
61
-
62
- Layer 1: 10 digit detectors (pattern matchers)
63
- Layer 2: 7 OR gates combining relevant digits for each segment
64
-
65
- ## Parameters
66
-
67
- | | |
68
- |---|---|
69
- | Inputs | 4 |
70
- | Outputs | 7 |
71
- | Neurons | 17 |
72
- | Layers | 2 |
73
- | Parameters | 127 |
74
- | Magnitude | 111 |
75
-
76
- ## Usage
77
-
78
- ```python
79
- from safetensors.torch import load_file
80
- # Full implementation in model.py
81
-
82
- # Example: Display digit 5
83
- # result = segment_decode(0, 1, 0, 1, weights)
84
- # -> {'a':1, 'b':0, 'c':1, 'd':1, 'e':0, 'f':1, 'g':1}
85
- ```
86
-
87
- ## License
88
-
89
- MIT
 
1
+ ---
2
+ license: mit
3
+ tags:
4
+ - pytorch
5
+ - safetensors
6
+ - threshold-logic
7
+ - neuromorphic
8
+ ---
9
+
10
+ # threshold-7segment
11
+
12
+ BCD to 7-segment display decoder.
13
+
14
+ ## Function
15
+
16
+ segment_decode(B3, B2, B1, B0) -> {a, b, c, d, e, f, g}
17
+
18
+ Converts 4-bit BCD input (0-9) to 7 segment control signals.
19
+
20
+ ## Segment Layout
21
+
22
+ ```
23
+ aaa
24
+ f b
25
+ ggg
26
+ e c
27
+ ddd
28
+ ```
29
+
30
+ ## Digit Patterns
31
+
32
+ | Digit | a | b | c | d | e | f | g | Display |
33
+ |-------|---|---|---|---|---|---|---|---------|
34
+ | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | `0` |
35
+ | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | `1` |
36
+ | 2 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | `2` |
37
+ | 3 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | `3` |
38
+ | 4 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | `4` |
39
+ | 5 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | `5` |
40
+ | 6 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | `6` |
41
+ | 7 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | `7` |
42
+ | 8 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | `8` |
43
+ | 9 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | `9` |
44
+
45
+ ## Architecture
46
+
47
+ Two-layer design:
48
+
49
+ ```
50
+ B3,B2,B1,B0 ─► [d0] ─┐
51
+ [d1] ──
52
+ [d2] ── [OR] ─► a
53
+ [d3] ─┼─────► [OR] ─► b
54
+ [d4] ── [OR] ─► c
55
+ [d5] ── [OR] ─► d
56
+ [d6] ── [OR] ─► e
57
+ [d7] ── [OR] ─► f
58
+ [d8] ── [OR] ─► g
59
+ [d9] β”€β”˜
60
+ ```
61
+
62
+ Layer 1: 10 digit detectors (pattern matchers)
63
+ Layer 2: 7 OR gates combining relevant digits for each segment
64
+
65
+ ## Parameters
66
+
67
+ | | |
68
+ |---|---|
69
+ | Inputs | 4 |
70
+ | Outputs | 7 |
71
+ | Neurons | 17 |
72
+ | Layers | 2 |
73
+ | Parameters | 127 |
74
+ | Magnitude | 111 |
75
+
76
+ ## Usage
77
+
78
+ ```python
79
+ from safetensors.torch import load_file
80
+ # Full implementation in model.py
81
+
82
+ # Example: Display digit 5
83
+ # result = segment_decode(0, 1, 0, 1, weights)
84
+ # -> {'a':1, 'b':0, 'c':1, 'd':1, 'e':0, 'f':1, 'g':1}
85
+ ```
86
+
87
+ ## License
88
+
89
+ MIT
config.json CHANGED
@@ -1,9 +1,9 @@
1
- {
2
- "name": "threshold-7segment",
3
- "description": "BCD to 7-segment display decoder",
4
- "inputs": 4,
5
- "outputs": 7,
6
- "neurons": 17,
7
- "layers": 2,
8
- "parameters": 127
9
- }
 
1
+ {
2
+ "name": "threshold-7segment",
3
+ "description": "BCD to 7-segment display decoder",
4
+ "inputs": 4,
5
+ "outputs": 7,
6
+ "neurons": 17,
7
+ "layers": 2,
8
+ "parameters": 127
9
+ }
create_safetensors.py CHANGED
@@ -1,105 +1,105 @@
1
- import torch
2
- from safetensors.torch import save_file
3
-
4
- # BCD to 7-segment decoder
5
- # Inputs: B3, B2, B1, B0 (4-bit BCD, 0-9)
6
- # Outputs: a, b, c, d, e, f, g (7 segments)
7
- #
8
- # Segment layout:
9
- # aaa
10
- # f b
11
- # ggg
12
- # e c
13
- # ddd
14
- #
15
- # Layer 1: 10 digit detectors (d0-d9)
16
- # Layer 2: 7 segment OR gates
17
-
18
- weights = {}
19
-
20
- # Segment patterns: which digits activate each segment
21
- # 0=OFF, 1=ON
22
- segments = {
23
- 'a': [1, 0, 1, 1, 0, 1, 1, 1, 1, 1], # 0,2,3,5,6,7,8,9
24
- 'b': [1, 1, 1, 1, 1, 0, 0, 1, 1, 1], # 0,1,2,3,4,7,8,9
25
- 'c': [1, 1, 0, 1, 1, 1, 1, 1, 1, 1], # 0,1,3,4,5,6,7,8,9
26
- 'd': [1, 0, 1, 1, 0, 1, 1, 0, 1, 1], # 0,2,3,5,6,8,9
27
- 'e': [1, 0, 1, 0, 0, 0, 1, 0, 1, 0], # 0,2,6,8
28
- 'f': [1, 0, 0, 0, 1, 1, 1, 0, 1, 1], # 0,4,5,6,8,9
29
- 'g': [0, 0, 1, 1, 1, 1, 1, 0, 1, 1], # 2,3,4,5,6,8,9
30
- }
31
-
32
- # Layer 1: Digit detectors
33
- # For digit d, fire when input matches d
34
- for d in range(10):
35
- b3, b2, b1, b0 = (d >> 3) & 1, (d >> 2) & 1, (d >> 1) & 1, d & 1
36
- w = [
37
- 1.0 if b3 else -1.0,
38
- 1.0 if b2 else -1.0,
39
- 1.0 if b1 else -1.0,
40
- 1.0 if b0 else -1.0,
41
- ]
42
- bias = -bin(d).count('1') # Need all 1-bits to match
43
- weights[f'd{d}.weight'] = torch.tensor([w], dtype=torch.float32)
44
- weights[f'd{d}.bias'] = torch.tensor([float(bias)], dtype=torch.float32)
45
-
46
- # Layer 2: Segment OR gates
47
- for seg_name, pattern in segments.items():
48
- # OR gate: weight 1 for each digit that activates this segment
49
- w = [float(pattern[d]) for d in range(10)]
50
- # OR fires if any input is 1: bias = -1
51
- weights[f'{seg_name}.weight'] = torch.tensor([w], dtype=torch.float32)
52
- weights[f'{seg_name}.bias'] = torch.tensor([-1.0], dtype=torch.float32)
53
-
54
- save_file(weights, 'model.safetensors')
55
-
56
- def segment_decode(b3, b2, b1, b0):
57
- inp = torch.tensor([float(b3), float(b2), float(b1), float(b0)])
58
-
59
- # Layer 1: detect which digit
60
- digits = []
61
- for d in range(10):
62
- val = int((inp @ weights[f'd{d}.weight'].T + weights[f'd{d}.bias'] >= 0).item())
63
- digits.append(val)
64
- digit_vec = torch.tensor([float(d) for d in digits])
65
-
66
- # Layer 2: compute segments
67
- result = {}
68
- for seg in ['a', 'b', 'c', 'd', 'e', 'f', 'g']:
69
- val = int((digit_vec @ weights[f'{seg}.weight'].T + weights[f'{seg}.bias'] >= 0).item())
70
- result[seg] = val
71
-
72
- return result
73
-
74
- print("Verifying 7segment decoder...")
75
- errors = 0
76
-
77
- expected_patterns = [
78
- "1111110", # 0
79
- "0110000", # 1
80
- "1101101", # 2
81
- "1111001", # 3
82
- "0110011", # 4
83
- "1011011", # 5
84
- "1011111", # 6
85
- "1110000", # 7
86
- "1111111", # 8
87
- "1111011", # 9
88
- ]
89
-
90
- for digit in range(10):
91
- b3, b2, b1, b0 = (digit >> 3) & 1, (digit >> 2) & 1, (digit >> 1) & 1, digit & 1
92
- result = segment_decode(b3, b2, b1, b0)
93
- pattern = ''.join([str(result[s]) for s in 'abcdefg'])
94
-
95
- if pattern != expected_patterns[digit]:
96
- errors += 1
97
- print(f"ERROR: digit {digit} -> {pattern}, expected {expected_patterns[digit]}")
98
-
99
- if errors == 0:
100
- print("All 10 test cases passed!")
101
- else:
102
- print(f"FAILED: {errors} errors")
103
-
104
- mag = sum(t.abs().sum().item() for t in weights.values())
105
- print(f"Magnitude: {mag:.0f}")
 
1
+ import torch
2
+ from safetensors.torch import save_file
3
+
4
+ # BCD to 7-segment decoder
5
+ # Inputs: B3, B2, B1, B0 (4-bit BCD, 0-9)
6
+ # Outputs: a, b, c, d, e, f, g (7 segments)
7
+ #
8
+ # Segment layout:
9
+ # aaa
10
+ # f b
11
+ # ggg
12
+ # e c
13
+ # ddd
14
+ #
15
+ # Layer 1: 10 digit detectors (d0-d9)
16
+ # Layer 2: 7 segment OR gates
17
+
18
+ weights = {}
19
+
20
+ # Segment patterns: which digits activate each segment
21
+ # 0=OFF, 1=ON
22
+ segments = {
23
+ 'a': [1, 0, 1, 1, 0, 1, 1, 1, 1, 1], # 0,2,3,5,6,7,8,9
24
+ 'b': [1, 1, 1, 1, 1, 0, 0, 1, 1, 1], # 0,1,2,3,4,7,8,9
25
+ 'c': [1, 1, 0, 1, 1, 1, 1, 1, 1, 1], # 0,1,3,4,5,6,7,8,9
26
+ 'd': [1, 0, 1, 1, 0, 1, 1, 0, 1, 1], # 0,2,3,5,6,8,9
27
+ 'e': [1, 0, 1, 0, 0, 0, 1, 0, 1, 0], # 0,2,6,8
28
+ 'f': [1, 0, 0, 0, 1, 1, 1, 0, 1, 1], # 0,4,5,6,8,9
29
+ 'g': [0, 0, 1, 1, 1, 1, 1, 0, 1, 1], # 2,3,4,5,6,8,9
30
+ }
31
+
32
+ # Layer 1: Digit detectors
33
+ # For digit d, fire when input matches d
34
+ for d in range(10):
35
+ b3, b2, b1, b0 = (d >> 3) & 1, (d >> 2) & 1, (d >> 1) & 1, d & 1
36
+ w = [
37
+ 1.0 if b3 else -1.0,
38
+ 1.0 if b2 else -1.0,
39
+ 1.0 if b1 else -1.0,
40
+ 1.0 if b0 else -1.0,
41
+ ]
42
+ bias = -bin(d).count('1') # Need all 1-bits to match
43
+ weights[f'd{d}.weight'] = torch.tensor([w], dtype=torch.float32)
44
+ weights[f'd{d}.bias'] = torch.tensor([float(bias)], dtype=torch.float32)
45
+
46
+ # Layer 2: Segment OR gates
47
+ for seg_name, pattern in segments.items():
48
+ # OR gate: weight 1 for each digit that activates this segment
49
+ w = [float(pattern[d]) for d in range(10)]
50
+ # OR fires if any input is 1: bias = -1
51
+ weights[f'{seg_name}.weight'] = torch.tensor([w], dtype=torch.float32)
52
+ weights[f'{seg_name}.bias'] = torch.tensor([-1.0], dtype=torch.float32)
53
+
54
+ save_file(weights, 'model.safetensors')
55
+
56
+ def segment_decode(b3, b2, b1, b0):
57
+ inp = torch.tensor([float(b3), float(b2), float(b1), float(b0)])
58
+
59
+ # Layer 1: detect which digit
60
+ digits = []
61
+ for d in range(10):
62
+ val = int((inp @ weights[f'd{d}.weight'].T + weights[f'd{d}.bias'] >= 0).item())
63
+ digits.append(val)
64
+ digit_vec = torch.tensor([float(d) for d in digits])
65
+
66
+ # Layer 2: compute segments
67
+ result = {}
68
+ for seg in ['a', 'b', 'c', 'd', 'e', 'f', 'g']:
69
+ val = int((digit_vec @ weights[f'{seg}.weight'].T + weights[f'{seg}.bias'] >= 0).item())
70
+ result[seg] = val
71
+
72
+ return result
73
+
74
+ print("Verifying 7segment decoder...")
75
+ errors = 0
76
+
77
+ expected_patterns = [
78
+ "1111110", # 0
79
+ "0110000", # 1
80
+ "1101101", # 2
81
+ "1111001", # 3
82
+ "0110011", # 4
83
+ "1011011", # 5
84
+ "1011111", # 6
85
+ "1110000", # 7
86
+ "1111111", # 8
87
+ "1111011", # 9
88
+ ]
89
+
90
+ for digit in range(10):
91
+ b3, b2, b1, b0 = (digit >> 3) & 1, (digit >> 2) & 1, (digit >> 1) & 1, digit & 1
92
+ result = segment_decode(b3, b2, b1, b0)
93
+ pattern = ''.join([str(result[s]) for s in 'abcdefg'])
94
+
95
+ if pattern != expected_patterns[digit]:
96
+ errors += 1
97
+ print(f"ERROR: digit {digit} -> {pattern}, expected {expected_patterns[digit]}")
98
+
99
+ if errors == 0:
100
+ print("All 10 test cases passed!")
101
+ else:
102
+ print(f"FAILED: {errors} errors")
103
+
104
+ mag = sum(t.abs().sum().item() for t in weights.values())
105
+ print(f"Magnitude: {mag:.0f}")
model.py CHANGED
@@ -1,43 +1,43 @@
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 segment_decode(b3, b2, b1, b0, weights):
8
- """BCD to 7-segment decoder. Returns dict with segments a-g."""
9
- inp = torch.tensor([float(b3), float(b2), float(b1), float(b0)])
10
-
11
- # Layer 1: detect which digit
12
- digits = []
13
- for d in range(10):
14
- val = int((inp @ weights[f'd{d}.weight'].T + weights[f'd{d}.bias'] >= 0).item())
15
- digits.append(val)
16
- digit_vec = torch.tensor([float(d) for d in digits])
17
-
18
- # Layer 2: compute segments
19
- result = {}
20
- for seg in ['a', 'b', 'c', 'd', 'e', 'f', 'g']:
21
- val = int((digit_vec @ weights[f'{seg}.weight'].T + weights[f'{seg}.bias'] >= 0).item())
22
- result[seg] = val
23
-
24
- return result
25
-
26
- def display_digit(segs):
27
- """ASCII art display of 7-segment pattern."""
28
- a = ' ' + ('_' * 3 if segs['a'] else ' ' * 3) + ' '
29
- b = ('|' if segs['f'] else ' ') + ' ' * 3 + ('|' if segs['b'] else ' ')
30
- g = ' ' + ('_' * 3 if segs['g'] else ' ' * 3) + ' '
31
- c = ('|' if segs['e'] else ' ') + ' ' * 3 + ('|' if segs['c'] else ' ')
32
- d = ' ' + ('_' * 3 if segs['d'] else ' ' * 3) + ' '
33
- return '\n'.join([a, b, g, c, d])
34
-
35
- if __name__ == '__main__':
36
- w = load_model()
37
- print('7-Segment Display Decoder:')
38
- for digit in range(10):
39
- b3, b2, b1, b0 = (digit >> 3) & 1, (digit >> 2) & 1, (digit >> 1) & 1, digit & 1
40
- result = segment_decode(b3, b2, b1, b0, w)
41
- pattern = ''.join([str(result[s]) for s in 'abcdefg'])
42
- print(f'\nDigit {digit} ({b3}{b2}{b1}{b0}) -> {pattern}')
43
- print(display_digit(result))
 
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 segment_decode(b3, b2, b1, b0, weights):
8
+ """BCD to 7-segment decoder. Returns dict with segments a-g."""
9
+ inp = torch.tensor([float(b3), float(b2), float(b1), float(b0)])
10
+
11
+ # Layer 1: detect which digit
12
+ digits = []
13
+ for d in range(10):
14
+ val = int((inp @ weights[f'd{d}.weight'].T + weights[f'd{d}.bias'] >= 0).item())
15
+ digits.append(val)
16
+ digit_vec = torch.tensor([float(d) for d in digits])
17
+
18
+ # Layer 2: compute segments
19
+ result = {}
20
+ for seg in ['a', 'b', 'c', 'd', 'e', 'f', 'g']:
21
+ val = int((digit_vec @ weights[f'{seg}.weight'].T + weights[f'{seg}.bias'] >= 0).item())
22
+ result[seg] = val
23
+
24
+ return result
25
+
26
+ def display_digit(segs):
27
+ """ASCII art display of 7-segment pattern."""
28
+ a = ' ' + ('_' * 3 if segs['a'] else ' ' * 3) + ' '
29
+ b = ('|' if segs['f'] else ' ') + ' ' * 3 + ('|' if segs['b'] else ' ')
30
+ g = ' ' + ('_' * 3 if segs['g'] else ' ' * 3) + ' '
31
+ c = ('|' if segs['e'] else ' ') + ' ' * 3 + ('|' if segs['c'] else ' ')
32
+ d = ' ' + ('_' * 3 if segs['d'] else ' ' * 3) + ' '
33
+ return '\n'.join([a, b, g, c, d])
34
+
35
+ if __name__ == '__main__':
36
+ w = load_model()
37
+ print('7-Segment Display Decoder:')
38
+ for digit in range(10):
39
+ b3, b2, b1, b0 = (digit >> 3) & 1, (digit >> 2) & 1, (digit >> 1) & 1, digit & 1
40
+ result = segment_decode(b3, b2, b1, b0, w)
41
+ pattern = ''.join([str(result[s]) for s in 'abcdefg'])
42
+ print(f'\nDigit {digit} ({b3}{b2}{b1}{b0}) -> {pattern}')
43
+ print(display_digit(result))