everydaytok commited on
Commit
678a72d
·
verified ·
1 Parent(s): e5df198

Update data_gen.py

Browse files
Files changed (1) hide show
  1. data_gen.py +37 -63
data_gen.py CHANGED
@@ -1,80 +1,54 @@
1
  """
2
  data_gen.py
3
-
4
- Scalar mesh test data. Each sample is (a, b, c) — all single floats.
5
-
6
- A ∈ [0.1, 0.9] — constraint scalar (top input)
7
- B ∈ [0.1, 0.9] — objective scalar (bottom input)
8
- C — feasibility center (what the mesh must learn to produce)
9
-
10
- All C values kept in [0.1, 0.9] so the scalar Hooke mesh can represent them
11
- without needing to amplify beyond the input range.
12
-
13
- SEEN during training : heavy_a | avg | diff
14
- OOD (test only) : heavy_b
15
-
16
- If the mesh generalises:
17
- It learned "weighted combination of A and B" as a concept
18
- → it applies unseen weighting (B-heavy) without training on it.
19
  """
 
 
20
 
21
- import numpy as np, json, pathlib, random, argparse
22
-
23
- SAMPLES_PER_TYPE = 2500 # × 4 types = 10 000 total
24
 
25
- DATASETS = {
26
- # name : (lambda, seen?)
27
- 'heavy_a': (lambda a, b: 0.8*a + 0.2*b, True),
28
- 'avg': (lambda a, b: 0.5*a + 0.5*b, True),
29
- 'diff': (lambda a, b: 0.5 + 0.4*(a - b), True), # signed diff, offset to [0.1,0.9]
30
- 'heavy_b': (lambda a, b: 0.2*a + 0.8*b, False), # OOD
31
- }
32
-
33
- def generate(n_per=SAMPLES_PER_TYPE, seed=42):
34
  rng = np.random.default_rng(seed)
35
  data = []
36
- for dtype, (fn, _) in DATASETS.items():
37
- for _ in range(n_per):
38
- a = float(rng.uniform(0.1, 0.9))
39
- b = float(rng.uniform(0.1, 0.9))
40
- c = fn(a, b)
41
- data.append({'a': round(a,4), 'b': round(b,4),
42
- 'c': round(c,4), 'type': dtype})
 
 
 
 
 
 
 
 
 
 
 
 
43
  random.shuffle(data)
44
  return data
45
 
 
 
 
46
  if __name__ == '__main__':
47
  parser = argparse.ArgumentParser()
48
- parser.add_argument('--n', type=int, default=SAMPLES_PER_TYPE)
49
- parser.add_argument('--out', type=str, default='data')
50
  args = parser.parse_args()
51
 
52
- data = generate(args.n)
53
-
54
- # Split: train = SEEN only (90%), test = 10% SEEN + ALL OOD
55
- seen = [d for d in data if DATASETS[d['type']][1]]
56
- ood = [d for d in data if not DATASETS[d['type']][1]]
57
-
58
- split = int(len(seen) * 0.9)
59
- train = seen[:split]
60
- test = seen[split:] + ood
61
-
62
- random.shuffle(test)
63
-
64
- out = pathlib.Path(args.out)
65
  out.mkdir(exist_ok=True)
66
  with open(out/'train.json','w') as f: json.dump(train, f)
67
  with open(out/'test.json', 'w') as f: json.dump(test, f)
68
-
69
- from collections import Counter
70
- tr = Counter(d['type'] for d in train)
71
- te = Counter(d['type'] for d in test)
72
-
73
- print(f"\n{'─'*50}")
74
- print(f" {'Type':<12} {'Train':>7} {'Test':>7} Split")
75
- print(f" {'─'*12} {'─'*7} {'─'*7} {'─'*8}")
76
- for t, (fn, seen_flag) in DATASETS.items():
77
- label = 'SEEN' if seen_flag else 'OOD ✗'
78
- print(f" {t:<12} {tr.get(t,0):>7} {te.get(t,0):>7} {label}")
79
- print(f"\n Train total: {len(train)} Test total: {len(test)}")
80
- print(f" Saved → {out}/train.json {out}/test.json\n")
 
1
  """
2
  data_gen.py
3
+ N-Dimensional Vector Data for the Triangulated Mesh.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  """
5
+ import numpy as np
6
+ import json, pathlib, random, argparse
7
 
8
+ DIM = 8 # N dimensions = N nodes at A, B, and C
9
+ SAMPLES_PER_TYPE = 1000
 
10
 
11
+ def generate(n_per=SAMPLES_PER_TYPE, dim=DIM, seed=42):
 
 
 
 
 
 
 
 
12
  rng = np.random.default_rng(seed)
13
  data = []
14
+
15
+ # We will train the mesh to physically wire three different logic gates:
16
+ for _ in range(n_per):
17
+ a = rng.uniform(0.1, 0.9, dim)
18
+ b = rng.uniform(0.1, 0.9, dim)
19
+
20
+ # 1. Direct blending (Straight down)
21
+ c_blend = 0.7 * a + 0.3 * b
22
+ data.append({'a': round_list(a), 'b': round_list(b), 'c': round_list(c_blend), 'type': 'blend'})
23
+
24
+ # 2. Subtraction logic
25
+ c_diff = 0.5 + 0.4 * (a - b)
26
+ data.append({'a': round_list(a), 'b': round_list(b), 'c': round_list(c_diff), 'type': 'diff'})
27
+
28
+ # 3. Lateral Routing (A rolls right by 1, B rolls left by 1)
29
+ # This forces the mesh to use its diagonal triangulated springs!
30
+ c_route = 0.5 * np.roll(a, 1) + 0.5 * np.roll(b, -1)
31
+ data.append({'a': round_list(a), 'b': round_list(b), 'c': round_list(c_route), 'type': 'route'})
32
+
33
  random.shuffle(data)
34
  return data
35
 
36
+ def round_list(arr):
37
+ return [round(float(x), 4) for x in arr]
38
+
39
  if __name__ == '__main__':
40
  parser = argparse.ArgumentParser()
41
+ parser.add_argument('--dim', type=int, default=DIM)
42
+ parser.add_argument('--n', type=int, default=SAMPLES_PER_TYPE)
43
  args = parser.parse_args()
44
 
45
+ data = generate(args.n, args.dim)
46
+
47
+ split = int(len(data) * 0.9)
48
+ train, test = data[:split], data[split:]
49
+
50
+ out = pathlib.Path('data')
 
 
 
 
 
 
 
51
  out.mkdir(exist_ok=True)
52
  with open(out/'train.json','w') as f: json.dump(train, f)
53
  with open(out/'test.json', 'w') as f: json.dump(test, f)
54
+ print(f"Generated {len(data)} samples (Dim={args.dim}). Saved to data/train.json and data/test.json")